421 lines
12 KiB
Markdown
421 lines
12 KiB
Markdown
|
|
# 全量迁移 `892-without-redis` 前端实施计划
|
|||
|
|
|
|||
|
|
> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking.
|
|||
|
|
|
|||
|
|
**Goal:** 在当前前端工程中迁入 `origin/892-without-redis` 的贷款定价页面、登录页与缓存监控相关行为,并与后端迁移后的接口契约完全对齐。
|
|||
|
|
|
|||
|
|
**Architecture:** 以前端 `ruoyi-ui` 为基线,新增贷款定价页面目录、API 封装、密码传输工具与页面测试脚本,按“接口先对齐、页面后对齐”的顺序迁移。对目标分支与当前分支冲突位置优先保留当前工程的 Vue2/RuoYi 组织方式,再把目标功能按现有结构接进去。
|
|||
|
|
|
|||
|
|
**Tech Stack:** Vue 2, Vue Router, Vuex, Element UI, Axios API wrappers, Node via nvm
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
> 仓库约束补充:执行前端验证时必须先在 `ruoyi-ui` 下执行 `nvm use`;若拉起前端 dev 进程,验证结束后要主动关闭。
|
|||
|
|
|
|||
|
|
## 文件结构映射
|
|||
|
|
|
|||
|
|
### 路由、登录、公共工具
|
|||
|
|
|
|||
|
|
- Modify: `ruoyi-ui/src/router/index.js`
|
|||
|
|
- Modify: `ruoyi-ui/src/views/login.vue`
|
|||
|
|
- Modify: `ruoyi-ui/src/api/login.js`
|
|||
|
|
- Create: `ruoyi-ui/src/utils/passwordTransfer.js`
|
|||
|
|
|
|||
|
|
### 贷款定价 API 与页面
|
|||
|
|
|
|||
|
|
- Create: `ruoyi-ui/src/api/loanPricing/workflow.js`
|
|||
|
|
- Create: `ruoyi-ui/src/views/loanPricing/workflow/index.vue`
|
|||
|
|
- Create: `ruoyi-ui/src/views/loanPricing/workflow/detail.vue`
|
|||
|
|
- Create: `ruoyi-ui/src/views/loanPricing/workflow/components/BargainingPoolDisplay.vue`
|
|||
|
|
- Create: `ruoyi-ui/src/views/loanPricing/workflow/components/CorporateCreateDialog.vue`
|
|||
|
|
- Create: `ruoyi-ui/src/views/loanPricing/workflow/components/CorporateWorkflowDetail.vue`
|
|||
|
|
- Create: `ruoyi-ui/src/views/loanPricing/workflow/components/CustomerTypeSelector.vue`
|
|||
|
|
- Create: `ruoyi-ui/src/views/loanPricing/workflow/components/ModelOutputDisplay.vue`
|
|||
|
|
- Create: `ruoyi-ui/src/views/loanPricing/workflow/components/PersonalCreateDialog.vue`
|
|||
|
|
- Create: `ruoyi-ui/src/views/loanPricing/workflow/components/PersonalWorkflowDetail.vue`
|
|||
|
|
|
|||
|
|
### 缓存监控页面
|
|||
|
|
|
|||
|
|
- Modify: `ruoyi-ui/src/api/monitor/cache.js`
|
|||
|
|
- Modify: `ruoyi-ui/src/views/monitor/cache/index.vue`
|
|||
|
|
- Modify: `ruoyi-ui/src/views/monitor/cache/list.vue`
|
|||
|
|
|
|||
|
|
### 前端静态测试脚本
|
|||
|
|
|
|||
|
|
- Create: `ruoyi-ui/tests/password-transfer-api.test.js`
|
|||
|
|
- Create: `ruoyi-ui/tests/personal-create-input-params.test.js`
|
|||
|
|
- Create: `ruoyi-ui/tests/retail-display-fields.test.js`
|
|||
|
|
- Create: `ruoyi-ui/tests/personal-final-calculate-rate-display.test.js`
|
|||
|
|
- Create: `ruoyi-ui/tests/workflow-detail-card-order.test.js`
|
|||
|
|
- Create: `ruoyi-ui/tests/workflow-index-refresh.test.js`
|
|||
|
|
- Create: `ruoyi-ui/tests/login-default-credentials.test.js`
|
|||
|
|
|
|||
|
|
### 前端实施记录
|
|||
|
|
|
|||
|
|
- Create: `doc/2026-04-15-全量迁移892-without-redis前端实施记录.md`
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### Task 1: 接入贷款定价路由、API 和页面骨架
|
|||
|
|
|
|||
|
|
**Files:**
|
|||
|
|
- Modify: `ruoyi-ui/src/router/index.js`
|
|||
|
|
- Create: `ruoyi-ui/src/api/loanPricing/workflow.js`
|
|||
|
|
- Create: `ruoyi-ui/src/views/loanPricing/workflow/index.vue`
|
|||
|
|
- Create: `ruoyi-ui/src/views/loanPricing/workflow/detail.vue`
|
|||
|
|
- Create: `ruoyi-ui/src/views/loanPricing/workflow/components/CustomerTypeSelector.vue`
|
|||
|
|
|
|||
|
|
- [ ] **Step 1: 先写路由/页面缺失断言脚本**
|
|||
|
|
|
|||
|
|
在 `ruoyi-ui/tests/workflow-index-refresh.test.js` 先写最小源码断言:
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
expect(routerSource).toContain("LoanPricingWorkflow")
|
|||
|
|
expect(routerSource).toContain("@/views/loanPricing/workflow/index")
|
|||
|
|
expect(routerSource).toContain("@/views/loanPricing/workflow/detail")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
- [ ] **Step 2: 创建 API 封装**
|
|||
|
|
|
|||
|
|
`ruoyi-ui/src/api/loanPricing/workflow.js` 至少提供:
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
export function listWorkflow(query) {}
|
|||
|
|
export function getWorkflow(serialNum) {}
|
|||
|
|
export function createPersonalWorkflow(data) {}
|
|||
|
|
export function createCorporateWorkflow(data) {}
|
|||
|
|
export function updateExecuteRate(data) {}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
- [ ] **Step 3: 接入默认首页和详情路由**
|
|||
|
|
|
|||
|
|
`ruoyi-ui/src/router/index.js` 需要包含:
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
component: () => import('@/views/loanPricing/workflow/index')
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
以及隐藏详情路由:
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
path: '/loanPricing/workflow-detail'
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
- [ ] **Step 4: 创建最小页面骨架**
|
|||
|
|
|
|||
|
|
`index.vue` 至少包含:
|
|||
|
|
|
|||
|
|
```vue
|
|||
|
|
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
`detail.vue` 至少包含:
|
|||
|
|
|
|||
|
|
```vue
|
|||
|
|
<personal-workflow-detail v-if="form.custType === '个人'" />
|
|||
|
|
<corporate-workflow-detail v-else />
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
- [ ] **Step 5: 运行前端源码测试**
|
|||
|
|
|
|||
|
|
Run:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cd ruoyi-ui && node tests/workflow-index-refresh.test.js
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Expected: 断言通过。
|
|||
|
|
|
|||
|
|
- [ ] **Step 6: 提交**
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
git add ruoyi-ui/src/router/index.js ruoyi-ui/src/api/loanPricing/workflow.js ruoyi-ui/src/views/loanPricing
|
|||
|
|
git commit -m "接入贷款定价前端页面骨架"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Task 2: 实现流程列表与详情展示行为
|
|||
|
|
|
|||
|
|
**Files:**
|
|||
|
|
- Modify: `ruoyi-ui/src/views/loanPricing/workflow/index.vue`
|
|||
|
|
- Modify: `ruoyi-ui/src/views/loanPricing/workflow/detail.vue`
|
|||
|
|
- Create: `ruoyi-ui/src/views/loanPricing/workflow/components/BargainingPoolDisplay.vue`
|
|||
|
|
- Create: `ruoyi-ui/src/views/loanPricing/workflow/components/CorporateWorkflowDetail.vue`
|
|||
|
|
- Create: `ruoyi-ui/src/views/loanPricing/workflow/components/PersonalWorkflowDetail.vue`
|
|||
|
|
- Create: `ruoyi-ui/src/views/loanPricing/workflow/components/ModelOutputDisplay.vue`
|
|||
|
|
- Test: `ruoyi-ui/tests/retail-display-fields.test.js`
|
|||
|
|
- Test: `ruoyi-ui/tests/personal-final-calculate-rate-display.test.js`
|
|||
|
|
- Test: `ruoyi-ui/tests/workflow-detail-card-order.test.js`
|
|||
|
|
|
|||
|
|
- [ ] **Step 1: 先写详情字段失败测试**
|
|||
|
|
|
|||
|
|
在源码断言里至少覆盖:
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
expect(source).toContain("loanTerm")
|
|||
|
|
expect(source).toContain("finalCalculateRate")
|
|||
|
|
expect(source).toContain("referenceRate")
|
|||
|
|
expect(source).toContain("smoothRange")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
并为卡片顺序加断言:
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
expect(detailSource.indexOf("基础信息")).toBeLessThan(detailSource.indexOf("测算结果"))
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
- [ ] **Step 2: 改列表列定义**
|
|||
|
|
|
|||
|
|
`index.vue` 要明确展示:
|
|||
|
|
|
|||
|
|
```vue
|
|||
|
|
<el-table-column label="测算利率(%)" prop="calculateRate" />
|
|||
|
|
<el-table-column label="执行利率(%)" prop="executeRate" />
|
|||
|
|
<el-table-column label="更新时间" prop="updateTime" />
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
个人最终测算利率按目标分支行为取后端返回的 `finalCalculateRate` 或已统一好的 `calculateRate`。
|
|||
|
|
|
|||
|
|
- [ ] **Step 3: 改详情页面与模型输出组件**
|
|||
|
|
|
|||
|
|
`PersonalWorkflowDetail.vue` 必须展示:
|
|||
|
|
|
|||
|
|
- `loanTerm`
|
|||
|
|
- `finalCalculateRate`
|
|||
|
|
- 调整后的详情卡片顺序
|
|||
|
|
|
|||
|
|
`ModelOutputDisplay.vue` 必须展示:
|
|||
|
|
|
|||
|
|
- `loanRateHistory`
|
|||
|
|
- `minRateProduct`
|
|||
|
|
- `smoothRange`
|
|||
|
|
- `finalCalculateRate`
|
|||
|
|
- `referenceRate`
|
|||
|
|
|
|||
|
|
- [ ] **Step 4: 运行源码测试**
|
|||
|
|
|
|||
|
|
Run:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cd ruoyi-ui && node tests/retail-display-fields.test.js && node tests/personal-final-calculate-rate-display.test.js && node tests/workflow-detail-card-order.test.js
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Expected: 断言通过。
|
|||
|
|
|
|||
|
|
- [ ] **Step 5: 提交**
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
git add ruoyi-ui/src/views/loanPricing ruoyi-ui/tests
|
|||
|
|
git commit -m "迁移流程列表与详情展示逻辑"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Task 3: 实现个人/企业建单弹窗与输入参数对齐
|
|||
|
|
|
|||
|
|
**Files:**
|
|||
|
|
- Create: `ruoyi-ui/src/views/loanPricing/workflow/components/CorporateCreateDialog.vue`
|
|||
|
|
- Create: `ruoyi-ui/src/views/loanPricing/workflow/components/PersonalCreateDialog.vue`
|
|||
|
|
- Modify: `ruoyi-ui/src/views/loanPricing/workflow/index.vue`
|
|||
|
|
- Test: `ruoyi-ui/tests/personal-create-input-params.test.js`
|
|||
|
|
|
|||
|
|
- [ ] **Step 1: 先写个人入参失败测试**
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
expect(source).toContain("loanPurpose")
|
|||
|
|
expect(source).toContain("loanTerm")
|
|||
|
|
expect(source).toContain("loanLoop")
|
|||
|
|
expect(source).toContain("collThirdParty")
|
|||
|
|
expect(source).toContain("['一类', '二类', '三类']")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
- [ ] **Step 2: 实现个人建单弹窗**
|
|||
|
|
|
|||
|
|
`PersonalCreateDialog.vue` 至少补齐:
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
form: {
|
|||
|
|
custIsn: '',
|
|||
|
|
custName: '',
|
|||
|
|
idType: '',
|
|||
|
|
idNum: '',
|
|||
|
|
guarType: '',
|
|||
|
|
applyAmt: '',
|
|||
|
|
loanPurpose: '',
|
|||
|
|
loanTerm: '',
|
|||
|
|
bizProof: false,
|
|||
|
|
loanLoop: false,
|
|||
|
|
collThirdParty: false,
|
|||
|
|
collType: ''
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
并在提交时直接调用 `createPersonalWorkflow`,不在前端增加补丁式兜底。
|
|||
|
|
|
|||
|
|
- [ ] **Step 3: 实现企业建单弹窗并接入列表页**
|
|||
|
|
|
|||
|
|
`index.vue` 中要能根据客户类型打开对应建单对话框,且提交后刷新列表。
|
|||
|
|
|
|||
|
|
- [ ] **Step 4: 跑源码测试**
|
|||
|
|
|
|||
|
|
Run:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cd ruoyi-ui && node tests/personal-create-input-params.test.js
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Expected: 断言通过。
|
|||
|
|
|
|||
|
|
- [ ] **Step 5: 提交**
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
git add ruoyi-ui/src/views/loanPricing ruoyi-ui/tests/personal-create-input-params.test.js
|
|||
|
|
git commit -m "迁移贷款定价建单弹窗"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Task 4: 迁移登录密码传输与登录页展示
|
|||
|
|
|
|||
|
|
**Files:**
|
|||
|
|
- Modify: `ruoyi-ui/src/views/login.vue`
|
|||
|
|
- Modify: `ruoyi-ui/src/api/login.js`
|
|||
|
|
- Create: `ruoyi-ui/src/utils/passwordTransfer.js`
|
|||
|
|
- Test: `ruoyi-ui/tests/password-transfer-api.test.js`
|
|||
|
|
- Test: `ruoyi-ui/tests/login-default-credentials.test.js`
|
|||
|
|
|
|||
|
|
- [ ] **Step 1: 先写登录页失败测试**
|
|||
|
|
|
|||
|
|
`login-default-credentials.test.js` 要先断言旧默认账号密码提示不存在:
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
expect(source).not.toContain("admin")
|
|||
|
|
expect(source).not.toContain("123456")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
`password-transfer-api.test.js` 要断言登录 API 使用密码传输工具:
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
expect(apiSource).toContain("transferPassword")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
- [ ] **Step 2: 新增密码传输工具**
|
|||
|
|
|
|||
|
|
`ruoyi-ui/src/utils/passwordTransfer.js` 最小接口:
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
export function transferPassword(password) {
|
|||
|
|
return password
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
后续再替换为与后端一致的实际传输处理,但调用入口先统一。
|
|||
|
|
|
|||
|
|
- [ ] **Step 3: 改登录 API 与页面**
|
|||
|
|
|
|||
|
|
`src/api/login.js` 在登录、注册、修改密码等调用入口统一接 `transferPassword`。
|
|||
|
|
|
|||
|
|
`src/views/login.vue` 删除默认账号密码展示,保留验证码、记住密码和现有交互。
|
|||
|
|
|
|||
|
|
- [ ] **Step 4: 跑源码测试**
|
|||
|
|
|
|||
|
|
Run:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cd ruoyi-ui && node tests/password-transfer-api.test.js && node tests/login-default-credentials.test.js
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Expected: 断言通过。
|
|||
|
|
|
|||
|
|
- [ ] **Step 5: 提交**
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
git add ruoyi-ui/src/api/login.js ruoyi-ui/src/utils/passwordTransfer.js ruoyi-ui/src/views/login.vue ruoyi-ui/tests
|
|||
|
|
git commit -m "迁移登录页与密码传输前端逻辑"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Task 5: 迁移缓存监控页并对齐内存缓存行为
|
|||
|
|
|
|||
|
|
**Files:**
|
|||
|
|
- Modify: `ruoyi-ui/src/api/monitor/cache.js`
|
|||
|
|
- Modify: `ruoyi-ui/src/views/monitor/cache/index.vue`
|
|||
|
|
- Modify: `ruoyi-ui/src/views/monitor/cache/list.vue`
|
|||
|
|
|
|||
|
|
- [ ] **Step 1: 先核对后端缓存接口字段**
|
|||
|
|
|
|||
|
|
执行前先读后端 `CacheController` 最终返回字段,记录页面需要显示哪些统计项,禁止继续按 Redis 键空间展示。
|
|||
|
|
|
|||
|
|
- [ ] **Step 2: 改 API 与页面展示**
|
|||
|
|
|
|||
|
|
`cache.js` 按后端实际接口字段更新。
|
|||
|
|
|
|||
|
|
`index.vue` / `list.vue` 改成展示内存缓存统计、命中率、键数量、过期数量等目标分支行为要求的内容。
|
|||
|
|
|
|||
|
|
- [ ] **Step 3: 做页面级静态检查**
|
|||
|
|
|
|||
|
|
至少确认源码里不再假设 Redis 特有结构,例如:
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
expect(source).not.toContain("redis")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
如需要,可新增一个简短源码测试脚本并与本任务一起提交。
|
|||
|
|
|
|||
|
|
- [ ] **Step 4: 提交**
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
git add ruoyi-ui/src/api/monitor/cache.js ruoyi-ui/src/views/monitor/cache
|
|||
|
|
git commit -m "迁移缓存监控前端页面"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Task 6: 前端总验收与实施记录
|
|||
|
|
|
|||
|
|
**Files:**
|
|||
|
|
- Modify: `doc/2026-04-15-全量迁移892-without-redis前端实施计划.md`
|
|||
|
|
- Create: `doc/2026-04-15-全量迁移892-without-redis前端实施记录.md`
|
|||
|
|
|
|||
|
|
- [ ] **Step 1: 安装依赖并构建**
|
|||
|
|
|
|||
|
|
Run:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cd ruoyi-ui
|
|||
|
|
nvm use
|
|||
|
|
npm install
|
|||
|
|
npm run build:prod
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Expected: 生产构建成功。
|
|||
|
|
|
|||
|
|
- [ ] **Step 2: 启动前端进行关键页面冒烟**
|
|||
|
|
|
|||
|
|
Run:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cd ruoyi-ui
|
|||
|
|
nvm use
|
|||
|
|
npm run dev
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
检查:
|
|||
|
|
|
|||
|
|
- 登录页
|
|||
|
|
- 流程列表
|
|||
|
|
- 流程详情
|
|||
|
|
- 个人建单
|
|||
|
|
- 缓存监控页
|
|||
|
|
|
|||
|
|
验证完成后主动停止前端进程。
|
|||
|
|
|
|||
|
|
- [ ] **Step 3: 补前端实施记录**
|
|||
|
|
|
|||
|
|
`doc/2026-04-15-全量迁移892-without-redis前端实施记录.md` 至少记录:
|
|||
|
|
|
|||
|
|
- 实际迁入页面与 API
|
|||
|
|
- 与目标分支不做原样搬运的整合点
|
|||
|
|
- `nvm use` 的 Node 版本
|
|||
|
|
- 构建结果
|
|||
|
|
- 页面冒烟结果
|
|||
|
|
|
|||
|
|
- [ ] **Step 4: 提交**
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
git add doc/2026-04-15-全量迁移892-without-redis前端实施计划.md doc/2026-04-15-全量迁移892-without-redis前端实施记录.md
|
|||
|
|
git commit -m "补充全量迁移前端实施记录"
|
|||
|
|
```
|