486 lines
15 KiB
Markdown
486 lines
15 KiB
Markdown
# Shangyu Pricing Field Adjustment Frontend Implementation Plan
|
|
|
|
> **For agentic workers:** Follow this repository's `AGENTS.md`: do not invoke `using-superpowers` or subagents during implementation unless the user explicitly requests them. Steps use checkbox (`- [ ]`) syntax for tracking.
|
|
|
|
**Goal:** Update the personal and corporate workflow create dialogs so the displayed fields, dynamic options, required `couponRate`, and submitted payload match the approved Shangyu pricing spec.
|
|
|
|
**Architecture:** Keep the existing Vue 2 create-dialog components and static Node assertion tests. Update each dialog in place, using computed properties for customer-type-specific collateral options and the `质押 + 存单质押` coupon-rate condition; verify with static tests, production build, and a real Playwright browser check.
|
|
|
|
**Tech Stack:** Vue 2, Element UI, RuoYi request wrapper, Node static tests, npm scripts, nvm-controlled frontend runtime, Playwright real browser verification.
|
|
|
|
---
|
|
|
|
## File Structure
|
|
|
|
- Modify: `ruoyi-ui/src/views/loanPricing/workflow/components/PersonalCreateDialog.vue`
|
|
- Change `businessType` options.
|
|
- Remove `loanPurpose` and `bizProof` UI, form fields, rules, reset values, and submit payload handling.
|
|
- Change personal `collateralTypeOptions`.
|
|
- Add `couponRate` conditional field and submit cleanup.
|
|
- Modify: `ruoyi-ui/src/views/loanPricing/workflow/components/CorporateCreateDialog.vue`
|
|
- Change `businessType` options.
|
|
- Change corporate `collateralTypeOptions`.
|
|
- Add `couponRate` conditional field and submit cleanup.
|
|
- Modify: `ruoyi-ui/tests/business-type-history-rate.test.js`
|
|
- Update business-type assertions from `新客` to `新增`.
|
|
- Add `couponRate` assertions.
|
|
- Modify: `ruoyi-ui/tests/personal-create-input-params.test.js`
|
|
- Assert personal removed fields are absent.
|
|
- Assert personal collateral options match the new spec.
|
|
- Modify: `ruoyi-ui/tests/corporate-create-input-params.test.js`
|
|
- Assert corporate collateral options match the new spec.
|
|
- Modify: `doc/implementation-report-2026-05-11-shangyu-pricing-field-adjustment.md`
|
|
- Add frontend implementation and Playwright verification notes after execution.
|
|
|
|
## Task 1: Update Frontend Static Assertions First
|
|
|
|
**Files:**
|
|
- Modify: `ruoyi-ui/tests/business-type-history-rate.test.js`
|
|
- Modify: `ruoyi-ui/tests/personal-create-input-params.test.js`
|
|
- Modify: `ruoyi-ui/tests/corporate-create-input-params.test.js`
|
|
|
|
- [ ] **Step 1: Update business-type assertions**
|
|
|
|
In `business-type-history-rate.test.js`, replace old assertions for `新客` with:
|
|
|
|
```js
|
|
;[
|
|
['个人新增弹窗', personalCreate],
|
|
['企业新增弹窗', corporateCreate]
|
|
].forEach(([name, source]) => {
|
|
assert(source.includes('label="业务种类"'), `${name} 缺少业务种类`)
|
|
assert(source.includes('value="新增"'), `${name} 缺少新增选项`)
|
|
assert(source.includes('value="存量新增"'), `${name} 缺少存量新增选项`)
|
|
assert(source.includes('value="存量转贷"'), `${name} 缺少存量转贷选项`)
|
|
assert(!source.includes('value="新客"'), `${name} 仍保留旧业务种类 新客`)
|
|
assert(source.includes("if (value === '存量转贷')"), `${name} 未保持仅存量转贷查询历史合同`)
|
|
})
|
|
```
|
|
|
|
- [ ] **Step 2: Add coupon-rate assertions**
|
|
|
|
In the same test file, add:
|
|
|
|
```js
|
|
;[
|
|
['个人新增弹窗', personalCreate],
|
|
['企业新增弹窗', corporateCreate]
|
|
].forEach(([name, source]) => {
|
|
assert(source.includes('label="存单票面利率"'), `${name} 缺少存单票面利率字段`)
|
|
assert(source.includes('prop="couponRate"'), `${name} 缺少 couponRate prop`)
|
|
assert(source.includes('isCertificatePledge'), `${name} 缺少存单质押条件计算`)
|
|
assert(source.includes("this.form.guarType === '质押'") && source.includes("this.form.collType === '存单质押'"), `${name} couponRate 条件不正确`)
|
|
assert(source.includes('delete data.couponRate'), `${name} 未在非适用条件删除 couponRate`)
|
|
assert(source.includes('存单票面利率不能为空'), `${name} 缺少 couponRate 必填提示`)
|
|
})
|
|
```
|
|
|
|
This shared `business-type-history-rate.test.js` is expected to remain failing until both personal and corporate dialogs are updated. Do not use it as a passing checkpoint after only the personal dialog is changed.
|
|
|
|
- [ ] **Step 3: Update personal-field assertions**
|
|
|
|
In `personal-create-input-params.test.js`, replace old required assertions for `loanPurpose` and `bizProof` with absence checks:
|
|
|
|
```js
|
|
assert(
|
|
!personalCreateDialog.includes('label="贷款用途"') &&
|
|
!personalCreateDialog.includes('prop="loanPurpose"') &&
|
|
!personalCreateDialog.includes('loanPurpose:'),
|
|
'个人新增弹窗不应继续保留贷款用途字段'
|
|
)
|
|
|
|
assert(
|
|
!personalCreateDialog.includes('label="是否有经营佐证"') &&
|
|
!personalCreateDialog.includes('prop="bizProof"') &&
|
|
!personalCreateDialog.includes('bizProof:'),
|
|
'个人新增弹窗不应继续保留是否有经营佐证字段'
|
|
)
|
|
```
|
|
|
|
Update personal collateral assertion:
|
|
|
|
```js
|
|
assert(
|
|
personalCreateDialog.includes("return ['一线', '一类', '二类', '三类']") &&
|
|
personalCreateDialog.includes("return ['存单质押', '其他质押']"),
|
|
'个人新增弹窗抵质押类型选项未按新口径动态切换'
|
|
)
|
|
```
|
|
|
|
- [ ] **Step 4: Update corporate collateral assertions**
|
|
|
|
In `corporate-create-input-params.test.js`, replace old collateral assertion with:
|
|
|
|
```js
|
|
assert(
|
|
corporateCreateDialog.includes("return ['一类', '二类', '三类', '四类', '排污权抵押', '设备等其他不动产抵押']") &&
|
|
corporateCreateDialog.includes("return ['存单质押', '股权质押', '其他质押']"),
|
|
'企业新增弹窗抵质押类型选项未按新口径动态切换'
|
|
)
|
|
```
|
|
|
|
- [ ] **Step 5: Run frontend static tests and confirm failure**
|
|
|
|
Run:
|
|
|
|
```bash
|
|
zsh -lic 'nvm use 14.21.3 >/dev/null && npm --prefix ruoyi-ui run test:business-type-history-rate && npm --prefix ruoyi-ui run test:personal-create-input-params && npm --prefix ruoyi-ui run test:corporate-create-input-params'
|
|
```
|
|
|
|
Expected: FAIL because the UI is not updated yet.
|
|
|
|
## Task 2: Update Personal Create Dialog
|
|
|
|
**Files:**
|
|
- Modify: `ruoyi-ui/src/views/loanPricing/workflow/components/PersonalCreateDialog.vue`
|
|
|
|
- [ ] **Step 1: Change business type options**
|
|
|
|
Replace the first option:
|
|
|
|
```vue
|
|
<el-option label="新增" value="新增"/>
|
|
<el-option label="存量新增" value="存量新增"/>
|
|
<el-option label="存量转贷" value="存量转贷"/>
|
|
```
|
|
|
|
- [ ] **Step 2: Remove personal fields from template**
|
|
|
|
Delete the `贷款用途` form item and its surrounding column. Delete the `是否有经营佐证` form item. Keep `借款期限(年)` and `循环功能`.
|
|
|
|
If a row becomes single-column, leave it as a normal `el-row` with one `el-col :span="12"`; do not restructure the whole dialog.
|
|
|
|
- [ ] **Step 3: Remove personal fields from data, rules, and submit payload**
|
|
|
|
Remove these from `form` initial state and `reset()`:
|
|
|
|
```js
|
|
loanPurpose: undefined,
|
|
bizProof: false,
|
|
```
|
|
|
|
Remove `loanPurpose` from `rules`.
|
|
|
|
Remove this submit conversion:
|
|
|
|
```js
|
|
bizProof: this.form.bizProof ? '1' : '0',
|
|
```
|
|
|
|
Keep:
|
|
|
|
```js
|
|
loanLoop: this.form.loanLoop ? '1' : '0'
|
|
```
|
|
|
|
- [ ] **Step 4: Update personal collateral options**
|
|
|
|
Change `collateralTypeOptions()` to:
|
|
|
|
```js
|
|
collateralTypeOptions() {
|
|
if (this.form.guarType === '抵押') {
|
|
return ['一线', '一类', '二类', '三类']
|
|
}
|
|
if (this.form.guarType === '质押') {
|
|
return ['存单质押', '其他质押']
|
|
}
|
|
return []
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 5: Add coupon-rate field**
|
|
|
|
Add under the collateral row:
|
|
|
|
```vue
|
|
<el-col :span="12" v-if="isCertificatePledge">
|
|
<el-form-item label="存单票面利率" prop="couponRate">
|
|
<el-input v-model="form.couponRate" placeholder="请输入存单票面利率"/>
|
|
</el-form-item>
|
|
</el-col>
|
|
```
|
|
|
|
If the row already has two columns, put this field in the same `抵质押信息` area and keep the existing `900px` dialog.
|
|
|
|
- [ ] **Step 6: Add computed condition and validator**
|
|
|
|
Add:
|
|
|
|
```js
|
|
isCertificatePledge() {
|
|
return this.form.guarType === '质押' && this.form.collType === '存单质押'
|
|
}
|
|
```
|
|
|
|
Add a validator in `data()`:
|
|
|
|
```js
|
|
const validateCouponRate = (rule, value, callback) => {
|
|
if (this.isCertificatePledge && !value) {
|
|
callback(new Error('存单票面利率不能为空'))
|
|
return
|
|
}
|
|
callback()
|
|
}
|
|
```
|
|
|
|
Add rule:
|
|
|
|
```js
|
|
couponRate: [
|
|
{validator: validateCouponRate, trigger: "blur"}
|
|
]
|
|
```
|
|
|
|
- [ ] **Step 7: Add coupon-rate state cleanup**
|
|
|
|
Add `couponRate: undefined` to `form` initial state and `reset()`.
|
|
|
|
Add watcher:
|
|
|
|
```js
|
|
'form.collType'() {
|
|
this.resetCouponRateIfNotCertificatePledge()
|
|
}
|
|
```
|
|
|
|
Add method:
|
|
|
|
```js
|
|
resetCouponRateIfNotCertificatePledge() {
|
|
if (!this.isCertificatePledge) {
|
|
this.form.couponRate = undefined
|
|
this.$nextTick(() => {
|
|
if (this.$refs.form) {
|
|
this.$refs.form.clearValidate(['couponRate'])
|
|
}
|
|
})
|
|
}
|
|
}
|
|
```
|
|
|
|
Call it at the end of `resetCollateralFields()`.
|
|
|
|
- [ ] **Step 8: Add submit cleanup and front-end guard**
|
|
|
|
In `submitForm`, before `this.submitting = true`, add:
|
|
|
|
```js
|
|
if (this.isCertificatePledge && !this.form.couponRate) {
|
|
this.$modal.msgWarning("存单票面利率不能为空")
|
|
return
|
|
}
|
|
```
|
|
|
|
After collateral handling:
|
|
|
|
```js
|
|
if (!this.isCertificatePledge) {
|
|
delete data.couponRate
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 9: Run personal static tests**
|
|
|
|
Run:
|
|
|
|
```bash
|
|
zsh -lic 'nvm use 14.21.3 >/dev/null && npm --prefix ruoyi-ui run test:personal-create-input-params'
|
|
```
|
|
|
|
Expected: PASS. The shared `test:business-type-history-rate` is intentionally not run here because it also asserts corporate changes that are implemented in Task 3.
|
|
|
|
- [ ] **Step 10: Commit personal frontend changes**
|
|
|
|
```bash
|
|
git add ruoyi-ui/src/views/loanPricing/workflow/components/PersonalCreateDialog.vue \
|
|
ruoyi-ui/tests/personal-create-input-params.test.js
|
|
git commit -m "调整上虞对私新增字段口径"
|
|
```
|
|
|
|
## Task 3: Update Corporate Create Dialog
|
|
|
|
**Files:**
|
|
- Modify: `ruoyi-ui/src/views/loanPricing/workflow/components/CorporateCreateDialog.vue`
|
|
- Modify: `ruoyi-ui/tests/corporate-create-input-params.test.js`
|
|
- Modify: `ruoyi-ui/tests/business-type-history-rate.test.js`
|
|
|
|
- [ ] **Step 1: Change business type options**
|
|
|
|
Use:
|
|
|
|
```vue
|
|
<el-option label="新增" value="新增"/>
|
|
<el-option label="存量新增" value="存量新增"/>
|
|
<el-option label="存量转贷" value="存量转贷"/>
|
|
```
|
|
|
|
- [ ] **Step 2: Update corporate collateral options**
|
|
|
|
Change `collateralTypeOptions()` to:
|
|
|
|
```js
|
|
collateralTypeOptions() {
|
|
if (this.form.guarType === '抵押') {
|
|
return ['一类', '二类', '三类', '四类', '排污权抵押', '设备等其他不动产抵押']
|
|
}
|
|
if (this.form.guarType === '质押') {
|
|
return ['存单质押', '股权质押', '其他质押']
|
|
}
|
|
return []
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 3: Add coupon-rate field and state**
|
|
|
|
Mirror the personal dialog implementation:
|
|
|
|
```vue
|
|
<el-col :span="12" v-if="isCertificatePledge">
|
|
<el-form-item label="存单票面利率" prop="couponRate">
|
|
<el-input v-model="form.couponRate" placeholder="请输入存单票面利率"/>
|
|
</el-form-item>
|
|
</el-col>
|
|
```
|
|
|
|
Add:
|
|
|
|
```js
|
|
couponRate: undefined
|
|
```
|
|
|
|
to initial `form` and `reset()`.
|
|
|
|
- [ ] **Step 4: Add computed condition, validator, watcher, and submit cleanup**
|
|
|
|
Use the same names as personal dialog:
|
|
|
|
```js
|
|
isCertificatePledge() {
|
|
return this.form.guarType === '质押' && this.form.collType === '存单质押'
|
|
}
|
|
```
|
|
|
|
Use the same `validateCouponRate`, `couponRate` rule, `form.collType` watcher, `resetCouponRateIfNotCertificatePledge`, front-end guard, and:
|
|
|
|
```js
|
|
if (!this.isCertificatePledge) {
|
|
delete data.couponRate
|
|
}
|
|
```
|
|
|
|
- [ ] **Step 5: Run corporate static tests**
|
|
|
|
Run:
|
|
|
|
```bash
|
|
zsh -lic 'nvm use 14.21.3 >/dev/null && npm --prefix ruoyi-ui run test:corporate-create-input-params && npm --prefix ruoyi-ui run test:business-type-history-rate'
|
|
```
|
|
|
|
Expected: PASS.
|
|
|
|
- [ ] **Step 6: Commit corporate frontend changes**
|
|
|
|
```bash
|
|
git add ruoyi-ui/src/views/loanPricing/workflow/components/CorporateCreateDialog.vue \
|
|
ruoyi-ui/tests/corporate-create-input-params.test.js \
|
|
ruoyi-ui/tests/business-type-history-rate.test.js
|
|
git commit -m "调整上虞对公新增字段口径"
|
|
```
|
|
|
|
## Task 4: Frontend Build and Real Page Verification
|
|
|
|
**Files:**
|
|
- Modify: `doc/implementation-report-2026-05-11-shangyu-pricing-field-adjustment.md`
|
|
|
|
- [ ] **Step 1: Run all related static tests**
|
|
|
|
Run:
|
|
|
|
```bash
|
|
zsh -lic 'nvm use 14.21.3 >/dev/null && npm --prefix ruoyi-ui run test:business-type-history-rate && npm --prefix ruoyi-ui run test:personal-create-input-params && npm --prefix ruoyi-ui run test:corporate-create-input-params'
|
|
```
|
|
|
|
Expected: PASS.
|
|
|
|
- [ ] **Step 2: Run production build**
|
|
|
|
Run:
|
|
|
|
```bash
|
|
zsh -lic 'nvm use 14.21.3 >/dev/null && npm --prefix ruoyi-ui run build:prod'
|
|
```
|
|
|
|
Expected: PASS and `ruoyi-ui/dist` generated.
|
|
|
|
- [ ] **Step 3: Start the local app stack**
|
|
|
|
Use the repository's existing startup scripts if available. If a frontend dev server is needed, run it with Node controlled by `nvm`:
|
|
|
|
```bash
|
|
zsh -lic 'nvm use 14.21.3 >/dev/null && npm --prefix ruoyi-ui run dev'
|
|
```
|
|
|
|
Record the PID and URL. If the backend also needs restart, use the existing repository backend restart script rather than inventing a new start path.
|
|
|
|
- [ ] **Step 4: Use Playwright on the real page**
|
|
|
|
Open the actual local workflow page, not a prototype. Verify:
|
|
|
|
- Personal create dialog:
|
|
- `业务种类` shows `新增/存量新增/存量转贷`.
|
|
- `新客` is absent.
|
|
- `贷款用途` is absent.
|
|
- `是否有经营佐证` is absent.
|
|
- `抵押` shows `一线/一类/二类/三类`.
|
|
- `质押 + 存单质押` shows `存单票面利率`.
|
|
- Leaving `存单票面利率` empty blocks submit.
|
|
- Corporate create dialog:
|
|
- `业务种类` shows `新增/存量新增/存量转贷`.
|
|
- `抵押` shows `一类/二类/三类/四类/排污权抵押/设备等其他不动产抵押`.
|
|
- `质押` shows `存单质押/股权质押/其他质押`.
|
|
- `质押 + 存单质押` shows `存单票面利率`.
|
|
- Leaving `存单票面利率` empty blocks submit.
|
|
- History-rate behavior:
|
|
- `存量转贷` triggers historical-contract query.
|
|
- `新增` and `存量新增` do not trigger historical-contract query.
|
|
|
|
- [ ] **Step 5: Stop test processes**
|
|
|
|
Stop any frontend/backend processes started in this task. Verify with:
|
|
|
|
```bash
|
|
ps -ef | rg 'vue-cli-service|ruoyi-admin|RuoYiApplication'
|
|
```
|
|
|
|
Expected: no leftover processes from this test run.
|
|
|
|
- [ ] **Step 6: Update implementation record**
|
|
|
|
Append:
|
|
|
|
```markdown
|
|
## 前端实现
|
|
|
|
- 调整个人/企业新增弹窗业务种类选项为 `新增/存量新增/存量转贷`。
|
|
- 个人新增弹窗剔除 `loanPurpose`、`bizProof`。
|
|
- 按客户类型和担保方式调整抵质押类型选项。
|
|
- 新增 `质押 + 存单质押` 下的 `couponRate` 存单票面利率字段、必填校验和提交清理。
|
|
|
|
## 前端验证
|
|
|
|
- `npm --prefix ruoyi-ui run test:business-type-history-rate`
|
|
- `npm --prefix ruoyi-ui run test:personal-create-input-params`
|
|
- `npm --prefix ruoyi-ui run test:corporate-create-input-params`
|
|
- `npm --prefix ruoyi-ui run build:prod`
|
|
- Playwright 真实页面验证:通过
|
|
```
|
|
|
|
- [ ] **Step 7: Commit frontend verification record**
|
|
|
|
```bash
|
|
git add doc/implementation-report-2026-05-11-shangyu-pricing-field-adjustment.md
|
|
git commit -m "记录上虞字段调整前端验证"
|
|
```
|