Files
ccdi/docs/plans/frontend/2026-04-23-staff-recruitment-dual-sheet-import-frontend-implementation.md

265 lines
8.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Staff Recruitment Dual-Sheet Import Frontend Implementation Plan
> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 将招聘信息管理前端导入交互改为单入口双 Sheet 模式,统一任务轮询与失败弹窗,并在失败列表中展示失败 Sheet、失败行号、失败原因。
**Architecture:** 前端只保留一个导入按钮和一个上传弹窗,统一使用 `/ccdi/staffRecruitment/importTemplate``/importData`。页面本地状态从“按导入类型区分任务”收口为“按唯一任务 ID 轮询”,失败记录统一通过一个弹窗展示,并用 `sheetName``sheetRowNum` 区分失败来源。
**Tech Stack:** Vue 2, Element UI, axios request wrapper, Node 14.21.3 via nvm, source-inspection unit tests, Playwright browser validation
---
## File Map
- Modify: `ruoyi-ui/src/views/ccdiStaffRecruitment/index.vue`
- 删除独立“导入工作经历”入口,收口上传弹窗、轮询状态和失败列表
- Modify: `ruoyi-ui/src/api/ccdiStaffRecruitment.js`
- 去掉独立工作经历导入模板/上传调用,保留统一导入 API
- Create: `ruoyi-ui/tests/unit/staff-recruitment-import-toolbar.test.js`
- 锁定顶部工具栏已收口为单入口
- Create: `ruoyi-ui/tests/unit/staff-recruitment-import-state.test.js`
- 锁定统一任务状态与轮询逻辑
- Create: `ruoyi-ui/tests/unit/staff-recruitment-import-failure-dialog.test.js`
- 锁定失败弹窗列定义与 `sheetRowNum` 展示格式
- Modify: `docs/reports/implementation/2026-04-23-staff-recruitment-dual-sheet-import-implementation.md`
- 追加前端改造与真实页面验证结果
### Task 1: 收口工具栏与上传 API
**Files:**
- Create: `ruoyi-ui/tests/unit/staff-recruitment-import-toolbar.test.js`
- Modify: `ruoyi-ui/src/views/ccdiStaffRecruitment/index.vue`
- Modify: `ruoyi-ui/src/api/ccdiStaffRecruitment.js`
- [ ] **Step 1: 先写工具栏与 API 契约失败测试**
```js
[
"handleImport()",
'"/ccdi/staffRecruitment/importData"',
"招聘信息管理导入模板"
].forEach((token) => {
assert(source.includes(token), `招聘导入入口缺少统一双Sheet能力: ${token}`)
})
[
"handleWorkImport",
"importWorkData",
"workImportTemplate"
].forEach((token) => {
assert(!source.includes(token), `招聘页不应继续保留独立工作经历导入: ${token}`)
})
```
- [ ] **Step 2: 运行测试确认失败**
Run: `node ruoyi-ui/tests/unit/staff-recruitment-import-toolbar.test.js`
Expected: FAIL提示页面仍保留“导入工作经历”按钮或 API 仍存在旧入口
- [ ] **Step 3: 最小化修改页面与 API**
```js
export function importTemplate() {
return request({
url: "/ccdi/staffRecruitment/importTemplate",
method: "post"
})
}
```
- [ ] **Step 4: 重跑测试**
Run: `node ruoyi-ui/tests/unit/staff-recruitment-import-toolbar.test.js`
Expected: PASS页面只剩一个导入入口API 只调用统一模板与上传接口
- [ ] **Step 5: 提交这一小步**
```bash
git add \
ruoyi-ui/src/views/ccdiStaffRecruitment/index.vue \
ruoyi-ui/src/api/ccdiStaffRecruitment.js \
ruoyi-ui/tests/unit/staff-recruitment-import-toolbar.test.js
git commit -m "收口招聘双Sheet导入前端入口"
```
### Task 2: 收口上传弹窗文案与统一任务状态
**Files:**
- Create: `ruoyi-ui/tests/unit/staff-recruitment-import-state.test.js`
- Modify: `ruoyi-ui/src/views/ccdiStaffRecruitment/index.vue`
- [ ] **Step 1: 先写统一状态失败测试**
```js
[
"模板包含“招聘信息”和“历史工作经历”两个 Sheet。",
"this.currentTaskId = taskId",
"this.showFailureButton = false",
"this.startImportStatusPolling(taskId)"
].forEach((token) => {
assert(source.includes(token), `招聘导入状态未统一到单任务: ${token}`)
})
[
"currentImportType",
"upload.importType",
"getImportTypeLabel"
].forEach((token) => {
assert(!source.includes(token), `招聘导入状态不应再按类型拆分: ${token}`)
})
```
- [ ] **Step 2: 运行测试确认失败**
Run: `node ruoyi-ui/tests/unit/staff-recruitment-import-state.test.js`
Expected: FAIL提示页面仍保留类型切换状态
- [ ] **Step 3: 最小化实现统一轮询状态**
```js
this.saveImportTaskToStorage({
taskId,
status: "PROCESSING",
hasFailures: false
})
this.currentTaskId = taskId
this.startImportStatusPolling(taskId)
```
- [ ] **Step 4: 重跑测试**
Run: `node ruoyi-ui/tests/unit/staff-recruitment-import-state.test.js`
Expected: PASS弹窗文案改为双 Sheet页面状态只围绕一个任务 ID 轮询
- [ ] **Step 5: 提交这一小步**
```bash
git add \
ruoyi-ui/src/views/ccdiStaffRecruitment/index.vue \
ruoyi-ui/tests/unit/staff-recruitment-import-state.test.js
git commit -m "统一招聘双Sheet导入轮询状态"
```
### Task 3: 调整统一失败弹窗列定义
**Files:**
- Create: `ruoyi-ui/tests/unit/staff-recruitment-import-failure-dialog.test.js`
- Modify: `ruoyi-ui/src/views/ccdiStaffRecruitment/index.vue`
- [ ] **Step 1: 先写失败弹窗失败测试**
```js
[
'label="失败Sheet"',
'label="失败行号"',
"scope.row.sheetName",
"scope.row.sheetRowNum",
"失败原因"
].forEach((token) => {
assert(source.includes(token), `招聘失败弹窗缺少双Sheet定位列: ${token}`)
})
```
- [ ] **Step 2: 运行测试确认失败**
Run: `node ruoyi-ui/tests/unit/staff-recruitment-import-failure-dialog.test.js`
Expected: FAIL提示弹窗仍按旧类型列展示
- [ ] **Step 3: 实现统一失败表格**
```vue
<el-table-column label="失败Sheet" prop="sheetName" align="center" width="140" />
<el-table-column label="失败行号" prop="sheetRowNum" align="center" width="120">
<template slot-scope="scope">
<span>{{ scope.row.sheetRowNum ? `${scope.row.sheetRowNum}` : "-" }}</span>
</template>
</el-table-column>
```
- [ ] **Step 4: 重跑测试**
Run: `node ruoyi-ui/tests/unit/staff-recruitment-import-failure-dialog.test.js`
Expected: PASS失败弹窗明确展示失败 Sheet、失败行号、失败原因
- [ ] **Step 5: 提交这一小步**
```bash
git add \
ruoyi-ui/src/views/ccdiStaffRecruitment/index.vue \
ruoyi-ui/tests/unit/staff-recruitment-import-failure-dialog.test.js
git commit -m "完善招聘双Sheet失败弹窗展示"
```
### Task 4: 做前端构建、真实页面验证与实施记录
**Files:**
- Modify: `ruoyi-ui/src/views/ccdiStaffRecruitment/index.vue`
- Modify: `ruoyi-ui/src/api/ccdiStaffRecruitment.js`
- Modify: `docs/reports/implementation/2026-04-23-staff-recruitment-dual-sheet-import-implementation.md`
- [ ] **Step 1: 切换 Node 版本并执行前端静态回归**
Run: `source ~/.nvm/nvm.sh && nvm use 14.21.3 >/dev/null && node ruoyi-ui/tests/unit/staff-recruitment-import-toolbar.test.js && node ruoyi-ui/tests/unit/staff-recruitment-import-state.test.js && node ruoyi-ui/tests/unit/staff-recruitment-import-failure-dialog.test.js`
Expected: PASS三个静态契约测试全部通过
- [ ] **Step 2: 执行前端构建**
Run: `source ~/.nvm/nvm.sh && nvm use 14.21.3 >/dev/null && cd ruoyi-ui && npm run build:prod`
Expected: BUILD SUCCESS
- [ ] **Step 3: 启动真实页面并做浏览器验证**
Run:
```bash
source ~/.nvm/nvm.sh && nvm use 14.21.3 >/dev/null
cd ruoyi-ui
npm run dev -- --port 8080
```
Expected: 前端开发服务启动成功,真实页面 `http://localhost:8080` 可访问
Playwright 验证最少覆盖:
- 进入真实 `招聘信息管理` 页面,不使用 prototype 页面
- 从页面下载双 Sheet 模板
- 只导 `招聘信息` Sheet
- 只导 `历史工作经历` Sheet
- 双 Sheet 同时导入
- 已存在工作经历时报错
- 失败弹窗显示 `失败Sheet / 失败行号 / 失败原因`
- [ ] **Step 4: 补前端实施记录**
```md
- 页面导入入口收口为一个按钮
- 上传弹窗提示调整为双 Sheet 文案
- 页面状态收口为单任务轮询
- 失败弹窗新增失败 Sheet、失败行号、失败原因
- 已完成真实页面 Playwright 验证
```
- [ ] **Step 5: 关闭测试进程并提交前端收尾**
Run: 关闭本轮 `npm run dev` 与后端联调用到的进程,确保无残留端口占用
```bash
git add \
ruoyi-ui/src/views/ccdiStaffRecruitment/index.vue \
ruoyi-ui/src/api/ccdiStaffRecruitment.js \
ruoyi-ui/tests/unit/staff-recruitment-import-toolbar.test.js \
ruoyi-ui/tests/unit/staff-recruitment-import-state.test.js \
ruoyi-ui/tests/unit/staff-recruitment-import-failure-dialog.test.js \
docs/reports/implementation/2026-04-23-staff-recruitment-dual-sheet-import-implementation.md
git commit -m "完成招聘双Sheet导入前端改造"
```