修改字段 登陆

This commit is contained in:
wkc
2026-04-03 10:47:16 +08:00
parent 1e9340bbda
commit 62784ee81a
18 changed files with 605 additions and 31 deletions

View File

@@ -5,7 +5,7 @@ set -eu
WEBAPP_ROOT="/home/webapp"
ENV_ROOT="$WEBAPP_ROOT/env"
APP_ROOT="$WEBAPP_ROOT/loan-pricing"
JAVA_HOME="$ENV_ROOT/jdk"
JAVA_HOME="$ENV_ROOT/java"
BACKEND_DIR="$APP_ROOT/backend"
LOG_DIR="$APP_ROOT/logs"
RUN_DIR="$APP_ROOT/run"
@@ -37,13 +37,6 @@ usage() {
EOF
}
require_root() {
if [ "$(id -u)" -ne 0 ]; then
log_error "请使用 root 用户执行脚本"
exit 1
fi
}
ensure_runtime_dirs() {
mkdir -p "$BACKEND_DIR" "$LOG_DIR" "$RUN_DIR"
}
@@ -133,8 +126,10 @@ stop_backend() {
}
start_backend() {
ensure_runtime_dirs
if [ ! -x "$JAVA_HOME/bin/java" ]; then
log_error "未检测到 Java,可先执行 /home/webapp/install_env.sh"
log_error "未检测到可执行 Java: $JAVA_HOME/bin/java"
exit 1
fi
@@ -164,19 +159,7 @@ start_backend() {
exit 1
fi
wait_seconds=0
while [ "$wait_seconds" -lt 30 ]; do
if ss -lnt 2>/dev/null | grep -q ":$BACKEND_PORT "; then
log_info "后端已监听端口: $BACKEND_PORT"
return 0
fi
sleep 1
wait_seconds=$((wait_seconds + 1))
done
log_error "后端未在预期时间内监听端口 $BACKEND_PORT"
exit 1
log_info "后端已启动PID: $backend_pid"
}
status_backend() {
@@ -186,11 +169,6 @@ status_backend() {
return 0
fi
if ss -lnt 2>/dev/null | grep -q ":$BACKEND_PORT "; then
log_info "未识别到脚本托管进程,但端口 $BACKEND_PORT 已被占用"
return 0
fi
log_info "后端未运行"
}

View File

@@ -0,0 +1,114 @@
#!/bin/sh
set -eu
ROOT_DIR=$(CDPATH= cd -- "$(dirname "$0")/../.." && pwd)
SCRIPT_UNDER_TEST="$ROOT_DIR/bin/prod/restart_java.sh"
fail() {
printf 'FAIL: %s\n' "$1" >&2
exit 1
}
assert_grep() {
pattern="$1"
target="$2"
if ! grep -Eq -- "$pattern" "$target"; then
fail "expected pattern [$pattern] in $target"
fi
}
assert_not_grep() {
pattern="$1"
target="$2"
if grep -Eq -- "$pattern" "$target"; then
fail "did not expect pattern [$pattern] in $target"
fi
}
create_fake_java() {
fake_java="$1"
cat > "$fake_java" <<'EOF'
#!/bin/sh
set -eu
while :; do
sleep 1
done
EOF
chmod +x "$fake_java"
}
prepare_script_env() {
work_dir="$1"
mkdir -p "$work_dir/env/java/bin" "$work_dir/loan-pricing/backend" "$work_dir/loan-pricing/logs" "$work_dir/loan-pricing/run"
create_fake_java "$work_dir/env/java/bin/java"
printf 'fake-jar\n' > "$work_dir/loan-pricing/backend/ruoyi-admin.jar"
cp "$SCRIPT_UNDER_TEST" "$work_dir/restart_java.sh"
perl -0pi -e "s#WEBAPP_ROOT=\"/home/webapp\"#WEBAPP_ROOT=\"$work_dir\"#" "$work_dir/restart_java.sh"
chmod +x "$work_dir/restart_java.sh"
}
cleanup_work_dir() {
work_dir="$1"
if [ -f "$work_dir/loan-pricing/run/backend.pid" ]; then
backend_pid=$(cat "$work_dir/loan-pricing/run/backend.pid" 2>/dev/null || true)
if [ -n "${backend_pid:-}" ]; then
kill "$backend_pid" 2>/dev/null || true
wait "$backend_pid" 2>/dev/null || true
fi
fi
rm -rf "$work_dir"
}
test_script_contract() {
assert_grep 'JAVA_HOME="\$ENV_ROOT/java"' "$SCRIPT_UNDER_TEST"
assert_grep '--spring\.profiles\.active=pro' "$SCRIPT_UNDER_TEST"
assert_not_grep 'mvn' "$SCRIPT_UNDER_TEST"
assert_not_grep 'require_root' "$SCRIPT_UNDER_TEST"
assert_not_grep '\b(ss|lsof|netstat)\b' "$SCRIPT_UNDER_TEST"
}
test_restart_flow() {
work_dir=$(mktemp -d)
trap 'cleanup_work_dir "$work_dir"' EXIT INT TERM
prepare_script_env "$work_dir"
"$work_dir/restart_java.sh" start
if [ ! -f "$work_dir/loan-pricing/run/backend.pid" ]; then
fail "expected backend pid file after start"
fi
backend_pid=$(cat "$work_dir/loan-pricing/run/backend.pid")
kill -0 "$backend_pid" 2>/dev/null || fail "expected backend process to be running after start"
status_output=$("$work_dir/restart_java.sh" status 2>&1 || true)
printf '%s\n' "$status_output" | grep -q '后端正在运行' || fail "expected status output to show running"
"$work_dir/restart_java.sh" restart
restarted_pid=$(cat "$work_dir/loan-pricing/run/backend.pid")
kill -0 "$restarted_pid" 2>/dev/null || fail "expected backend process to be running after restart"
"$work_dir/restart_java.sh" stop
if [ -f "$work_dir/loan-pricing/run/backend.pid" ]; then
fail "expected backend pid file to be removed after stop"
fi
trap - EXIT INT TERM
cleanup_work_dir "$work_dir"
}
main() {
[ -f "$SCRIPT_UNDER_TEST" ] || fail "script under test not found: $SCRIPT_UNDER_TEST"
test_script_contract
test_restart_flow
printf 'PASS: restart_java tests\n'
}
main "$@"

View File

@@ -0,0 +1,84 @@
# 个人模型详情缺失展示字段补齐后端实施计划
> **For agentic workers:** REQUIRED: Use superpowers:executing-plans to implement this plan in this repository. Do not use subagents. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 补齐个人模型输出对象与零售模型输出表结构的新增字段,确保个人详情接口可承载并持久化最新展示字段。
**Architecture:** 后端补齐 `ModelRetailOutputFields` 实体字段,并为 `model_retail_output_fields` 表增加 5 个对应列。保持现有控制器、服务与 Mapper 链路不变,让模型返回字段按既有流程直接反序列化、入库并回查。
**Tech Stack:** Java 17、Spring Boot、MyBatis Plus、Maven、JUnit 5
---
### Task 1: 通过测试锁定缺失字段
**Files:**
- Create: `ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/domain/entity/ModelRetailOutputFieldsTest.java`
- [ ] **Step 1: 编写实体字段断言测试**
新增测试,断言 `ModelRetailOutputFields` 包含以下字段:
```java
"loanRateHistory",
"minRateProduct",
"smoothRange",
"finalCalculateRate",
"referenceRate"
```
- [ ] **Step 2: 运行测试并确认先失败**
Run: `mvn -pl ruoyi-loan-pricing -Dtest=ModelRetailOutputFieldsTest test`
Expected: FAIL提示缺少新增字段。
### Task 2: 补齐个人模型输出实体字段
**Files:**
- Modify: `ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/entity/ModelRetailOutputFields.java`
- [ ] **Step 1: 在实体中新增 5 个字段**
新增以下字段:
- `loanRateHistory`
- `minRateProduct`
- `smoothRange`
- `finalCalculateRate`
- `referenceRate`
- [ ] **Step 2: 保持现有命名与注释风格一致**
新增字段使用与现有实体一致的 `private String` 定义和中文注释,不引入额外注解。
- [ ] **Step 3: 重新运行测试确认通过**
Run: `mvn -pl ruoyi-loan-pricing -Dtest=ModelRetailOutputFieldsTest test`
Expected: PASS
### Task 3: 补齐零售模型输出表结构
**Files:**
- Create: `sql/add_model_retail_output_rate_fields_20260403.sql`
- Modify: `sql/model_retail.sql`
- Modify: `sql/loan_pricing_schema_20260328.sql`
- Modify: `sql/loan_pricing_prod_init_20260331.sql`
- [ ] **Step 1: 新增数据库迁移脚本**
在迁移脚本中为 `model_retail_output_fields` 增加以下列:
- `loan_rate_history`
- `min_rate_product`
- `smooth_range`
- `final_calculate_rate`
- `reference_rate`
- [ ] **Step 2: 同步更新建表基线 SQL**
将相同列同步到仓库中的零售模型输出表建表脚本,避免新环境继续缺列。
- [ ] **Step 3: 对开发库执行迁移并验证列存在**
Run: `mysql ... < sql/add_model_retail_output_rate_fields_20260403.sql`
Expected: 迁移执行成功,`SHOW COLUMNS FROM model_retail_output_fields` 可看到新增 5 列

View File

@@ -0,0 +1,113 @@
# 个人模型详情缺失展示字段补齐设计文档
## 1. 背景
个人模型接口返回字段有更新。根据 `doc/上虞对私利率测算_上传字段与展示字段.xlsx``展示指标` sheet当前个人详情页仍缺少部分应展示字段需要补齐页面展示并保证接口链路字段完整。
## 2. 已确认范围
- 仅处理个人客户详情页
- 仅补齐 `展示指标` sheet 中当前缺失的 6 个字段
- 不调整企业客户页面
- 不新增兼容逻辑、兜底逻辑或额外展示区域
- 保持现有页面结构和分组,按最短路径补齐
## 3. 缺失字段
经核对,当前页面缺少以下字段:
- `loanTerm` 借款期限
- `loanRateHistory` 历史利率
- `minRateProduct` 产品最低利率下限
- `smoothRange` 平滑幅度
- `finalCalculateRate` 最终测算利率
- `referenceRate` 参考利率
其中:
- `loanTerm` 属于流程明细字段,来自 `LoanPricingWorkflow`
- 其余 5 个字段属于个人模型输出字段,来自 `ModelRetailOutputFields`
- 其余 5 个字段同时要求 `model_retail_output_fields` 表具备对应列,否则新流程详情无法完整落库展示
## 4. 现状分析
### 4.1 前端现状
个人详情页由两个主要区域组成:
- `PersonalWorkflowDetail.vue` 负责流程详情与左侧关键信息
- `ModelOutputDisplay.vue` 负责个人模型输出分组展示
当前页面已覆盖大部分 `展示指标` 字段,但个人详情页“业务信息”中未展示 `loanTerm`,个人模型输出“测算结果”中也未展示 5 个新增利率相关字段。
### 4.2 后端现状
- `LoanPricingWorkflow` 已包含 `loanTerm`
- `ModelRetailOutputFields` 当前未包含 `loanRateHistory``minRateProduct``smoothRange``finalCalculateRate``referenceRate`
因此前端目前无法从个人模型输出对象中读取这 5 个字段。
同时,开发库 `model_retail_output_fields` 表当前也未包含这 5 个字段列。如果只补代码而不补表结构,新的个人流程在模型结果入库时将无法完整保存这些字段。
## 5. 方案对比
### 方案一:在现有分组内补齐字段
做法:
- 在个人详情页“业务信息”区域补 `loanTerm`
- 在个人模型输出“测算结果”区域补 5 个新增利率字段
- 后端仅补 `ModelRetailOutputFields` 缺失字段定义
优点:
- 改动最小
- 不影响现有页面结构
- 与现有字段分组最贴合
缺点:
- 需要同时修改前后端
### 方案二:单独新增“利率结果扩展”分组
做法:
- 新增一个专门的 Tab 或卡片展示 5 个新增利率字段
优点:
- 新增字段集中展示
缺点:
- 页面改动更大
- 用户认知路径变化
- 不符合本次最短路径要求
## 6. 设计结论
采用方案一。
实现方式如下:
- 后端在 `ModelRetailOutputFields` 中新增 5 个字段定义,保证接口对象具备完整返回结构
- 数据库为 `model_retail_output_fields` 新增 5 个对应列,保证模型输出可正常落库
- 前端在 `PersonalWorkflowDetail.vue` 的“业务信息”中补齐 `loanTerm`
- 前端在 `ModelOutputDisplay.vue` 的个人“测算结果”中补齐 `loanRateHistory``minRateProduct``smoothRange``finalCalculateRate``referenceRate`
## 7. 验证设计
本次按最小可执行验证:
- 后端新增一个实体字段断言测试,先验证缺失字段不存在并失败,再补齐后验证通过
- 前端新增一个源码断言脚本,先验证缺失展示未实现并失败,再补齐后验证通过
- 对开发库执行表结构迁移
- 创建新的个人流程并打开详情页,确认新增字段可在真实页面展示
- 最后执行前端生产构建,确认页面代码可正常打包
## 8. 非目标
- 不调整企业详情页
- 不修改模型计算逻辑
- 不重构页面布局

View File

@@ -0,0 +1,81 @@
# 个人模型详情缺失展示字段补齐前端实施计划
> **For agentic workers:** REQUIRED: Use superpowers:executing-plans to implement this plan in this repository. Do not use subagents. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 在个人详情页补齐 `展示指标` sheet 中缺失的 6 个字段展示。
**Architecture:** 前端沿用现有个人详情页结构,在流程详情的“业务信息”中补 `loanTerm`,在模型输出“测算结果”中补 5 个新增利率字段,不新增页面分组和交互。
**Tech Stack:** Vue 2、Element UI、Node.js
---
### Task 1: 通过前端断言测试锁定缺失展示
**Files:**
- Create: `ruoyi-ui/tests/retail-display-fields.test.js`
- Modify: `ruoyi-ui/package.json`
- [ ] **Step 1: 编写源码断言脚本**
断言以下展示已存在:
- `PersonalWorkflowDetail.vue` 包含 `借款期限``detailData.loanTerm`
- `ModelOutputDisplay.vue` 包含以下字段展示:
- `loanRateHistory`
- `minRateProduct`
- `smoothRange`
- `finalCalculateRate`
- `referenceRate`
- [ ] **Step 2: 运行脚本并确认先失败**
Run: `npm --prefix ruoyi-ui run test:retail-display-fields`
Expected: FAIL提示缺失展示实现。
### Task 2: 补齐个人详情页字段展示
**Files:**
- Modify: `ruoyi-ui/src/views/loanPricing/workflow/components/PersonalWorkflowDetail.vue`
- Modify: `ruoyi-ui/src/views/loanPricing/workflow/components/ModelOutputDisplay.vue`
- Reference: `ruoyi-loan-pricing/src/main/resources/data/retail_output.json`
- [ ] **Step 1: 在业务信息中补齐借款期限**
`PersonalWorkflowDetail.vue` 的“业务信息”区域新增:
```vue
<el-descriptions-item label="借款期限">{{ detailData.loanTerm || '-' }}</el-descriptions-item>
```
- [ ] **Step 2: 在个人测算结果中补齐 5 个字段**
`ModelOutputDisplay.vue` 的个人“测算结果”中新增:
- 历史利率
- 产品最低利率下限
- 平滑幅度
- 最终测算利率
- 参考利率
- [ ] **Step 3: 重新运行前端断言脚本**
Run: `npm --prefix ruoyi-ui run test:retail-display-fields`
Expected: PASS
- [ ] **Step 4: 执行前端构建验证**
Run: `npm --prefix ruoyi-ui run build:prod`
Expected: 构建成功,输出包含 `Build complete.`
- [ ] **Step 5: 启动前后端并打开个人流程详情页验证**
使用浏览器打开新的个人流程详情页,确认:
- 流程详情“业务信息”出现 `借款期限`
- 模型输出“测算结果”出现并可查看以下字段
- 历史利率
- 产品最低利率下限
- 平滑幅度
- 最终测算利率
- 参考利率

View File

@@ -0,0 +1,24 @@
# 生产后端重启脚本实施记录
## 修改内容
- 收敛生产后端重启脚本 `bin/prod/restart_java.sh`
- 脚本固定面向已部署的 `backend/ruoyi-admin.jar` 执行启停,不再包含构建逻辑
- 后端启动 profile 固定为 `pro`
- Java 路径统一为 `/home/webapp/env/java/bin/java`,与现有生产安装脚本保持一致
- 移除 `root` 执行校验与端口监听校验,只保留 `start|stop|restart|status` 所需的最小启停逻辑
- 新增脚本自测文件 `bin/prod/restart_java_test.sh`
## 实现说明
- `start` 仅检查 Java 可执行文件、目标 jar 是否存在以及当前是否已有同脚本托管进程
- `stop` 继续基于 PID 文件和 `-Dloan.pricing.home=/home/webapp/loan-pricing` 进程标记识别并停止当前后端进程
- `restart` 按“先停后起”执行,适用于生产环境已部署 jar 的直接重启
- `status` 仅返回脚本托管进程状态,不再增加端口占用类附加判断
## 验证结果
- 已执行 `sh bin/prod/restart_java_test.sh`
- 已验证以下场景:
- 脚本固定使用 `/home/webapp/env/java`
- 脚本固定使用 `--spring.profiles.active=pro`
- 脚本不包含 `mvn``require_root``ss/lsof/netstat` 相关依赖
- `start -> status -> restart -> stop` 流程执行通过
- 自测使用临时目录中的假 `java` 进程完成,测试结束后已自动清理对应进程和临时目录

View File

@@ -0,0 +1,72 @@
# 个人模型详情缺失展示字段补齐实施记录
## 实施时间
- 2026-04-03
## 修改内容
- 补齐个人详情页“业务信息”中的 `借款期限`
- 补齐个人模型输出“测算结果”中的 5 个字段:
- `历史利率`
- `产品最低利率下限`
- `平滑幅度`
- `最终测算利率`
- `参考利率`
- 在后端 `ModelRetailOutputFields` 中新增对应 5 个字段定义
- 在零售模型 mock 数据中补齐对应 5 个字段样例值
- 新增零售模型输出表结构迁移脚本,并同步更新建表基线 SQL
- 新增后端字段断言测试与前端源码断言脚本
## 修改文件
- `ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/entity/ModelRetailOutputFields.java`
- `ruoyi-loan-pricing/src/main/resources/data/retail_output.json`
- `ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/domain/entity/ModelRetailOutputFieldsTest.java`
- `ruoyi-ui/src/views/loanPricing/workflow/components/PersonalWorkflowDetail.vue`
- `ruoyi-ui/src/views/loanPricing/workflow/components/ModelOutputDisplay.vue`
- `ruoyi-ui/tests/retail-display-fields.test.js`
- `ruoyi-ui/package.json`
- `sql/add_model_retail_output_rate_fields_20260403.sql`
- `sql/model_retail.sql`
- `sql/loan_pricing_schema_20260328.sql`
- `sql/loan_pricing_prod_init_20260331.sql`
- `doc/2026-04-03-retail-display-fields-design.md`
- `doc/2026-04-03-retail-display-fields-backend-plan.md`
- `doc/2026-04-03-retail-display-fields-frontend-plan.md`
- `doc/implementation-report-2026-04-03-retail-display-fields.md`
## 验证方式
1. 新增后端测试,断言 `ModelRetailOutputFields` 包含 5 个新增字段,先失败后通过
2. 新增前端源码断言脚本,断言个人详情页与模型输出页已补齐字段,先失败后通过
3. 执行前端生产构建,确认页面代码可正常打包
4. 检查开发库 `model_retail_output_fields` 表结构,确认最初缺少 5 个新列
5. 执行 `sql/add_model_retail_output_rate_fields_20260403.sql` 到开发库,并再次确认 5 个新列存在
6. 重新编译并重启后端,确保新的实体字段已进入运行中的 SQL 映射
7. 创建新的个人流程 `20260403100514909`,调用详情接口确认返回以下真实值:
- `loanRateHistory = 6.40`
- `minRateProduct = 5.50`
- `smoothRange = -0.10`
- `finalCalculateRate = 6.05`
- `referenceRate = 5.95`
8. 启动前端开发服务并使用浏览器自动化打开详情页,确认:
- 页面出现 `借款期限`
- 切换到“测算结果”页签后5 个新增字段及对应值均可见
9. 验证结束后,停止本次启动的前后端进程
## 验证结果
- `mvn -pl ruoyi-loan-pricing -Dtest=ModelRetailOutputFieldsTest test` 首次失败,补齐后通过
- `npm --prefix ruoyi-ui run test:retail-display-fields` 首次失败,补齐后通过
- `npm --prefix ruoyi-ui run build:prod` 成功,输出包含 `Build complete.`
- 已确认开发库 `model_retail_output_fields` 初始缺少:
- `loan_rate_history`
- `min_rate_product`
- `smooth_range`
- `final_calculate_rate`
- `reference_rate`
- 已执行迁移脚本并确认以上 5 列存在
- 已确认旧后端进程因未加载最新依赖导致 SQL 仍缺新列,重编译并重启后问题消失
- 已创建个人流程 `20260403100514909` 并通过详情接口拿到 5 个新增字段的真实值
- 已通过浏览器自动化确认个人详情页展示位与“测算结果”页签展示均正确
- 本次验证期间启动的前后端进程均已停止
## 说明
- `loanTerm` 本次仅补齐详情页展示位;个人创建表单当前无该字段录入入口,不属于本次“模型返回字段更新”范围
- 为保证新字段在新环境中也可正常落库,本次同步更新了零售模型输出表的建表基线 SQL

View File

@@ -170,6 +170,21 @@ public class ModelRetailOutputFields {
// 测算利率
private String calculateRate;
// 历史利率
private String loanRateHistory;
// 产品最低利率下限
private String minRateProduct;
// 平滑幅度
private String smoothRange;
// 最终测算利率
private String finalCalculateRate;
// 参考利率
private String referenceRate;
@TableField(fill = FieldFill.INSERT)
private Date createTime;
}

View File

@@ -52,7 +52,12 @@
"bpGreyOverdue": "98",
"totoalBpRisk": "95",
"totalBp": "350",
"calculateRate": "6.15"
"calculateRate": "6.15",
"loanRateHistory": "6.40",
"minRateProduct": "5.50",
"smoothRange": "-0.10",
"finalCalculateRate": "6.05",
"referenceRate": "5.95"
},
"extensionMap": {},
"reasonMessage": "Running successfully",
@@ -65,4 +70,4 @@
"workflowVersion": 14,
"callTime": 1736405548630,
"status": 1
}
}

