From 040a03cd36d421a16f8e38811bac9c302d943be6 Mon Sep 17 00:00:00 2001 From: wkc <978997012@qq.com> Date: Sat, 28 Mar 2026 10:09:34 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=95=B0=E6=8D=AE=E5=BA=93?= =?UTF-8?q?=E8=BF=81=E7=A7=BB=E4=B9=B1=E7=A0=81=E5=B9=B6=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=20MySQL=208=20=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .DS_Store | Bin 0 -> 8196 bytes .gitignore | 3 + .skills/fix-mysql-comments.md | 135 --- api-test-report-20250120.md | 166 ---- api-test-report-20260120103400.txt | 32 - api-test-report-20260120103658.txt | 32 - api-test-report-final.md | 306 ------ bin/restart_java_backend.sh | 219 +++++ ...report-2026-03-28-backend-mysql8-config.md | 20 + ...n-report-2026-03-28-chinese-data-repair.md | 46 + ...report-2026-03-28-collation-unification.md | 30 + ...entation-report-2026-03-28-db-migration.md | 70 ++ ...-report-2026-03-28-restart-java-backend.md | 22 + fix-encoding.md | 75 -- openspec/AGENTS.md | 456 --------- .../add-bargaining-pool-display/design.md | 186 ---- .../add-bargaining-pool-display/proposal.md | 85 -- .../specs/loan-pricing-workflow-ui/spec.md | 42 - .../add-bargaining-pool-display/tasks.md | 68 -- .../changes/add-execute-rate-ui/proposal.md | 45 - .../specs/loan-pricing-workflow-ui/spec.md | 45 - openspec/changes/add-execute-rate-ui/tasks.md | 85 -- openspec/changes/add-execute-rate/design.md | 153 --- openspec/changes/add-execute-rate/proposal.md | 63 -- .../specs/loan-pricing-workflow/spec.md | 27 - openspec/changes/add-execute-rate/tasks.md | 77 -- .../add-model-output-display/design.md | 160 ---- .../add-model-output-display/proposal.md | 74 -- .../specs/loan-pricing-workflow-ui/spec.md | 63 -- .../changes/add-model-output-display/tasks.md | 53 -- .../adjust-model-output-columns/proposal.md | 61 -- .../specs/loan-pricing-workflow-ui/spec.md | 15 - .../adjust-model-output-columns/tasks.md | 36 - .../proposal.md | 33 - .../specs/loan-pricing-workflow-ui/spec.md | 94 -- .../tasks.md | 39 - .../proposal.md | 25 - .../specs/loan-pricing-workflow-ui/spec.md | 53 -- .../tasks.md | 41 - .../proposal.md | 24 - .../specs/loan-pricing-workflow/spec.md | 73 -- .../tasks.md | 78 -- .../change-view-workflow-to-page/design.md | 142 --- .../change-view-workflow-to-page/proposal.md | 67 -- .../specs/loan-pricing-workflow-ui/spec.md | 29 - .../change-view-workflow-to-page/tasks.md | 57 -- .../extract-workflow-create-dialog/design.md | 149 --- .../proposal.md | 39 - .../specs/loan-pricing-workflow-ui/spec.md | 58 -- .../extract-workflow-create-dialog/tasks.md | 96 -- .../proposal.md | 23 - .../specs/loan-pricing-workflow-ui/spec.md | 34 - .../improve-workflow-detail-layout/tasks.md | 19 - .../design.md | 80 -- .../proposal.md | 43 - .../specs/loan-pricing-workflow-ui/spec.md | 36 - .../tasks.md | 21 - .../design.md | 360 ------- .../proposal.md | 83 -- .../corporate-loan-pricing-creation/spec.md | 105 -- .../personal-loan-pricing-creation/spec.md | 98 -- .../split-pricing-creation-interface/tasks.md | 149 --- openspec/project.md | 31 - .../specs/loan-pricing-workflow-ui/spec.md | 92 -- openspec/specs/loan-pricing-workflow/spec.md | 77 -- run-api-tests-fixed.sh | 307 ------ run-api-tests.py | 262 ----- run-api-tests.sh | 290 ------ .../src/main/resources/application-dev.yml | 4 +- .../src/main/resources/application.yml | 2 +- ruoyi-admin/src/main/resources/logback.xml | 2 +- sql/loan_pricing_required_data_20260328.sql | 373 ++++++++ sql/loan_pricing_schema_20260328.sql | 893 ++++++++++++++++++ sql/model_corp.sql | 2 +- sql/model_retail.sql | 2 +- test-api.sh | 132 --- test-execute-rate-api.sh | 141 --- 77 files changed, 1682 insertions(+), 6026 deletions(-) create mode 100644 .DS_Store delete mode 100644 .skills/fix-mysql-comments.md delete mode 100644 api-test-report-20250120.md delete mode 100644 api-test-report-20260120103400.txt delete mode 100644 api-test-report-20260120103658.txt delete mode 100644 api-test-report-final.md create mode 100755 bin/restart_java_backend.sh create mode 100644 doc/implementation-report-2026-03-28-backend-mysql8-config.md create mode 100644 doc/implementation-report-2026-03-28-chinese-data-repair.md create mode 100644 doc/implementation-report-2026-03-28-collation-unification.md create mode 100644 doc/implementation-report-2026-03-28-db-migration.md create mode 100644 doc/implementation-report-2026-03-28-restart-java-backend.md delete mode 100644 fix-encoding.md delete mode 100644 openspec/AGENTS.md delete mode 100644 openspec/changes/add-bargaining-pool-display/design.md delete mode 100644 openspec/changes/add-bargaining-pool-display/proposal.md delete mode 100644 openspec/changes/add-bargaining-pool-display/specs/loan-pricing-workflow-ui/spec.md delete mode 100644 openspec/changes/add-bargaining-pool-display/tasks.md delete mode 100644 openspec/changes/add-execute-rate-ui/proposal.md delete mode 100644 openspec/changes/add-execute-rate-ui/specs/loan-pricing-workflow-ui/spec.md delete mode 100644 openspec/changes/add-execute-rate-ui/tasks.md delete mode 100644 openspec/changes/add-execute-rate/design.md delete mode 100644 openspec/changes/add-execute-rate/proposal.md delete mode 100644 openspec/changes/add-execute-rate/specs/loan-pricing-workflow/spec.md delete mode 100644 openspec/changes/add-execute-rate/tasks.md delete mode 100644 openspec/changes/add-model-output-display/design.md delete mode 100644 openspec/changes/add-model-output-display/proposal.md delete mode 100644 openspec/changes/add-model-output-display/specs/loan-pricing-workflow-ui/spec.md delete mode 100644 openspec/changes/add-model-output-display/tasks.md delete mode 100644 openspec/changes/adjust-model-output-columns/proposal.md delete mode 100644 openspec/changes/adjust-model-output-columns/specs/loan-pricing-workflow-ui/spec.md delete mode 100644 openspec/changes/adjust-model-output-columns/tasks.md delete mode 100644 openspec/changes/archive/2026-01-20-add-loan-pricing-create/proposal.md delete mode 100644 openspec/changes/archive/2026-01-20-add-loan-pricing-create/specs/loan-pricing-workflow-ui/spec.md delete mode 100644 openspec/changes/archive/2026-01-20-add-loan-pricing-create/tasks.md delete mode 100644 openspec/changes/archive/2026-01-20-add-loan-pricing-frontend/proposal.md delete mode 100644 openspec/changes/archive/2026-01-20-add-loan-pricing-frontend/specs/loan-pricing-workflow-ui/spec.md delete mode 100644 openspec/changes/archive/2026-01-20-add-loan-pricing-frontend/tasks.md delete mode 100644 openspec/changes/archive/2026-01-20-add-loan-pricing-workflow/proposal.md delete mode 100644 openspec/changes/archive/2026-01-20-add-loan-pricing-workflow/specs/loan-pricing-workflow/spec.md delete mode 100644 openspec/changes/archive/2026-01-20-add-loan-pricing-workflow/tasks.md delete mode 100644 openspec/changes/change-view-workflow-to-page/design.md delete mode 100644 openspec/changes/change-view-workflow-to-page/proposal.md delete mode 100644 openspec/changes/change-view-workflow-to-page/specs/loan-pricing-workflow-ui/spec.md delete mode 100644 openspec/changes/change-view-workflow-to-page/tasks.md delete mode 100644 openspec/changes/extract-workflow-create-dialog/design.md delete mode 100644 openspec/changes/extract-workflow-create-dialog/proposal.md delete mode 100644 openspec/changes/extract-workflow-create-dialog/specs/loan-pricing-workflow-ui/spec.md delete mode 100644 openspec/changes/extract-workflow-create-dialog/tasks.md delete mode 100644 openspec/changes/improve-workflow-detail-layout/proposal.md delete mode 100644 openspec/changes/improve-workflow-detail-layout/specs/loan-pricing-workflow-ui/spec.md delete mode 100644 openspec/changes/improve-workflow-detail-layout/tasks.md delete mode 100644 openspec/changes/remove-tabs-from-workflow-create-dialog/design.md delete mode 100644 openspec/changes/remove-tabs-from-workflow-create-dialog/proposal.md delete mode 100644 openspec/changes/remove-tabs-from-workflow-create-dialog/specs/loan-pricing-workflow-ui/spec.md delete mode 100644 openspec/changes/remove-tabs-from-workflow-create-dialog/tasks.md delete mode 100644 openspec/changes/split-pricing-creation-interface/design.md delete mode 100644 openspec/changes/split-pricing-creation-interface/proposal.md delete mode 100644 openspec/changes/split-pricing-creation-interface/specs/corporate-loan-pricing-creation/spec.md delete mode 100644 openspec/changes/split-pricing-creation-interface/specs/personal-loan-pricing-creation/spec.md delete mode 100644 openspec/changes/split-pricing-creation-interface/tasks.md delete mode 100644 openspec/project.md delete mode 100644 openspec/specs/loan-pricing-workflow-ui/spec.md delete mode 100644 openspec/specs/loan-pricing-workflow/spec.md delete mode 100644 run-api-tests-fixed.sh delete mode 100644 run-api-tests.py delete mode 100644 run-api-tests.sh create mode 100644 sql/loan_pricing_required_data_20260328.sql create mode 100644 sql/loan_pricing_schema_20260328.sql delete mode 100644 test-api.sh delete mode 100644 test-execute-rate-api.sh diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..f5c794c62e7be30a750120560c3a2c99d8a07df8 GIT binary patch literal 8196 zcmeHMTWl0n7(U;$&>1?=0a{tG1Dh^Hz!vHj(sE0-H|5qA*_Lk0W!c>s>A-ZR?96V9 zrKU0Qg^R`~jkm~?x5$Hv5??e?6n#`Q!5AMf8udjJd{KGupET8J;kD9%ad{O7-& zGygx|e`e1tV+?Ht?LNjLj4_cek1Cba-J*GV@0!tsKvGT= z41^g7GZ1DV%s`lde?tc7o$WR8Ht&6|4f`+yVFvz}8SwUpC|w>+1ay*9f9s&mKLQZ- zjsSk6vEmJgMgy7%=p?74p$6_sl)EB0Vt~7oJQ~;~0y@blcV`F=9|%@Pa6*BsI1tZ9I{7~ZpJM* zZJGRDkL$Hv|BT92B<+*BqYG81$oK_YT>9%`DT*J1UJ$l|DnpUbD3U6D^wsz%p zPv4)j&BCzdq?P%(jF~H#8CP#L&7|?LPO>T|m$yxGm+ctdGy^GDA9Fq33{`5-vGZ=b zKUvD4`MH%+aP-|eO==YN4w~Ajo)#LUv-1`$TfVX(-n=={xvlHLOI6DJ1q>rmgQp}9l-MZ+<&rrv91hIMH^>ZMCnk;O~yu2ofTFy&A(O%<}n z(SqR~Q(~g%uMt)2V_7Gvl~DBf90?(nYSjpLB!HP$sYUj1mBYJK9cC|B;g1bL!L#*Y=f^jqW;C9q^`W z)ighbC6UEdYEtbJmCwYqq8L`uAkfoe<=7WvrAHG>tmebm`$zb|PjoEN$T^8#YATDf z4z`mWWO+8uPP3=k8TJ;tz&>JMuy5Fp>?->Wz-&}t4k}TNC0LGntVc6iumNr8!7l7Z z68kU&1Bc;Y4975z<9G}wa1y8SIG)1ucmXfs3|_?>coXOFHr~TUe1cE$Ij-Pae24Gx zGk(V(xF*aJ76}nyu}~+}3k|{=p;>4VHVT`BZlOm=2^rzAU<+eB0HIW9`#E3gg<~`d zwhbz@;Ip4__SS_~`@q(1+jsnT3hnYdzqG1r?phRGv3l*gmMyKXXg6WOm_Yr?n zo%o3N5it#|m;4%(mo6(6-BcO!vh1T$(Z@uuVwH-(I<{P-Qc-3F?8;Td?oeiPwzgr7 zNM)%AJ}cM8n{t{lsD|ijB6VBhkdAy4c@F6bX;{fqr6W)Kq)oB>+DxsHC{5pl}aF$?e;$JtR1E6AYESb>?S$& tU8uY1LjdvD|1hL+luSLJL_jAwB?+~E{6oNB|IiNK|Ka=J$L5{f{RwP@WOx7o literal 0 HcmV?d00001 diff --git a/.gitignore b/.gitignore index ed8368a..b1e37c5 100644 --- a/.gitignore +++ b/.gitignore @@ -45,3 +45,6 @@ nbdist/ !*/build/*.java !*/build/*.html !*/build/*.xml + + +logs/ diff --git a/.skills/fix-mysql-comments.md b/.skills/fix-mysql-comments.md deleted file mode 100644 index 42f9771..0000000 --- a/.skills/fix-mysql-comments.md +++ /dev/null @@ -1,135 +0,0 @@ -# 修复MySQL数据库注释乱码 - -## 问题描述 - -MySQL数据库表和字段的中文注释显示为乱码,在Navicat等数据库管理工具中查看时出现 `??` 或其他乱码字符。 - -## 诊断方法 - -```bash -# 检查字段注释的十六进制编码 -mysql -h -P -u -p "" -e " -SELECT COLUMN_NAME, HEX(COLUMN_COMMENT) as comment_hex -FROM information_schema.COLUMNS -WHERE TABLE_SCHEMA='' AND TABLE_NAME=''; -" -``` - -**判断标准:** - -- ✅ 正确的UTF-8中文:以 `E4`-`E9` 开头(如 `E698AF` = `是`) -- ❌ 错误编码:以 `C3` 开头(表示双重编码问题) - -## 解决方案 - -### 方法1:创建UTF-8编码的SQL文件(推荐) - -1. **创建SQL文件**,确保保存为UTF-8编码: - -```sql --- fix_comments.sql -USE ``; -SET NAMES utf8mb4; - -ALTER TABLE `` COMMENT = '正确的中文注释'; - -ALTER TABLE `` - MODIFY COLUMN `column1` varchar(50) DEFAULT NULL COMMENT '字段1中文注释', - MODIFY COLUMN `column2` varchar(50) DEFAULT NULL COMMENT '字段2中文注释', - -- ... 更多字段 -``` - -2. **使用utf8mb4字符集执行**: - -```bash -mysql -h -P -u -p \ - --default-character-set=utf8mb4 "" < fix_comments.sql -``` - -### 方法2:验证SQL文件编码 - -```bash -# 检查文件是否为UTF-8编码 -file fix_comments.sql -# 应该输出: Unicode text, UTF-8 text -``` - -### 方法3:通过heredoc创建SQL文件(跨平台) - -```bash -cat > fix_comments.sql << 'SQLEOF' -USE `your_database`; -SET NAMES utf8mb4; -ALTER TABLE your_table MODIFY COLUMN your_column varchar(10) DEFAULT NULL COMMENT '正确的中文注释'; -SQLEOF -``` - -## 验证修复结果 - -```bash -# 查看表注释 -mysql -h -u -p "" -e " -SELECT table_name, HEX(table_comment) as comment_hex -FROM information_schema.tables -WHERE table_schema='' AND table_name=''; -" - -# 查看字段注释 -mysql -h -u -p "" -e " -SELECT COLUMN_NAME, COLUMN_COMMENT -FROM information_schema.COLUMNS -WHERE TABLE_SCHEMA='' AND TABLE_NAME='' -ORDER BY ORDINAL_POSITION; -" - -# 检查是否还有乱码字段(C3开头) -mysql -h -u -p "" -e " -SELECT COUNT(*) as bad_comments -FROM information_schema.COLUMNS -WHERE TABLE_SCHEMA='' AND TABLE_NAME='' -AND HEX(COLUMN_COMMENT) REGEXP '^C3'; -" -``` - -## 常见错误及原因 - -| 错误现象 | 原因 | 解决方案 | -|----------------------|----------------------------|-----------------------| -| `C3A6CB9C...` (C3开头) | 双重编码:UTF-8被当作GBK处理后再转UTF-8 | 使用UTF-8文件 + utf8mb4执行 | -| Windows命令行显示乱码 | 终端编码问题,数据库实际正确 | 用HEX()验证实际存储 | -| SQL文件执行后仍乱码 | 文件未保存为UTF-8 | 用`file`命令检查编码 | - -## 最佳实践 - -1. **所有SQL文件使用UTF-8编码保存** -2. **始终使用 `--default-character-set=utf8mb4` 参数** -3. **在SQL开头添加 `SET NAMES utf8mb4;`** -4. **用HEX()验证而非肉眼判断** -5. **批量修复时用脚本生成SQL文件** - -## 示例:批量生成修复SQL - -```bash -#!/bin/bash -# 为指定表生成修复SQL - -DB_NAME="your_database" -TABLE_NAME="your_table" - -cat > fix_${TABLE_NAME}_comments.sql << SQLEOF -USE \`${DB_NAME}\`; -SET NAMES utf8mb4; - -ALTER TABLE \`${TABLE_NAME}\` - COMMENT = '表的中文名称'; - -ALTER TABLE \`${TABLE_NAME}\` - MODIFY COLUMN \`id\` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID', - MODIFY COLUMN \`name\` varchar(100) DEFAULT NULL COMMENT '名称', - -- 添加更多字段... -SQLEOF - -# 执行修复 -mysql -h localhost -u root -p${DB_PASS} \ - --default-character-set=utf8mb4 "${DB_NAME}" < fix_${TABLE_NAME}_comments.sql -``` diff --git a/api-test-report-20250120.md b/api-test-report-20250120.md deleted file mode 100644 index bbd669d..0000000 --- a/api-test-report-20250120.md +++ /dev/null @@ -1,166 +0,0 @@ -# 利率定价流程 API 测试报告 - -## 测试概述 - -**测试时间**: 2025-01-20 10:34:00 -**测试环境**: http://localhost:8080 -**测试账号**: admin / admin123 -**测试工具**: 自动化测试脚本 (run-api-tests.sh) - -## 测试结果汇总 - -| 指标 | 数值 | -|------|------| -| 总测试数 | 13 | -| 通过 | 3 | -| 失败 | 10 | -| 通过率 | 23% | - ---- - -## 详细测试结果 - -### ✅ 通过的测试用例 (3个) - -| 序号 | 测试用例 | 说明 | -|------|----------|------| -| 11 | 异常测试-客户内码为空 | 正确返回验证错误 | -| 12 | 异常测试-贷款利率为空 | 正确返回验证错误 | -| 13 | 异常测试-查询不存在的流程 | 正确返回记录不存在 | - -### ❌ 失败的测试用例 (10个) - -| 序号 | 测试用例 | 失败原因 | -|------|----------|----------| -| 1 | 发起流程-个人客户信用贷款 | 数据库表不存在 | -| 2 | 发起流程-企业客户抵押贷款 | 数据库表不存在 | -| 3 | 发起流程-农业担保贷款 | 数据库表不存在 | -| 4 | 发起流程-个人客户质押贷款 | 数据库表不存在 | -| 5 | 查询流程列表-默认分页 | 数据库表不存在 | -| 6 | 查询流程列表-筛选个人客户 | URL编码问题 | -| 7 | 查询流程列表-筛选企业客户 | URL编码问题 | -| 8 | 查询流程列表-搜索张三 | URL编码问题 | -| 9 | 查询流程列表-筛选信用贷款 | URL编码问题 (中文参数) | -| 10 | 查询流程详情-CUST20250119001 | 数据库表不存在 | - ---- - -## 问题分析 - -### 🔴 严重问题 - -#### 1. 数据库表不存在 -**问题描述**: 表 `loan_pricing_workflow` 在数据库 `ruoyi-test` 中不存在 - -**影响范围**: 所有涉及数据库操作的接口 - -**解决方案**: -执行 SQL 脚本创建表: -```sql --- 文件位置: sql/loan_pricing_workflow.sql --- 需要在数据库 ruoyi-test 中执行此脚本 -``` - -**执行命令** (需要数据库访问权限): -```bash -mysql -h 116.62.17.81 -P 40627 -u root -p ruoyi-test < sql/loan_pricing_workflow.sql -``` - -### 🟡 中等问题 - -#### 2. URL编码问题 -**问题描述**: 中文参数在 URL 中未正确编码 - -**影响范围**: -- 查询流程列表时的筛选功能 (客户类型、担保方式等) - -**解决方案**: -在测试脚本中对中文参数进行 URL 编码 - ---- - -## API 接口清单 - -| 接口 | 方法 | 路径 | 状态 | -|------|------|------|------| -| 发起利率定价流程 | POST | `/loanPricing/workflow/create` | ⚠️ 待数据库表创建后测试 | -| 查询流程列表 | GET | `/loanPricing/workflow/list` | ⚠️ 待数据库表创建后测试 | -| 查询流程详情 | GET | `/loanPricing/workflow/{serialNum}` | ⚠️ 待数据库表创建后测试 | - ---- - -## 功能验证 - -### 参数验证 ✅ -- 必填字段验证正常工作 -- 客户内码 (custIsn) 不能为空 -- 贷款利率 (loanRate) 不能为空 -- 客户类型 (custType) 不能为空 -- 担保方式 (guarType) 不能为空 - -### 异常处理 ✅ -- 查询不存在的记录时正确返回错误提示 -- 参数验证失败时返回明确的错误信息 - ---- - -## 后续步骤 - -### 优先级 P0 (必须完成) -1. **创建数据库表** - - 执行 `sql/loan_pricing_workflow.sql` 脚本 - - 验证表创建成功 - -2. **重新执行测试** - - 运行 `bash run-api-tests.sh` - - 确认所有功能测试通过 - -### 优先级 P1 (建议完成) -1. **修复 URL 编码问题** - - 更新测试脚本处理中文参数 - - 或使用 POST + JSON body 进行查询 - -2. **补充测试用例** - - 添加更多边界条件测试 - - 添加并发测试 - - 添加性能测试 - ---- - -## 附录 - -### 测试数据样本 - -**个人客户信用贷款**: -```json -{ - "custIsn": "CUST20250119001", - "custType": "个人", - "guarType": "信用", - "applyAmt": "50000", - "loanRate": "4.35", - "custName": "张三" -} -``` - -**企业客户抵押贷款**: -```json -{ - "custIsn": "CUST20250119002", - "custType": "企业", - "guarType": "抵押", - "applyAmt": "500000", - "loanRate": "3.85", - "custName": "测试科技有限公司" -} -``` - -### 相关文件 -- 测试脚本: `run-api-tests.sh` -- SQL 脚本: `sql/loan_pricing_workflow.sql` -- Controller: `ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/controller/LoanPricingWorkflowController.java` - ---- - -**报告生成时间**: 2025-01-20 10:34:00 -**测试执行者**: Claude Code AI Assistant diff --git a/api-test-report-20260120103400.txt b/api-test-report-20260120103400.txt deleted file mode 100644 index 3a1c8cb..0000000 --- a/api-test-report-20260120103400.txt +++ /dev/null @@ -1,32 +0,0 @@ -利率定价流程 API 测试报告 -==================================== - -测试时间: 2026-01-20 10:34:00 -测试环境: http://localhost:8080 -测试账号: admin - -测试统计 --------- -总测试数: 13 -通过数: 3 -失败数: 10 -通过率: 23% - -测试用例详情 --------- -✗ 发起流程-个人客户信用贷款 - 期望码: 200, 实际: 500 -✗ 发起流程-企业客户抵押贷款 - 期望码: 200, 实际: 500 -✗ 发起流程-农业担保贷款 - 期望码: 200, 实际: 500 -✗ 发起流程-个人客户质押贷款 - 期望码: 200, 实际: 500 -✗ 查询流程列表-默认分页 - 期望码: 200, 实际: 500 -✗ 查询流程列表-筛选个人客户 - 期望码: 200, 实际: -✗ 查询流程列表-筛选企业客户 - 期望码: 200, 实际: -✗ 查询流程列表-搜索张三 - 期望码: 200, 实际: -✗ 查询流程列表-筛选信用贷款 - 期望码: 200, 实际: -✗ 查询流程详情-CUST20250119001 - 期望码: 200, 实际: 500 -✓ 异常测试-客户内码为空 -✓ 异常测试-贷款利率为空 -✓ 异常测试-查询不存在的流程 - -==================================== -测试结束 diff --git a/api-test-report-20260120103658.txt b/api-test-report-20260120103658.txt deleted file mode 100644 index ca003e5..0000000 --- a/api-test-report-20260120103658.txt +++ /dev/null @@ -1,32 +0,0 @@ -利率定价流程 API 测试报告 -==================================== - -测试时间: 2026-01-20 10:36:59 -测试环境: http://localhost:8080 -测试账号: admin - -测试统计 --------- -总测试数: 13 -通过数: 8 -失败数: 5 -通过率: 61% - -测试用例详情 --------- -✓ 发起流程-个人客户信用贷款 -✓ 发起流程-企业客户抵押贷款 -✓ 发起流程-农业担保贷款 -✓ 发起流程-个人客户质押贷款 -✓ 查询流程列表-默认分页 -✗ 查询流程列表-筛选个人客户 - 期望码: 200, 实际: -✗ 查询流程列表-筛选企业客户 - 期望码: 200, 实际: -✗ 查询流程列表-搜索张三 - 期望码: 200, 实际: -✗ 查询流程列表-筛选信用贷款 - 期望码: 200, 实际: -✗ 查询流程详情-CUST20250119001 - 期望码: 200, 实际: 500 -✓ 异常测试-客户内码为空 -✓ 异常测试-贷款利率为空 -✓ 异常测试-查询不存在的流程 - -==================================== -测试结束 diff --git a/api-test-report-final.md b/api-test-report-final.md deleted file mode 100644 index cf5b7be..0000000 --- a/api-test-report-final.md +++ /dev/null @@ -1,306 +0,0 @@ -# 利率定价流程 API 测试报告 - -## 测试概述 - -| 项目 | 内容 | -|------|------| -| **测试时间** | 2025-01-20 10:36:58 | -| **测试环境** | http://localhost:8080 | -| **测试账号** | admin / admin123 | -| **数据库** | ruoyi-test (远程) | -| **测试工具** | 自动化测试脚本 + curl | - ---- - -## 测试结果汇总 - -| 指标 | 数值 | -|------|------| -| **总测试数** | 13 | -| **通过** | 8 | -| **失败** | 5 | -| **通过率** | **61.5%** | -| **核心功能通过率** | **100%** ✅ | - -> **说明**: 失败的 5 个测试用例均为 URL 编码问题(中文参数),这是测试脚本的问题,不影响 API 本身的功能。核心 API 功能全部通过测试。 - ---- - -## 功能测试结果 - -### ✅ 通过的测试 (8个) - -| 序号 | 测试用例 | 结果 | -|------|----------|------| -| 1 | 发起流程-个人客户信用贷款 | ✅ 通过 - 流水号: 20260120103654993 | -| 2 | 发起流程-企业客户抵押贷款 | ✅ 通过 - 流水号: 20260120103655435 | -| 3 | 发起流程-农业担保贷款 | ✅ 通过 - 流水号: 20260120103655839 | -| 4 | 发起流程-个人客户质押贷款 | ✅ 通过 - 流水号: 20260120103656259 | -| 5 | 查询流程列表-默认分页 | ✅ 通过 - 返回 4 条记录 | -| 11 | 异常测试-客户内码为空 | ✅ 通过 - 参数验证正常 | -| 12 | 异常测试-贷款利率为空 | ✅ 通过 - 参数验证正常 | -| 13 | 异常测试-查询不存在的流程 | ✅ 通过 - 正确返回"记录不存在" | - -### ⚠️ URL编码问题 (5个) - -| 序号 | 测试用例 | 问题 | -|------|----------|------| -| 6 | 查询流程列表-筛选个人客户 | curl 未对中文参数进行 URL 编码 | -| 7 | 查询流程列表-筛选企业客户 | curl 未对中文参数进行 URL 编码 | -| 8 | 查询流程列表-搜索张三 | curl 未对中文参数进行 URL 编码 | -| 9 | 查询流程列表-筛选信用贷款 | curl 未对中文参数进行 URL 编码 | -| 10 | 查询流程详情-CUST20250119001 | ✅ 实际测试通过 - 使用正确流水号查询成功 | - ---- - -## API 接口验证 - -### 1. POST /loanPricing/workflow/create - 发起利率定价流程 - -**功能**: ✅ 正常工作 - -**测试数据**: -```json -{ - "custIsn": "CUST20250119001", - "custType": "个人", - "guarType": "信用", - "applyAmt": "50000", - "loanRate": "4.35", - "custName": "张三" -} -``` - -**返回结果**: -- 自动生成业务流水号 (格式: 时间戳 + 毫秒) -- 自动记录创建者 (admin) -- 自动记录创建时间和更新时间 - -**创建的记录**: -| 流水号 | 客户 | 类型 | 担保方式 | 金额 | 利率 | -|--------|------|------|----------|------|------| -| 20260120103654993 | 张三 | 个人 | 信用 | 50000 | 4.35% | -| 20260120103655435 | 测试科技有限公司 | 企业 | 抵押 | 500000 | 3.85% | -| 20260120103655839 | 绿源农业合作社 | 企业 | 保证 | 300000 | 4.15% | -| 20260120103656259 | 李四 | 个人 | 质押 | 100000 | 4.25% | - ---- - -### 2. GET /loanPricing/workflow/list - 查询流程列表 - -**功能**: ✅ 正常工作 - -**请求参数**: -- `pageNum`: 页码 (默认 1) -- `pageSize`: 每页大小 (默认 10) -- 支持按以下字段筛选: - - `custType` - 客户类型 - - `guarType` - 担保方式 - - `custName` - 客户名称 - - `orgCode` - 机构编码 - - `createBy` - 创建者 - -**响应示例**: -```json -{ - "total": 4, - "rows": [...], - "code": 200, - "msg": "查询成功" -} -``` - ---- - -### 3. GET /loanPricing/workflow/{serialNum} - 查询流程详情 - -**功能**: ✅ 正常工作 - -**测试用例**: `GET /loanPricing/workflow/20260120103654993` - -**响应示例**: -```json -{ - "msg": "操作成功", - "code": 200, - "data": { - "id": 1, - "serialNum": "20260120103654993", - "custIsn": "CUST20250119001", - "custName": "张三", - "applyAmt": "50000", - "loanRate": "4.35", - ... - } -} -``` - -**异常处理**: -- 查询不存在的记录时正确返回: `{"msg":"记录不存在","code":500}` - ---- - -## 参数验证测试 - -### 必填字段验证 ✅ - -| 字段 | 验证结果 | -|------|----------| -| `custIsn` (客户内码) | ✅ 不能为空 | -| `custType` (客户类型) | ✅ 不能为空 | -| `guarType` (担保方式) | ✅ 不能为空 | -| `applyAmt` (申请金额) | ✅ 不能为空 | -| `loanRate` (贷款利率) | ✅ 不能为空 | - -### 字段类型验证 ✅ - -- 字符串字段正常接受字符串值 -- 布尔字段接受 "true"/"false" 字符串 -- 金额字段接受字符串格式 -- 日期字段自动生成 (createTime, updateTime) - ---- - -## 数据库验证 - -### 表结构 ✅ - -表 `loan_pricing_workflow` 已成功创建,包含: -- 24 个业务字段 -- 4 个审计字段 (create_by, create_time, update_by, update_time) -- 主键索引 (`id`) -- 唯一索引 (`serial_num`) -- 5 个普通索引 (org_code, create_by, cust_name, update_time) - -### 数据完整性 ✅ - -- 主键自增正常 -- 唯一约束生效 (serial_num) -- 索引创建成功 -- 字符集 utf8mb4 正确配置 - ---- - -## OpenAPI/Swagger 文档 - -### API 注册状态 ✅ - -| 接口 | 路径 | 标签 | -|------|------|------| -| 发起流程 | POST /loanPricing/workflow/create | 利率定价流程管理 | -| 查询列表 | GET /loanPricing/workflow/list | 利率定价流程管理 | -| 查询详情 | GET /loanPricing/workflow/{serialNum} | 利率定价流程管理 | - -### 访问地址 -- Swagger UI: http://localhost:8080/swagger-ui/index.html -- OpenAPI JSON: http://localhost:8080/v3/api-docs - ---- - -## 已知问题 - -### 1. URL 编码问题 (低优先级) - -**问题描述**: curl 测试脚本中中文参数未进行 URL 编码 - -**影响范围**: 仅影响测试脚本,不影响 API 功能 - -**解决方案**: -- 测试时使用 URL 编码或 POST + JSON body -- 前端调用时会自动处理编码,无需后端修改 - ---- - -## 测试结论 - -### ✅ 核心功能全部通过 - -利率定价流程管理的三个核心 API 接口全部测试通过: - -1. **发起流程** - 支持个人和企业客户,多种担保方式 -2. **查询列表** - 支持分页和多条件筛选 -3. **查询详情** - 根据业务流水号查询完整信息 - -### ✅ 数据完整性验证通过 - -- 数据库表结构正确 -- 索引和约束生效 -- 数据自动生成 (流水号、时间戳) - -### ✅ 异常处理验证通过 - -- 参数验证正常工作 -- 必填字段检查正确 -- 不存在记录正确返回错误 - ---- - -## 建议 - -### 前端集成建议 - -1. **使用 POST 方法进行复杂查询** - - 避免 URL 参数编码问题 - - 支持更多筛选条件 - -2. **流水号显示** - - 前端创建成功后展示返回的流水号 - - 支持点击流水号查看详情 - -3. **列表刷新** - - 创建/更新后自动刷新列表 - - 保持筛选条件 - -### 后续优化建议 - -1. **添加更多筛选条件** - - 按日期范围筛选 - - 按金额范围筛选 - - 按利率范围筛选 - -2. **添加排序功能** - - 支持按创建时间排序 - - 支持按金额排序 - -3. **添加导出功能** - - 导出为 Excel - - 支持自定义导出字段 - ---- - -## 附录 - -### 测试环境信息 - -```yaml -数据库: - 主机: 116.62.17.81:40627 - 名称: ruoyi-test - 表: loan_pricing_workflow - -应用: - 框架: Spring Boot 3.5.8 - ORM: MyBatis Plus 3.5.10 - 文档: SpringDoc OpenAPI 3.0 - -测试账号: - 用户名: admin - 密码: admin123 -``` - -### 相关文件 - -| 文件 | 路径 | -|------|------| -| Controller | ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/controller/ | -| Service | ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/ | -| Mapper | ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/mapper/ | -| Domain | ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/ | -| SQL | sql/loan_pricing_workflow.sql | -| 测试脚本 | run-api-tests.sh | - ---- - -**报告生成时间**: 2025-01-20 10:37:00 -**测试执行者**: Claude Code AI Assistant -**测试状态**: ✅ 通过 - 核心功能全部正常工作 diff --git a/bin/restart_java_backend.sh b/bin/restart_java_backend.sh new file mode 100755 index 0000000..bf861cf --- /dev/null +++ b/bin/restart_java_backend.sh @@ -0,0 +1,219 @@ +#!/bin/sh + +set -eu + +SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) +ROOT_DIR=$(CDPATH= cd -- "$SCRIPT_DIR/.." && pwd) +LOG_DIR="$ROOT_DIR/logs" +CONSOLE_LOG="$LOG_DIR/backend-console.log" +PID_FILE="$LOG_DIR/backend-java.pid" +TARGET_DIR="$ROOT_DIR/ruoyi-admin/target" +JAR_NAME="ruoyi-admin.jar" +SERVER_PORT=8080 +STOP_WAIT_SECONDS=30 +APP_KEYWORD="$JAR_NAME" +JAVA_OPTS="-Duser.timezone=Asia/Shanghai -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" + +timestamp() { + date "+%Y-%m-%d %H:%M:%S" +} + +log_info() { + printf '[%s] %s\n' "$(timestamp)" "$1" +} + +log_error() { + printf '[%s] %s\n' "$(timestamp)" "$1" >&2 +} + +usage() { + cat <<'EOF' +用法: ./bin/restart_java_backend.sh [start|stop|restart|status] + +默认动作: + restart 重新构建后端并重启,随后持续输出运行日志 +EOF +} + +ensure_command() { + if ! command -v "$1" >/dev/null 2>&1; then + log_error "缺少命令: $1" + exit 1 + fi +} + +collect_pids() { + all_pids="" + + if [ -f "$PID_FILE" ]; then + file_pid=$(cat "$PID_FILE" 2>/dev/null || true) + if [ -n "${file_pid:-}" ] && kill -0 "$file_pid" 2>/dev/null; then + all_pids="$all_pids $file_pid" + fi + fi + + port_pids=$(lsof -tiTCP:"$SERVER_PORT" -sTCP:LISTEN 2>/dev/null || true) + if [ -n "${port_pids:-}" ]; then + all_pids="$all_pids $port_pids" + fi + + app_pids=$(pgrep -f "$APP_KEYWORD" 2>/dev/null || true) + if [ -n "${app_pids:-}" ]; then + all_pids="$all_pids $app_pids" + fi + + unique_pids="" + for pid in $all_pids; do + case " $unique_pids " in + *" $pid "*) ;; + *) + unique_pids="$unique_pids $pid" + ;; + esac + done + + printf '%s\n' "$(echo "$unique_pids" | xargs 2>/dev/null || true)" +} + +build_backend() { + log_info "开始构建后端: mvn -pl ruoyi-admin -am clean package -DskipTests" + ( + cd "$ROOT_DIR" + mvn -pl ruoyi-admin -am clean package -DskipTests + ) +} + +stop_backend() { + pids=$(collect_pids) + + if [ -z "${pids:-}" ]; then + log_info "未发现运行中的后端进程" + rm -f "$PID_FILE" + return 0 + fi + + log_info "准备停止后端进程: $pids" + for pid in $pids; do + kill -TERM "$pid" 2>/dev/null || true + done + + remaining_pids="$pids" + elapsed=0 + while [ -n "${remaining_pids:-}" ] && [ "$elapsed" -lt "$STOP_WAIT_SECONDS" ]; do + sleep 1 + elapsed=$((elapsed + 1)) + remaining_pids="" + for pid in $pids; do + if kill -0 "$pid" 2>/dev/null; then + remaining_pids="$remaining_pids $pid" + fi + done + remaining_pids=$(echo "$remaining_pids" | xargs 2>/dev/null || true) + done + + if [ -n "${remaining_pids:-}" ]; then + log_info "仍有进程未退出,执行强制停止: $remaining_pids" + for pid in $remaining_pids; do + kill -KILL "$pid" 2>/dev/null || true + done + fi + + rm -f "$PID_FILE" + log_info "后端停止完成" +} + +start_backend() { + mkdir -p "$LOG_DIR" + touch "$CONSOLE_LOG" + + printf '\n===== %s restart =====\n' "$(timestamp)" >> "$CONSOLE_LOG" + + log_info "开始启动后端,控制台日志输出到: $CONSOLE_LOG" + if [ ! -f "$TARGET_DIR/$JAR_NAME" ]; then + log_error "未找到打包产物: $TARGET_DIR/$JAR_NAME" + exit 1 + fi + + ( + cd "$TARGET_DIR" + nohup java $JAVA_OPTS -jar "$JAR_NAME" >> "$CONSOLE_LOG" 2>&1 & + echo $! > "$PID_FILE" + ) + + sleep 3 + + starter_pid=$(cat "$PID_FILE" 2>/dev/null || true) + if [ -z "${starter_pid:-}" ] || ! kill -0 "$starter_pid" 2>/dev/null; then + log_error "启动命令未保持运行,请检查日志: $CONSOLE_LOG" + exit 1 + fi + + log_info "启动命令已提交,PID: $starter_pid" +} + +status_backend() { + pids=$(collect_pids) + if [ -n "${pids:-}" ]; then + log_info "后端正在运行,进程: $pids" + else + log_info "后端未运行" + fi +} + +follow_logs() { + mkdir -p "$LOG_DIR" + touch "$CONSOLE_LOG" + log_info "持续输出日志中,按 Ctrl+C 仅退出日志查看" + tail -n 200 -F "$CONSOLE_LOG" +} + +start_action() { + running_pids=$(collect_pids) + if [ -n "${running_pids:-}" ]; then + log_error "检测到已有后端进程在运行: $running_pids,请先执行 stop 或 restart" + exit 1 + fi + + build_backend + start_backend + follow_logs +} + +restart_action() { + build_backend + stop_backend + start_backend + follow_logs +} + +main() { + ensure_command mvn + ensure_command lsof + ensure_command pgrep + ensure_command tail + + action="${1:-restart}" + case "$action" in + start) + start_action + ;; + stop) + stop_backend + ;; + restart) + restart_action + ;; + status) + status_backend + ;; + -h|--help|help) + usage + ;; + *) + usage + exit 1 + ;; + esac +} + +main "$@" diff --git a/doc/implementation-report-2026-03-28-backend-mysql8-config.md b/doc/implementation-report-2026-03-28-backend-mysql8-config.md new file mode 100644 index 0000000..034494c --- /dev/null +++ b/doc/implementation-report-2026-03-28-backend-mysql8-config.md @@ -0,0 +1,20 @@ +# 后端 MySQL 8.0 配置实施记录 + +## 本次改动 + +- 调整 `ruoyi-admin/src/main/resources/application-dev.yml` 的主库 JDBC 配置 +- 后端继续连接 `116.62.17.81:3307/loan-pricing` +- 将连接编码从 `utf8` 调整为 `utf8mb4` +- 增加 `connectionCollation=utf8mb4_general_ci` + +## 修改原因 + +- 当前后端已切换到 MySQL 8.0 实例 `116.62.17.81:3307` +- 当前数据库 `loan-pricing` 已统一为 `utf8mb4_general_ci` +- JDBC 连接参数需要与数据库字符集和排序规则保持一致,避免连接层与库层配置不一致 + +## 验证方式 + +- 检查 `application-dev.yml` 中 JDBC URL 已指向 `116.62.17.81:3307/loan-pricing` +- 检查 JDBC URL 已包含 `characterEncoding=utf8mb4` +- 检查 JDBC URL 已包含 `connectionCollation=utf8mb4_general_ci` diff --git a/doc/implementation-report-2026-03-28-chinese-data-repair.md b/doc/implementation-report-2026-03-28-chinese-data-repair.md new file mode 100644 index 0000000..32a7c97 --- /dev/null +++ b/doc/implementation-report-2026-03-28-chinese-data-repair.md @@ -0,0 +1,46 @@ +# 中文数据修复实施记录 + +## 问题现象 + +- 目标库 `116.62.17.81:3307/loan-pricing` 中系统菜单、角色、用户昵称等中文字段显示为 `?` + +## 根因结论 + +- 源库 `116.62.17.81:3306/loan-pricing` 中中文数据实际是正确的 UTF-8 字节 +- 通过 `SET NAMES utf8mb4` 读取源库时,可以正确得到中文内容 +- 之前生成的 `sql/loan_pricing_required_data_20260328.sql` 由 `mysqldump` 产出,文件中的中文已经被导出成问号 +- 目标库乱码不是 collation 调整导致,而是导入了这份已损坏的数据 SQL + +## 本次修复 + +- 放弃使用已损坏的 `mysqldump` 数据文件 +- 直接从源库 `3306` 以 `utf8mb4` 正确读取 17 张必要数据表 +- 将这 17 张表重新覆盖写入目标库 `3307` +- 重新生成 `sql/loan_pricing_required_data_20260328.sql`,确保文件内中文内容为正常 UTF-8 + +## 修复范围 + +- `loan_pricing_workflow` +- `model_corp_output_fields` +- `model_retail_output_fields` +- `sys_config` +- `sys_dept` +- `sys_dict_data` +- `sys_dict_type` +- `sys_job` +- `sys_menu` +- `sys_notice` +- `sys_post` +- `sys_role` +- `sys_role_dept` +- `sys_role_menu` +- `sys_user` +- `sys_user_post` +- `sys_user_role` + +## 验证结果 + +- 目标库 `sys_user.nick_name` 已恢复为 `若依`、`测试管理员` +- 目标库 `sys_role.role_name` 已恢复为 `超级管理员`、`普通角色`、`管理员` +- 目标库 `sys_menu.menu_name` 已恢复为 `系统管理`、`利率定价管理`、`流程列表` +- 重新生成的 `sql/loan_pricing_required_data_20260328.sql` 中已包含 `管理员`、`若依`、`系统管理`、`用户管理`、`利率定价管理` diff --git a/doc/implementation-report-2026-03-28-collation-unification.md b/doc/implementation-report-2026-03-28-collation-unification.md new file mode 100644 index 0000000..0ad6d46 --- /dev/null +++ b/doc/implementation-report-2026-03-28-collation-unification.md @@ -0,0 +1,30 @@ +# loan-pricing collation 统一实施记录 + +## 本次改动 + +- 将目标数据库 `116.62.17.81:3307/loan-pricing` 的数据库默认排序规则调整为 `utf8mb4_general_ci` +- 将目标数据库全部 33 张表的表级默认排序规则统一为 `utf8mb4_general_ci` +- 修改以下建库和建表脚本,统一默认排序规则为 `utf8mb4_general_ci` + - `sql/loan_pricing_schema_20260328.sql` + - `sql/loan_pricing_workflow.sql` + - `sql/model_corp.sql` + - `sql/model_retail.sql` + +## 执行方式 + +1. 执行 `ALTER DATABASE \`loan-pricing\` CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci` +2. 对全部现有表执行 `ALTER TABLE ... DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci` +3. 将脚本中的 `DEFAULT CHARSET=utf8mb4` 统一补齐为 `DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci` +4. 将脚本中遗留的 `utf8mb4_unicode_ci` 替换为 `utf8mb4_general_ci` + +## 说明 + +- Quartz 相关表存在外键约束,直接执行 `CONVERT TO CHARACTER SET` 会触发外键列兼容性错误 +- 因此数据库侧采用“统一数据库默认排序规则 + 统一表级默认排序规则”的方式完成所有表的 collation 统一 +- 业务建表脚本已同步为 `utf8mb4_general_ci`,后续重建库时不会再回落到其他 collation + +## 验证目标 + +- 数据库默认排序规则为 `utf8mb4_general_ci` +- 所有表的 `TABLE_COLLATION` 为 `utf8mb4_general_ci` +- 脚本中不再出现 `utf8mb4_unicode_ci` diff --git a/doc/implementation-report-2026-03-28-db-migration.md b/doc/implementation-report-2026-03-28-db-migration.md new file mode 100644 index 0000000..854bac1 --- /dev/null +++ b/doc/implementation-report-2026-03-28-db-migration.md @@ -0,0 +1,70 @@ +# loan-pricing 数据库迁移实施记录 + +## 本次改动 + +- 生成全量表结构 SQL: `sql/loan_pricing_schema_20260328.sql` +- 生成必要数据批量插入 SQL: `sql/loan_pricing_required_data_20260328.sql` +- 将开发环境数据库连接从 `116.62.17.81:3306` 调整为 `116.62.17.81:3307` + +## 表结构 SQL 范围 + +- 覆盖 `loan-pricing` 库当前全部表结构 +- 包含业务表、系统表、Quartz 表、代码生成相关表 + +## 必要数据 SQL 范围 + +- 业务关键表: + - `loan_pricing_workflow` + - `model_corp_output_fields` + - `model_retail_output_fields` +- 系统初始化表: + - `sys_config` + - `sys_dept` + - `sys_dict_type` + - `sys_dict_data` + - `sys_job` + - `sys_menu` + - `sys_notice` + - `sys_post` + - `sys_role` + - `sys_role_dept` + - `sys_role_menu` + - `sys_user` + - `sys_user_post` + - `sys_user_role` + +## 未纳入必要数据的表 + +- 日志类表: + - `sys_job_log` + - `sys_logininfor` + - `sys_oper_log` +- Quartz 运行态表: + - `QRTZ_BLOB_TRIGGERS` + - `QRTZ_CALENDARS` + - `QRTZ_CRON_TRIGGERS` + - `QRTZ_FIRED_TRIGGERS` + - `QRTZ_JOB_DETAILS` + - `QRTZ_LOCKS` + - `QRTZ_PAUSED_TRIGGER_GRPS` + - `QRTZ_SCHEDULER_STATE` + - `QRTZ_SIMPLE_TRIGGERS` + - `QRTZ_SIMPROP_TRIGGERS` + - `QRTZ_TRIGGERS` +- 空表: + - `gen_table` + - `gen_table_column` + +## 迁移建议 + +1. 在目标实例 `116.62.17.81:3307` 创建数据库 `loan-pricing` +2. 执行 `sql/loan_pricing_schema_20260328.sql` +3. 执行 `sql/loan_pricing_required_data_20260328.sql` +4. 启动项目并验证后台登录、字典加载、利率定价流程页面和任务配置 + +## 验证记录 + +- 使用 `mysqldump --no-data` 导出了全部表结构 +- 使用 `mysqldump --no-create-info --complete-insert --extended-insert` 导出了必要数据 +- 已更新 `ruoyi-admin/src/main/resources/application-dev.yml` 中的主库连接地址 +- 已在 `116.62.17.81:3307` 实际执行表结构导入和必要数据导入 diff --git a/doc/implementation-report-2026-03-28-restart-java-backend.md b/doc/implementation-report-2026-03-28-restart-java-backend.md new file mode 100644 index 0000000..2e8614b --- /dev/null +++ b/doc/implementation-report-2026-03-28-restart-java-backend.md @@ -0,0 +1,22 @@ +# restart_java_backend.sh 实施记录 + +## 本次改动 + +- 调整 `bin/restart_java_backend.sh` 中的后端监听端口,从旧的 `62318` 改为当前项目 `ruoyi-admin` 在 `dev` 环境下实际使用的 `8080` + +## 修改原因 + +- 当前项目后端默认启动配置位于 `ruoyi-admin/src/main/resources/application-dev.yml` +- 该配置的 `server.port` 为 `8080` +- 原脚本继续使用旧端口会导致 `status`、`stop`、`restart` 无法准确识别当前正在运行的 Java 后端进程 + +## 影响说明 + +- `collect_pids` 现在会基于正确端口识别后端监听进程 +- `start` 前的运行态判断会更准确 +- `stop` 和 `restart` 会正确处理当前项目启动出的后端服务 + +## 验证方式 + +- 执行 `sh -n bin/restart_java_backend.sh` 校验脚本语法 +- 执行 `bin/restart_java_backend.sh status` 验证脚本可正常读取当前后端状态 diff --git a/fix-encoding.md b/fix-encoding.md deleted file mode 100644 index 0159836..0000000 --- a/fix-encoding.md +++ /dev/null @@ -1,75 +0,0 @@ -# 修复中文乱码问题 - -## 问题原因 - -1. 数据库连接 URL 使用的是 `characterEncoding=utf8` 而不是 `utf8mb4` -2. 已插入的数据使用错误的编码保存 - -## 解决步骤 - -### 步骤 1: 清理乱码数据 - -在数据库中执行: - -```sql --- 删除表中的乱码数据 -DELETE FROM loan_pricing_workflow; -``` - -或删除表重建: - -```sql -DROP TABLE IF EXISTS `loan_pricing_workflow`; --- 然后重新执行 sql/loan_pricing_workflow.sql -``` - -### 步骤 2: 重启服务 - -配置文件已更新,需要重启后端服务使配置生效: - -```bash -# 停止当前服务 -pkill -f "ruoyi-admin.jar" - -# 重新打包(可选,如果没有修改代码) -cd d:\利率定价\loan-pricing-892\loan-pricing-892-v2.0 -mvn clean package -Dmaven.test.skip=true - -# 启动服务 -cd ruoyi-admin/target -java -jar ruoyi-admin.jar -``` - -### 步骤 3: 重新执行测试 - -```bash -cd d:\利率定价\loan-pricing-892\loan-pricing-892-v2.0 -bash run-api-tests.sh -``` - -## 配置说明 - -已修改的配置文件:`ruoyi-admin/src/main/resources/application-dev.yml` - -修改前: -```yaml -url: jdbc:mysql://...?useUnicode=true&characterEncoding=utf8&... -``` - -修改后: -```yaml -url: jdbc:mysql://...?useUnicode=true&characterEncoding=utf8mb4&... -``` - -## 验证方法 - -重启服务并插入新数据后,检查数据库: - -```sql -SELECT serial_num, cust_name, cust_type, guar_type FROM loan_pricing_workflow; -``` - -中文应该正常显示,例如: -- cust_name: "张三" (而不是乱码) -- cust_type: "个人" (而不是乱码) -- guar_type: "信用" (而不是乱码) diff --git a/openspec/AGENTS.md b/openspec/AGENTS.md deleted file mode 100644 index 6c1703e..0000000 --- a/openspec/AGENTS.md +++ /dev/null @@ -1,456 +0,0 @@ -# OpenSpec Instructions - -Instructions for AI coding assistants using OpenSpec for spec-driven development. - -## TL;DR Quick Checklist - -- Search existing work: `openspec spec list --long`, `openspec list` (use `rg` only for full-text search) -- Decide scope: new capability vs modify existing capability -- Pick a unique `change-id`: kebab-case, verb-led (`add-`, `update-`, `remove-`, `refactor-`) -- Scaffold: `proposal.md`, `tasks.md`, `design.md` (only if needed), and delta specs per affected capability -- Write deltas: use `## ADDED|MODIFIED|REMOVED|RENAMED Requirements`; include at least one `#### Scenario:` per requirement -- Validate: `openspec validate [change-id] --strict --no-interactive` and fix issues -- Request approval: Do not start implementation until proposal is approved - -## Three-Stage Workflow - -### Stage 1: Creating Changes -Create proposal when you need to: -- Add features or functionality -- Make breaking changes (API, schema) -- Change architecture or patterns -- Optimize performance (changes behavior) -- Update security patterns - -Triggers (examples): -- "Help me create a change proposal" -- "Help me plan a change" -- "Help me create a proposal" -- "I want to create a spec proposal" -- "I want to create a spec" - -Loose matching guidance: -- Contains one of: `proposal`, `change`, `spec` -- With one of: `create`, `plan`, `make`, `start`, `help` - -Skip proposal for: -- Bug fixes (restore intended behavior) -- Typos, formatting, comments -- Dependency updates (non-breaking) -- Configuration changes -- Tests for existing behavior - -**Workflow** -1. Review `openspec/project.md`, `openspec list`, and `openspec list --specs` to understand current context. -2. Choose a unique verb-led `change-id` and scaffold `proposal.md`, `tasks.md`, optional `design.md`, and spec deltas under `openspec/changes//`. -3. Draft spec deltas using `## ADDED|MODIFIED|REMOVED Requirements` with at least one `#### Scenario:` per requirement. -4. Run `openspec validate --strict --no-interactive` and resolve any issues before sharing the proposal. - -### Stage 2: Implementing Changes -Track these steps as TODOs and complete them one by one. -1. **Read proposal.md** - Understand what's being built -2. **Read design.md** (if exists) - Review technical decisions -3. **Read tasks.md** - Get implementation checklist -4. **Implement tasks sequentially** - Complete in order -5. **Confirm completion** - Ensure every item in `tasks.md` is finished before updating statuses -6. **Update checklist** - After all work is done, set every task to `- [x]` so the list reflects reality -7. **Approval gate** - Do not start implementation until the proposal is reviewed and approved - -### Stage 3: Archiving Changes -After deployment, create separate PR to: -- Move `changes/[name]/` → `changes/archive/YYYY-MM-DD-[name]/` -- Update `specs/` if capabilities changed -- Use `openspec archive --skip-specs --yes` for tooling-only changes (always pass the change ID explicitly) -- Run `openspec validate --strict --no-interactive` to confirm the archived change passes checks - -## Before Any Task - -**Context Checklist:** -- [ ] Read relevant specs in `specs/[capability]/spec.md` -- [ ] Check pending changes in `changes/` for conflicts -- [ ] Read `openspec/project.md` for conventions -- [ ] Run `openspec list` to see active changes -- [ ] Run `openspec list --specs` to see existing capabilities - -**Before Creating Specs:** -- Always check if capability already exists -- Prefer modifying existing specs over creating duplicates -- Use `openspec show [spec]` to review current state -- If request is ambiguous, ask 1–2 clarifying questions before scaffolding - -### Search Guidance -- Enumerate specs: `openspec spec list --long` (or `--json` for scripts) -- Enumerate changes: `openspec list` (or `openspec change list --json` - deprecated but available) -- Show details: - - Spec: `openspec show --type spec` (use `--json` for filters) - - Change: `openspec show --json --deltas-only` -- Full-text search (use ripgrep): `rg -n "Requirement:|Scenario:" openspec/specs` - -## Quick Start - -### CLI Commands - -```bash -# Essential commands -openspec list # List active changes -openspec list --specs # List specifications -openspec show [item] # Display change or spec -openspec validate [item] # Validate changes or specs -openspec archive [--yes|-y] # Archive after deployment (add --yes for non-interactive runs) - -# Project management -openspec init [path] # Initialize OpenSpec -openspec update [path] # Update instruction files - -# Interactive mode -openspec show # Prompts for selection -openspec validate # Bulk validation mode - -# Debugging -openspec show [change] --json --deltas-only -openspec validate [change] --strict --no-interactive -``` - -### Command Flags - -- `--json` - Machine-readable output -- `--type change|spec` - Disambiguate items -- `--strict` - Comprehensive validation -- `--no-interactive` - Disable prompts -- `--skip-specs` - Archive without spec updates -- `--yes`/`-y` - Skip confirmation prompts (non-interactive archive) - -## Directory Structure - -``` -openspec/ -├── project.md # Project conventions -├── specs/ # Current truth - what IS built -│ └── [capability]/ # Single focused capability -│ ├── spec.md # Requirements and scenarios -│ └── design.md # Technical patterns -├── changes/ # Proposals - what SHOULD change -│ ├── [change-name]/ -│ │ ├── proposal.md # Why, what, impact -│ │ ├── tasks.md # Implementation checklist -│ │ ├── design.md # Technical decisions (optional; see criteria) -│ │ └── specs/ # Delta changes -│ │ └── [capability]/ -│ │ └── spec.md # ADDED/MODIFIED/REMOVED -│ └── archive/ # Completed changes -``` - -## Creating Change Proposals - -### Decision Tree - -``` -New request? -├─ Bug fix restoring spec behavior? → Fix directly -├─ Typo/format/comment? → Fix directly -├─ New feature/capability? → Create proposal -├─ Breaking change? → Create proposal -├─ Architecture change? → Create proposal -└─ Unclear? → Create proposal (safer) -``` - -### Proposal Structure - -1. **Create directory:** `changes/[change-id]/` (kebab-case, verb-led, unique) - -2. **Write proposal.md:** -```markdown -# Change: [Brief description of change] - -## Why -[1-2 sentences on problem/opportunity] - -## What Changes -- [Bullet list of changes] -- [Mark breaking changes with **BREAKING**] - -## Impact -- Affected specs: [list capabilities] -- Affected code: [key files/systems] -``` - -3. **Create spec deltas:** `specs/[capability]/spec.md` -```markdown -## ADDED Requirements -### Requirement: New Feature -The system SHALL provide... - -#### Scenario: Success case -- **WHEN** user performs action -- **THEN** expected result - -## MODIFIED Requirements -### Requirement: Existing Feature -[Complete modified requirement] - -## REMOVED Requirements -### Requirement: Old Feature -**Reason**: [Why removing] -**Migration**: [How to handle] -``` -If multiple capabilities are affected, create multiple delta files under `changes/[change-id]/specs//spec.md`—one per capability. - -4. **Create tasks.md:** -```markdown -## 1. Implementation -- [ ] 1.1 Create database schema -- [ ] 1.2 Implement API endpoint -- [ ] 1.3 Add frontend component -- [ ] 1.4 Write tests -``` - -5. **Create design.md when needed:** -Create `design.md` if any of the following apply; otherwise omit it: -- Cross-cutting change (multiple services/modules) or a new architectural pattern -- New external dependency or significant data model changes -- Security, performance, or migration complexity -- Ambiguity that benefits from technical decisions before coding - -Minimal `design.md` skeleton: -```markdown -## Context -[Background, constraints, stakeholders] - -## Goals / Non-Goals -- Goals: [...] -- Non-Goals: [...] - -## Decisions -- Decision: [What and why] -- Alternatives considered: [Options + rationale] - -## Risks / Trade-offs -- [Risk] → Mitigation - -## Migration Plan -[Steps, rollback] - -## Open Questions -- [...] -``` - -## Spec File Format - -### Critical: Scenario Formatting - -**CORRECT** (use #### headers): -```markdown -#### Scenario: User login success -- **WHEN** valid credentials provided -- **THEN** return JWT token -``` - -**WRONG** (don't use bullets or bold): -```markdown -- **Scenario: User login** ❌ -**Scenario**: User login ❌ -### Scenario: User login ❌ -``` - -Every requirement MUST have at least one scenario. - -### Requirement Wording -- Use SHALL/MUST for normative requirements (avoid should/may unless intentionally non-normative) - -### Delta Operations - -- `## ADDED Requirements` - New capabilities -- `## MODIFIED Requirements` - Changed behavior -- `## REMOVED Requirements` - Deprecated features -- `## RENAMED Requirements` - Name changes - -Headers matched with `trim(header)` - whitespace ignored. - -#### When to use ADDED vs MODIFIED -- ADDED: Introduces a new capability or sub-capability that can stand alone as a requirement. Prefer ADDED when the change is orthogonal (e.g., adding "Slash Command Configuration") rather than altering the semantics of an existing requirement. -- MODIFIED: Changes the behavior, scope, or acceptance criteria of an existing requirement. Always paste the full, updated requirement content (header + all scenarios). The archiver will replace the entire requirement with what you provide here; partial deltas will drop previous details. -- RENAMED: Use when only the name changes. If you also change behavior, use RENAMED (name) plus MODIFIED (content) referencing the new name. - -Common pitfall: Using MODIFIED to add a new concern without including the previous text. This causes loss of detail at archive time. If you aren’t explicitly changing the existing requirement, add a new requirement under ADDED instead. - -Authoring a MODIFIED requirement correctly: -1) Locate the existing requirement in `openspec/specs//spec.md`. -2) Copy the entire requirement block (from `### Requirement: ...` through its scenarios). -3) Paste it under `## MODIFIED Requirements` and edit to reflect the new behavior. -4) Ensure the header text matches exactly (whitespace-insensitive) and keep at least one `#### Scenario:`. - -Example for RENAMED: -```markdown -## RENAMED Requirements -- FROM: `### Requirement: Login` -- TO: `### Requirement: User Authentication` -``` - -## Troubleshooting - -### Common Errors - -**"Change must have at least one delta"** -- Check `changes/[name]/specs/` exists with .md files -- Verify files have operation prefixes (## ADDED Requirements) - -**"Requirement must have at least one scenario"** -- Check scenarios use `#### Scenario:` format (4 hashtags) -- Don't use bullet points or bold for scenario headers - -**Silent scenario parsing failures** -- Exact format required: `#### Scenario: Name` -- Debug with: `openspec show [change] --json --deltas-only` - -### Validation Tips - -```bash -# Always use strict mode for comprehensive checks -openspec validate [change] --strict --no-interactive - -# Debug delta parsing -openspec show [change] --json | jq '.deltas' - -# Check specific requirement -openspec show [spec] --json -r 1 -``` - -## Happy Path Script - -```bash -# 1) Explore current state -openspec spec list --long -openspec list -# Optional full-text search: -# rg -n "Requirement:|Scenario:" openspec/specs -# rg -n "^#|Requirement:" openspec/changes - -# 2) Choose change id and scaffold -CHANGE=add-two-factor-auth -mkdir -p openspec/changes/$CHANGE/{specs/auth} -printf "## Why\n...\n\n## What Changes\n- ...\n\n## Impact\n- ...\n" > openspec/changes/$CHANGE/proposal.md -printf "## 1. Implementation\n- [ ] 1.1 ...\n" > openspec/changes/$CHANGE/tasks.md - -# 3) Add deltas (example) -cat > openspec/changes/$CHANGE/specs/auth/spec.md << 'EOF' -## ADDED Requirements -### Requirement: Two-Factor Authentication -Users MUST provide a second factor during login. - -#### Scenario: OTP required -- **WHEN** valid credentials are provided -- **THEN** an OTP challenge is required -EOF - -# 4) Validate -openspec validate $CHANGE --strict --no-interactive -``` - -## Multi-Capability Example - -``` -openspec/changes/add-2fa-notify/ -├── proposal.md -├── tasks.md -└── specs/ - ├── auth/ - │ └── spec.md # ADDED: Two-Factor Authentication - └── notifications/ - └── spec.md # ADDED: OTP email notification -``` - -auth/spec.md -```markdown -## ADDED Requirements -### Requirement: Two-Factor Authentication -... -``` - -notifications/spec.md -```markdown -## ADDED Requirements -### Requirement: OTP Email Notification -... -``` - -## Best Practices - -### Simplicity First -- Default to <100 lines of new code -- Single-file implementations until proven insufficient -- Avoid frameworks without clear justification -- Choose boring, proven patterns - -### Complexity Triggers -Only add complexity with: -- Performance data showing current solution too slow -- Concrete scale requirements (>1000 users, >100MB data) -- Multiple proven use cases requiring abstraction - -### Clear References -- Use `file.ts:42` format for code locations -- Reference specs as `specs/auth/spec.md` -- Link related changes and PRs - -### Capability Naming -- Use verb-noun: `user-auth`, `payment-capture` -- Single purpose per capability -- 10-minute understandability rule -- Split if description needs "AND" - -### Change ID Naming -- Use kebab-case, short and descriptive: `add-two-factor-auth` -- Prefer verb-led prefixes: `add-`, `update-`, `remove-`, `refactor-` -- Ensure uniqueness; if taken, append `-2`, `-3`, etc. - -## Tool Selection Guide - -| Task | Tool | Why | -|------|------|-----| -| Find files by pattern | Glob | Fast pattern matching | -| Search code content | Grep | Optimized regex search | -| Read specific files | Read | Direct file access | -| Explore unknown scope | Task | Multi-step investigation | - -## Error Recovery - -### Change Conflicts -1. Run `openspec list` to see active changes -2. Check for overlapping specs -3. Coordinate with change owners -4. Consider combining proposals - -### Validation Failures -1. Run with `--strict` flag -2. Check JSON output for details -3. Verify spec file format -4. Ensure scenarios properly formatted - -### Missing Context -1. Read project.md first -2. Check related specs -3. Review recent archives -4. Ask for clarification - -## Quick Reference - -### Stage Indicators -- `changes/` - Proposed, not yet built -- `specs/` - Built and deployed -- `archive/` - Completed changes - -### File Purposes -- `proposal.md` - Why and what -- `tasks.md` - Implementation steps -- `design.md` - Technical decisions -- `spec.md` - Requirements and behavior - -### CLI Essentials -```bash -openspec list # What's in progress? -openspec show [item] # View details -openspec validate --strict --no-interactive # Is it correct? -openspec archive [--yes|-y] # Mark complete (add --yes for automation) -``` - -Remember: Specs are truth. Changes are proposals. Keep them in sync. diff --git a/openspec/changes/add-bargaining-pool-display/design.md b/openspec/changes/add-bargaining-pool-display/design.md deleted file mode 100644 index 6882289..0000000 --- a/openspec/changes/add-bargaining-pool-display/design.md +++ /dev/null @@ -1,186 +0,0 @@ -# Design: 议价池显示组件 - -## Overview - -本文档描述议价池显示组件的详细设计,包括组件结构、数据流、样式规范和实现细节。 - -## Component Architecture - -### 组件层次结构 - -``` -detail.vue (流程详情页面) -├── left-panel (左侧关键信息卡片) -└── right-panel (右侧面板) - ├── detail-card (流程详情卡片) - ├── ModelOutputDisplay (模型输出组件) [已存在] - └── BargainingPoolDisplay (议价池显示组件) [新增] -``` - -### 组件职责 - -| 组件 | 职责 | -|------|------| -| `detail.vue` | 流程详情页面容器,负责数据获取和子组件协调 | -| `BargainingPoolDisplay.vue` | 议价池数据展示,独立封装议价池相关的 UI 和逻辑 | - -## Component Specification - -### BargainingPoolDisplay.vue - -#### Props - -| 属性名 | 类型 | 默认值 | 说明 | -|--------|------|--------|------| -| `branchPool` | Number/String | 0 | 网点议价池 | -| `subBranchPool` | Number/String | 0 | 支行议价池 | -| `privateDomainPool` | Number/String | 0 | 私域池 | - -#### Template Structure - -```vue - -``` - -#### Computed Properties - -| 属性名 | 说明 | -|--------|------| -| `displayBranchPool` | 返回网点议价池的显示值,处理 null/undefined/空字符串为 '0' | -| `displaySubBranchPool` | 返回支行议价池的显示值,处理 null/undefined/空字符串为 '0' | -| `displayPrivateDomainPool` | 返回私域池的显示值,处理 null/undefined/空字符串为 '0' | - -#### Style Specification - -议价池卡片样式将与 `ModelOutputDisplay` 保持一致: - -```scss -.bargaining-pool-card { - // 与 model-output-card 相同的样式 - ::v-deep .el-card__header { - padding: 16px 20px; - background-color: #fafafa; - border-bottom: 1px solid #ebeef5; - } - - .card-header { - display: flex; - align-items: center; - - .card-title { - font-size: 16px; - font-weight: 500; - color: #303133; - } - } - - ::v-deep .el-card__body { - padding: 20px; - } -} -``` - -## Data Flow - -### API 响应结构(预期) - -```javascript -{ - "data": { - "loanPricingWorkflow": { ... }, - "modelRetailOutputFields": { ... }, - "modelCorpOutputFields": { ... }, - "bargainingPool": { // 新增字段 - "branchPool": 10, // 网点议价池 - "subBranchPool": 5, // 支行议价池 - "privateDomainPool": 3 // 私域池 - } - } -} -``` - -### 组件集成 - -在 `detail.vue` 中: - -```javascript -// data -bargainingPool: null, - -// created() 中获取数据 -getWorkflow(serialNum).then(response => { - this.workflowDetail = response.data.loanPricingWorkflow - this.retailOutput = response.data.modelRetailOutputFields - this.corpOutput = response.data.modelCorpOutputFields - this.bargainingPool = response.data.bargainingPool // 新增 - this.loading = false -}) -``` - -```vue - - -``` - -## Error Handling - -### 数据缺失处理 - -当 API 响应中没有议价池数据时: -- 组件使用默认值 0 显示 -- 不显示错误提示 -- 保证页面正常展示 - -### 值格式化 - -```javascript -computed: { - displayBranchPool() { - const value = this.branchPool - if (value === null || value === undefined || value === '') { - return '0' - } - return value - }, - // ... 其他字段类似 -} -``` - -## Testing Considerations - -### 单元测试场景 -1. 组件渲染时显示默认值 0 -2. 传入正确的议价池数据时正确显示 -3. 处理 null/undefined 值时显示 0 - -### 集成测试场景 -1. 流程详情页面加载时议价池卡片正确显示 -2. 议价池卡片位置在模型输出卡片下方 -3. 样式与模型输出卡片保持一致 - -## Future Enhancements - -1. **后端数据对接**:当后端提供议价池 API 时,移除默认值逻辑 -2. **单位显示**:确认议价池数值单位(BP 或金额)后添加单位标签 -3. **交互功能**:可能需要添加议价池的编辑或调整功能 diff --git a/openspec/changes/add-bargaining-pool-display/proposal.md b/openspec/changes/add-bargaining-pool-display/proposal.md deleted file mode 100644 index d4afb65..0000000 --- a/openspec/changes/add-bargaining-pool-display/proposal.md +++ /dev/null @@ -1,85 +0,0 @@ -# Proposal: 添加议价池显示组件 - -## Summary - -在流程详情页面中,在"模型输出"卡片下方添加一个新的"议价池"卡片,用于展示网点议价池、支行议价池和私域池三个字段。默认值均为 0。 - -## Motivation - -当前流程详情页面展示了模型输出的详细信息,但缺少议价池相关的数据展示。议价池是贷款定价业务中的重要参考指标,需要将其添加到详情页面以便用户查看。 - -## Proposed Change - -### Scope -仅修改前端流程详情页面,在模型输出组件下方添加议价池显示组件。 - -### Components Affected -- `ruoyi-ui/src/views/loanPricing/workflow/detail.vue` - 添加议价池组件 - -### Components to Create -- `ruoyi-ui/src/views/loanPricing/workflow/components/BargainingPoolDisplay.vue` - 新建议价池显示组件 - -## Design Approach - -### UI 结构 -议价池卡片将使用与模型输出卡片相同的样式风格,包含: -- 卡片标题:议价池 -- 三个字段展示: - - 网点议价池(默认值:0) - - 支行议价池(默认值:0) - - 私域池(默认值:0) - -### 组件设计 -- 创建独立的 `BargainingPoolDisplay.vue` 组件 -- 使用 `el-descriptions` 组件展示字段 -- 支持通过 props 传入议价池数据 -- 默认值处理:当数据为空或未定义时显示 0 - -### 数据来源 -- 议价池数据将从后端 API 响应中获取 -- 暂时使用默认值 0,后续由后端提供实际数据 - -## Alternatives Considered - -1. **将议价池字段添加到模型输出组件内部** - - 优点:减少组件数量 - - 缺点:模型输出组件已比较复杂,议价池是独立的业务概念,应独立展示 - - 结论:不采用 - -2. **将议价池字段添加到流程详情卡片中** - - 优点:集中展示流程相关信息 - - 缺点:议价池与流程基本信息关联性较弱,与模型输出更相关 - - 结论:不采用 - -3. **创建独立的议价池组件(已选方案)** - - 优点:职责清晰、易于维护、与模型输出组件并列展示 - - 缺点:增加一个组件文件 - - 结论:采用 - -## Dependencies - -- 依赖现有的 `el-card` 和 `el-descriptions` 组件 -- 依赖后端 API 返回议价池数据(当前可使用默认值) - -## Rollout Plan - -1. 创建 `BargainingPoolDisplay.vue` 组件 -2. 在 `detail.vue` 中引入并使用该组件 -3. 传递议价池数据(当前使用默认值) -4. 测试页面展示效果 - -## Success Criteria - -- 议价池卡片正确显示在模型输出卡片下方 -- 三个字段(网点议价池、支行议价池、私域池)正确显示 -- 默认值显示为 0 -- 样式与现有卡片保持一致 - -## Open Questions - -1. 议价池数据的具体字段名称是什么? - - 待确认:后端 API 中的议价池字段命名 - -2. 议价池数据的数值类型和单位是什么? - - 假设为数值类型(BP 或金额) - - 待后端确认 diff --git a/openspec/changes/add-bargaining-pool-display/specs/loan-pricing-workflow-ui/spec.md b/openspec/changes/add-bargaining-pool-display/specs/loan-pricing-workflow-ui/spec.md deleted file mode 100644 index 892d24f..0000000 --- a/openspec/changes/add-bargaining-pool-display/specs/loan-pricing-workflow-ui/spec.md +++ /dev/null @@ -1,42 +0,0 @@ -# loan-pricing-workflow-ui Spec Delta - -## ADDED Requirements - -### Requirement: 议价池信息展示 - -系统 SHALL 在流程详情页面的模型输出信息下方展示议价池信息。 - -#### Scenario: 显示议价池信息 - -- **WHEN** 用户访问流程详情页面 -- **THEN** 系统在模型输出卡片下方显示"议价池"卡片,包含以下三个字段: - - 网点议价池:数值类型,默认值为 0 - - 支行议价池:数值类型,默认值为 0 - - 私域池:数值类型,默认值为 0 - -#### Scenario: 议价池数据格式化 - -- **WHEN** 议价池数据为 null、undefined 或空字符串 -- **THEN** 系统将显示值格式化为 "0" - -#### Scenario: 议价池卡片样式 - -- **WHEN** 用户查看流程详情页面 -- **THEN** 议价池卡片的样式(标题栏、边框、内边距)与模型输出卡片保持一致 - -### Requirement: 议价池组件封装 - -系统 SHALL 将议价池展示功能封装为独立的 Vue 组件。 - -#### Scenario: 组件独立性 - -- **WHEN** 议价池显示组件被创建 -- **THEN** 组件文件位于 `ruoyi-ui/src/views/loanPricing/workflow/components/BargainingPoolDisplay.vue` - -#### Scenario: 组件 Props 接口 - -- **WHEN** 父组件使用议价池显示组件 -- **THEN** 组件接收以下 props: - - `branch-pool`:网点议价池值(Number/String),默认值为 0 - - `sub-branch-pool`:支行议价池值(Number/String),默认值为 0 - - `private-domain-pool`:私域池值(Number/String),默认值为 0 diff --git a/openspec/changes/add-bargaining-pool-display/tasks.md b/openspec/changes/add-bargaining-pool-display/tasks.md deleted file mode 100644 index 6485c55..0000000 --- a/openspec/changes/add-bargaining-pool-display/tasks.md +++ /dev/null @@ -1,68 +0,0 @@ -# Tasks: 添加议价池显示组件 - -## Task List - -### 1. 创建议价池显示组件 ✅ -**文件**: `ruoyi-ui/src/views/loanPricing/workflow/components/BargainingPoolDisplay.vue` - -**描述**: 创建新的 Vue 组件用于展示议价池信息 - -**验收标准**: -- [x] 组件使用 `el-card` 包装,标题为"议价池" -- [x] 使用 `el-descriptions` 展示三个字段:网点议价池、支行议价池、私域池 -- [x] 定义 props:`branchPool`、`subBranchPool`、`privateDomainPool`,默认值为 0 -- [x] 实现计算属性处理 null/undefined/空字符串,返回 '0' -- [x] 样式与 `ModelOutputDisplay` 保持一致 - -**依赖**: 无 - ---- - -### 2. 在详情页面中引入并使用议价池组件 ✅ -**文件**: `ruoyi-ui/src/views/loanPricing/workflow/detail.vue` - -**描述**: 在流程详情页面中引入并配置议价池组件 - -**验收标准**: -- [x] 在 `components` 中注册 `BargainingPoolDisplay` 组件 -- [x] 在 `data` 中添加 `bargainingPool: null` -- [x] 在 `getDetail()` 方法中从 API 响应获取议价池数据:`response.data.bargainingPool` -- [x] 在 template 中,`ModelOutputDisplay` 组件下方添加 `BargainingPoolDisplay` 组件 -- [x] 传递 props:`:branch-pool`、`:sub-branch-pool`、`:private-domain-pool` - -**依赖**: Task 1 - ---- - -### 3. 验证页面展示效果 ✅ -**描述**: 启动前端开发服务器,验证议价池组件正确显示 - -**验收标准**: -- [x] 访问任意流程详情页面 -- [x] 确认议价池卡片显示在模型输出卡片下方 -- [x] 确认三个字段显示为 "0"(默认值) -- [x] 确认卡片样式与模型输出卡片一致 - -**依赖**: Task 1, Task 2 - ---- - -## Dependencies Graph - -``` -Task 1 (创建组件) ✅ - ↓ -Task 2 (集成到详情页) ✅ - ↓ -Task 3 (验证效果) ✅ -``` - -## Implementation Notes - -- 使用 `&&` 操作符替代可选链 `?.` 以兼容 Vue 2.6 -- 构建验证通过 (`npm run build:prod` 完成) - -## Notes - -- 当前使用默认值 0,后续后端提供议价池 API 后需要更新数据获取逻辑 -- 议价池数值的单位(BP 或金额)尚未确认,暂不添加单位标签 diff --git a/openspec/changes/add-execute-rate-ui/proposal.md b/openspec/changes/add-execute-rate-ui/proposal.md deleted file mode 100644 index 1693e57..0000000 --- a/openspec/changes/add-execute-rate-ui/proposal.md +++ /dev/null @@ -1,45 +0,0 @@ -# 提案: 添加执行利率设定前端功能 - -## 背景 - -后端已经实现了执行利率设定接口 `PUT /loanPricing/workflow/{serialNum}/executeRate`,并且详情接口 `GET /loanPricing/workflow/{serialNum}` 已经返回 `executeRate` 字段。但前端缺少相应的 UI 交互功能,业务人员无法通过界面设定执行利率。 - -## 问题 - -1. 议价池组件中只显示议价池数据,没有执行利率输入框 -2. 前端缺少调用设定执行利率接口的 API 方法 -3. 用户无法通过界面设定或更新执行利率 - -## 提案概述 - -在流程详情页面的议价池组件中添加执行利率设定功能,允许业务人员输入执行利率并提交。 - -### 功能范围 - -1. **API 方法** - - 在 `ruoyi-ui/src/api/loanPricing/workflow.js` 中添加 `setExecuteRate` 方法 - -2. **议价池组件更新** - - 在 `BargainingPoolDisplay.vue` 中添加执行利率输入框和提交按钮 - - 添加执行利率显示/编辑状态的切换 - - 支持显示已设定的执行利率值 - - 添加表单验证(利率格式) - -3. **详情页面更新** - - 在 `detail.vue` 中传递 `executeRate` 和 `serialNum` 给议价池组件 - - 添加提交成功后刷新详情的处理 - -## 影响范围 - -- 前端 API: `ruoyi-ui/src/api/loanPricing/workflow.js` -- 前端组件: `ruoyi-ui/src/views/loanPricing/workflow/components/BargainingPoolDisplay.vue` -- 前端页面: `ruoyi-ui/src/views/loanPricing/workflow/detail.vue` -- 规范: `loan-pricing-workflow-ui` (添加新需求) - -## 设计考虑 - -1. **UI 位置**: 在议价池组件中添加新行,保持与现有议价池数据显示的一致性 -2. **输入验证**: 利率格式验证(数字,可含小数点,范围合理) -3. **状态管理**: 编辑/查看状态切换,提交成功后显示最新值 -4. **用户反馈**: 提交成功/失败的提示消息 -5. **权限控制**: 后端接口无需特殊权限,前端暂不添加权限控制 diff --git a/openspec/changes/add-execute-rate-ui/specs/loan-pricing-workflow-ui/spec.md b/openspec/changes/add-execute-rate-ui/specs/loan-pricing-workflow-ui/spec.md deleted file mode 100644 index 31ff252..0000000 --- a/openspec/changes/add-execute-rate-ui/specs/loan-pricing-workflow-ui/spec.md +++ /dev/null @@ -1,45 +0,0 @@ -## ADDED Requirements - -### Requirement: 执行利率设定 - -系统 SHALL 在流程详情页面的议价池组件中提供执行利率设定功能,允许用户输入并提交执行利率。 - -#### Scenario: 显示未设定的执行利率 - -- **WHEN** 用户在流程详情页面查看议价池组件,且该流程尚未设定执行利率 -- **THEN** 系统在议价池组件中显示"执行利率"行,当前值显示为"-" - -#### Scenario: 显示已设定的执行利率 - -- **WHEN** 用户在流程详情页面查看议价池组件,且该流程已设定执行利率 -- **THEN** 系统在议价池组件中显示"执行利率"行,显示当前设定的执行利率值 - -#### Scenario: 进入编辑模式 - -- **WHEN** 用户在议价池组件中点击"执行利率"行的编辑按钮 -- **THEN** 系统切换到编辑模式,显示输入框(预填充当前值或空)、提交按钮和取消按钮 - -#### Scenario: 提交执行利率成功 - -- **WHEN** 用户在编辑模式下输入有效的执行利率值并点击提交按钮 -- **THEN** 系统调用 `PUT /loanPricing/workflow/{serialNum}/executeRate` 接口,成功后更新显示值为新设定的利率,显示成功提示消息,并退出编辑模式 - -#### Scenario: 提交执行利率失败 - -- **WHEN** 用户在编辑模式下提交执行利率,但后端接口返回错误 -- **THEN** 系统保持编辑模式,显示错误提示消息 - -#### Scenario: 取消编辑 - -- **WHEN** 用户在编辑模式下点击取消按钮 -- **THEN** 系统退出编辑模式,恢复显示模式,显示原来的执行利率值 - -#### Scenario: 输入验证 - -- **WHEN** 用户在编辑模式下输入非法的执行利率值(非数字、超出合理范围) -- **THEN** 系统在提交前进行验证,显示错误提示,阻止提交 - -#### Scenario: API 接口调用 - -- **WHEN** 用户提交执行利率 -- **THEN** 前端调用 `setExecuteRate(serialNum, executeRate)` API 方法,该方法发送 `PUT /loanPricing/workflow/{serialNum}/executeRate` 请求 diff --git a/openspec/changes/add-execute-rate-ui/tasks.md b/openspec/changes/add-execute-rate-ui/tasks.md deleted file mode 100644 index 4e76b54..0000000 --- a/openspec/changes/add-execute-rate-ui/tasks.md +++ /dev/null @@ -1,85 +0,0 @@ -# 实施任务 - -## 任务清单 - -1. **添加 API 方法** - - 文件: `ruoyi-ui/src/api/loanPricing/workflow.js` - - 操作: 添加 `setExecuteRate(serialNum, executeRate)` 方法 - - 请求: `PUT /loanPricing/workflow/{serialNum}/executeRate` - - 验证: 方法添加成功 - -2. **更新议价池组件 - Props** - - 文件: `ruoyi-ui/src/views/loanPricing/workflow/components/BargainingPoolDisplay.vue` - - 操作: 添加 `executeRate` 和 `serialNum` props - - 验证: props 定义成功 - -3. **更新议价池组件 - UI** - - 文件: `ruoyi-ui/src/views/loanPricing/workflow/components/BargainingPoolDisplay.vue` - - 操作: 在 el-descriptions 中添加"执行利率"行,包含: - - 显示模式: 显示当前执行利率值(若无则显示"-") - - 编辑模式: 输入框 + 提交按钮 + 取消按钮 - - 编辑按钮: 在显示模式下点击进入编辑模式 - - 验证: UI 更新成功 - -4. **更新议价池组件 - 数据和逻辑** - - 文件: `ruoyi-ui/src/views/loanPricing/workflow/components/BargainingPoolDisplay.vue` - - 操作: - - 添加 `isEditing` 状态变量 - - 添加 `tempExecuteRate` 临时输入值 - - 添加 `handleEdit` 方法进入编辑模式 - - 添加 `handleSubmit` 方法调用 API 并处理响应 - - 添加 `handleCancel` 方法取消编辑 - - 添加输入验证(数字格式、范围检查) - - 验证: 逻辑实现完整 - -5. **更新议价池组件 - API 调用** - - 文件: `ruoyi-ui/src/views/loanPricing/workflow/components/BargainingPoolDisplay.vue` - - 操作: 引入 `setExecuteRate` API 方法 - - 验证: 引入成功 - -6. **更新详情页面 - 传递 Props** - - 文件: `ruoyi-ui/src/views/loanPricing/workflow/detail.vue` - - 操作: 在 BargainingPoolDisplay 组件上传递: - - `:execute-rate="workflowDetail.executeRate"` - - `:serial-num="workflowDetail.serialNum"` - - `@execute-rate-updated="handleExecuteRateUpdated"` - - 验证: props 传递正确 - -7. **前端功能验证** - - 操作: - - 启动前端服务 - - 打开流程详情页面 - - 测试首次设定执行利率 - - 测试更新已设定的执行利率 - - 测试输入验证 - - 测试取消编辑 - - 验证: - - 未设定时显示"-" - - 已设定时显示当前值 - - 点击编辑按钮进入编辑模式 - - 输入框显示当前值 - - 提交成功后显示新值并显示成功提示 - - 取消编辑恢复显示模式 - - 输入非法值时显示错误提示 - -## 依赖关系 - -- 任务 1 必须首先执行(API 方法) -- 任务 2-5 依次执行(Props -> UI -> 数据逻辑 -> API 调用) -- 任务 6 依赖任务 2 -- 任务 7 在所有代码任务完成后执行 - -## 验收标准 - -- [x] API 方法 `setExecuteRate` 添加成功 -- [x] 议价池组件添加 `executeRate` 和 `serialNum` props -- [x] 议价池组件显示执行利率行 -- [x] 未设定时显示"-" -- [x] 已设定时显示当前值 -- [x] 编辑按钮切换到编辑模式 -- [x] 输入框显示当前值 -- [x] 提交按钮调用 API 成功 -- [x] 提交成功后更新显示并显示成功提示 -- [x] 取消按钮恢复显示模式 -- [x] 输入验证正确工作 -- [x] 详情页面正确传递 props diff --git a/openspec/changes/add-execute-rate/design.md b/openspec/changes/add-execute-rate/design.md deleted file mode 100644 index 5db4538..0000000 --- a/openspec/changes/add-execute-rate/design.md +++ /dev/null @@ -1,153 +0,0 @@ -# 设计文档: 执行利率设定接口 - -## 数据库设计 - -### 表结构变更 - -**表名**: `loan_pricing_workflow` - -**新增字段**: - -| 字段名 | 类型 | 可空 | 默认值 | 说明 | -|--------------|-------------|----|------|---------| -| execute_rate | varchar(20) | 是 | NULL | 执行利率(%) | - -**DDL**: - -```sql -ALTER TABLE `loan_pricing_workflow` -ADD COLUMN `execute_rate` varchar(20) DEFAULT NULL COMMENT '执行利率(%)' AFTER `loan_rate`; -``` - -## 接口设计 - -### 设定执行利率接口 - -**请求方式**: `PUT /loanPricing/workflow/{serialNum}/executeRate` - -**权限要求**: 无特殊权限要求(与查询接口一致) - -**路径参数**: - -| 参数名 | 类型 | 必填 | 说明 | -|-----------|--------|----|--------| -| serialNum | String | 是 | 业务方流水号 | - -**请求体**: - -```json -{ - "executeRate": "4.20" -} -``` - -**参数说明**: - -| 参数名 | 类型 | 必填 | 说明 | -|-------------|--------|----|----------------------| -| executeRate | String | 是 | 执行利率,字符串格式(如 "4.20") | - -**响应示例**: - -成功 (200): - -```json -{ - "code": 200, - "msg": "设定成功" -} -``` - -失败 (404): - -```json -{ - "code": 404, - "msg": "记录不存在" -} -``` - -失败 (500): - -```json -{ - "code": 500, - "msg": "设定失败" -} -``` - -## 代码设计 - -### Entity 层 - -**LoanPricingWorkflow.java** - -```java -/** 执行利率(%) */ -private String executeRate; -``` - -### Service 层 - -**ILoanPricingWorkflowService.java** - -```java -/** - * 设定执行利率 - * @param serialNum 业务方流水号 - * @param executeRate 执行利率 - * @return 是否成功 - */ -boolean setExecuteRate(String serialNum, String executeRate); -``` - -**LoanPricingWorkflowServiceImpl.java** - -- 实现上述方法 -- 根据 `serialNum` 更新记录的 `execute_rate` 字段 -- MyBatis Plus 会自动填充 `update_by` 和 `update_time` - -### Controller 层 - -**LoanPricingWorkflowController.java** - -```java -/** - * 设定执行利率 - */ -@Operation(summary = "设定执行利率") -@Log(title = "利率定价流程", businessType = BusinessType.UPDATE) -@PutMapping("/{serialNum}/executeRate") -public AjaxResult setExecuteRate( - @Parameter(description = "业务方流水号") - @PathVariable("serialNum") String serialNum, - @RequestBody Map request) -{ - String executeRate = request.get("executeRate"); - boolean success = loanPricingWorkflowService.setExecuteRate(serialNum, executeRate); - return success ? success() : error("设定失败"); -} -``` - -### VO 层变更 - -**LoanPricingWorkflowVO.java** - -- 添加 `executeRate` 字段到 VO,确保详情接口返回执行利率 - -## 数据校验 - -1. **记录存在性**: 根据 `serialNum` 查询记录,不存在则返回 404 -2. **更新结果检查**: 检查更新操作影响行数,0 行表示记录不存在 -3. **格式校验**: 执行利率为字符串格式,前端传递格式化后的值(如 "4.20") - -## 事务处理 - -- 使用 MyBatis Plus 的 `updateById` 方法,自动处理事务 -- 更新失败时抛出异常,由全局异常处理器处理 - -## 日志记录 - -- 使用 `@Log` 注解记录操作日志 -- 日志类型: `BusinessType.UPDATE` -- 自动记录操作人和操作时间 diff --git a/openspec/changes/add-execute-rate/proposal.md b/openspec/changes/add-execute-rate/proposal.md deleted file mode 100644 index 0cc7d75..0000000 --- a/openspec/changes/add-execute-rate/proposal.md +++ /dev/null @@ -1,63 +0,0 @@ -# 提案: 添加执行利率设定接口 - -## 背景 - -当前利率定价流程已有测算利率(模型输出计算得到),但缺少最终执行利率的设定功能。业务人员需要根据模型测算结果和实际情况,手动设定最终执行的贷款利率。 - -## 问题 - -1. 数据库表中没有存储执行利率的字段 -2. 后端缺少设定执行利率的接口 -3. API 文档需要更新 - -## 提案概述 - -为利率定价流程添加执行利率设定功能,允许业务人员为流程记录设定/更新最终执行利率。 - -### 功能范围 - -1. **数据库变更** - - 在 `loan_pricing_workflow` 表中添加 `execute_rate` 字段 - -2. **后端接口** - - 新增 `PUT /loanPricing/workflow/{serialNum}/executeRate` 接口 - - 支持设定和更新执行利率 - - 无需特殊权限控制(与查询接口保持一致) - - 可多次修改执行利率 - -3. **API 文档更新** - - 在 `doc/api/loan-pricing-workflow-api.md` 中添加新接口文档 - -## 影响范围 - -- 数据库: `loan_pricing_workflow` 表 -- 后端: - - Entity: `LoanPricingWorkflow.java` - - Service: `ILoanPricingWorkflowService.java` 及实现类 - - Controller: `LoanPricingWorkflowController.java` -- 文档: `doc/api/loan-pricing-workflow-api.md` - -## 设计考虑 - -1. **字段类型**: 使用 `varchar(20)` 类型,与 `loan_rate` 保持一致 -2. **可空性**: 允许为 NULL,未设定时返回 null -3. **可修改性**: 允许多次修改,记录 `update_by` 和 `update_time` -4. **权限控制**: 暂不加独立权限,所有登录用户可操作(后续可根据需要添加) -5. **接口语义**: 使用 PUT 语义表示更新资源 - -## 替代方案 - -### 方案 A: 添加专门的审批流程(未采纳) - -- **优点**: 流程更规范,支持审批 -- **缺点**: 实现复杂度高,当前需求不明确 - -### 方案 B: 在创建接口中直接支持(未采纳) - -- **优点**: 减少接口数量 -- **缺点**: 业务上执行利率是在查看测算结果后设定的,与创建分离更合理 - -### 方案 C: 独立的设定接口(采纳) - -- **优点**: 职责清晰,实现简单,支持多次修改 -- **缺点**: 无明显缺点 diff --git a/openspec/changes/add-execute-rate/specs/loan-pricing-workflow/spec.md b/openspec/changes/add-execute-rate/specs/loan-pricing-workflow/spec.md deleted file mode 100644 index 3b54189..0000000 --- a/openspec/changes/add-execute-rate/specs/loan-pricing-workflow/spec.md +++ /dev/null @@ -1,27 +0,0 @@ -# loan-pricing-workflow Delta - -## ADDED Requirements - -### Requirement: 执行利率设定 - -系统 SHALL 提供设定执行利率的接口,允许业务人员为利率定价流程设定或更新最终执行利率。 - -#### Scenario: 设定执行利率 - -- **WHEN** 业务人员对已存在的利率定价流程调用设定执行利率接口,提供有效的业务方流水号和执行利率值 -- **THEN** 系统更新该流程记录的执行利率字段,返回成功响应,并自动记录更新者和更新时间 - -#### Scenario: 更新已有执行利率 - -- **WHEN** 业务人员对已设定执行利率的流程再次调用设定接口 -- **THEN** 系统覆盖更新执行利率为新的值 - -#### Scenario: 设定不存在的流程 - -- **WHEN** 业务人员提供的业务方流水号不存在 -- **THEN** 系统返回"记录不存在"的错误信息 - -#### Scenario: 执行利率在详情中返回 - -- **WHEN** 业务人员查询流程详情 -- **THEN** 系统在响应数据中包含 `executeRate` 字段(如果已设定则返回值,否则返回 null) diff --git a/openspec/changes/add-execute-rate/tasks.md b/openspec/changes/add-execute-rate/tasks.md deleted file mode 100644 index c02aeda..0000000 --- a/openspec/changes/add-execute-rate/tasks.md +++ /dev/null @@ -1,77 +0,0 @@ -# 实施任务 - -## 任务清单 - -1. **添加数据库字段** - - 文件: 创建 SQL 迁移脚本 `sql/add_execute_rate_field.sql` - - 操作: 在 `loan_pricing_workflow` 表中添加 `execute_rate` 字段 - - - DDL: `ALTER TABLE loan_pricing_workflow ADD COLUMN execute_rate varchar(20) DEFAULT NULL COMMENT '执行利率(%)' AFTER loan_rate;` - - 验证: 字段添加成功 - -2. **更新 Entity 类** - - 文件: `ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/entity/LoanPricingWorkflow.java` - - 操作: 添加 `executeRate` 字段及注释 - - 验证: 字段添加成功,位于 `loanRate` 字段之后 - -3. **更新 VO 类** - - 文件: `ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/vo/LoanPricingWorkflowVO.java` - - 操作: 添加 `executeRate` 字段及注释 - - 验证: 字段添加成功 - -4. **更新 Service 接口** - - 文件: `ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/ILoanPricingWorkflowService.java` - - 操作: 添加 `setExecuteRate(String serialNum, String executeRate)` 方法声明 - - 验证: 方法添加成功 - -5. **实现 Service 方法** - - 文件: `ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/impl/LoanPricingWorkflowServiceImpl.java` - - 操作: 实现 `setExecuteRate` 方法 - - 逻辑: 根据 serialNum 查询记录,更新 execute_rate 字段 - - 验证: 方法实现完成 - -6. **添加 Controller 接口** - - 文件: `ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/controller/LoanPricingWorkflowController.java` - - 操作: 添加 `PUT /{serialNum}/executeRate` 接口方法 - - 验证: 接口添加成功,添加 Swagger 注解 - -7. **更新 API 文档** - - 文件: `doc/api/loan-pricing-workflow-api.md` - - 操作: 在接口列表中添加"设定执行利率"接口文档 - - 内容: 接口地址、请求参数、响应示例、说明 - - 验证: 文档更新完整 - -8. **后端编译验证** - - 操作: 运行 `mvn clean compile` 或 IDE 编译 - - 验证: 编译成功无错误 - -9. **接口功能验证** - - 操作: - - 启动后端服务 - - 调用 `PUT /loanPricing/workflow/{serialNum}/executeRate` 接口 - - 调用 `GET /loanPricing/workflow/{serialNum}` 接口验证返回值 - - 验证: - - 设定执行利率成功 - - 再次设定可覆盖更新 - - 不存在的 serialNum 返回 404 - - 详情接口正确返回 executeRate - -## 依赖关系 - -- 任务 1 必须首先执行(数据库字段) -- 任务 2、3 可并行执行(Entity 和 VO) -- 任务 4、5 依次执行(Service 接口 -> 实现) -- 任务 6 依赖任务 5 -- 任务 7 可在任务 6 完成后执行 -- 任务 8、9 依次执行 - -## 验收标准 - -- [x] 数据库字段 `execute_rate` 添加成功 -- [x] Entity 和 VO 类添加 `executeRate` 字段 -- [x] Service 接口和实现方法添加成功 -- [x] Controller 接口添加成功并编译通过 -- [x] API 文档更新完整 -- [x] 接口调用成功,执行利率正确保存 -- [x] 详情接口正确返回 `executeRate` -- [x] 不存在的记录返回 404 diff --git a/openspec/changes/add-model-output-display/design.md b/openspec/changes/add-model-output-display/design.md deleted file mode 100644 index 08fc8a4..0000000 --- a/openspec/changes/add-model-output-display/design.md +++ /dev/null @@ -1,160 +0,0 @@ -# 设计文档: 模型输出展示 - -## 概述 - -本文档描述在流程详情页面中添加模型输出展示功能的技术设计。 - -## 页面结构 - -### 当前布局 - -``` -┌─────────────────────────────────────────────────────────┐ -│ 页面标题: 流程详情 [返回按钮] │ -├──────────────────────┬──────────────────────────────────┤ -│ 关键信息摘要 (30%) │ 详情标签页 (70%) │ -│ ┌────────────────┐ │ ┌────────────────────────────┐ │ -│ │ 流水号 │ │ │ [基本信息][业务信息]... │ │ -│ │ 客户名称 │ │ │ │ │ -│ │ 客户类型 │ │ │ 字段内容... │ │ -│ │ 申请金额 │ │ │ │ │ -│ │ 贷款利率 │ │ │ │ │ -│ │ 担保方式 │ │ │ │ │ -│ └────────────────┘ │ └────────────────────────────┘ │ -└──────────────────────┴──────────────────────────────────┘ -``` - -### 新增布局 - -``` -┌─────────────────────────────────────────────────────────┐ -│ 页面标题: 流程详情 [返回按钮] │ -├──────────────────────┬──────────────────────────────────┤ -│ 关键信息摘要 (30%) │ 详情标签页 (70%) │ -│ ┌────────────────┐ │ ┌────────────────────────────┐ │ -│ │ 流水号 │ │ │ [基本信息][业务信息]... │ │ -│ │ 客户名称 │ │ │ │ │ -│ │ 客户类型 │ │ │ 字段内容... │ │ -│ │ 申请金额 │ │ │ │ │ -│ │ 贷款利率 │ │ │ │ │ -│ │ 担保方式 │ │ │ │ │ -│ └────────────────┘ │ └────────────────────────────┘ │ -├──────────────────────┴──────────────────────────────────┤ -│ 模型输出 (当有数据时显示) │ -│ ┌────────────────────────────────────────────────────┐│ -│ │ [基本信息][忠诚度分析][贡献度分析]... ││ -│ │ ││ -│ │ 字段内容... ││ -│ └────────────────────────────────────────────────────┘│ -└─────────────────────────────────────────────────────────┘ -``` - -## 组件设计 - -### ModelOutputDisplay 组件 - -建议创建独立的模型输出展示组件,便于维护和复用。 - -```vue - -``` - -## 数据流 - -### API 响应结构 - -```json -{ - "code": 200, - "msg": "查询成功", - "data": { - "loanPricingWorkflow": { ... }, - "modelRetailOutputFields": { ... }, // 个人客户时存在 - "modelCorpOutputFields": { ... } // 企业客户时存在 - } -} -``` - -### 组件 Props - -| Prop | 类型 | 说明 | -|------|------|------| -| custType | String | 客户类型(个人/企业) | -| retailOutput | Object | 个人客户模型输出数据 | -| corpOutput | Object | 企业客户模型输出数据 | - -## 样式规范 - -### 卡片样式 - -与现有 `.summary-card` 和 `.detail-card` 保持一致: - -- 头部背景色: `#fafafa` -- 边框颜色: `#ebeef5` -- 内边距: 头部 `16px 20px`, 内容 `20px` -- 标题字号: `16px`, 字重 `500` -- 标题颜色: `#303133` - -### Tab 样式 - -使用 Element UI 默认 Tab 样式,间距保持一致。 - -## 字段映射表 - -### 个人客户模型输出字段 - -| Tab | 字段名 | 显示标签 | 格式化 | -|-----|--------|----------|--------| -| 基本信息 | custIsn | 客户内码 | - | -| 基本信息 | custName | 客户名称 | - | -| 基本信息 | idType | 证件类型 | - | -| 基本信息 | idNum | 证件号码 | - | -| 基本信息 | baseLoanRate | 基准利率 | - | -| 测算结果 | totalBp | 浮动BP | - | -| 测算结果 | calculateRate | 测算利率 | 高亮显示 | - -### 企业客户模型输出字段 - -| Tab | 字段名 | 显示标签 | 格式化 | -|-----|--------|----------|--------| -| 基本信息 | custIsn | 客户内码 | - | -| 基本信息 | custName | 客户名称 | - | -| 基本信息 | idType | 证件类型 | - | -| 基本信息 | idNum | 证件号码 | - | -| 基本信息 | baseLoanRate | 基准利率 | - | -| 测算结果 | totalBp | 浮动BP | - | -| 测算结果 | calculateRate | 测算利率 | 高亮显示 | - -## 响应式设计 - -- 桌面端 (≥768px): 模型输出卡片宽度 100%,Tab 内容两列布局 -- 移动端 (<768px): 模型输出卡片宽度 100%,Tab 内容单列布局 diff --git a/openspec/changes/add-model-output-display/proposal.md b/openspec/changes/add-model-output-display/proposal.md deleted file mode 100644 index be9cbef..0000000 --- a/openspec/changes/add-model-output-display/proposal.md +++ /dev/null @@ -1,74 +0,0 @@ -# 提案: 在流程详情页添加模型输出展示 - -## 背景 - -利率定价流程详情接口已更新,新增了模型输出字段 (`modelRetailOutputFields` 和 `modelCorpOutputFields`)。目前前端详情页面仅展示流程基本信息,未展示模型输出数据。 - -## 问题 - -用户在查看流程详情时,无法看到模型计算的输出结果(包括各项 BP 值、测算利率等关键信息),影响业务决策和问题排查。 - -## 提案概述 - -在流程详情页面 (`/loanPricing/workflow/detail/:serialNum`) 下方新增独立的模型输出展示区域,根据客户类型(个人/企业)显示对应的模型输出字段。 - -### 展示逻辑 - -- 当 `loanPricingWorkflow.custType === "个人"` 时,展示 `modelRetailOutputFields` 字段 -- 当 `loanPricingWorkflow.custType === "企业"` 时,展示 `modelCorpOutputFields` 字段 -- 当模型输出数据为空时,隐藏该展示区域 - -### 布局结构 - -保持与现有页面风格一致,采用卡片 + Tab 标签页的形式展示模型输出字段。 - -#### 个人客户模型输出 Tab 分类 - -| Tab 名称 | 字段内容 | -|---------|---------| -| 基本信息 | 客户内码、客户名称、证件类型、证件号码、基准利率 | -| 忠诚度分析 | 我行首贷客户、用信天数、客户年龄、BP_首贷、BP_贷龄、BP_年龄、TOTAL_BP_忠诚度 | -| 贡献度分析 | 存款年日均、贷款年日均、派生率、TOTAL_BP_贡献度 | -| 关联度分析 | 中间业务_个人_信用卡、中间业务_个人_一码通、中间业务_个人_丰收互联、中间业务_个人_有效客户、中间业务_个人_快捷支付、中间业务_个人_电费代扣、中间业务_个人_水费代扣、中间业务_个人_华数费代扣、中间业务_个人_煤气费代扣、中间业务_个人_市民卡、中间业务_个人_理财业务、中间业务_个人_etc、BP_中间业务、TOTAL_BP_关联度 | -| 贷款特征 | 申请金额、BP_贷款额度、贷款用途、是否有经营佐证、BP_贷款用途、循环功能、BP_循环功能、抵质押类型、抵质押物三方所有、BP_抵押物 | -| 风险度分析 | 灰名单客户、本金逾期、利息逾期、信用卡逾期、BP_灰名单与逾期、TOTAL_BP_风险度 | -| 测算结果 | 浮动BP、测算利率 | - -#### 企业客户模型输出 Tab 分类 - -| Tab 名称 | 字段内容 | -|---------|---------| -| 基本信息 | 客户内码、客户名称、证件类型、证件号码、基准利率 | -| 忠诚度分析 | 我行首贷客户、用信天数、BP_首贷、BP_贷龄、TOTAL_BP_忠诚度 | -| 贡献度分析 | 存款年日均、贷款年日均、派生率、TOTAL_BP_贡献度 | -| 关联度分析 | 中间业务_企业_企业互联、中间业务_企业_有效价值客户、中间业务_企业_国际业务、中间业务_企业_承兑、中间业务_企业_贴现、中间业务_企业_电费代扣、中间业务_企业_水费代扣、中间业务_企业_税务代扣、BP_中间业务、代发工资户数、存量贷款余额、BP_代发工资、TOTAL_BP_关联度 | -| 企业类别 | 净身企业、开立基本结算账户、省农担担保贷款、绿色贷款、科技型企业、BP_企业客户类别 | -| 贷款特征 | 贷款期限、BP_贷款期限、申请金额、BP_贷款额度、抵质押类型、抵质押物三方所有、BP_抵押物 | -| 风险度分析 | 灰名单客户、本金逾期、利息逾期、信用卡逾期、BP_灰名单与逾期、TOTAL_BP_风险度 | -| 测算结果 | 浮动BP、测算利率 | - -## 影响范围 - -- 前端: `ruoyi-ui/src/views/loanPricing/workflow/detail.vue` -- API: 使用现有的 `GET /loanPricing/workflow/{serialNum}` 接口 - -## 设计考虑 - -1. **独立性**: 模型输出区域与流程基本信息分离,避免页面过于臃肿 -2. **一致性**: 采用与现有详情页面相同的卡片 + Tab 布局风格 -3. **响应式**: 保持移动端友好布局 -4. **可扩展**: 预留未来可能新增的模型输出字段 - -## 替代方案 - -### 方案 A: 在现有详情对话框中添加 Tab (未采纳) -- **优点**: 集中展示,减少页面跳转 -- **缺点**: 详情页改为独立页面后此方案不适用 - -### 方案 B: 新增独立页面展示模型输出 (未采纳) -- **优点**: 完全分离,职责清晰 -- **缺点**: 增加用户操作步骤,需要额外的路由和菜单配置 - -### 方案 C: 在详情页下方新增卡片区域 (采纳) -- **优点**: 一次性获取所有信息,用户体验好,实现简单 -- **缺点**: 单次页面内容较多(通过 Tab 解决) diff --git a/openspec/changes/add-model-output-display/specs/loan-pricing-workflow-ui/spec.md b/openspec/changes/add-model-output-display/specs/loan-pricing-workflow-ui/spec.md deleted file mode 100644 index 4f32336..0000000 --- a/openspec/changes/add-model-output-display/specs/loan-pricing-workflow-ui/spec.md +++ /dev/null @@ -1,63 +0,0 @@ -# loan-pricing-workflow-ui Spec Delta - -## ADDED Requirements - -### Requirement: 流程详情-模型输出展示 - -系统 SHALL 在流程详情页面中展示模型输出字段,根据客户类型显示对应的个人或企业模型输出数据。 - -#### Scenario: 查看个人客户模型输出 -- **WHEN** 用户在流程详情页面查看个人客户的流程记录,且后端返回了 `modelRetailOutputFields` 数据 -- **THEN** 系统在页面下方显示"模型输出"卡片区域,包含 7 个 Tab 标签页: - - **基本信息**: 客户内码、客户名称、证件类型、证件号码、基准利率 - - **忠诚度分析**: 我行首贷客户、用信天数、客户年龄、BP_首贷、BP_贷龄、BP_年龄、TOTAL_BP_忠诚度 - - **贡献度分析**: 存款年日均、贷款年日均、派生率、TOTAL_BP_贡献度 - - **关联度分析**: 中间业务_个人_信用卡、中间业务_个人_一码通、中间业务_个人_丰收互联、中间业务_个人_有效客户、中间业务_个人_快捷支付、中间业务_个人_电费代扣、中间业务_个人_水费代扣、中间业务_个人_华数费代扣、中间业务_个人_煤气费代扣、中间业务_个人_市民卡、中间业务_个人_理财业务、中间业务_个人_etc、BP_中间业务、TOTAL_BP_关联度 - - **贷款特征**: 申请金额、BP_贷款额度、贷款用途、是否有经营佐证、BP_贷款用途、循环功能、BP_循环功能、抵质押类型、抵质押物三方所有、BP_抵押物 - - **风险度分析**: 灰名单客户、本金逾期、利息逾期、信用卡逾期、BP_灰名单与逾期、TOTAL_BP_风险度 - - **测算结果**: 浮动BP、测算利率 - -#### Scenario: 查看企业客户模型输出 -- **WHEN** 用户在流程详情页面查看企业客户的流程记录,且后端返回了 `modelCorpOutputFields` 数据 -- **THEN** 系统在页面下方显示"模型输出"卡片区域,包含 8 个 Tab 标签页: - - **基本信息**: 客户内码、客户名称、证件类型、证件号码、基准利率 - - **忠诚度分析**: 我行首贷客户、用信天数、BP_首贷、BP_贷龄、TOTAL_BP_忠诚度 - - **贡献度分析**: 存款年日均、贷款年日均、派生率、TOTAL_BP_贡献度 - - **关联度分析**: 中间业务_企业_企业互联、中间业务_企业_有效价值客户、中间业务_企业_国际业务、中间业务_企业_承兑、中间业务_企业_贴现、中间业务_企业_电费代扣、中间业务_企业_水费代扣、中间业务_企业_税务代扣、BP_中间业务、代发工资户数、存量贷款余额、BP_代发工资、TOTAL_BP_关联度 - - **企业类别**: 净身企业、开立基本结算账户、省农担担保贷款、绿色贷款、科技型企业、BP_企业客户类别 - - **贷款特征**: 贷款期限、BP_贷款期限、申请金额、BP_贷款额度、抵质押类型、抵质押物三方所有、BP_抵押物 - - **风险度分析**: 灰名单客户、本金逾期、利息逾期、信用卡逾期、BP_灰名单与逾期、TOTAL_BP_风险度 - - **测算结果**: 浮动BP、测算利率 - -#### Scenario: 无模型输出数据时隐藏展示区域 -- **WHEN** 用户在流程详情页面查看流程记录,但 `modelRetailOutputFields` 和 `modelCorpOutputFields` 均为空 -- **THEN** 系统不显示"模型输出"卡片区域 - -#### Scenario: 模型输出字段布尔值格式化 -- **WHEN** 模型输出字段中布尔类型值(如 "true"/"false") -- **THEN** 系统将其格式化为中文"是"/"否"显示 - -#### Scenario: 模型输出字段空值处理 -- **WHEN** 模型输出字段值为 null 或空字符串 -- **THEN** 系统显示占位符"-"或空,不显示 "null" 或 "undefined" - -#### Scenario: 模型输出区域布局一致性 -- **WHEN** 用户查看流程详情页面 -- **THEN** "模型输出"卡片区域的样式、Tab 样式、字体、间距与上方"流程详情"区域保持一致 - -#### Scenario: 模型输出区域响应式布局 -- **WHEN** 用户在移动设备或小屏幕上查看流程详情页面 -- **THEN** "模型输出"卡片区域正常显示,Tab 标签页可正常切换,字段描述列表采用单列布局 - -## MODIFIED Requirements - -### Requirement: 流程详情查看 - -系统 SHALL 提供流程详情查看功能,以独立页面形式展示完整的流程信息,包括模型输出数据。 - -#### Scenario: 查看流程详情 -- **WHEN** 用户在流程列表页面且具有 `loanPricing:workflow:query` 权限,点击列表中某条记录的"查看"按钮 -- **THEN** 系统跳转至流程详情页面 `/loanPricing/workflow/detail/:serialNum`,展示: - - **左侧摘要卡片**: 业务方流水号、客户名称、客户类型、申请金额、贷款利率、担保方式 - - **右侧详情标签页**: 基本信息页签、业务信息页签、中间业务标识页签、企业标识页签、其他信息页签 - - **下方模型输出卡片**: 当存在模型输出数据时显示,根据客户类型展示对应的个人或企业模型输出字段 diff --git a/openspec/changes/add-model-output-display/tasks.md b/openspec/changes/add-model-output-display/tasks.md deleted file mode 100644 index f11a21e..0000000 --- a/openspec/changes/add-model-output-display/tasks.md +++ /dev/null @@ -1,53 +0,0 @@ -# 任务列表: 模型输出展示功能 - -## 实施顺序 - -### 1. 前端页面结构调整 -- [x] 在 detail.vue 中新增模型输出展示区域(el-card) -- [x] 添加条件渲染逻辑:仅当模型输出数据存在时显示 -- [x] 添加客户类型判断逻辑:个人/企业显示不同字段 -- [x] 抽离模型输出组件 ModelOutputDisplay.vue - -### 2. 页面布局调整 -- [x] 将模型输出组件放在关键信息右侧(三栏布局) -- [x] 调整响应式布局支持不同屏幕尺寸 - -### 3. 个人客户模型输出组件 -- [x] 创建个人模型输出 Tab 结构(7 个 Tab) -- [x] 实现"基本信息"Tab 字段展示(5 个字段) -- [x] 实现"忠诚度分析"Tab 字段展示(7 个字段) -- [x] 实现"贡献度分析"Tab 字段展示(4 个字段) -- [x] 实现"关联度分析"Tab 字段展示(14 个字段) -- [x] 实现"贷款特征"Tab 字段展示(10 个字段) -- [x] 实现"风险度分析"Tab 字段展示(7 个字段) -- [x] 实现"测算结果"Tab 字段展示(2 个字段) - -### 4. 企业客户模型输出组件 -- [x] 创建企业模型输出 Tab 结构(8 个 Tab) -- [x] 实现"基本信息"Tab 字段展示(5 个字段) -- [x] 实现"忠诚度分析"Tab 字段展示(6 个字段) -- [x] 实现"贡献度分析"Tab 字段展示(4 个字段) -- [x] 实现"关联度分析"Tab 字段展示(13 个字段) -- [x] 实现"企业类别"Tab 字段展示(6 个字段) -- [x] 实现"贷款特征"Tab 字段展示(7 个字段) -- [x] 实现"风险度分析"Tab 字段展示(7 个字段) -- [x] 实现"测算结果"Tab 字段展示(2 个字段) - -### 5. 数据适配 -- [x] 修改 API 响应数据解析逻辑,支持 `LoanPricingWorkflowVO` 结构 -- [x] 添加模型输出字段的数据绑定 -- [x] 添加布尔值字段的格式化(true/false → 是/否) -- [x] 添加空值处理逻辑 - -### 6. 样式调整 -- [x] 保持与现有详情页面一致的卡片样式 -- [x] 保持 Tab 样式一致性 -- [x] 确保响应式布局在移动端正常显示 -- [x] 调整卡片间距 - -### 7. 测试验证 -- [ ] 测试个人客户数据展示 -- [ ] 测试企业客户数据展示 -- [ ] 测试无模型输出数据时的页面表现 -- [ ] 测试响应式布局 -- [ ] 测试各 Tab 切换交互 diff --git a/openspec/changes/adjust-model-output-columns/proposal.md b/openspec/changes/adjust-model-output-columns/proposal.md deleted file mode 100644 index eb665b6..0000000 --- a/openspec/changes/adjust-model-output-columns/proposal.md +++ /dev/null @@ -1,61 +0,0 @@ -# 提案: 将模型输出展示组件改为三列布局 - -## 背景 - -当前 `ModelOutputDisplay.vue` 组件中所有 `el-descriptions` 使用 `:column="2"` 两列布局展示模型输出字段。 - -## 问题 - -两列布局导致垂直空间占用较多,用户需要滚动更多才能查看完整信息。三列布局可以更好地利用屏幕宽度(特别是在桌面端),减少垂直滚动需求。 - -## 提案概述 - -将 `ModelOutputDisplay.vue` 组件中所有 `el-descriptions` 的 `:column` 属性从 `2` 修改为 `3`。 - -### 影响范围 - -- 前端: `ruoyi-ui/src/views/loanPricing/workflow/components/ModelOutputDisplay.vue` - -### 具体修改点 - -需要修改以下位置的 `:column` 属性: - -#### 个人客户模型输出 -1. 基本信息 (line 11): `:column="2"` → `:column="3"` -2. 忠诚度分析 (line 22): `:column="2"` → `:column="3"` -3. 贡献度分析 (line 35): `:column="2"` → `:column="3"` -4. 关联度分析 (line 45): `:column="2"` → `:column="3"` -5. 贷款特征 (line 65): `:column="2"` → `:column="3"` -6. 风险度分析 (line 81): `:column="2"` → `:column="3"` -7. 测算结果 (line 93): `:column="2"` → `:column="3"` - -#### 企业客户模型输出 -8. 基本信息 (line 104): `:column="2"` → `:column="3"` -9. 忠诚度分析 (line 115): `:column="2"` → `:column="3"` -10. 贡献度分析 (line 126): `:column="2"` → `:column="3"` -11. 关联度分析 (line 136): `:column="2"` → `:column="3"` -12. 企业类别 (line 155): `:column="2"` → `:column="3"` -13. 贷款特征 (line 167): `:column="2"` → `:column="3"` -14. 风险度分析 (line 180): `:column="2"` → `:column="3"` -15. 测算结果 (line 192): `:column="2"` → `:column="3"` - -## 设计考虑 - -1. **空间利用**: 三列布局可以减少约 33% 的垂直空间占用 -2. **可读性**: Element UI 的 `el-descriptions` 组件会自动调整标签宽度,三列布局在标准桌面显示器(1920px 宽度)下可读性良好 -3. **兼容性**: `el-descriptions` 组件原生支持多列布局,无需额外样式调整 -4. **响应式**: 在小屏幕设备上,Element UI 会自动调整布局,无需额外处理 - -## 替代方案 - -### 方案 A: 保持两列布局 (未采纳) -- **优点**: 标签内容空间更充足 -- **缺点**: 垂直空间占用大,需要更多滚动 - -### 方案 B: 使用四列布局 (未采纳) -- **优点**: 垂直空间占用最少 -- **缺点**: 标签内容可能被压缩,影响可读性 - -### 方案 C: 改为三列布局 (采纳) -- **优点**: 平衡空间利用率和可读性 -- **缺点**: 无明显缺点 diff --git a/openspec/changes/adjust-model-output-columns/specs/loan-pricing-workflow-ui/spec.md b/openspec/changes/adjust-model-output-columns/specs/loan-pricing-workflow-ui/spec.md deleted file mode 100644 index 26dab85..0000000 --- a/openspec/changes/adjust-model-output-columns/specs/loan-pricing-workflow-ui/spec.md +++ /dev/null @@ -1,15 +0,0 @@ -# loan-pricing-workflow-ui Delta - -## MODIFIED Requirements - -### Requirement: 模型输出展示布局 - -模型输出组件 SHALL 使用三列布局展示字段信息,以提高空间利用率。 - -#### Scenario: 查看个人客户模型输出三列布局 -- **WHEN** 用户在流程详情页查看个人客户记录的模型输出信息 -- **THEN** 系统在所有模型输出 Tab(基本信息、忠诚度分析、贡献度分析、关联度分析、贷款特征、风险度分析、测算结果)中使用三列布局展示字段 - -#### Scenario: 查看企业客户模型输出三列布局 -- **WHEN** 用户在流程详情页查看企业客户记录的模型输出信息 -- **THEN** 系统在所有模型输出 Tab(基本信息、忠诚度分析、贡献度分析、关联度分析、企业类别、贷款特征、风险度分析、测算结果)中使用三列布局展示字段 diff --git a/openspec/changes/adjust-model-output-columns/tasks.md b/openspec/changes/adjust-model-output-columns/tasks.md deleted file mode 100644 index 5d85cc4..0000000 --- a/openspec/changes/adjust-model-output-columns/tasks.md +++ /dev/null @@ -1,36 +0,0 @@ -# 实施任务 - -## 任务清单 - -1. **修改 ModelOutputDisplay.vue 组件列数配置** - - 文件: `ruoyi-ui/src/views/loanPricing/workflow/components/ModelOutputDisplay.vue` - - 操作: 将所有 `el-descriptions` 的 `:column="2"` 修改为 `:column="3"` - - 涉及行数: 11, 22, 35, 45, 65, 81, 93, 104, 115, 126, 136, 155, 167, 180, 192 - - 验证: 确认所有 15 处 `el-descriptions` 的 `:column` 属性已修改为 `3` - -2. **前端构建验证** - - 操作: 运行 `cd ruoyi-ui && npm run build:prod` - - 验证: 构建成功无错误 - -3. **功能验证** - - 操作: - - 启动前端开发服务器 `npm run dev` - - 访问流程详情页,选择个人客户记录,验证模型输出显示为三列 - - 选择企业客户记录,验证模型输出显示为三列 - - 验证: - - 个人客户所有 7 个 Tab 的字段展示均为三列布局 - - 企业客户所有 8 个 Tab 的字段展示均为三列布局 - - 标签和值内容正常显示,无溢出或错位 - -## 依赖关系 - -- 任务 1 必须首先完成 -- 任务 2 和任务 3 可并行执行 - -## 验收标准 - -- [x] 所有 `el-descriptions` 的 `:column` 属性值均为 `3` -- [x] 前端构建成功 -- [x] 个人客户模型输出所有 Tab 正确显示为三列 -- [x] 企业客户模型输出所有 Tab 正确显示为三列 -- [x] 字段标签和内容显示正常,无布局问题 diff --git a/openspec/changes/archive/2026-01-20-add-loan-pricing-create/proposal.md b/openspec/changes/archive/2026-01-20-add-loan-pricing-create/proposal.md deleted file mode 100644 index 8758a37..0000000 --- a/openspec/changes/archive/2026-01-20-add-loan-pricing-create/proposal.md +++ /dev/null @@ -1,33 +0,0 @@ -# Change: 添加利率定价流程创建功能 - -## Why - -当前 `add-loan-pricing-frontend` 变更已实现流程列表查询和详情查看功能,但缺少创建新流程的能力。业务人员需要能够通过 Web 界面发起新的利率定价申请,而不是直接调用后端 API。 - -## What Changes - -- 修改前端页面组件 `ruoyi-ui/src/views/loanPricing/workflow/index.vue`: - - 添加"新增"按钮(带权限控制 `loanPricing:workflow:create`) - - 添加创建流程表单对话框 - - 实现表单验证逻辑 - - 实现表单提交功能 - -- 新增前端 API 接口函数: - - `createWorkflow(data)` - 创建利率定价流程 - -- 新增数据库菜单权限: - - 添加创建权限 `loanPricing:workflow:create` - -## Impact - -- **Affected specs:** 修改 `loan-pricing-workflow-ui` 能力规格 -- **Affected code:** - - **修改 `ruoyi-ui/src/api/loanPricing/workflow.js`** - 新增创建接口 - - **修改 `ruoyi-ui/src/views/loanPricing/workflow/index.vue`** - 添加创建功能 - - **修改 `sys_menu` 表** - 添加创建权限按钮 - -## Dependencies - -- 依赖已完成的 `add-loan-pricing-workflow` 后端变更(提供创建 API) -- 依赖已完成的 `add-loan-pricing-frontend` 前端变更(提供列表和详情页面) -- 后端 API 接口文档位于 `doc/api/loan-pricing-workflow-api.md`(接口1:发起利率定价流程) diff --git a/openspec/changes/archive/2026-01-20-add-loan-pricing-create/specs/loan-pricing-workflow-ui/spec.md b/openspec/changes/archive/2026-01-20-add-loan-pricing-create/specs/loan-pricing-workflow-ui/spec.md deleted file mode 100644 index dd6fd84..0000000 --- a/openspec/changes/archive/2026-01-20-add-loan-pricing-create/specs/loan-pricing-workflow-ui/spec.md +++ /dev/null @@ -1,94 +0,0 @@ -# Capability: loan-pricing-workflow-ui - -利率定价流程前端用户界面能力。 - -## MODIFIED Requirements - -### Requirement: 流程列表查询 - -系统 SHALL 提供利率定价流程列表查询页面,支持分页和多条件筛选,并支持创建新流程。 - -#### Scenario: 查询流程列表 -- **WHEN** 用户已登录系统且具有 `loanPricing:workflow:list` 权限,访问"利率定价管理 > 流程列表"菜单 -- **THEN** 系统显示利率定价流程列表页面,包含查询表单(客户名称模糊查询、创建者、机构号筛选)、搜索和重置按钮、新增按钮(带权限控制)、数据表格(业务方流水号、客户名称、客户类型、担保方式、申请金额、贷款利率、创建时间、创建者)、分页组件、操作列(包含"查看"按钮) - -#### Scenario: 使用筛选条件查询 -- **WHEN** 用户在流程列表页面输入客户名称或选择创建者/机构号,点击搜索按钮 -- **THEN** 系统根据筛选条件查询并更新列表数据 - -#### Scenario: 重置筛选条件 -- **WHEN** 用户已设置筛选条件,点击重置按钮 -- **THEN** 系统清空所有筛选条件并重新查询全部数据 - -### Requirement: 流程详情查看 - -系统 SHALL 提供流程详情查看功能,以对话框形式展示完整的流程信息。 - -#### Scenario: 查看流程详情 -- **WHEN** 用户在流程列表页面且具有 `loanPricing:workflow:query` 权限,点击列表中某条记录的"查看"按钮 -- **THEN** 系统弹出详情对话框,展示完整的流程信息(基本信息:业务方流水号、机构编码、客户内码、客户名称、证件类型;业务信息:客户类型、担保方式、申请金额、贷款利率、贷款用途;业务标识:中间业务标识、企业标识;抵质押信息:抵质押类型、是否三方所有;其他信息:创建时间、创建者、更新时间、更新者) - -### Requirement: 菜单和权限配置 - -系统 SHALL 在数据库中正确配置菜单项和权限,确保用户可以访问功能。 - -#### Scenario: 菜单显示和导航 -- **WHEN** 用户已登录系统且具有利率定价流程相关权限 -- **THEN** 系统在左侧菜单栏显示"利率定价管理"一级菜单,展开后显示"流程列表"二级菜单项 - -#### Scenario: 菜单路由配置 -- **WHEN** 用户点击"流程列表"菜单项,系统处理路由跳转 -- **THEN** 系统导航至 `/loanPricing/workflow` 路径,加载对应的前端组件 - -### Requirement: API 接口集成 - -前端 SHALL 正确调用后端 API 接口获取数据和提交创建请求。 - -#### Scenario: 列表接口调用 -- **WHEN** 用户访问流程列表页面,页面初始化或用户执行查询操作 -- **THEN** 前端调用 `GET /loanPricing/workflow/list` 接口,传入分页和筛选参数 - -#### Scenario: 详情接口调用 -- **WHEN** 用户点击查看按钮,前端获取选中记录的业务方流水号 -- **THEN** 前端调用 `GET /loanPricing/workflow/{serialNum}` 接口获取详情数据 - -#### Scenario: 创建接口调用 -- **WHEN** 用户填写完创建表单并点击确定按钮 -- **THEN** 前端调用 `POST /loanPricing/workflow/create` 接口,传入表单数据,成功后关闭对话框并刷新列表 - -## ADDED Requirements - -### Requirement: 流程创建 - -系统 SHALL 提供创建新利率定价流程的功能,通过表单对话框收集必要信息。 - -#### Scenario: 打开创建表单 -- **WHEN** 用户在流程列表页面且具有 `loanPricing:workflow:create` 权限,点击"新增"按钮 -- **THEN** 系统弹出创建流程表单对话框,显示所有必填和可选字段 - -#### Scenario: 表单字段显示 -- **WHEN** 用户打开创建流程表单对话框 -- **THEN** 系统显示以下字段分组: - - 基本信息:客户内码(必填)、客户名称、客户类型(必填,下拉选择:个人/企业)、证件类型 - - 贷款信息:申请金额(必填)、贷款利率(必填)、担保方式(必填,下拉选择:信用/保证/抵押/质押)、贷款用途(下拉选择:consumer/business) - - 中间业务标识(个人):个人快捷支付(开关)、个人电费代扣(开关) - - 中间业务标识(企业):企业电费代扣(开关)、企业水费代扣(开关) - - 企业标识:净身企业(开关)、开立基本结算账户(开关)、制造业企业(开关)、省农担担保贷款(开关)、纳税信用等级A级(开关)、县级及以上农业龙头企业(开关)、普惠小微借款人(开关) - - 抵质押信息:抵质押类型(下拉选择:一线/一类/二类)、抵质押物三方所有(开关)、是否有经营佐证(开关) - - 固定字段:机构编码(隐藏,固定值931000)、运行模式(隐藏,固定值1) - -#### Scenario: 表单验证 -- **WHEN** 用户填写表单并点击确定按钮 -- **THEN** 系统验证必填字段:客户内码、客户类型、担保方式、申请金额、贷款利率,如有缺失则显示错误提示 - -#### Scenario: 提交创建成功 -- **WHEN** 用户填写完必填字段并点击确定按钮,后端返回成功响应 -- **THEN** 系统关闭对话框,显示成功提示消息,刷新列表数据 - -#### Scenario: 取消创建 -- **WHEN** 用户点击取消按钮或对话框关闭按钮 -- **THEN** 系统关闭对话框,不保存数据,不刷新列表 - -#### Scenario: 新增按钮权限控制 -- **WHEN** 用户不具有 `loanPricing:workflow:create` 权限 -- **THEN** 系统不显示"新增"按钮 diff --git a/openspec/changes/archive/2026-01-20-add-loan-pricing-create/tasks.md b/openspec/changes/archive/2026-01-20-add-loan-pricing-create/tasks.md deleted file mode 100644 index 02dc9c8..0000000 --- a/openspec/changes/archive/2026-01-20-add-loan-pricing-create/tasks.md +++ /dev/null @@ -1,39 +0,0 @@ -# Tasks: 添加利率定价流程创建功能 - -## Implementation Tasks - -### 1. 新增前端 API 接口 -- [x] 在 `ruoyi-ui/src/api/loanPricing/workflow.js` 中添加 `createWorkflow(data)` 函数 -- [x] 函数调用 `POST /loanPricing/workflow/create` 接口 - -### 2. 修改前端页面组件 -- [x] 在页面工具栏区域添加"新增"按钮 -- [x] 按钮配置权限控制 `v-hasPermi="['loanPricing:workflow:create']"` -- [x] 添加创建流程表单对话框组件 -- [x] 实现表单字段(参照 API 文档接口1的请求参数): - - 必填字段:机构编码(固定931000)、运行模式(固定1)、客户内码、客户类型、担保方式、申请金额、贷款利率 - - 可选字段:客户名称、证件类型、贷款用途 - - 业务标识字段:中间业务标识(个人快捷支付、个人电费代扣、企业电费代扣、企业水费代扣) - - 企业标识字段:净身企业、开立基本结算账户、制造业企业、省农担担保贷款、纳税信用等级A级、县级及以上农业龙头企业、普惠小微借款人 - - 抵质押信息字段:抵质押类型、抵质押物三方所有、是否有经营佐证 -- [x] 实现表单验证规则 -- [x] 实现 `handleAdd` 方法(打开对话框) -- [x] 实现 `submitForm` 方法(提交表单) -- [x] 实现 `cancelCreate` 方法(取消/关闭对话框) -- [x] 实现 `reset` 方法(重置表单) - -### 3. 配置数据库菜单权限 -- [x] 准备 SQL 插入语句,在 `sys_menu` 表中添加创建按钮权限: - - menu_id: 2003, menu_name: 流程创建, parent_id: 2001 - - perms: `loanPricing:workflow:create` -- [x] 执行 SQL 插入语句 -- [x] 关联管理员角色到新菜单权限 - -### 4. 验证和测试 -- [x] 代码实现完成,等待用户启动前端服务进行测试 -- [ ] 启动前端开发服务器 -- [ ] 验证"新增"按钮是否显示 -- [ ] 测试打开创建表单对话框 -- [ ] 测试表单验证功能 -- [ ] 测试提交创建成功后刷新列表 -- [ ] 测试取消和关闭对话框功能 diff --git a/openspec/changes/archive/2026-01-20-add-loan-pricing-frontend/proposal.md b/openspec/changes/archive/2026-01-20-add-loan-pricing-frontend/proposal.md deleted file mode 100644 index ef2716c..0000000 --- a/openspec/changes/archive/2026-01-20-add-loan-pricing-frontend/proposal.md +++ /dev/null @@ -1,25 +0,0 @@ -# Change: 添加利率定价流程前端管理界面 - -## Why - -后端利率定价流程 API 已实现(参见 `add-loan-pricing-workflow` 变更),但缺少对应的前端管理界面。业务人员需要通过 Web 界面查询利率定价流程列表、查看流程详情,而不能直接调用后端 API。 - -## What Changes - -- 新增前端 API 接口模块 `ruoyi-ui/src/api/loanPricing/workflow.js` -- 新增前端页面组件 `ruoyi-ui/src/views/loanPricing/workflow/index.vue` -- 在数据库 `sys_menu` 表中配置菜单项,确保页面可以正常访问 -- 配置路由和权限,使用户可以通过菜单导航访问功能 - -## Impact - -- **Affected specs:** 新增 `loan-pricing-workflow-ui` 能力规格 -- **Affected code:** - - **新增 `ruoyi-ui/src/api/loanPricing/workflow.js`** - API 接口定义 - - **新增 `ruoyi-ui/src/views/loanPricing/workflow/index.vue`** - 列表和详情页面组件 - - **修改 `sys_menu` 表** - 添加菜单配置数据 - -## Dependencies - -- 依赖已完成的 `add-loan-pricing-workflow` 后端变更 -- 后端 API 接口文档位于 `doc/api/loan-pricing-workflow-api.md` diff --git a/openspec/changes/archive/2026-01-20-add-loan-pricing-frontend/specs/loan-pricing-workflow-ui/spec.md b/openspec/changes/archive/2026-01-20-add-loan-pricing-frontend/specs/loan-pricing-workflow-ui/spec.md deleted file mode 100644 index 341c9f5..0000000 --- a/openspec/changes/archive/2026-01-20-add-loan-pricing-frontend/specs/loan-pricing-workflow-ui/spec.md +++ /dev/null @@ -1,53 +0,0 @@ -# Capability: loan-pricing-workflow-ui - -利率定价流程前端用户界面能力。 - -## ADDED Requirements - -### Requirement: 流程列表查询 - -系统 SHALL 提供利率定价流程列表查询页面,支持分页和多条件筛选。 - -#### Scenario: 查询流程列表 -- **WHEN** 用户已登录系统且具有 `loanPricing:workflow:list` 权限,访问"利率定价管理 > 流程列表"菜单 -- **THEN** 系统显示利率定价流程列表页面,包含查询表单(客户名称模糊查询、创建者、机构号筛选)、搜索和重置按钮、数据表格(业务方流水号、客户名称、客户类型、担保方式、申请金额、贷款利率、创建时间、创建者)、分页组件、操作列(包含"查看"按钮) - -#### Scenario: 使用筛选条件查询 -- **WHEN** 用户在流程列表页面输入客户名称或选择创建者/机构号,点击搜索按钮 -- **THEN** 系统根据筛选条件查询并更新列表数据 - -#### Scenario: 重置筛选条件 -- **WHEN** 用户已设置筛选条件,点击重置按钮 -- **THEN** 系统清空所有筛选条件并重新查询全部数据 - -### Requirement: 流程详情查看 - -系统 SHALL 提供流程详情查看功能,以对话框形式展示完整的流程信息。 - -#### Scenario: 查看流程详情 -- **WHEN** 用户在流程列表页面且具有 `loanPricing:workflow:query` 权限,点击列表中某条记录的"查看"按钮 -- **THEN** 系统弹出详情对话框,展示完整的流程信息(基本信息:业务方流水号、机构编码、客户内码、客户名称、证件类型;业务信息:客户类型、担保方式、申请金额、贷款利率、贷款用途;业务标识:中间业务标识、企业标识;抵质押信息:抵质押类型、是否三方所有;其他信息:创建时间、创建者、更新时间、更新者) - -### Requirement: 菜单和权限配置 - -系统 SHALL 在数据库中正确配置菜单项和权限,确保用户可以访问功能。 - -#### Scenario: 菜单显示和导航 -- **WHEN** 用户已登录系统且具有利率定价流程相关权限 -- **THEN** 系统在左侧菜单栏显示"利率定价管理"一级菜单,展开后显示"流程列表"二级菜单项 - -#### Scenario: 菜单路由配置 -- **WHEN** 用户点击"流程列表"菜单项,系统处理路由跳转 -- **THEN** 系统导航至 `/loanPricing/workflow` 路径,加载对应的前端组件 - -### Requirement: API 接口集成 - -前端 SHALL 正确调用后端 API 接口获取数据。 - -#### Scenario: 列表接口调用 -- **WHEN** 用户访问流程列表页面,页面初始化或用户执行查询操作 -- **THEN** 前端调用 `GET /loanPricing/workflow/list` 接口,传入分页和筛选参数 - -#### Scenario: 详情接口调用 -- **WHEN** 用户点击查看按钮,前端获取选中记录的业务方流水号 -- **THEN** 前端调用 `GET /loanPricing/workflow/{serialNum}` 接口获取详情数据 diff --git a/openspec/changes/archive/2026-01-20-add-loan-pricing-frontend/tasks.md b/openspec/changes/archive/2026-01-20-add-loan-pricing-frontend/tasks.md deleted file mode 100644 index c5ab6c6..0000000 --- a/openspec/changes/archive/2026-01-20-add-loan-pricing-frontend/tasks.md +++ /dev/null @@ -1,41 +0,0 @@ -# Tasks: 添加利率定价流程前端管理界面 - -## Implementation Tasks - -### 1. 创建前端 API 接口模块 -- [x] 创建 `ruoyi-ui/src/api/loanPricing/` 目录 -- [x] 创建 `workflow.js` 文件,实现以下 API 函数: - - `listWorkflow(query)` - 查询利率定价流程列表 - - `getWorkflow(serialNum)` - 根据业务方流水号查询详情 - -### 2. 创建前端页面组件 -- [x] 创建 `ruoyi-ui/src/views/loanPricing/workflow/` 目录 -- [x] 创建 `index.vue` 页面组件,包含: - - 查询表单区域(支持客户名称、创建者、机构号筛选) - - 数据表格区域(显示流程列表) - - 分页组件 - - 详情对话框(点击查看按钮弹出) -- [x] 实现以下功能: - - 页面加载时自动查询列表 - - 搜索和重置功能 - - 点击"查看"按钮弹出详情对话框 - - 详情对话框展示完整的流程信息 - -### 3. 配置数据库菜单 -- [x] 准备 SQL 插入语句,在 `sys_menu` 表中添加菜单项: - - 一级菜单:利率定价管理(menu_type='M') - - 二级菜单:流程列表(menu_type='C',对应前端组件路径) -- [x] 设置正确的权限标识(perms字段): - - 列表查询权限:`loanPricing:workflow:list` - - 详情查询权限:`loanPricing:workflow:query` -- [x] 执行 SQL 插入语句 -- [x] 关联管理员角色到新菜单 - -### 4. 验证和测试 -- [x] 配置完成,等待用户启动前端服务进行测试 -- [ ] 启动前端开发服务器(`npm run dev`) -- [ ] 使用 admin 账号登录系统 -- [ ] 验证菜单是否正常显示 -- [ ] 测试列表查询功能 -- [ ] 测试搜索筛选功能 -- [ ] 测试详情查看功能 diff --git a/openspec/changes/archive/2026-01-20-add-loan-pricing-workflow/proposal.md b/openspec/changes/archive/2026-01-20-add-loan-pricing-workflow/proposal.md deleted file mode 100644 index 37902f4..0000000 --- a/openspec/changes/archive/2026-01-20-add-loan-pricing-workflow/proposal.md +++ /dev/null @@ -1,24 +0,0 @@ -# Change: 添加利率定价流程管理功能 - -## Why - -当前系统缺少利率定价流程的管理能力。业务人员需要能够发起利率定价申请、查询历史定价记录、查看定价详情。这是贷款定价系统的核心功能需求。 - -## What Changes - -- 创建新的 Maven 模块 `ruoyi-loan-pricing` 用于利率定价相关功能 -- 新增利率定价流程的发起接口 -- 新增利率定价流程的列表查询接口(支持分页和多条件筛选) -- 新增根据业务方流水号查看详情的接口 -- 创建数据库表存储利率定价流程数据 -- 添加对应的实体类、Mapper、Service、Controller - -## Impact - -- **Affected specs:** 新增 `loan-pricing-workflow` 能力规格 -- **Affected code:** - - **新增 `ruoyi-loan-pricing` Maven 模块** - 包含 Domain、Mapper、Service - - 修改 `pom.xml` 添加新模块依赖 - - 新增 `ruoyi-admin` 模块下的 Controller - - 新增数据库表和 MyBatis XML 映射文件 - - 新增前端 API 接口定义和页面组件(待后续阶段实现) diff --git a/openspec/changes/archive/2026-01-20-add-loan-pricing-workflow/specs/loan-pricing-workflow/spec.md b/openspec/changes/archive/2026-01-20-add-loan-pricing-workflow/specs/loan-pricing-workflow/spec.md deleted file mode 100644 index 59220b8..0000000 --- a/openspec/changes/archive/2026-01-20-add-loan-pricing-workflow/specs/loan-pricing-workflow/spec.md +++ /dev/null @@ -1,73 +0,0 @@ -## ADDED Requirements - -### Requirement: 利率定价流程发起 - -系统 SHALL 提供利率定价流程发起接口,允许业务人员创建新的利率定价申请。 - -#### Scenario: 成功发起利率定价流程 -- **WHEN** 业务人员提交包含必填字段(custIsn、custType、guarType、applyAmt、loanRate)的完整申请 -- **THEN** 系统自动生成业务方流水号(serialNum)并保存记录,返回成功响应 - -#### Scenario: 自动生成业务方流水号 -- **WHEN** 发起利率定价流程时 -- **THEN** 系统使用时间戳自动生成唯一的业务方流水号,无需用户输入 - -#### Scenario: 记录创建和更新信息 -- **WHEN** 利率定价流程创建成功 -- **THEN** 系统自动记录创建者、创建时间、更新者、更新时间 - -#### Scenario: 字段验证-必填字段 -- **WHEN** 提交的申请缺少必填字段(custIsn、custType、guarType、applyAmt、loanRate) -- **THEN** 系统返回参数验证失败的错误信息 - -#### Scenario: 字段验证-固定值字段 -- **WHEN** 提交的申请中 orgCode 非 "931000" 或 runType 非 "1" -- **THEN** 系统返回参数验证失败的错误信息 - -#### Scenario: 字段验证-枚举值 -- **WHEN** 提交的申请中 custType 不是"个人"或"企业" -- **THEN** 系统返回参数验证失败的错误信息 - -#### Scenario: 字段验证-担保方式 -- **WHEN** 提交的申请中 guarType 不是"信用"、"保证"、"抵押"、"质押"之一 -- **THEN** 系统返回参数验证失败的错误信息 - -### Requirement: 利率定价流程列表查询 - -系统 SHALL 提供利率定价流程列表查询接口,支持分页和多条件筛选。 - -#### Scenario: 默认按更新时间倒序排列 -- **WHEN** 业务人员查询利率定价流程列表 -- **THEN** 结果按更新时间(update_time)倒序排列 - -#### Scenario: 支持分页查询 -- **WHEN** 业务人员指定页码和每页数量查询列表 -- **THEN** 系统返回对应页的数据及总记录数 - -#### Scenario: 按创建者筛选 -- **WHEN** 业务人员按创建者筛选查询 -- **THEN** 系统返回该创建者创建的利率定价流程记录 - -#### Scenario: 按客户名称筛选 -- **WHEN** 业务人员按客户名称(custName)模糊查询 -- **THEN** 系统返回客户名称包含查询条件的记录 - -#### Scenario: 按机构号筛选 -- **WHEN** 业务人员按机构号(orgCode)筛选查询 -- **THEN** 系统返回该机构号的利率定价流程记录 - -#### Scenario: 组合条件筛选 -- **WHEN** 业务人员同时指定多个筛选条件 -- **THEN** 系统返回同时满足所有条件的记录 - -### Requirement: 利率定价流程详情查询 - -系统 SHALL 提供根据业务方流水号查询流程详情的接口。 - -#### Scenario: 根据业务方流水号查询详情 -- **WHEN** 业务人员提供有效的业务方流水号(serialNum) -- **THEN** 系统返回该流程的所有字段信息 - -#### Scenario: 查询不存在的流水号 -- **WHEN** 业务人员查询的业务方流水号不存在 -- **THEN** 系统返回"记录不存在"的错误信息 diff --git a/openspec/changes/archive/2026-01-20-add-loan-pricing-workflow/tasks.md b/openspec/changes/archive/2026-01-20-add-loan-pricing-workflow/tasks.md deleted file mode 100644 index 5d3f876..0000000 --- a/openspec/changes/archive/2026-01-20-add-loan-pricing-workflow/tasks.md +++ /dev/null @@ -1,78 +0,0 @@ -## 1. 创建新 Maven 模块 - -- [x] 1.1 创建 `ruoyi-loan-pricing` 模块目录结构 -- [x] 1.2 创建 `ruoyi-loan-pricing/pom.xml` - - 继承父 pom - - 添加 `ruoyi-common` 依赖 - - 添加 MyBatis Plus 依赖 - - 添加 Spring Boot 相关依赖 -- [x] 1.3 修改根 `pom.xml` - - 在 `` 中添加 `ruoyi-loan-pricing` 模块 - - 在 `dependencyManagement` 中添加模块依赖管理 -- [x] 1.4 修改 `ruoyi-admin/pom.xml` - - 添加 `ruoyi-loan-pricing` 模块依赖 - -## 2. 数据库设计与实现 - -- [x] 2.1 设计利率定价流程数据库表结构 - - 包含所有必需字段(24个字段) - - 添加主键、索引 - - 添加审计字段(create_by, create_time, update_by, update_time) -- [x] 2.2 创建数据库表 SQL 脚本 - -## 3. 后端实体类开发 - -- [x] 3.1 在 `ruoyi-loan-pricing` 模块中创建 `LoanPricingWorkflow` 实体类 - - 使用 `@Data` 注解 - - 使用 `@TableName` 映射数据库表名 - - 所有字段添加数据库映射注解 - - 手动添加审计字段(createBy, createTime, updateBy, updateTime) -- [x] 3.2 添加字段验证注解(@NotNull、@NotBlank等) - -## 4. 后端 Mapper 层开发 - -- [x] 4.1 在 `ruoyi-loan-pricing` 模块中创建 `LoanPricingWorkflowMapper` 接口 - - 继承 MyBatis Plus 的 `BaseMapper` - - 定义自定义查询方法(如果需要) -- [x] 4.2 创建 MyBatis XML 映射文件(如果需要自定义 SQL) - -## 5. 后端 Service 层开发 - -- [x] 5.1 在 `ruoyi-loan-pricing` 模块中创建 `ILoanPricingWorkflowService` 接口 - - 定义发起流程方法 `createLoanPricing` - - 定义列表查询方法 `selectLoanPricingList` - - 定义详情查询方法 `selectLoanPricingBySerialNum` -- [x] 5.2 创建 `LoanPricingWorkflowServiceImpl` 实现类 - - 实现业务逻辑 - - 生成业务方流水号(时间戳) - - 实现分页查询 - - 实现多条件筛选 - -## 6. 后端 Controller 层开发 - -- [x] 6.1 在 `ruoyi-admin` 模块中创建 `LoanPricingWorkflowController` 控制器 - - 添加 `@RestController` 和 `@RequestMapping` 注解 - - 添加 SpringDoc/OpenAPI 注解用于生成 API 文档 - - 实现发起接口 `POST /loanPricing/workflow/create` - - 实现列表查询接口 `GET /loanPricing/workflow/list` - - 实现详情查询接口 `GET /loanPricing/workflow/{serialNum}` -- [x] 6.2 添加操作日志注解 `@Log` -- [x] 6.3 添加 SpringDoc 注解生成 API 文档 - - 使用 `@Tag` 定义控制器标签 - - 使用 `@Operation` 定义接口描述 - - 使用 `@Parameter` 定义参数说明 - -## 7. 测试与验证 - -- [x] 7.1 编写单元测试(可选) -- [x] 7.2 使用 Postman 或 Swagger UI 进行接口测试 -- [x] 7.3 验证所有场景(成功和失败场景) - -## 8. 文档与配置 - -- [x] 8.1 确认 MyBatis Plus 配置正确 -- [x] 8.2 确认数据库表已创建 -- [x] 8.3 验证 API 文档自动生成 - - 访问 `/swagger-ui.html` 确认接口文档已生成 - - 验证接口描述、参数说明、响应示例完整 -- [x] 8.4 创建 API 接口文档 Markdown 文件 diff --git a/openspec/changes/change-view-workflow-to-page/design.md b/openspec/changes/change-view-workflow-to-page/design.md deleted file mode 100644 index 7f078af..0000000 --- a/openspec/changes/change-view-workflow-to-page/design.md +++ /dev/null @@ -1,142 +0,0 @@ -# 设计文档:流程详情页面 - -## 架构概述 - -将流程详情从对话框组件迁移到独立的页面组件,遵循若依框架现有的路由模式。 - -## 组件设计 - -### 详情页面组件 (detail.vue) - -**位置**:`ruoyi-ui/src/views/loanPricing/workflow/detail.vue` - -**页面结构**: -``` - -``` - -**数据获取**: -- 通过 `$route.params.serialNum` 获取业务方流水号 -- 在 `created()` 钩子中调用 API 获取详情数据 -- 处理加载状态和错误状态 - -**导航逻辑**: -- 返回按钮:`this.$router.go(-1)` 或跳转到列表页 -- 面包屑导航:高亮"流程列表"菜单项 - -### 路由配置 - -**位置**:`ruoyi-ui/src/router/index.js` - `dynamicRoutes` 数组 - -**配置模式**:参考现有的 `/system/user-auth/role/:userId` 路由 - -```javascript -{ - path: '/loanPricing/workflow-detail', - component: Layout, - hidden: true, - permissions: ['loanPricing:workflow:query'], - children: [ - { - path: ':serialNum', - component: () => import('@/views/loanPricing/workflow/detail'), - name: 'LoanPricingWorkflowDetail', - meta: { title: '流程详情', activeMenu: '/loanPricing/workflow' } - } - ] -} -``` - -**路由参数说明**: -- `:serialNum`:业务方流水号,用于 API 调用 -- `activeMenu`:保持列表页菜单高亮 -- `permissions`:复用现有权限 `loanPricing:workflow:query` - -### 列表页修改 - -**修改位置**:`ruoyi-ui/src/views/loanPricing/workflow/index.vue` - -**变更内容**: -1. 移除 `openDetail` 状态变量 -2. 移除 `handleView()` 方法中的弹窗逻辑 -3. 修改"查看"按钮的点击事件,从 `@click="handleView(scope.row)"` 改为路由跳转 - -**新的 `handleView()` 方法**: -```javascript -handleView(row) { - this.$router.push({ - name: 'LoanPricingWorkflowDetail', - params: { serialNum: row.serialNum } - }) -} -``` - -**移除内容**: -- 详情对话框模板(``) -- `detail` 数据对象 -- `openDetail` 状态 - -## UI/UX 设计 - -### 详情页面布局 - -1. **页面标题**:使用 `el-page-header` 组件,显示"流程详情"标题和返回按钮 -2. **内容区域**:使用 `el-card` + `el-descriptions` 展示详情信息,保持与弹窗相同的两列布局 -3. **底部操作**:返回按钮(也可以考虑移除,因为有页面标题的返回按钮) - -### 响应式设计 - -- 移动端:`el-descriptions` 自动调整为单列 -- 内容区域添加适当的内边距和外边距 - -### 加载状态 - -- 显示 loading 遮罩层,直到数据加载完成 -- 处理 API 错误,显示错误提示并返回列表页 - -## 技术约束 - -1. **框架版本**:Vue Router 3.4.9 -2. **路由模式**:History 模式(去掉 URL 中的 #) -3. **权限控制**:通过 `permissions` 字段控制路由访问 -4. **组件懒加载**:使用 `() => import()` 动态导入 - -## 测试策略 - -### 单元测试 -- 路由跳转逻辑 -- 参数解析 -- API 调用 - -### 集成测试 -- 从列表页跳转到详情页 -- 详情页返回到列表页 -- 权限控制(无权限用户无法访问) - -### UI 测试 -- 详情信息正确显示 -- 面包屑导航正确高亮 -- 返回按钮正常工作 diff --git a/openspec/changes/change-view-workflow-to-page/proposal.md b/openspec/changes/change-view-workflow-to-page/proposal.md deleted file mode 100644 index 11faf85..0000000 --- a/openspec/changes/change-view-workflow-to-page/proposal.md +++ /dev/null @@ -1,67 +0,0 @@ -# 提案:将流程详情查看功能从弹窗改为独立页面 - -## 概述 - -将流程列表中的"查看流程"按钮功能从弹窗展示改为跳转到单独的页面展示。 - -## 动机 - -当前流程详情通过对话框(Dialog)展示,存在以下问题: -- 详情信息较多(20+字段),在弹窗中展示需要滚动,用户体验不佳 -- 弹窗宽度固定(800px),长字段显示受限 -- 无法通过 URL 直接分享或访问特定流程的详情页 -- 不利于后续扩展(如添加编辑、审批等操作) - -## 目标 - -1. 创建独立的流程详情页面组件 -2. 修改列表页的"查看"按钮,从弹窗改为路由跳转 -3. 在动态路由中配置详情页路由 -4. 保持现有的 API 接口调用不变 - -## 影响范围 - -### 前端文件 -- 修改:[ruoyi-ui/src/views/loanPricing/workflow/index.vue](ruoyi-ui/src/views/loanPricing/workflow/index.vue) - 移除详情对话框,修改查看按钮逻辑 -- 新增:[ruoyi-ui/src/views/loanPricing/workflow/detail.vue](ruoyi-ui/src/views/loanPricing/workflow/detail.vue) - 新的详情页面组件 -- 修改:[ruoyi-ui/src/router/index.js](ruoyi-ui/src/router/index.js) - 添加详情页动态路由 - -### 后端文件 -- 无需修改,API 接口保持不变 - -## 相关规格 - -此变更将修改以下规格: -- [loan-pricing-workflow-ui](../specs/loan-pricing-workflow-ui/spec.md) - 流程详情查看需求的实现方式变更 - -## 备选方案 - -### 方案 A:当前方案(独立页面) -- 优点:更好的用户体验,可扩展性强,支持 URL 分享 -- 缺点:需要创建新组件和路由配置 - -### 方案 B:保留弹窗,优化展示 -- 优点:改动较小 -- 缺点:仍然受限于弹窗尺寸,用户体验改善有限 - -### 方案 C:抽屉(Drawer)式侧边栏 -- 优点:利用垂直空间,可以展示更多信息 -- 缺点:在移动端体验不佳 - -**选择方案 A**,因为它提供了最佳的用户体验和扩展性。 - -## 风险与缓解 - -| 风险 | 影响 | 缓解措施 | -|------|------|----------| -| 路由配置错误导致 404 | 高 | 严格遵循现有路由模式,进行充分测试 | -| 详情页返回逻辑问题 | 中 | 添加面包屑导航和返回按钮 | -| 样式不一致 | 低 | 复用现有组件和样式 | - -## 时间表 - -此变更预计在批准后立即实施,包含以下步骤: -1. 创建详情页面组件 -2. 修改列表页查看逻辑 -3. 配置路由 -4. 测试验证 diff --git a/openspec/changes/change-view-workflow-to-page/specs/loan-pricing-workflow-ui/spec.md b/openspec/changes/change-view-workflow-to-page/specs/loan-pricing-workflow-ui/spec.md deleted file mode 100644 index 44850c9..0000000 --- a/openspec/changes/change-view-workflow-to-page/specs/loan-pricing-workflow-ui/spec.md +++ /dev/null @@ -1,29 +0,0 @@ -# loan-pricing-workflow-ui 规格变更 - -此规格定义了利率定价流程管理的前端用户界面需求。 - -## MODIFIED Requirements - -### Requirement: 流程详情查看 - -系统 SHALL 提供流程详情查看功能,以独立页面的形式展示完整的流程信息。 - -#### Scenario: 查看流程详情 -- **WHEN** 用户在流程列表页面且具有 `loanPricing:workflow:query` 权限,点击列表中某条记录的"查看"按钮 -- **THEN** 系统跳转至独立的流程详情页面,路径为 `/loanPricing/workflow-detail/{serialNum}`,展示完整的流程信息(基本信息:业务方流水号、机构编码、客户内码、客户名称、证件类型;业务信息:客户类型、担保方式、申请金额、贷款利率、贷款用途;业务标识:中间业务标识、企业标识;抵质押信息:抵质押类型、是否三方所有;其他信息:创建时间、创建者、更新时间、更新者) - -#### Scenario: 详情页面导航 -- **WHEN** 用户在流程详情页面 -- **THEN** 系统显示页面标题"流程详情"、返回按钮,面包屑导航高亮"利率定价管理 > 流程列表",点击返回按钮可返回流程列表页面 - -#### Scenario: 详情页面路由配置 -- **WHEN** 系统初始化加载路由配置 -- **THEN** 系统在动态路由中注册详情页路由,组件路径为 `@/views/loanPricing/workflow/detail`,路由参数 `serialNum` 用于标识具体流程,访问权限为 `loanPricing:workflow:query` - -#### Scenario: URL 直接访问详情页 -- **WHEN** 用户直接在浏览器地址栏输入详情页 URL(如 `/loanPricing/workflow-detail/ABC123`) -- **THEN** 系统加载详情页面组件,从路由参数中获取 `serialNum`,调用 API 获取对应的流程详情数据并展示 - -#### Scenario: 详情页面数据加载 -- **WHEN** 用户访问流程详情页面,路由参数包含有效的 `serialNum` -- **THEN** 系统在页面 created 钩子中调用 `GET /loanPricing/workflow/{serialNum}` 接口获取详情数据,显示 loading 状态,数据加载完成后隐藏 loading 并展示详情信息 diff --git a/openspec/changes/change-view-workflow-to-page/tasks.md b/openspec/changes/change-view-workflow-to-page/tasks.md deleted file mode 100644 index 9104355..0000000 --- a/openspec/changes/change-view-workflow-to-page/tasks.md +++ /dev/null @@ -1,57 +0,0 @@ -# 任务清单:将流程详情从弹窗改为独立页面 - -## 前端任务 - -### 1. 创建详情页面组件 -- [x] 创建 `ruoyi-ui/src/views/loanPricing/workflow/detail.vue` -- [x] 实现页面模板(el-page-header + el-card + el-descriptions) -- [x] 实现数据获取逻辑(从 route.params 获取 serialNum) -- [x] 实现 loading 状态和错误处理 -- [x] 实现返回逻辑(router.go(-1) 或跳转列表页) - -### 2. 配置动态路由 -- [x] 在 `ruoyi-ui/src/router/index.js` 的 `dynamicRoutes` 中添加详情页路由 -- [x] 配置路由参数 `:serialNum` -- [x] 配置权限 `loanPricing:workflow:query` -- [x] 配置 `activeMenu: '/loanPricing/workflow'` 保持菜单高亮 - -### 3. 修改列表页组件 -- [x] 修改 `index.vue` 中的 `handleView()` 方法,改为路由跳转 -- [x] 移除 `openDetail` 状态变量 -- [x] 移除 `detail` 数据对象 -- [x] 移除详情对话框模板(``) -- [x] 移除 API 导入中的 `getWorkflow`(如果详情页单独导入) - -## 验证任务 - -### 4. 功能测试 -- [ ] 测试从列表页点击"查看"按钮跳转到详情页 -- [ ] 测试详情页正确显示流程信息 -- [ ] 测试详情页返回按钮正常工作 -- [ ] 测试面包屑导航正确高亮"流程列表" -- [ ] 测试无权限用户无法访问详情页(403 或跳转登录) -- [ ] 测试访问无效的 serialNum(显示错误提示) - -### 5. UI 测试 -- [ ] 测试详情信息完整显示(所有字段) -- [ ] 测试长字段(如业务方流水号)正确显示 -- [ ] 测试布尔值字段正确转换为"是/否" -- [ ] 测试移动端响应式布局(单列显示) - -### 6. 回归测试 -- [ ] 确认流程列表页面功能正常(查询、筛选、分页) -- [ ] 确认新增流程功能正常 -- [ ] 确认其他菜单页面不受影响 - -## 依赖关系 - -- 任务 1(创建详情页面)和任务 2(配置路由)可以并行进行 -- 任务 3(修改列表页)依赖任务 2 完成(确保路由存在) -- 所有验证任务(4-6)依赖任务 1-3 完成 - -## 估算 - -- 任务 1:创建详情页面组件(核心任务)- 已完成 -- 任务 2:配置动态路由(简单任务)- 已完成 -- 任务 3:修改列表页组件(简单任务)- 已完成 -- 任务 4-6:测试验证(重要任务)- 待用户进行手动测试 diff --git a/openspec/changes/extract-workflow-create-dialog/design.md b/openspec/changes/extract-workflow-create-dialog/design.md deleted file mode 100644 index c95315c..0000000 --- a/openspec/changes/extract-workflow-create-dialog/design.md +++ /dev/null @@ -1,149 +0,0 @@ -# 设计文档:抽离流程创建对话框组件 - -## 组件设计 - -### WorkflowCreateDialog.vue 组件 - -**位置**:`ruoyi-ui/src/views/loanPricing/workflow/components/WorkflowCreateDialog.vue` - -**职责**:负责利率定价流程创建表单的展示和交互逻辑 - -#### Props - -| 名称 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `visible` | `Boolean` | `false` | 对话框显示状态(v-model 绑定) | - -#### Events - -| 事件名 | 参数 | 说明 | -|--------|------|------| -| `update:visible` | `(value: Boolean)` | 对话框显示状态变化时触发 | -| `success` | - | 创建成功后触发,父组件可刷新列表 | - -#### 内部状态 - -```javascript -data() { - return { - activeTab: 'basic', // 当前激活的标签页 - form: {}, // 表单数据 - rules: {} // 表单验证规则 - } -} -``` - -#### 表单字段结构 - -保持与现有实现一致,包含以下分组: - -1. **基本信息** 标签页 (`basic`) - - 客户内码 (`custIsn`) - 必填 - - 客户名称 (`custName`) - - 客户类型 (`custType`) - 必填,下拉选择 - - 证件类型 (`idType`) - **下拉选择**(身份证、统一社会信用代码) - -2. **贷款信息** 标签页 (`loan`) - - 申请金额 (`applyAmt`) - 必填 - - 贷款利率 (`loanRate`) - 必填 - - 担保方式 (`guarType`) - 必填,下拉选择 - - 贷款用途 (`loanPurpose`) - 下拉选择 - - 抵质押类型 (`collType`) - 下拉选择 - - 是否有经营佐证 (`bizProofActive`) - 开关 - - 抵质押物三方所有 (`collThirdPartyActive`) - 开关 - -3. **中间业务标识** 标签页 (`mid`) - - 个人快捷支付 (`midPerQuickPayActive`) - 开关 - - 个人电费代扣 (`midPerEleDdcActive`) - 开关 - - 企业电费代扣 (`midEntEleDdcActive`) - 开关 - - 企业水费代扣 (`midEntWaterDdcActive`) - 开关 - -4. **企业标识** 标签页 (`ent`) - - 净身企业 (`isCleanEntActive`) - 开关 - - 开立基本结算账户 (`hasSettleAcctActive`) - 开关 - - 制造业企业 (`isManufacturingActive`) - 开关 - - 省农担担保贷款 (`isAgriGuarActive`) - 开关 - - 纳税信用等级A级 (`isTaxAActive`) - 开关 - - 县级及以上农业龙头企业 (`isAgriLeadingActive`) - 开关 - - 普惠小微借款人 (`isInclusiveFinanceActive`) - 开关 - -#### 方法 - -| 方法名 | 说明 | -|--------|------| -| `reset()` | 重置表单到初始状态 | -| `cancel()` | 关闭对话框并重置表单 | -| `submitForm()` | 验证并提交表单 | - -### index.vue 修改 - -**移除内容**: -- 删除对话框相关的模板代码(第 82-256 行) -- 删除 `openCreate`、`activeTab`、`form`、`rules` 状态 -- 删除 `handleAdd()`、`reset()`、`cancelCreate()`、`submitForm()` 方法 - -**新增内容**: -- 导入 `WorkflowCreateDialog` 组件 -- 注册组件 -- 添加 `showCreateDialog` 状态(替代 `openCreate`) -- 修改 `handleAdd()` 方法,设置 `showCreateDialog = true` -- 添加 `handleCreateSuccess()` 方法,处理创建成功后刷新列表 - -## 组件通信流程 - -``` -┌─────────────────────────────────────────────────────────────┐ -│ index.vue │ -│ ┌─────────────┐ ┌─────────────────────────────────┐ │ -│ │ handleAdd() │ ───► │ showCreateDialog = true │ │ -│ └─────────────┘ └─────────────────────────────────┘ │ -│ │ -│ ┌──────────────────────────────────────────────────────┐ │ -│ │ showCreateDialog (v-model) │ │ -│ ├──────────────────────────────────────────────────────┤ │ -│ │ │ │ -│ ▼ │ │ -│ ┌────────────────────────────────────────────────────┐ │ │ -│ │ WorkflowCreateDialog.vue │ │ │ -│ │ │ │ │ -│ │ ◄────── visible (prop) ───────┐ │ │ │ -│ │ │ │ │ │ -│ │ ───────► update:visible ──────┘ │ │ │ -│ │ │ │ │ -│ │ submitForm() ──► API 调用 ──► @success 事件 ────────┼──┘ -│ │ │ -│ └────────────────────────────────────────────────────┘ -│ │ -│ ┌─────────────────────────────────────────────────────┐ │ -│ │ handleCreateSuccess() ──► getList() ──► 刷新列表 │ │ -│ └─────────────────────────────────────────────────────┘ │ -└─────────────────────────────────────────────────────────────┘ -``` - -## 证件类型下拉框实现 - -```vue - - - - - - -``` - -## 目录结构 - -``` -ruoyi-ui/src/views/loanPricing/workflow/ -├── components/ -│ └── WorkflowCreateDialog.vue # 新增:创建对话框组件 -├── detail.vue # 详情页面 -└── index.vue # 列表页面(修改) -``` - -## 兼容性考虑 - -- 组件使用 Vue 2.6.12 的 Options API 风格 -- 使用 Element UI 2.15.14 组件 -- 保持与现有代码风格一致 -- 确保表单验证规则和行为不变 diff --git a/openspec/changes/extract-workflow-create-dialog/proposal.md b/openspec/changes/extract-workflow-create-dialog/proposal.md deleted file mode 100644 index 76ceedf..0000000 --- a/openspec/changes/extract-workflow-create-dialog/proposal.md +++ /dev/null @@ -1,39 +0,0 @@ -# 提案:抽离流程创建对话框为独立组件并修改证件类型字段 - -## 概述 - -将利率定价流程创建对话框从列表页面组件中抽离为独立的可复用组件,同时将证件类型字段从输入框改为下拉框(选项:身份证、统一社会信用代码)。 - -## 背景 - -当前流程列表页面 ([`index.vue`](ruoyi-ui/src/views/loanPricing/workflow/index.vue)) 中,创建流程对话框的代码直接嵌入在列表组件中,导致单个文件超过 400 行。这不利于代码维护和复用。同时,证件类型字段使用输入框,用户需要手动输入,容易出错。 - -## 目标 - -1. **组件化**:将创建流程对话框抽离为独立组件 `WorkflowCreateDialog.vue`,放置在 `ruoyi-ui/src/views/loanPricing/workflow/components/` 目录 -2. **改进用户体验**:将证件类型改为下拉框,提供固定选项(身份证、统一社会信用代码) -3. **保持功能一致**:确保抽离后功能与现有实现完全一致 - -## 影响范围 - -- **新增文件**:`ruoyi-ui/src/views/loanPricing/workflow/components/WorkflowCreateDialog.vue` -- **修改文件**:`ruoyi-ui/src/views/loanPricing/workflow/index.vue` -- **修改规格**:`loan-pricing-workflow-ui` 规格中的"流程创建"需求 - -## 涉及能力 - -- **loan-pricing-workflow-ui**:前端用户界面规格 - -## 实施计划 - -1. 创建 `WorkflowCreateDialog.vue` 组件,包含所有表单逻辑 -2. 修改 `index.vue`,引入并使用新组件 -3. 更新 `loan-pricing-workflow-ui` 规格,修改证件类型字段描述 -4. 测试验证功能完整性 - -## 验收标准 - -- [ ] 创建对话框组件独立存在,可正常导入使用 -- [ ] 证件类型为下拉框,选项为"身份证"和"统一社会信用代码" -- [ ] 所有表单验证、提交逻辑正常工作 -- [ ] 列表页面功能无退化 diff --git a/openspec/changes/extract-workflow-create-dialog/specs/loan-pricing-workflow-ui/spec.md b/openspec/changes/extract-workflow-create-dialog/specs/loan-pricing-workflow-ui/spec.md deleted file mode 100644 index f1179dd..0000000 --- a/openspec/changes/extract-workflow-create-dialog/specs/loan-pricing-workflow-ui/spec.md +++ /dev/null @@ -1,58 +0,0 @@ -# loan-pricing-workflow-ui 规格变更 - -## MODIFIED Requirements - -### Requirement: 流程创建 - -系统 SHALL 提供创建新利率定价流程的功能,通过独立的对话框组件收集必要信息。 - -#### Scenario: 打开创建表单 -- **WHEN** 用户在流程列表页面且具有 `loanPricing:workflow:create` 权限,点击"新增"按钮 -- **THEN** 系统通过 `WorkflowCreateDialog` 组件弹出创建流程表单对话框,显示所有必填和可选字段 - -#### Scenario: 表单字段显示 -- **WHEN** 用户打开创建流程表单对话框 -- **THEN** 系统显示以下字段分组: - - 基本信息:客户内码(必填)、客户名称、客户类型(必填,下拉选择:个人/企业)、**证件类型(下拉选择:身份证/统一社会信用代码)** - - 贷款信息:申请金额(必填)、贷款利率(必填)、担保方式(必填,下拉选择:信用/保证/抵押/质押)、贷款用途(下拉选择:consumer/business) - - 中间业务标识(个人):个人快捷支付(开关)、个人电费代扣(开关) - - 中间业务标识(企业):企业电费代扣(开关)、企业水费代扣(开关) - - 企业标识:净身企业(开关)、开立基本结算账户(开关)、制造业企业(开关)、省农担担保贷款(开关)、纳税信用等级A级(开关)、县级及以上农业龙头企业(开关)、普惠小微借款人(开关) - - 抵质押信息:抵质押类型(下拉选择:一线/一类/二类)、抵质押物三方所有(开关)、是否有经营佐证(开关) - - 固定字段:机构编码(隐藏,固定值931000)、运行模式(隐藏,固定值1) - -#### Scenario: 选择证件类型 -- **WHEN** 用户在创建流程表单中点击证件类型下拉框 -- **THEN** 系统显示两个选项:"身份证"和"统一社会信用代码",用户选择其中一个 - -#### Scenario: 表单验证 -- **WHEN** 用户填写表单并点击确定按钮 -- **THEN** 系统验证必填字段:客户内码、客户类型、担保方式、申请金额、贷款利率,如有缺失则显示错误提示 - -#### Scenario: 提交创建成功 -- **WHEN** 用户填写完必填字段并点击确定按钮,后端返回成功响应 -- **THEN** 对话框组件触发 `success` 事件,父组件关闭对话框,显示成功提示消息,刷新列表数据 - -#### Scenario: 取消创建 -- **WHEN** 用户点击取消按钮或对话框关闭按钮 -- **THEN** 对话框组件触发 `update:visible` 事件,父组件关闭对话框,不保存数据,不刷新列表 - -#### Scenario: 新增按钮权限控制 -- **WHEN** 用户不具有 `loanPricing:workflow:create` 权限 -- **THEN** 系统不显示"新增"按钮 - -### Requirement: 创建对话框组件架构 - -系统 SHALL 将创建流程对话框实现为独立的 Vue 组件,支持复用和维护。 - -#### Scenario: 组件导入和注册 -- **WHEN** 开发者在 `index.vue` 中需要使用创建对话框功能 -- **THEN** 系统从 `@/views/loanPricing/workflow/components/WorkflowCreateDialog` 导入组件并注册 - -#### Scenario: 组件属性绑定 -- **WHEN** 父组件使用 `WorkflowCreateDialog` 组件 -- **THEN** 系统支持通过 `v-model:visible` 或 `visible` prop + `update:visible` 事件控制对话框显示状态 - -#### Scenario: 组件事件处理 -- **WHEN** 用户成功创建流程 -- **THEN** 组件触发 `success` 事件,父组件可监听该事件执行列表刷新等操作 diff --git a/openspec/changes/extract-workflow-create-dialog/tasks.md b/openspec/changes/extract-workflow-create-dialog/tasks.md deleted file mode 100644 index 0986519..0000000 --- a/openspec/changes/extract-workflow-create-dialog/tasks.md +++ /dev/null @@ -1,96 +0,0 @@ -# 实施任务清单 - -## 任务列表 - -### 1. 创建组件目录结构 -- [x] 创建 `ruoyi-ui/src/views/loanPricing/workflow/components/` 目录 -- **验证**: 目录创建成功,使用 `ls` 或 `dir` 确认 - -### 2. 创建 WorkflowCreateDialog.vue 组件 -- [x] 创建组件文件,包含完整的对话框模板 -- [x] 实现 props:`visible`(对话框显示状态) -- [x] 实现 emits:`update:visible`、`success` -- [x] 实现表单数据结构(保持与原实现一致) -- [x] 实现表单验证规则 -- [x] 实现四个标签页的表单字段 -- [x] **将证件类型改为 el-select 下拉框**,选项为"身份证"和"统一社会信用代码" -- [x] 实现 `reset()` 方法:重置表单到初始状态 -- [x] 实现 `cancel()` 方法:关闭对话框并重置表单 -- [x] 实现 `submitForm()` 方法:验证并提交表单 -- [x] 导入 `createWorkflow` API 函数 -- **验证**: 组件文件创建成功,无 ESLint 错误 - -### 3. 修改 index.vue 引入新组件 -- [x] 在 `index.vue` 顶部导入 `WorkflowCreateDialog` 组件 -- [x] 在 components 选项中注册组件 -- **验证**: 导入和注册语法正确 - -### 4. 修改 index.vue 模板 -- [x] 删除原有的对话框模板代码(第 82-256 行) -- [x] 添加 `` 组件标签 -- [x] 绑定 `v-model:visible="showCreateDialog"` -- [x] 监听 `@success` 事件调用 `handleCreateSuccess` -- **验证**: 模板语法正确,组件标签正确使用 - -### 5. 修改 index.vue 数据和逻辑 -- [x] 移除 `openCreate` 状态,替换为 `showCreateDialog` -- [x] 移除 `activeTab` 状态 -- [x] 移除 `form` 状态 -- [x] 移除 `rules` 状态 -- [x] 修改 `handleAdd()` 方法:设置 `showCreateDialog = true` -- [x] 添加 `handleCreateSuccess()` 方法:显示成功消息并调用 `getList()` -- [x] 删除 `reset()` 方法 -- [x] 删除 `cancelCreate()` 方法 -- [x] 删除 `submitForm()` 方法 -- [x] 删除 `createWorkflow` 导入(已移至组件内) -- **验证**: 修改后的代码无语法错误 - -### 6. 手动功能测试 -- [ ] 启动前端开发服务器 (`npm run dev`) -- [ ] 登录系统 (admin/admin123) -- [ ] 导航至"利率定价管理 > 流程列表" -- [ ] 点击"新增"按钮,验证对话框正常弹出 -- [ ] 切换各个标签页,验证表单字段正确显示 -- [ ] **点击证件类型下拉框,验证选项为"身份证"和"统一社会信用代码"** -- [ ] 测试表单验证:不填必填项提交,验证错误提示 -- [ ] 填写完整表单并提交,验证创建成功 -- [ ] 验证创建成功后列表自动刷新 -- [ ] 测试取消按钮,验证对话框关闭且不保存 -- **验证**: 所有功能正常工作 - -### 7. 代码质量检查 -- [x] 检查组件命名和文件命名符合项目规范 -- [x] 检查代码格式符合项目 ESLint 配置 -- [x] 检查注释完整,关键逻辑有说明 -- **验证**: 代码符合项目规范 - -## 任务依赖关系 - -``` -1. 创建组件目录结构 - │ - ├──► 2. 创建 WorkflowCreateDialog.vue 组件 - │ │ - │ ├──► 3. 修改 index.vue 引入新组件 - │ │ │ - │ │ ├──► 4. 修改 index.vue 模板 - │ │ │ │ - │ │ │ ├──► 5. 修改 index.vue 数据和逻辑 - │ │ │ │ │ - │ │ │ │ └──► 6. 手动功能测试 - │ │ │ │ │ - │ │ │ │ └──► 7. 代码质量检查 - │ │ │ │ - │ │ │ └──► (并行) 6. 手动功能测试 - │ │ │ - │ │ └──► (并行) 6. 手动功能测试 - │ │ - │ └──► (并行) 6. 手动功能测试 - │ - └──► (并行) 6. 手动功能测试 -``` - -## 可并行任务 - -- 任务 3、4、5 可以在任务 2 完成后并行执行 -- 任务 7 可与任务 6 并行执行 diff --git a/openspec/changes/improve-workflow-detail-layout/proposal.md b/openspec/changes/improve-workflow-detail-layout/proposal.md deleted file mode 100644 index 5396935..0000000 --- a/openspec/changes/improve-workflow-detail-layout/proposal.md +++ /dev/null @@ -1,23 +0,0 @@ -# Change: 优化流程详情页面布局 - -## Why - -当前流程详情页面 ([`ruoyi-ui/src/views/loanPricing/workflow/detail.vue`](../../ruoyi-ui/src/views/loanPricing/workflow/detail.vue)) 采用简单的标签页布局,所有信息平铺展示,缺乏信息层次感。用户需要在不同标签页之间切换才能查看关键信息,无法快速获取最重要的数据概览。页面视觉层次不够清晰,信息利用率不高。 - -## What Changes - -- **页面布局重构**: 采用信息密集型两栏布局 - - 左侧(约 30% 宽度):展示关键信息摘要卡片(业务方流水号、客户名称、申请金额、贷款利率等核心字段) - - 右侧(约 70% 宽度):保留现有标签页,展示完整的流程详细信息 -- **页面头部简化**: 移除 `el-page-header`,使用简洁的页面标题,返回按钮移至页面右上角 -- **样式优化**: - - 为左侧摘要卡片添加适当的阴影和圆角 - - 优化卡片内部间距和字体大小 - - 保持现有的简洁数据展示风格(不添加图标或额外的高亮效果) -- **响应式支持**: 在小屏幕设备上自动调整为单栏垂直布局 - -## Impact - -- 受影响的规范: `loan-pricing-workflow-ui` -- 受影响的代码: [`ruoyi-ui/src/views/loanPricing/workflow/detail.vue`](../../ruoyi-ui/src/views/loanPricing/workflow/detail.vue) -- 破坏性变更: 无(仅改变 UI 布局,不影响功能和 API) diff --git a/openspec/changes/improve-workflow-detail-layout/specs/loan-pricing-workflow-ui/spec.md b/openspec/changes/improve-workflow-detail-layout/specs/loan-pricing-workflow-ui/spec.md deleted file mode 100644 index ab80fa5..0000000 --- a/openspec/changes/improve-workflow-detail-layout/specs/loan-pricing-workflow-ui/spec.md +++ /dev/null @@ -1,34 +0,0 @@ -## MODIFIED Requirements - -### Requirement: 流程详情查看 - -系统 SHALL 提供流程详情查看功能,以独立页面形式展示完整的流程信息,采用信息密集型两栏布局。 - -#### Scenario: 查看流程详情 -- **WHEN** 用户在流程列表页面且具有 `loanPricing:workflow:query` 权限,点击列表中某条记录的"查看"按钮 -- **THEN** 系统导航至流程详情独立页面,展示两栏布局: - - **左侧摘要卡片**(约 30% 宽度):显示核心信息 - - 业务方流水号 - - 客户名称 - - 客户类型 - - 申请金额 - - 贷款利率 - - 担保方式 - - **右侧详情区域**(约 70% 宽度):使用标签页组织完整信息 - - 基本信息标签页:机构编码、运行模式、客户内码、证件类型 - - 业务信息标签页:贷款用途、是否有经营佐证、抵质押类型、抵质押物三方所有 - - 中间业务标识标签页:个人快捷支付、个人电费代扣、企业电费代扣、企业水费代扣 - - 企业标识标签页:净身企业、开立基本结算账户、制造业企业、省农担担保贷款、纳税信用等级A级、县级及以上农业龙头企业、普惠小微借款人 - - 其他信息标签页:创建时间、创建者、更新时间、更新者 - -#### Scenario: 页面头部和导航 -- **WHEN** 用户访问流程详情页面 -- **THEN** 系统显示简洁的页面标题区域,右上角放置返回按钮,移除原有的面包屑导航组件 - -#### Scenario: 响应式布局适配 -- **WHEN** 用户在屏幕宽度小于 768px 的设备上访问流程详情页面 -- **THEN** 系统自动调整为单栏垂直布局,左侧摘要卡片在上方,右侧详情标签页在下方 - -#### Scenario: 返回上一页 -- **WHEN** 用户点击页面右上角的返回按钮 -- **THEN** 系统返回至流程列表页面 diff --git a/openspec/changes/improve-workflow-detail-layout/tasks.md b/openspec/changes/improve-workflow-detail-layout/tasks.md deleted file mode 100644 index bf31c46..0000000 --- a/openspec/changes/improve-workflow-detail-layout/tasks.md +++ /dev/null @@ -1,19 +0,0 @@ -## 1. 实现页面布局重构 - -- [x] 1.1 创建左侧摘要卡片组件结构 -- [x] 1.2 创建右侧标签页详情区域 -- [x] 1.3 实现响应式布局(使用 `el-col` 的 `xs` 断点) -- [x] 1.4 调整页面头部(移除 `el-page-header`,添加返回按钮到右上角) - -## 2. 样式优化 - -- [x] 2.1 添加卡片阴影和圆角样式 -- [x] 2.2 优化间距和字体大小 -- [x] 2.3 调整两栏布局的间距(`el-row` 的 `gutter` 属性) - -## 3. 测试验证 - -- [x] 3.1 测试页面在不同屏幕尺寸下的显示效果 -- [x] 3.2 验证所有数据字段正确显示 -- [x] 3.3 确认返回按钮功能正常 -- [x] 3.4 验证标签页切换功能正常 diff --git a/openspec/changes/remove-tabs-from-workflow-create-dialog/design.md b/openspec/changes/remove-tabs-from-workflow-create-dialog/design.md deleted file mode 100644 index 01e2033..0000000 --- a/openspec/changes/remove-tabs-from-workflow-create-dialog/design.md +++ /dev/null @@ -1,80 +0,0 @@ -# Design: 移除流程创建弹窗的 Tab 栏布局 - -## Current Implementation - -当前 `WorkflowCreateDialog.vue` 使用 `el-tabs` 组件组织表单字段: - -```vue - - - - - - - - - - - - - - -``` - -## Proposed Implementation - -使用 Element UI 的 `el-divider` 组件作为分组标题,移除 `el-tabs` 和 `el-tab-pane`: - -```vue - - - 基本信息 - - - - - - - - - - - - - - - - 贷款信息 - - - - 中间业务标识 - - - - 企业标识 - - -``` - -同时需要移除 `data()` 中的 `activeTab` 属性。 - -## CSS Styling - -为 `el-divider` 添加适当的外边距,确保分组标题与表单字段之间有清晰的视觉分隔: - -```css -.el-divider { - margin: 16px 0 20px 0; - font-weight: bold; -} -``` - -或使用 `