# Employee Asset Maintenance Frontend Implementation Plan > **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. **Goal:** Extend the employee maintenance page so users can maintain employee assets inside the add/edit dialog, view all assets in the detail dialog, and import asset data with a dedicated failure-record entry. **Architecture:** Keep the existing employee page and API module in place, and add a nested asset-table editing experience within `ccdiBaseStaff/index.vue`. Reuse the existing async import interaction model, but isolate all asset-import state, storage keys, dialogs, and button copy from the original employee-import flow. **Tech Stack:** Vue 2, Element UI 2, RuoYi request wrapper, scoped SFC styles, Node-based source assertions or existing frontend unit checks --- ### Task 1: Extend the frontend API layer for asset import **Files:** - Modify: `ruoyi-ui/src/api/ccdiBaseStaff.js` - Create: `ruoyi-ui/src/api/ccdiAssetInfo.js` - Test: `ruoyi-ui/tests/unit/employee-asset-api-contract.test.js` **Step 1: Write the failing test** Add a focused source-based test that asserts: - employee detail save payload can include `assetInfoList` - a dedicated asset import API module exists - asset import API exposes template, upload, status, and failure methods **Step 2: Run test to verify it fails** Run: ```bash node ruoyi-ui/tests/unit/employee-asset-api-contract.test.js ``` Expected: FAIL because the asset API module does not exist yet. **Step 3: Implement the minimal API surface** Create `ccdiAssetInfo.js` with: - `importAssetTemplate` - `importAssetData` - `getAssetImportStatus` - `getAssetImportFailures` Keep `ccdiBaseStaff.js` for employee CRUD. **Step 4: Run the test again** Run: ```bash node ruoyi-ui/tests/unit/employee-asset-api-contract.test.js ``` Expected: PASS ### Task 2: Add a regression test for the new employee asset UI structure **Files:** - Create: `ruoyi-ui/tests/unit/employee-asset-maintenance-layout.test.js` - Modify: `ruoyi-ui/src/views/ccdiBaseStaff/index.vue` **Step 1: Write the failing test** Assert the employee page contains: - an “导入资产信息” trigger - a “查看员工资产导入失败记录” trigger hook - an “资产信息” section inside the add/edit dialog - an add-asset action - a detail-table section for assets **Step 2: Run test to verify it fails** Run: ```bash node ruoyi-ui/tests/unit/employee-asset-maintenance-layout.test.js ``` Expected: FAIL because the current page lacks all asset-maintenance UI. ### Task 3: Add the editable asset section to the employee dialog **Files:** - Modify: `ruoyi-ui/src/views/ccdiBaseStaff/index.vue` - Test: `ruoyi-ui/tests/unit/employee-asset-maintenance-layout.test.js` **Step 1: Add asset form state** Extend `form` defaults with `assetInfoList: []`. **Step 2: Add UI helpers** Add methods for: - create an empty asset row - add one asset row - remove one asset row - normalize empty asset rows before submit **Step 3: Add the asset editing table** Render a section below basic employee info with columns for: - `assetMainType` - `assetSubType` - `assetName` - `ownershipRatio` - `purchaseEvalDate` - `originalValue` - `currentValue` - `valuationDate` - `assetStatus` - `remarks` - row delete action **Step 4: Run the layout test** Run: ```bash node ruoyi-ui/tests/unit/employee-asset-maintenance-layout.test.js ``` Expected: PASS ### Task 4: Add detail dialog asset display **Files:** - Modify: `ruoyi-ui/src/views/ccdiBaseStaff/index.vue` - Test: `ruoyi-ui/tests/unit/employee-asset-maintenance-layout.test.js` **Step 1: Add an asset table section to the detail dialog** Render employee assets below the existing basic info card. **Step 2: Add an empty state** If `employeeDetail.assetInfoList` is empty, show “暂无资产信息”. **Step 3: Keep existing employee detail fields intact** Do not regress name, staff ID, department, ID card, phone, hire date, or status display. ### Task 5: Wire add/edit/detail requests to aggregate employee data **Files:** - Modify: `ruoyi-ui/src/views/ccdiBaseStaff/index.vue` - Test: `ruoyi-ui/tests/unit/employee-asset-submit-flow.test.js` **Step 1: Write the failing test** Assert that: - `handleAdd` initializes an empty `assetInfoList` - `handleUpdate` stores returned `assetInfoList` - `submitForm` posts the employee object with `assetInfoList` - empty asset rows are filtered before submit **Step 2: Run test to verify it fails** Run: ```bash node ruoyi-ui/tests/unit/employee-asset-submit-flow.test.js ``` Expected: FAIL because submit logic does not process asset rows yet. **Step 3: Implement minimal submit behavior** Update: - `reset` - `handleAdd` - `handleUpdate` - `handleDetail` - `submitForm` so they all preserve `assetInfoList`. **Step 4: Run the submit-flow test** Run: ```bash node ruoyi-ui/tests/unit/employee-asset-submit-flow.test.js ``` Expected: PASS ### Task 6: Add dedicated asset import UI state and upload dialog **Files:** - Modify: `ruoyi-ui/src/views/ccdiBaseStaff/index.vue` - Test: `ruoyi-ui/tests/unit/employee-asset-import-ui.test.js` **Step 1: Write the failing test** Verify the page defines dedicated asset-import state: - independent upload dialog object - independent polling timer - independent current task ID - independent failure dialog state - asset-specific localStorage key **Step 2: Run test to verify it fails** Run: ```bash node ruoyi-ui/tests/unit/employee-asset-import-ui.test.js ``` Expected: FAIL because only employee import state exists today. **Step 3: Implement the asset import dialog** Add: - “导入资产信息” button - asset upload dialog with template download - asset-specific upload methods - independent polling and completion handlers **Step 4: Distinguish failure record copy** Ensure the failure entry text is exactly `查看员工资产导入失败记录`. **Step 5: Run the import UI test** Run: ```bash node ruoyi-ui/tests/unit/employee-asset-import-ui.test.js ``` Expected: PASS ### Task 7: Add the asset failure record dialog and isolate storage **Files:** - Modify: `ruoyi-ui/src/views/ccdiBaseStaff/index.vue` - Test: `ruoyi-ui/tests/unit/employee-asset-import-ui.test.js` **Step 1: Add an asset failure dialog** The dialog title must be `员工资产导入失败记录`. **Step 2: Add asset failure columns** Show: - `personId` - `assetMainType` - `assetSubType` - `assetName` - `errorMessage` **Step 3: Use a dedicated localStorage key** Keep employee import history under `employee_import_last_task` and store asset import history under a new asset-specific key. **Step 4: Keep the original employee import flow unchanged** Do not rename or regress the existing employee import controls and methods unless needed for clear separation. ### Task 8: Refine styles for the embedded asset table **Files:** - Modify: `ruoyi-ui/src/views/ccdiBaseStaff/index.vue` - Test: `ruoyi-ui/tests/unit/employee-asset-maintenance-layout.test.js` **Step 1: Add focused scoped styles** Style: - asset section header row - editable asset table - empty asset state - detail asset block **Step 2: Preserve the existing employee dialog layout** Ensure basic info layout remains readable on desktop and mobile widths. ### Task 9: Verify the frontend changes end to end **Files:** - Modify: `ruoyi-ui/src/views/ccdiBaseStaff/index.vue` - Modify: `ruoyi-ui/src/api/ccdiAssetInfo.js` - Modify: `ruoyi-ui/src/api/ccdiBaseStaff.js` **Step 1: Run focused frontend tests** Run: ```bash node ruoyi-ui/tests/unit/employee-asset-api-contract.test.js node ruoyi-ui/tests/unit/employee-asset-maintenance-layout.test.js node ruoyi-ui/tests/unit/employee-asset-submit-flow.test.js node ruoyi-ui/tests/unit/employee-asset-import-ui.test.js ``` Expected: all focused tests pass. **Step 2: Run production build verification** Run: ```bash npm run build:prod ``` Workdir: `ruoyi-ui` Expected: build succeeds without Vue template or script errors. **Step 3: Commit** ```bash git add ruoyi-ui/src/api/ccdiAssetInfo.js ruoyi-ui/src/api/ccdiBaseStaff.js ruoyi-ui/src/views/ccdiBaseStaff/index.vue ruoyi-ui/tests/unit docs/plans/2026-03-12-employee-asset-maintenance-frontend-implementation.md git commit -m "新增员工资产信息前端实施计划" ```