View File

@@ -0,0 +1,26 @@
package com.ruoyi.loanpricing.domain.entity;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;
import org.junit.jupiter.api.Test;
class ModelRetailOutputFieldsTest
{
@Test
void shouldContainLatestRetailDisplayRateFields()
{
Set<String> fieldNames = Arrays.stream(ModelRetailOutputFields.class.getDeclaredFields())
.map(Field::getName)
.collect(Collectors.toSet());
assertTrue(fieldNames.contains("loanRateHistory"), "缺少字段 loanRateHistory");
assertTrue(fieldNames.contains("minRateProduct"), "缺少字段 minRateProduct");
assertTrue(fieldNames.contains("smoothRange"), "缺少字段 smoothRange");
assertTrue(fieldNames.contains("finalCalculateRate"), "缺少字段 finalCalculateRate");
assertTrue(fieldNames.contains("referenceRate"), "缺少字段 referenceRate");
}
}

View File

@@ -9,7 +9,8 @@
"build:prod": "vue-cli-service build",
"build:stage": "vue-cli-service build --mode staging",
"preview": "node build/index.js --preview",
"test:password-transfer": "node tests/password-transfer-api.test.js"
"test:password-transfer": "node tests/password-transfer-api.test.js",
"test:retail-display-fields": "node tests/retail-display-fields.test.js"
},
"keywords": [
"vue",

View File

@@ -93,6 +93,11 @@
<el-descriptions :column="2" border size="small">
<el-descriptions-item label="浮动BP"><span class="total-bp-value">{{ retailOutput.totalBp || '-' }}</span></el-descriptions-item>
<el-descriptions-item label="测算利率"><span class="calculate-rate">{{ retailOutput.calculateRate || '-' }}</span> %</el-descriptions-item>
<el-descriptions-item label="历史利率">{{ retailOutput.loanRateHistory || '-' }}</el-descriptions-item>
<el-descriptions-item label="产品最低利率下限">{{ retailOutput.minRateProduct || '-' }}</el-descriptions-item>
<el-descriptions-item label="平滑幅度">{{ retailOutput.smoothRange || '-' }}</el-descriptions-item>
<el-descriptions-item label="最终测算利率"><span class="calculate-rate">{{ retailOutput.finalCalculateRate || '-' }}</span> %</el-descriptions-item>
<el-descriptions-item label="参考利率"><span class="calculate-rate">{{ retailOutput.referenceRate || '-' }}</span> %</el-descriptions-item>
</el-descriptions>
</el-tab-pane>
</template>

View File

@@ -72,6 +72,7 @@
<el-descriptions :column="2" border>
<el-descriptions-item label="担保方式">{{ detailData.guarType }}</el-descriptions-item>
<el-descriptions-item label="申请金额">{{ detailData.applyAmt }} </el-descriptions-item>
<el-descriptions-item label="借款期限">{{ detailData.loanTerm || '-' }}</el-descriptions-item>
<el-descriptions-item label="是否有经营佐证">{{
formatBoolean(detailData.bizProof)
}}

View File

@@ -0,0 +1,29 @@
const fs = require('fs')
const path = require('path')
const assert = require('assert')
function read(relativePath) {
return fs.readFileSync(path.join(__dirname, '..', relativePath), 'utf8')
}
const personalDetail = read('src/views/loanPricing/workflow/components/PersonalWorkflowDetail.vue')
const modelOutput = read('src/views/loanPricing/workflow/components/ModelOutputDisplay.vue')
assert(
personalDetail.includes('label="借款期限"') && personalDetail.includes('detailData.loanTerm'),
'个人详情页缺少借款期限展示'
)
const requiredRetailFields = [
'retailOutput.loanRateHistory',
'retailOutput.minRateProduct',
'retailOutput.smoothRange',
'retailOutput.finalCalculateRate',
'retailOutput.referenceRate'
]
requiredRetailFields.forEach((field) => {
assert(modelOutput.includes(field), `模型输出缺少字段展示: ${field}`)
})
console.log('retail display fields assertions passed')

View File

@@ -0,0 +1,6 @@
ALTER TABLE `model_retail_output_fields`
ADD COLUMN `loan_rate_history` varchar(100) DEFAULT '' COMMENT '历史利率' AFTER `calculate_rate`,
ADD COLUMN `min_rate_product` varchar(100) DEFAULT '' COMMENT '产品最低利率下限' AFTER `loan_rate_history`,
ADD COLUMN `smooth_range` varchar(100) DEFAULT '' COMMENT '平滑幅度' AFTER `min_rate_product`,
ADD COLUMN `final_calculate_rate` varchar(100) DEFAULT '' COMMENT '最终测算利率' AFTER `smooth_range`,
ADD COLUMN `reference_rate` varchar(100) DEFAULT '' COMMENT '参考利率' AFTER `final_calculate_rate`;

View File

@@ -908,6 +908,11 @@ CREATE TABLE `model_retail_output_fields` (
`totoal_bp_risk` varchar(100) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'TOTAL_BP_风险度',
`total_bp` varchar(100) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '浮动BP',
`calculate_rate` varchar(100) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '测算利率',
`loan_rate_history` varchar(100) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '历史利率',
`min_rate_product` varchar(100) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '产品最低利率下限',
`smooth_range` varchar(100) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '平滑幅度',
`final_calculate_rate` varchar(100) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '最终测算利率',
`reference_rate` varchar(100) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '参考利率',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='零售模型输出字段表';

View File

@@ -490,6 +490,11 @@ CREATE TABLE `model_retail_output_fields` (
`totoal_bp_risk` varchar(100) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'TOTAL_BP_风险度',
`total_bp` varchar(100) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '浮动BP',
`calculate_rate` varchar(100) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '测算利率',
`loan_rate_history` varchar(100) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '历史利率',
`min_rate_product` varchar(100) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '产品最低利率下限',
`smooth_range` varchar(100) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '平滑幅度',
`final_calculate_rate` varchar(100) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '最终测算利率',
`reference_rate` varchar(100) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '参考利率',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='零售模型输出字段表';

View File

@@ -106,9 +106,19 @@ CREATE TABLE IF NOT EXISTS model_retail_output_fields (
total_bp VARCHAR(100) DEFAULT '' COMMENT '浮动BP',
-- 测算利率百分比如6.15
calculate_rate VARCHAR(100) DEFAULT '' COMMENT '测算利率',
-- 历史利率
loan_rate_history VARCHAR(100) DEFAULT '' COMMENT '历史利率',
-- 产品最低利率下限
min_rate_product VARCHAR(100) DEFAULT '' COMMENT '产品最低利率下限',
-- 平滑幅度
smooth_range VARCHAR(100) DEFAULT '' COMMENT '平滑幅度',
-- 最终测算利率
final_calculate_rate VARCHAR(100) DEFAULT '' COMMENT '最终测算利率',
-- 参考利率
reference_rate VARCHAR(100) DEFAULT '' COMMENT '参考利率',
-- 创建时间(审计字段)
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-- 主键约束
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='零售模型输出字段表';
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='零售模型输出字段表';