From 4e696eff1e0246fcd452041cd005e18f0ee7ef5e Mon Sep 17 00:00:00 2001 From: wkc <978997012@qq.com> Date: Thu, 12 Mar 2026 10:46:40 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=8B=89=E5=8F=96=E6=9C=AC?= =?UTF-8?q?=E8=A1=8C=E4=BF=A1=E6=81=AF=E5=BC=B9=E7=AA=97=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=E4=BA=A4=E4=BA=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...-button-hit-area-backend-implementation.md | 40 +++++ ...button-hit-area-frontend-implementation.md | 113 ++++++++++++ .../components/detail/UploadData.vue | 163 +++++++++++++++--- ...-data-pull-bank-info-dialog-layout.test.js | 39 +++++ 4 files changed, 332 insertions(+), 23 deletions(-) create mode 100644 docs/plans/2026-03-12-pull-bank-info-upload-button-hit-area-backend-implementation.md create mode 100644 docs/plans/2026-03-12-pull-bank-info-upload-button-hit-area-frontend-implementation.md create mode 100644 ruoyi-ui/tests/unit/upload-data-pull-bank-info-dialog-layout.test.js diff --git a/docs/plans/2026-03-12-pull-bank-info-upload-button-hit-area-backend-implementation.md b/docs/plans/2026-03-12-pull-bank-info-upload-button-hit-area-backend-implementation.md new file mode 100644 index 0000000..67b34da --- /dev/null +++ b/docs/plans/2026-03-12-pull-bank-info-upload-button-hit-area-backend-implementation.md @@ -0,0 +1,40 @@ +# Pull Bank Info Upload Button Hit Area Backend Implementation Plan + +> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** Confirm this UI optimization does not require backend changes and document the verification boundary. + +**Architecture:** The issue is caused by the frontend dialog structure and scoped styles in the upload page. Backend APIs, request payloads, and parsing logic remain unchanged, so this plan only records the no-op backend conclusion and the checks needed to avoid accidental interface regressions. + +**Tech Stack:** Java 21, Spring Boot 3, Maven, existing `ccdi-project` upload APIs + +--- + +### Task 1: Verify backend impact is zero + +**Files:** +- Review: `docs/plans/2026-03-12-pull-bank-info-upload-button-hit-area-design.md` +- Review: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/controller/` +- Review: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/` + +**Step 1: Confirm the bug scope** + +Check that the reported problem is limited to the frontend dialog button hit area and layout, not request construction or backend response handling. + +**Step 2: Verify no API contract changes are needed** + +Review the existing pull-bank-info request fields and confirm the dialog still submits the same `projectId`, `idCards`, `startDate`, and `endDate`. + +**Step 3: Keep backend code unchanged** + +Do not modify controller, service, mapper, or DTO classes for this task. + +**Step 4: Run targeted regression verification if frontend payload changes are suspected** + +Run only if implementation unexpectedly touches request assembly: + +```bash +mvn test -Dtest=CcdiFileUploadServiceImplTest +``` + +Expected: related backend tests pass and no interface behavior changes are introduced. diff --git a/docs/plans/2026-03-12-pull-bank-info-upload-button-hit-area-frontend-implementation.md b/docs/plans/2026-03-12-pull-bank-info-upload-button-hit-area-frontend-implementation.md new file mode 100644 index 0000000..46f2ce0 --- /dev/null +++ b/docs/plans/2026-03-12-pull-bank-info-upload-button-hit-area-frontend-implementation.md @@ -0,0 +1,113 @@ +# Pull Bank Info Upload Button Hit Area Frontend Implementation Plan + +> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** Make the pull-bank-info dialog file selector hit area match the visible trigger and improve the field layout without changing upload behavior. + +**Architecture:** Keep the existing `el-upload` parsing flow and API calls, but replace the current loose inline upload layout with a dedicated upload panel inside the dialog. Add a focused unit test that asserts the new dialog structure and class hooks, then update scoped styles so the button-style uploader no longer inherits the full-width drag-upload hit area behavior. + +**Tech Stack:** Vue 2, Element UI 2, scoped SCSS, Node-based source assertions in `ruoyi-ui/tests/unit` + +--- + +### Task 1: Add a regression test for the dialog structure + +**Files:** +- Create: `ruoyi-ui/tests/unit/upload-data-pull-bank-info-dialog-layout.test.js` +- Modify: `ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue` + +**Step 1: Write the failing test** + +Add a source-based unit test that checks all of the following in the pull-bank-info dialog: + +- the dialog contains a dedicated `pull-bank-info-form` container +- the file import area uses a `pull-bank-file-panel` +- the upload trigger uses a `pull-bank-file-upload` +- the template includes a visible selected-file summary block + +**Step 2: Run test to verify it fails** + +Run: + +```bash +node ruoyi-ui/tests/unit/upload-data-pull-bank-info-dialog-layout.test.js +``` + +Expected: FAIL because the current dialog does not contain the new structure/classes. + +### Task 2: Restructure the dialog template with minimal logic changes + +**Files:** +- Modify: `ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue` +- Test: `ruoyi-ui/tests/unit/upload-data-pull-bank-info-dialog-layout.test.js` + +**Step 1: Update the dialog markup** + +Keep the existing fields and event handlers, but: + +- wrap the dialog form with `pull-bank-info-form` +- split the dialog into clearer sections +- move the upload button and helper text into `pull-bank-file-panel` +- add a selected-file summary row bound to `idCardFileList` +- keep `handleIdCardFileChange`, `handleIdCardFileRemove`, and `parsingIdCardFile` intact + +**Step 2: Run the new test** + +Run: + +```bash +node ruoyi-ui/tests/unit/upload-data-pull-bank-info-dialog-layout.test.js +``` + +Expected: PASS + +### Task 3: Adjust scoped styles so hit area and layout align + +**Files:** +- Modify: `ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue` +- Test: `ruoyi-ui/tests/unit/upload-data-pull-bank-info-dialog-layout.test.js` + +**Step 1: Add focused dialog styles** + +Add SCSS for: + +- `pull-bank-info-form` +- `pull-bank-file-panel` +- `pull-bank-file-upload` +- `selected-id-card-file` +- `pull-bank-range-picker` + +Use these styles to make the trigger area content-sized instead of full-row clickable, and improve spacing/alignment for desktop and mobile. + +**Step 2: Keep drag-upload dialogs unchanged** + +Retain the existing full-width dragger behavior for `upload-area` and `batch-upload-area`. + +**Step 3: Run regression tests** + +Run: + +```bash +node ruoyi-ui/tests/unit/upload-data-pull-bank-info-dialog-layout.test.js +node ruoyi-ui/tests/unit/upload-data-batch-upload.test.js +node ruoyi-ui/tests/unit/upload-data-file-list-settings.test.js +``` + +Expected: all tests pass. + +### Task 4: Run final verification + +**Files:** +- Modify: `ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue` + +**Step 1: Run production build verification** + +Run: + +```bash +npm run build:prod +``` + +Workdir: `ruoyi-ui` + +Expected: build succeeds without introducing Vue template or style compilation errors. diff --git a/ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue b/ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue index 89602f8..a703a0d 100644 --- a/ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue +++ b/ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue @@ -210,7 +210,11 @@ :close-on-click-modal="false" width="640px" > - + +
+ 支持逗号、中文逗号、换行分隔,文件解析结果会自动合并并去重 +
- - 选择文件 -
- 支持 .xls、.xlsx 文件 +
+
+ + + 选择文件 + + +
+ 支持 .xls、.xlsx 文件,解析后自动补充证件号码 +
+
+
+
+ + + {{ idCardFileList[0].name }} + +
+ + 移除 + +
+
+ 正在解析身份证文件...
- -
- 正在解析身份证文件...
@@ -1442,17 +1468,20 @@ export default { // 上传弹窗样式 ::v-deep .el-dialog__wrapper { - .upload-area { + .upload-area, + .batch-upload-area { width: 100%; } - .el-upload { + .upload-area .el-upload, + .batch-upload-area .el-upload { width: 100%; + } - .el-upload-dragger { - width: 100%; - height: 200px; - } + .upload-area .el-upload-dragger, + .batch-upload-area .el-upload-dragger { + width: 100%; + height: 200px; } .el-upload__tip { @@ -1462,6 +1491,76 @@ export default { } } +.pull-bank-info-form { + .pull-bank-field-tip { + margin-top: 8px; + font-size: 12px; + color: #909399; + line-height: 1.5; + } +} + +.pull-bank-file-panel { + padding: 16px; + border: 1px solid #e4e7ed; + border-radius: 8px; + background: #fafcff; + + .pull-bank-file-actions { + display: flex; + align-items: center; + gap: 12px; + flex-wrap: wrap; + } + + .pull-bank-file-tip { + font-size: 12px; + color: #606266; + line-height: 1.5; + } +} + +.pull-bank-file-upload { + display: inline-flex; + flex: 0 0 auto; +} + +.selected-id-card-file { + margin-top: 12px; + padding: 10px 12px; + border-radius: 6px; + background: #ffffff; + border: 1px solid #ebeef5; + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + + .selected-id-card-file__info { + min-width: 0; + display: flex; + align-items: center; + gap: 8px; + color: #303133; + } + + .selected-id-card-file__name { + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .el-button { + flex-shrink: 0; + padding: 0; + } +} + +.pull-bank-range-picker { + width: 100%; +} + // 批量上传弹窗样式 .batch-upload-area { width: 100%; @@ -1586,5 +1685,23 @@ export default { align-items: flex-start; gap: 12px; } + + .pull-bank-file-panel { + padding: 12px; + + .pull-bank-file-actions { + align-items: stretch; + gap: 10px; + } + } + + .pull-bank-file-upload { + width: 100%; + } + + .selected-id-card-file { + align-items: flex-start; + flex-direction: column; + } } diff --git a/ruoyi-ui/tests/unit/upload-data-pull-bank-info-dialog-layout.test.js b/ruoyi-ui/tests/unit/upload-data-pull-bank-info-dialog-layout.test.js new file mode 100644 index 0000000..2c755e2 --- /dev/null +++ b/ruoyi-ui/tests/unit/upload-data-pull-bank-info-dialog-layout.test.js @@ -0,0 +1,39 @@ +const assert = require("assert"); +const fs = require("fs"); +const path = require("path"); + +const componentPath = path.resolve( + __dirname, + "../../src/views/ccdiProject/components/detail/UploadData.vue" +); +const source = fs.readFileSync(componentPath, "utf8"); + +const dialogIndex = source.indexOf('title="拉取本行信息"'); +assert.notStrictEqual(dialogIndex, -1, "未找到拉取本行信息弹窗"); + +const dialogEndIndex = source.indexOf("", dialogIndex); +assert.notStrictEqual(dialogEndIndex, -1, "未找到拉取本行信息弹窗结束标签"); + +const dialogSource = source.slice(dialogIndex, dialogEndIndex); + +assert( + /class="pull-bank-info-form"/.test(dialogSource), + "拉取本行信息弹窗应使用独立表单容器,便于控制排版" +); + +assert( + /class="pull-bank-file-panel"/.test(dialogSource), + "拉取本行信息弹窗应提供独立的文件导入面板" +); + +assert( + /class="pull-bank-file-upload"/.test(dialogSource), + "文件选择区域应有独立样式钩子,避免点击范围铺满整行" +); + +assert( + /class="selected-id-card-file"/.test(dialogSource), + "选择文件后应显示已选文件摘要区域" +); + +console.log("upload-data-pull-bank-info-dialog-layout test passed");