From 47eed3e63c672a68e1231992934be9616186df1f Mon Sep 17 00:00:00 2001
From: wkc <978997012@qq.com>
Date: Tue, 24 Mar 2026 13:59:36 +0800
Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=E5=BE=81=E4=BF=A1=E5=AF=BC?=
=?UTF-8?q?=E5=85=A5=E5=85=A5=E5=8F=A3=E8=B7=B3=E8=BD=AC=E5=88=B0=E5=BE=81?=
=?UTF-8?q?=E4=BF=A1=E7=BB=B4=E6=8A=A4=E9=A1=B5=E9=9D=A2?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
...project-upload-credit-entry-jump-design.md | 4 +-
...redit-entry-jump-backend-implementation.md | 90 ++++++++
...edit-entry-jump-frontend-implementation.md | 218 ++++++++++++++++++
...upload-credit-entry-jump-backend-record.md | 17 ++
...pload-credit-entry-jump-frontend-record.md | 18 ++
.../components/detail/UploadData.vue | 131 +----------
.../project-upload-credit-entry-jump.test.js | 26 +++
7 files changed, 374 insertions(+), 130 deletions(-)
create mode 100644 docs/plans/backend/2026-03-24-project-upload-credit-entry-jump-backend-implementation.md
create mode 100644 docs/plans/frontend/2026-03-24-project-upload-credit-entry-jump-frontend-implementation.md
create mode 100644 docs/reports/implementation/2026-03-24-project-upload-credit-entry-jump-backend-record.md
create mode 100644 docs/reports/implementation/2026-03-24-project-upload-credit-entry-jump-frontend-record.md
create mode 100644 ruoyi-ui/tests/unit/project-upload-credit-entry-jump.test.js
diff --git a/docs/design/2026-03-24-project-upload-credit-entry-jump-design.md b/docs/design/2026-03-24-project-upload-credit-entry-jump-design.md
index 200f02d6..e8ee895c 100644
--- a/docs/design/2026-03-24-project-upload-credit-entry-jump-design.md
+++ b/docs/design/2026-03-24-project-upload-credit-entry-jump-design.md
@@ -32,7 +32,7 @@
## 最终方案
采用方案一。
-将项目详情页 [`UploadData.vue`](/Users/wkc/Desktop/ccdi/ccdi/ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue) 中“征信导入”按钮的点击行为,从“打开征信上传弹窗”调整为直接执行前端路由跳转,目标页面为“信息维护-征信维护”对应的 `"/creditInfo"`。
+将项目详情页 [`UploadData.vue`](/Users/wkc/Desktop/ccdi/ccdi/ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue) 中“征信导入”按钮的点击行为,从“打开征信上传弹窗”调整为直接执行前端路由跳转,目标页面为“信息维护-征信维护”对应的 `"/maintain/creditInfo"`。
原按钮专属的本地弹窗入口不再作为用户操作路径保留。本次只处理入口行为,不调整征信维护页 [`index.vue`](/Users/wkc/Desktop/ccdi/ccdi/ruoyi-ui/src/views/ccdiCreditInfo/index.vue) 的既有交互与接口调用。
@@ -44,7 +44,7 @@
## 数据流与交互
1. 用户在项目详情页进入“上传数据”
2. 点击“征信导入”按钮
-3. 前端执行 `this.$router.push('/creditInfo')`
+3. 前端执行 `this.$router.push('/maintain/creditInfo')`
4. 系统进入“信息维护-征信维护”页面
## 异常处理
diff --git a/docs/plans/backend/2026-03-24-project-upload-credit-entry-jump-backend-implementation.md b/docs/plans/backend/2026-03-24-project-upload-credit-entry-jump-backend-implementation.md
new file mode 100644
index 00000000..aecf6130
--- /dev/null
+++ b/docs/plans/backend/2026-03-24-project-upload-credit-entry-jump-backend-implementation.md
@@ -0,0 +1,90 @@
+# Project Upload Credit Entry Jump Backend 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:** 对“上传数据”页征信导入入口改为页面跳转的需求完成后端影响面确认,明确本次无后端代码改动、无接口改动、无数据库改动。
+
+**Architecture:** 该需求仅发生在前端入口层,征信维护页面与 `ccdi/creditInfo/*` 接口链路已存在且继续复用。本计划只保留后端影响面检查和实施记录,避免误改后端逻辑。
+
+**Tech Stack:** Spring Boot 3, Java 21, SQL 脚本检视, 文档记录
+
+---
+
+## 文件结构与职责
+
+**修改文件**
+
+- `docs/reports/implementation/2026-03-24-project-upload-credit-entry-jump-backend-record.md`
+ 记录本次后端影响评估结果,明确无代码改动。
+
+**参考文件**
+
+- `docs/design/2026-03-24-project-upload-credit-entry-jump-design.md`
+- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiCreditInfoController.java`
+- `sql/ccdi_credit_info_menu.sql`
+
+## Task 1: 确认后端无改动需求
+
+**Files:**
+- Review: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiCreditInfoController.java`
+- Review: `sql/ccdi_credit_info_menu.sql`
+
+- [ ] **Step 1: 检查征信维护入口已有后端能力**
+
+Run:
+
+```bash
+rg -n "/ccdi/creditInfo|征信维护|ccdi:creditInfo" ccdi-info-collection/src/main/java sql/ccdi_credit_info_menu.sql
+```
+
+Expected:
+
+- PASS,能看到征信维护接口与菜单配置已存在。
+
+- [ ] **Step 2: 明确本次无需后端改造**
+
+结论需要覆盖:
+
+```text
+1. 按钮跳转发生在前端页面层
+2. 目标页面和其调用接口已经存在
+3. 本次不需要新增 controller、service、mapper、SQL
+```
+
+## Task 2: 补后端实施记录
+
+**Files:**
+- Create: `docs/reports/implementation/2026-03-24-project-upload-credit-entry-jump-backend-record.md`
+
+- [ ] **Step 1: 新增后端实施记录**
+
+记录以下内容:
+
+```markdown
+# 上传数据页征信导入入口跳转后端实施记录
+
+## 结论
+- 本次需求仅调整前端按钮入口
+- 征信维护后端接口与菜单数据已存在
+- 后端代码、SQL、数据库均无需改动
+
+## 检查范围
+- ccdi-info-collection Controller
+- 征信维护菜单 SQL
+
+## 验证
+- rg -n "/ccdi/creditInfo|征信维护|ccdi:creditInfo" ccdi-info-collection/src/main/java sql/ccdi_credit_info_menu.sql
+```
+```
+
+- [ ] **Step 2: 复核本计划执行结果**
+
+Run:
+
+```bash
+git diff -- docs/reports/implementation/2026-03-24-project-upload-credit-entry-jump-backend-record.md
+```
+
+Expected:
+
+- PASS,仅包含后端影响评估记录,无后端源码改动。
diff --git a/docs/plans/frontend/2026-03-24-project-upload-credit-entry-jump-frontend-implementation.md b/docs/plans/frontend/2026-03-24-project-upload-credit-entry-jump-frontend-implementation.md
new file mode 100644
index 00000000..b9a00d19
--- /dev/null
+++ b/docs/plans/frontend/2026-03-24-project-upload-credit-entry-jump-frontend-implementation.md
@@ -0,0 +1,218 @@
+# Project Upload Credit Entry Jump 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:** 将项目详情“上传数据”页的“征信导入”按钮改为直接跳转到“信息维护-征信维护”页面,不再在当前页打开征信上传弹窗。
+
+**Architecture:** 仅调整 `UploadData.vue` 中“征信导入”入口的前端交互,沿用现有动态菜单路由 `/maintain/creditInfo` 作为跳转目标。保持征信维护页面和后端接口完全不变,避免双入口并减少交互分叉。
+
+**Tech Stack:** Vue 2, Vue Router, Element UI, Node.js 源码契约测试
+
+---
+
+## 文件结构与职责
+
+**修改文件**
+
+- `ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue`
+ 将“征信导入”按钮点击行为从打开弹窗改为路由跳转,并清理不再使用的本地征信上传入口逻辑。
+- `docs/reports/implementation/2026-03-24-project-upload-credit-entry-jump-frontend-record.md`
+ 记录本次前端实施内容、验证命令与结果。
+
+**新增测试文件**
+
+- `ruoyi-ui/tests/unit/project-upload-credit-entry-jump.test.js`
+ 锁定“征信导入”按钮使用路由跳转且不再依赖本地上传弹窗入口。
+
+**参考文件**
+
+- `docs/design/2026-03-24-project-upload-credit-entry-jump-design.md`
+- `ruoyi-ui/src/views/ccdiCreditInfo/index.vue`
+- `sql/ccdi_credit_info_menu.sql`
+
+## Task 1: 先锁定入口跳转契约
+
+**Files:**
+- Create: `ruoyi-ui/tests/unit/project-upload-credit-entry-jump.test.js`
+- Test: `ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue`
+
+- [ ] **Step 1: 编写失败契约测试**
+
+在 `ruoyi-ui/tests/unit/project-upload-credit-entry-jump.test.js` 中读取 `UploadData.vue` 源码,至少断言以下关键点:
+
+```javascript
+const assert = require("assert");
+const fs = require("fs");
+const path = require("path");
+
+const viewPath = path.resolve(
+ __dirname,
+ "../../src/views/ccdiProject/components/detail/UploadData.vue"
+);
+const source = fs.readFileSync(viewPath, "utf8");
+
+assert(source.includes("@click=\"handleOpenCreditUpload\""), "征信导入按钮事件已变化,需先看到旧入口");
+assert(source.includes("showCreditUploadDialog"), "旧征信导入弹窗状态不存在,无法证明改动前行为");
+```
+
+- [ ] **Step 2: 运行测试确认当前为旧行为**
+
+Run:
+
+```bash
+node ruoyi-ui/tests/unit/project-upload-credit-entry-jump.test.js
+```
+
+Expected:
+
+- PASS,证明当前按钮仍绑定旧的弹窗入口。
+
+- [ ] **Step 3: 改写测试为目标行为**
+
+将断言改为目标行为:
+
+```javascript
+[
+ "@click=\"handleGoCreditInfoPage\"",
+ "this.$router.push(\"/maintain/creditInfo\")",
+].forEach((token) => {
+ assert(source.includes(token), `缺少征信入口跳转关键代码: ${token}`);
+});
+
+[
+ "showCreditUploadDialog",
+ "handleConfirmCreditUpload",
+ "handleCreditFileChange",
+].forEach((token) => {
+ assert(!source.includes(token), `旧征信弹窗逻辑未清理: ${token}`);
+});
+```
+
+- [ ] **Step 4: 运行测试确认失败**
+
+Run:
+
+```bash
+node ruoyi-ui/tests/unit/project-upload-credit-entry-jump.test.js
+```
+
+Expected:
+
+- FAIL,因为代码尚未切换到跳页实现。
+
+## Task 2: 实现按钮跳转并清理旧入口
+
+**Files:**
+- Modify: `ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue`
+- Test: `ruoyi-ui/tests/unit/project-upload-credit-entry-jump.test.js`
+
+- [ ] **Step 1: 修改模板点击事件**
+
+把“征信导入”按钮点击事件:
+
+```vue
+@click="handleOpenCreditUpload"
+```
+
+改为:
+
+```vue
+@click="handleGoCreditInfoPage"
+```
+
+- [ ] **Step 2: 删除本地征信导入弹窗模板**
+
+移除 `title="征信导入"` 的 `el-dialog` 以及其中的 `el-upload`、底部按钮,确保该按钮点击后不再出现本地弹窗。
+
+- [ ] **Step 3: 删除无用状态与方法并新增跳转方法**
+
+删除以下无用状态与方法:
+
+```javascript
+showCreditUploadDialog: false,
+creditFileList: [],
+creditUploading: false,
+```
+
+```javascript
+handleOpenCreditUpload() {}
+handleCreditFileChange() {}
+handleConfirmCreditUpload() {}
+pollCreditImportStatus() {}
+```
+
+新增最小跳转实现:
+
+```javascript
+handleGoCreditInfoPage() {
+ if (this.isProjectTagging) {
+ return;
+ }
+ this.$router.push("/maintain/creditInfo");
+}
+```
+
+- [ ] **Step 4: 处理无用 import**
+
+若 `uploadFile`、`getImportStatus` 仅服务于旧征信弹窗逻辑,则从 `UploadData.vue` 顶部 import 中删除,避免残留死代码。
+
+- [ ] **Step 5: 运行契约测试确认通过**
+
+Run:
+
+```bash
+node ruoyi-ui/tests/unit/project-upload-credit-entry-jump.test.js
+```
+
+Expected:
+
+- PASS
+
+- [ ] **Step 6: 手工检视跳转链路**
+
+至少检查:
+
+```bash
+rg -n "handleGoCreditInfoPage|/maintain/creditInfo|征信导入" ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue
+```
+
+Expected:
+
+- PASS,按钮事件与路由目标清晰可见,不再出现旧弹窗控制逻辑。
+
+## Task 3: 补前端实施记录
+
+**Files:**
+- Create: `docs/reports/implementation/2026-03-24-project-upload-credit-entry-jump-frontend-record.md`
+
+- [ ] **Step 1: 新增实施记录文档**
+
+记录以下内容:
+
+```markdown
+# 上传数据页征信导入入口跳转前端实施记录
+
+## 本次改动
+- 将项目详情上传数据页“征信导入”按钮改为直接跳转征信维护页面
+- 删除当前页征信导入弹窗入口逻辑
+
+## 影响文件
+- ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue
+- ruoyi-ui/tests/unit/project-upload-credit-entry-jump.test.js
+
+## 验证
+- node ruoyi-ui/tests/unit/project-upload-credit-entry-jump.test.js
+```
+```
+
+- [ ] **Step 2: 复核暂存区仅包含本次前端相关文件**
+
+Run:
+
+```bash
+git status --short
+```
+
+Expected:
+
+- 仅暂存本次前端计划执行产生的相关文件;若有无关文件已暂存,先移出暂存区。
diff --git a/docs/reports/implementation/2026-03-24-project-upload-credit-entry-jump-backend-record.md b/docs/reports/implementation/2026-03-24-project-upload-credit-entry-jump-backend-record.md
new file mode 100644
index 00000000..ac2e3199
--- /dev/null
+++ b/docs/reports/implementation/2026-03-24-project-upload-credit-entry-jump-backend-record.md
@@ -0,0 +1,17 @@
+# 上传数据页征信导入入口跳转后端实施记录
+
+## 结论
+- 本次需求仅调整前端按钮入口
+- 征信维护后端接口与菜单数据已存在
+- 后端代码、SQL、数据库均无需改动
+
+## 检查范围
+- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiCreditInfoController.java`
+- `sql/ccdi_credit_info_menu.sql`
+
+## 验证
+- `rg -n "/ccdi/creditInfo|征信维护|ccdi:creditInfo" ccdi-info-collection/src/main/java sql/ccdi_credit_info_menu.sql -S`
+
+## 验证结果
+- 已确认征信维护 Controller、权限点与菜单配置均存在
+- 本次无需新增或修改 controller、service、mapper、SQL
diff --git a/docs/reports/implementation/2026-03-24-project-upload-credit-entry-jump-frontend-record.md b/docs/reports/implementation/2026-03-24-project-upload-credit-entry-jump-frontend-record.md
new file mode 100644
index 00000000..36c62fec
--- /dev/null
+++ b/docs/reports/implementation/2026-03-24-project-upload-credit-entry-jump-frontend-record.md
@@ -0,0 +1,18 @@
+# 上传数据页征信导入入口跳转前端实施记录
+
+## 本次改动
+- 将项目详情上传数据页“征信导入”按钮改为直接跳转征信维护页面
+- 删除当前页征信导入弹窗入口逻辑
+- 新增源码契约测试,锁定入口跳转和旧逻辑清理结果
+
+## 影响文件
+- `ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue`
+- `ruoyi-ui/tests/unit/project-upload-credit-entry-jump.test.js`
+
+## 验证
+- `node ruoyi-ui/tests/unit/project-upload-credit-entry-jump.test.js`
+- `rg -n "handleGoCreditInfoPage|/maintain/creditInfo|showCreditUploadDialog|handleConfirmCreditUpload|handleCreditFileChange" ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue -S`
+
+## 验证结果
+- 契约测试通过,确认按钮改为跳转到 `/maintain/creditInfo`
+- 源码检索确认旧征信导入弹窗状态与方法已清理
diff --git a/ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue b/ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue
index a4f523dd..d91fa770 100644
--- a/ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue
+++ b/ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue
@@ -27,7 +27,7 @@
size="small"
icon="el-icon-upload2"
:disabled="isProjectTagging"
- @click="handleOpenCreditUpload"
+ @click="handleGoCreditInfoPage"
>
征信导入
@@ -167,41 +167,6 @@
-->
-
-
-
- 将文件拖到此处,或点击上传
-
- 支持 HTML 格式文件
-
-
-
- 取消
-
- 确定
-
-
-
-
import {
- getImportStatus,
getUploadStatus,
pullBankInfo,
parseIdCardFile,
- uploadFile,
batchUploadFiles,
getFileUploadList,
getFileUploadStatistics,
@@ -397,9 +360,6 @@ export default {
currentMenuTitle: "上传数据",
// 圆环周长
circumference: 2 * Math.PI * 14,
- showCreditUploadDialog: false,
- creditFileList: [],
- creditUploading: false,
pullBankInfoDialogVisible: false,
pullBankInfoLoading: false,
parsingIdCardFile: false,
@@ -619,12 +579,11 @@ export default {
}
this.$emit("menu-change", { key: "overview", route: "overview" });
},
- handleOpenCreditUpload() {
+ handleGoCreditInfoPage() {
if (this.isProjectTagging) {
return;
}
- this.creditFileList = [];
- this.showCreditUploadDialog = true;
+ this.$router.push("/maintain/creditInfo");
},
/** 上传卡片点击 */
handleUploadClick(key) {
@@ -636,90 +595,6 @@ export default {
this.selectedFiles = [];
}
},
- handleCreditFileChange(file, fileList) {
- this.creditFileList = fileList.slice(-1);
- },
- async handleConfirmCreditUpload() {
- if (this.isProjectTagging) {
- this.$message.warning("项目正在进行银行流水打标,暂不可上传或拉取数据");
- return;
- }
- if (this.creditFileList.length === 0) {
- this.$message.warning("请选择要上传的文件");
- return;
- }
-
- this.creditUploading = true;
-
- try {
- const res = await uploadFile(
- this.projectId,
- "CREDIT",
- this.creditFileList[0].raw
- );
-
- this.showCreditUploadDialog = false;
- this.$message.success("征信文件上传成功,正在处理中...");
- this.$emit("data-uploaded", { type: "credit" });
-
- await this.loadUploadStatus();
- this.pollCreditImportStatus(res && res.data);
- } catch (error) {
- this.$message.error("征信上传失败:" + (error.msg || "未知错误"));
- } finally {
- this.creditUploading = false;
- this.creditFileList = [];
- }
- },
- async pollCreditImportStatus(taskId) {
- if (!taskId) {
- return;
- }
-
- const maxAttempts = 20;
- let attempts = 0;
-
- const poll = async () => {
- if (attempts >= maxAttempts) {
- this.$message.warning("征信导入处理超时,请稍后查看");
- return;
- }
-
- try {
- const res = await getImportStatus(taskId);
- const status = res.data;
-
- if (!status) {
- attempts += 1;
- setTimeout(poll, 30000);
- return;
- }
-
- if (status.uploadStatus === "SUCCESS") {
- await this.loadUploadStatus();
- this.$message.success("征信导入处理完成");
- return;
- }
-
- if (status.uploadStatus === "FAILED") {
- await this.loadUploadStatus();
- this.$message.error(
- "征信导入处理失败:" + (status.errorMessage || "未知错误")
- );
- return;
- }
-
- attempts += 1;
- setTimeout(poll, 30000);
- } catch (error) {
- console.error("轮询征信导入状态失败:", error);
- attempts += 1;
- setTimeout(poll, 30000);
- }
- };
-
- poll();
- },
async loadUploadStatus() {
try {
const res = await getUploadStatus(this.projectId);
diff --git a/ruoyi-ui/tests/unit/project-upload-credit-entry-jump.test.js b/ruoyi-ui/tests/unit/project-upload-credit-entry-jump.test.js
new file mode 100644
index 00000000..bf7e07ee
--- /dev/null
+++ b/ruoyi-ui/tests/unit/project-upload-credit-entry-jump.test.js
@@ -0,0 +1,26 @@
+const assert = require("assert");
+const fs = require("fs");
+const path = require("path");
+
+const viewPath = path.resolve(
+ __dirname,
+ "../../src/views/ccdiProject/components/detail/UploadData.vue"
+);
+const source = fs.readFileSync(viewPath, "utf8");
+
+[
+ '@click="handleGoCreditInfoPage"',
+ 'this.$router.push("/maintain/creditInfo")',
+].forEach((token) => {
+ assert(source.includes(token), `缺少征信入口跳转关键代码: ${token}`);
+});
+
+[
+ "showCreditUploadDialog",
+ "handleConfirmCreditUpload",
+ "handleCreditFileChange",
+].forEach((token) => {
+ assert(!source.includes(token), `旧征信弹窗逻辑未清理: ${token}`);
+});
+
+console.log("征信入口跳转契约检查通过");