# 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 ``` - [ ] **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导入前端改造" ```