统一个人测算入参与重启脚本进程识别
This commit is contained in:
6
.playwright-cli/page-2026-04-09T09-31-22-009Z.yml
Normal file
6
.playwright-cli/page-2026-04-09T09-31-22-009Z.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
- generic [ref=e2]:
|
||||
- heading "Example Domain" [level=1] [ref=e3]
|
||||
- paragraph [ref=e4]: This domain is for use in documentation examples without needing permission. Avoid use in operations.
|
||||
- paragraph [ref=e5]:
|
||||
- link "Learn more" [ref=e6] [cursor=pointer]:
|
||||
- /url: https://iana.org/domains/example
|
||||
6
.playwright-cli/page-2026-04-09T09-39-00-226Z.yml
Normal file
6
.playwright-cli/page-2026-04-09T09-39-00-226Z.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
- generic [ref=e2]:
|
||||
- heading "Example Domain" [level=1] [ref=e3]
|
||||
- paragraph [ref=e4]: This domain is for use in documentation examples without needing permission. Avoid use in operations.
|
||||
- paragraph [ref=e5]:
|
||||
- link "Learn more" [ref=e6] [cursor=pointer]:
|
||||
- /url: https://iana.org/domains/example
|
||||
18
.playwright-cli/page-2026-04-10T06-51-19-033Z.yml
Normal file
18
.playwright-cli/page-2026-04-10T06-51-19-033Z.yml
Normal file
@@ -0,0 +1,18 @@
|
||||
- generic [ref=e2]:
|
||||
- generic [ref=e3]:
|
||||
- generic [ref=e4]:
|
||||
- heading "上虞利率定价系统" [level=3] [ref=e5]
|
||||
- generic [ref=e8]:
|
||||
- textbox "账号" [ref=e9]
|
||||
- img [ref=e11]
|
||||
- generic [ref=e15]:
|
||||
- textbox "密码" [ref=e16]
|
||||
- img [ref=e18]
|
||||
- generic [ref=e20] [cursor=pointer]:
|
||||
- generic [ref=e21]:
|
||||
- checkbox "记住密码"
|
||||
- generic [ref=e23]: 记住密码
|
||||
- button "登 录" [ref=e26] [cursor=pointer]:
|
||||
- generic [ref=e27]: 登 录
|
||||
- generic [ref=e28]: Copyright © 2018-2026 RuoYi. All Rights Reserved.
|
||||
- text:
|
||||
22
.playwright-cli/page-2026-04-10T06-52-06-995Z.yml
Normal file
22
.playwright-cli/page-2026-04-10T06-52-06-995Z.yml
Normal file
@@ -0,0 +1,22 @@
|
||||
- generic [active] [ref=e1]:
|
||||
- generic [ref=e2]:
|
||||
- generic [ref=e3]:
|
||||
- generic [ref=e4]:
|
||||
- heading "上虞利率定价系统" [level=3] [ref=e5]
|
||||
- generic [ref=e8]:
|
||||
- textbox "账号" [ref=e9]: admin
|
||||
- img [ref=e11]
|
||||
- generic [ref=e15]:
|
||||
- textbox "密码" [ref=e16]: "123456"
|
||||
- img [ref=e18]
|
||||
- generic [ref=e20] [cursor=pointer]:
|
||||
- generic [ref=e21]:
|
||||
- checkbox "记住密码"
|
||||
- generic [ref=e23]: 记住密码
|
||||
- button "登 录" [ref=e26] [cursor=pointer]:
|
||||
- generic [ref=e27]: 登 录
|
||||
- generic [ref=e28]: Copyright © 2018-2026 RuoYi. All Rights Reserved.
|
||||
- text:
|
||||
- alert [ref=e29]:
|
||||
- generic [ref=e30]:
|
||||
- paragraph [ref=e31]: 用户不存在/密码错误
|
||||
18
.playwright-cli/page-2026-04-10T06-54-38-568Z.yml
Normal file
18
.playwright-cli/page-2026-04-10T06-54-38-568Z.yml
Normal file
@@ -0,0 +1,18 @@
|
||||
- generic [ref=e2]:
|
||||
- generic [ref=e3]:
|
||||
- generic [ref=e4]:
|
||||
- heading "上虞利率定价系统" [level=3] [ref=e5]
|
||||
- generic [ref=e8]:
|
||||
- textbox "账号" [ref=e9]
|
||||
- img [ref=e11]
|
||||
- generic [ref=e15]:
|
||||
- textbox "密码" [ref=e16]
|
||||
- img [ref=e18]
|
||||
- generic [ref=e20] [cursor=pointer]:
|
||||
- generic [ref=e21]:
|
||||
- checkbox "记住密码"
|
||||
- generic [ref=e23]: 记住密码
|
||||
- button "登 录" [ref=e26] [cursor=pointer]:
|
||||
- generic [ref=e27]: 登 录
|
||||
- generic [ref=e28]: Copyright © 2018-2026 RuoYi. All Rights Reserved.
|
||||
- text:
|
||||
18
.playwright-cli/page-2026-04-10T06-55-43-705Z.yml
Normal file
18
.playwright-cli/page-2026-04-10T06-55-43-705Z.yml
Normal file
@@ -0,0 +1,18 @@
|
||||
- generic [ref=e2]:
|
||||
- generic [ref=e3]:
|
||||
- generic [ref=e4]:
|
||||
- heading "上虞利率定价系统" [level=3] [ref=e5]
|
||||
- generic [ref=e8]:
|
||||
- textbox "账号" [ref=e9]
|
||||
- img [ref=e11]
|
||||
- generic [ref=e15]:
|
||||
- textbox "密码" [ref=e16]
|
||||
- img [ref=e18]
|
||||
- generic [ref=e20] [cursor=pointer]:
|
||||
- generic [ref=e21]:
|
||||
- checkbox "记住密码"
|
||||
- generic [ref=e23]: 记住密码
|
||||
- button "登 录" [ref=e26] [cursor=pointer]:
|
||||
- generic [ref=e27]: 登 录
|
||||
- generic [ref=e28]: Copyright © 2018-2026 RuoYi. All Rights Reserved.
|
||||
- text:
|
||||
BIN
bin/.DS_Store
vendored
BIN
bin/.DS_Store
vendored
Binary file not shown.
@@ -71,7 +71,16 @@ collect_backend_pids() {
|
||||
fi
|
||||
fi
|
||||
|
||||
marker_pids=$(pgrep -f "$BACKEND_MARKER" 2>/dev/null || true)
|
||||
marker_pids=$(ps -ef | awk -v marker="$BACKEND_MARKER" -v jar="$BACKEND_JAR" '
|
||||
index($0, "<defunct>") == 0 && index($0, marker) > 0 {
|
||||
for (i = 1; i < NF; i++) {
|
||||
if ($i == "-jar" && $(i + 1) == jar) {
|
||||
print $2
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
' | xargs 2>/dev/null || true)
|
||||
if [ -n "${marker_pids:-}" ]; then
|
||||
for pid in $marker_pids; do
|
||||
if is_managed_backend_pid "$pid"; then
|
||||
|
||||
@@ -44,8 +44,8 @@ EOF
|
||||
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"
|
||||
mkdir -p "$work_dir/env/jdk/bin" "$work_dir/loan-pricing/backend" "$work_dir/loan-pricing/logs" "$work_dir/loan-pricing/run"
|
||||
create_fake_java "$work_dir/env/jdk/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"
|
||||
@@ -67,8 +67,10 @@ cleanup_work_dir() {
|
||||
}
|
||||
|
||||
test_script_contract() {
|
||||
assert_grep 'JAVA_HOME="\$ENV_ROOT/java"' "$SCRIPT_UNDER_TEST"
|
||||
assert_grep 'JAVA_HOME="\$ENV_ROOT/jdk"' "$SCRIPT_UNDER_TEST"
|
||||
assert_grep '--spring\.profiles\.active=pro' "$SCRIPT_UNDER_TEST"
|
||||
assert_grep 'ps -ef' "$SCRIPT_UNDER_TEST"
|
||||
assert_not_grep 'pgrep' "$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"
|
||||
|
||||
@@ -83,7 +83,16 @@ collect_pids() {
|
||||
fi
|
||||
fi
|
||||
|
||||
marker_pids=$(pgrep -f "$APP_MARKER" 2>/dev/null || true)
|
||||
marker_pids=$(ps -ef | awk -v marker="$APP_MARKER" -v jar="$JAR_NAME" '
|
||||
index($0, "<defunct>") == 0 && index($0, marker) > 0 {
|
||||
for (i = 1; i < NF; i++) {
|
||||
if ($i == "-jar" && $(i + 1) == jar) {
|
||||
print $2
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
' | xargs 2>/dev/null || true)
|
||||
if [ -n "${marker_pids:-}" ]; then
|
||||
for pid in $marker_pids; do
|
||||
if is_managed_backend_pid "$pid"; then
|
||||
@@ -225,7 +234,6 @@ restart_action() {
|
||||
main() {
|
||||
ensure_command mvn
|
||||
ensure_command lsof
|
||||
ensure_command pgrep
|
||||
ensure_command ps
|
||||
ensure_command tail
|
||||
|
||||
|
||||
42
bin/restart_java_backend_test.sh
Normal file
42
bin/restart_java_backend_test.sh
Normal file
@@ -0,0 +1,42 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
ROOT_DIR=$(CDPATH= cd -- "$(dirname "$0")/.." && pwd)
|
||||
SCRIPT_UNDER_TEST="$ROOT_DIR/bin/restart_java_backend.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
|
||||
}
|
||||
|
||||
test_script_contract() {
|
||||
assert_grep 'ps -ef' "$SCRIPT_UNDER_TEST"
|
||||
assert_not_grep 'pgrep' "$SCRIPT_UNDER_TEST"
|
||||
assert_grep 'APP_MARKER=' "$SCRIPT_UNDER_TEST"
|
||||
assert_grep 'status_backend\(\)' "$SCRIPT_UNDER_TEST"
|
||||
}
|
||||
|
||||
main() {
|
||||
[ -f "$SCRIPT_UNDER_TEST" ] || fail "script under test not found: $SCRIPT_UNDER_TEST"
|
||||
test_script_contract
|
||||
printf 'PASS: restart_java_backend tests\n'
|
||||
}
|
||||
|
||||
main "$@"
|
||||
@@ -181,7 +181,7 @@
|
||||
- 下拉选项:`consumer`、`business`
|
||||
- `loanTerm`
|
||||
- 固定年限下拉
|
||||
- 选项按 Excel 的 `1/2/3/4/5/6……` 组织
|
||||
- 选项固定为 `1/2/3/4/5/6`
|
||||
|
||||
同时修正:
|
||||
|
||||
@@ -307,12 +307,12 @@
|
||||
- 提交流程后详情页能回显 `loanPurpose`、`loanTerm`
|
||||
- 验证完成后停止本次启动的前后端进程
|
||||
|
||||
## 9. 待确认项
|
||||
## 9. 已确认项
|
||||
|
||||
- 当前代码中的 `orgCode` 默认值为 `892000`
|
||||
- `ModelInvokeDTO` 注释中写的是固定值 `931000`
|
||||
|
||||
本次设计不擅自调整该默认值,保持现有运行逻辑,待业务另行确认后再处理。
|
||||
- `orgCode` 统一为 `892000`
|
||||
- `ModelInvokeDTO` 注释已统一为 `892000`
|
||||
- 数据库 `loan_pricing_workflow.org_code` 默认值已统一为 `892000`
|
||||
- 存量 `loan_pricing_workflow.org_code` 数据已通过迁移脚本统一为 `892000`
|
||||
|
||||
## 10. 非目标
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ git commit -m "新增个人测算输入参数前端断言"
|
||||
```vue
|
||||
<el-form-item label="借款期限(年)" prop="loanTerm">
|
||||
<el-select v-model="form.loanTerm" placeholder="请选择借款期限" style="width: 100%">
|
||||
<el-option v-for="item in loanTermOptions" :key="item" :label="item" :value="item" />
|
||||
<el-option v-for="item in ['1', '2', '3', '4', '5', '6']" :key="item" :label="item" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
```
|
||||
|
||||
@@ -32,10 +32,12 @@
|
||||
| idNum | String | 否 | 证件号码 |
|
||||
| guarType | String | 是 | 担保方式,可选值: 信用/保证/抵押/质押 |
|
||||
| applyAmt | String | 是 | 申请金额,单位: 元 |
|
||||
| bizProof | String | 否 | 是否有经营佐证,值: true/false |
|
||||
| loanLoop | String | 否 | 循环功能,值: true/false |
|
||||
| collType | String | 否 | 抵质押类型,可选值: 一线/一类/二类 |
|
||||
| collThirdParty | String | 否 | 抵质押物是否三方所有,值: true/false |
|
||||
| loanPurpose | String | 是 | 贷款用途,可选值: consumer/business |
|
||||
| loanTerm | String | 是 | 借款期限(年),固定下拉选项按模型文档配置 |
|
||||
| bizProof | String | 否 | 是否有经营佐证,值: 0/1 |
|
||||
| loanLoop | String | 否 | 循环功能,值: 0/1 |
|
||||
| collType | String | 否 | 抵质押类型,可选值: 一类/二类/三类 |
|
||||
| collThirdParty | String | 否 | 抵质押物是否三方所有,值: 0/1 |
|
||||
|
||||
**请求示例:**
|
||||
|
||||
@@ -47,10 +49,12 @@
|
||||
"idNum": "110101199001011234",
|
||||
"guarType": "抵押",
|
||||
"applyAmt": "500000",
|
||||
"bizProof": "true",
|
||||
"loanLoop": "false",
|
||||
"loanPurpose": "business",
|
||||
"loanTerm": "3",
|
||||
"bizProof": "1",
|
||||
"loanLoop": "0",
|
||||
"collType": "一类",
|
||||
"collThirdParty": "false"
|
||||
"collThirdParty": "0"
|
||||
}
|
||||
```
|
||||
|
||||
@@ -64,12 +68,14 @@
|
||||
"id": 1,
|
||||
"modelOutputId": 100,
|
||||
"serialNum": "20250119143025123",
|
||||
"orgCode": "931000",
|
||||
"orgCode": "892000",
|
||||
"runType": "1",
|
||||
"custIsn": "CUST001",
|
||||
"custType": "个人",
|
||||
"guarType": "抵押",
|
||||
"applyAmt": "500000",
|
||||
"loanPurpose": "business",
|
||||
"loanTerm": "3",
|
||||
"custName": "张三",
|
||||
"idType": "身份证",
|
||||
"createTime": "2025-01-19 14:30:25",
|
||||
@@ -136,7 +142,7 @@
|
||||
"id": 2,
|
||||
"modelOutputId": 101,
|
||||
"serialNum": "20250119143125456",
|
||||
"orgCode": "931000",
|
||||
"orgCode": "892000",
|
||||
"runType": "1",
|
||||
"custIsn": "CORP001",
|
||||
"custType": "企业",
|
||||
@@ -189,7 +195,7 @@ GET /loanPricing/workflow/list?pageNum=1&pageSize=10&custName=科技
|
||||
"id": 1,
|
||||
"modelOutputId": 100,
|
||||
"serialNum": "20250119143025123",
|
||||
"orgCode": "931000",
|
||||
"orgCode": "892000",
|
||||
"custIsn": "CUST001",
|
||||
"custType": "企业",
|
||||
"guarType": "抵押",
|
||||
@@ -240,7 +246,7 @@ GET /loanPricing/workflow/20250119143025123
|
||||
"id": 1,
|
||||
"modelOutputId": 100,
|
||||
"serialNum": "20250119143025123",
|
||||
"orgCode": "931000",
|
||||
"orgCode": "892000",
|
||||
"runType": "1",
|
||||
"custIsn": "CUST001",
|
||||
"custType": "企业",
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
# 2026-04-09 默认切换 Node 25 以支持 Playwright 实施记录
|
||||
|
||||
## 变更内容
|
||||
- 将 `nvm` 默认别名从 `14` 调整为 `25`
|
||||
- 清理了本次验证过程中残留的 Playwright 浏览器安装进程
|
||||
|
||||
## 执行命令
|
||||
- `zsh -lic 'nvm alias default 25'`
|
||||
|
||||
## 变更结果
|
||||
- 新开的交互式 `zsh` 默认 Node 版本变为 `v25.9.0`
|
||||
- 默认 npm/npx 版本变为 `11.12.1`
|
||||
|
||||
## 验证结果
|
||||
- `zsh -lic 'node -v && npm -v && npx -v && nvm current && nvm alias default'`
|
||||
- `node v25.9.0`
|
||||
- `npm 11.12.1`
|
||||
- `npx 11.12.1`
|
||||
- `nvm current = v25.9.0`
|
||||
- `default -> 25 (-> v25.9.0 *)`
|
||||
- `zsh -lic '... playwright_cli.sh --help'`
|
||||
- Playwright CLI 帮助输出正常
|
||||
- `zsh -lic '... playwright_cli.sh --session verify-default-25 open https://example.com && snapshot && close && list'`
|
||||
- 页面成功打开
|
||||
- 页面标题为 `Example Domain`
|
||||
- 快照成功输出
|
||||
- 浏览器关闭后 `list` 返回 `(no browsers)`
|
||||
|
||||
## 结论
|
||||
- 默认 shell 环境下已可直接使用 Playwright,无需再先手动执行 `nvm use 25`
|
||||
@@ -0,0 +1,30 @@
|
||||
# 2026-04-09 安装 Node 25 与 Node 14 实施记录
|
||||
|
||||
## 变更内容
|
||||
- 使用 `nvm` 安装 `node v25.9.0`
|
||||
- 使用 `nvm` 安装 `node v14.21.3`
|
||||
- 调整 `/Users/wkc/.npmrc`,删除与 `nvm` 冲突的 `prefix=~/.npm-global`
|
||||
- 保留 npm 镜像配置:`registry=https://registry.npmmirror.com`
|
||||
|
||||
## 处理过程
|
||||
- `node 25` 通过 `nvm` 正常安装成功
|
||||
- `node 14` 在 Apple Silicon 原生环境下无法直接下载 `darwin-arm64` 安装包
|
||||
- 原生源码编译 `node 14` 失败,错误来自当前 macOS Command Line Tools/SDK 与旧版 `node 14` 源码不兼容
|
||||
- 改为通过 Rosetta 以 `x64` 方式安装 `node 14`,安装成功
|
||||
|
||||
## 验证结果
|
||||
- `zsh -lic 'nvm use 25 && node -v && npm -v'` 验证结果:
|
||||
- `node v25.9.0`
|
||||
- `npm 11.12.1`
|
||||
- `zsh -lic 'nvm use 14 && node -v && npm -v'` 验证结果:
|
||||
- `node v14.21.3`
|
||||
- `npm 6.14.18`
|
||||
- `arch -x86_64 /bin/zsh -lic 'nvm use 14 && node -v && npm -v'` 验证结果:
|
||||
- `node v14.21.3`
|
||||
- `npm 6.14.18`
|
||||
- 新开的交互式 `zsh` 默认版本:
|
||||
- `node v14.21.3`
|
||||
- `npm 6.14.18`
|
||||
|
||||
## 备注
|
||||
- `nvm` 当前默认别名已指向 `14`
|
||||
@@ -0,0 +1,25 @@
|
||||
# 2026-04-09 Node 卸载与 nvm 安装实施记录
|
||||
|
||||
## 变更内容
|
||||
- 卸载了 Homebrew 安装的 `node 25.8.1_1`
|
||||
- 删除了本地目录 `/Users/wkc/.local/node-v14.21.3-darwin-x64`
|
||||
- 更新了 `/Users/wkc/.zshrc`
|
||||
- 安装了 `nvm 0.40.4`
|
||||
|
||||
## shell 配置调整
|
||||
- 删除旧配置:`export PATH="/Users/wkc/.local/node-v14.21.3-darwin-x64/bin:$PATH"`
|
||||
- 新增 `nvm` 初始化配置:
|
||||
|
||||
```sh
|
||||
export NVM_DIR="$HOME/.nvm"
|
||||
[ -s "/opt/homebrew/opt/nvm/nvm.sh" ] && \. "/opt/homebrew/opt/nvm/nvm.sh"
|
||||
[ -s "/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm" ] && \. "/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm"
|
||||
```
|
||||
|
||||
## 验证结果
|
||||
- 交互式 `zsh` 下 `nvm --version` 返回 `0.40.4`
|
||||
- `node` 命令已不存在,说明当前环境中已无非 `nvm` 管理的 Node 版本
|
||||
- `nvm ls` 返回 `N/A`,说明尚未通过 `nvm` 安装任何 Node 版本
|
||||
|
||||
## 备注
|
||||
- `brew uninstall node` 过程中触发了 Homebrew 自动移除若干仅供该版本 Node 使用的依赖库
|
||||
@@ -0,0 +1,25 @@
|
||||
# 证件输入校验移除实施记录
|
||||
|
||||
## 实施时间
|
||||
- 2026-04-09
|
||||
|
||||
## 修改内容
|
||||
- 移除个人新增弹窗中的证件号码格式校验
|
||||
- 移除企业新增弹窗中的证件号码格式校验
|
||||
- 两个新增弹窗的证件号码规则统一保留为必填校验
|
||||
- 新增前端源码断言,约束后续不再恢复证件号码格式校验
|
||||
|
||||
## 修改文件
|
||||
- `ruoyi-ui/src/views/loanPricing/workflow/components/PersonalCreateDialog.vue`
|
||||
- `ruoyi-ui/src/views/loanPricing/workflow/components/CorporateCreateDialog.vue`
|
||||
- `ruoyi-ui/tests/id-number-validation-removal.test.js`
|
||||
- `ruoyi-ui/package.json`
|
||||
- `doc/implementation-report-2026-04-09-remove-id-number-validation.md`
|
||||
|
||||
## 验证方式
|
||||
1. `npm --prefix ruoyi-ui run test:id-number-validation-removal`
|
||||
2. `npm --prefix ruoyi-ui run build:prod`
|
||||
|
||||
## 说明
|
||||
- 本次移除的是前端证件号码格式校验,不影响证件号码必填约束
|
||||
- 后端本次未新增或调整证件号码格式校验逻辑
|
||||
@@ -0,0 +1,93 @@
|
||||
# 上虞个人利率测算输入参数对齐实施记录
|
||||
|
||||
## 实施时间
|
||||
- 2026-04-09
|
||||
|
||||
## 修改内容
|
||||
- 个人新增弹窗补齐 `loanPurpose`、`loanTerm`
|
||||
- 个人新增弹窗 `loanTerm` 固定为 `1-6` 年
|
||||
- 个人新增弹窗 `collType` 选项统一为 `一类/二类/三类`
|
||||
- 个人新增弹窗开关字段提交值由 `true/false` 调整为 `1/0`
|
||||
- 个人详情页补齐 `贷款用途` 展示
|
||||
- 个人与企业详情、模型输出布尔展示兼容 `1/0`
|
||||
- 后端个人创建 DTO 补齐 `loanPurpose`、`loanTerm`
|
||||
- 后端个人 DTO 到流程实体映射补齐 `loanPurpose`、`loanTerm`
|
||||
- 后端模型调用 DTO 补齐 `loanTerm`、`loanLoop`
|
||||
- 后端个人模型调用前统一将 `bizProof`、`loanLoop`、`collThirdParty` 规范为 `0/1`
|
||||
- `orgCode` 统一为 `892000`
|
||||
- `ModelInvokeDTO` 注释、接口文档、SQL 基线和迁移脚本同步统一为 `892000`
|
||||
- 新增前端源码断言与后端单元测试
|
||||
|
||||
## 修改文件
|
||||
- `ruoyi-ui/src/views/loanPricing/workflow/components/PersonalCreateDialog.vue`
|
||||
- `ruoyi-ui/src/views/loanPricing/workflow/components/PersonalWorkflowDetail.vue`
|
||||
- `ruoyi-ui/src/views/loanPricing/workflow/components/ModelOutputDisplay.vue`
|
||||
- `ruoyi-ui/src/views/loanPricing/workflow/components/CorporateWorkflowDetail.vue`
|
||||
- `ruoyi-ui/src/views/loanPricing/workflow/components/CorporateCreateDialog.vue`
|
||||
- `ruoyi-ui/tests/personal-create-input-params.test.js`
|
||||
- `ruoyi-ui/package.json`
|
||||
- `ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/PersonalLoanPricingCreateDTO.java`
|
||||
- `ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/ModelInvokeDTO.java`
|
||||
- `ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/util/LoanPricingConverter.java`
|
||||
- `ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/LoanPricingModelService.java`
|
||||
- `ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/LoanPricingModelServicePersonalParamsTest.java`
|
||||
- `doc/api/loan-pricing-workflow-api.md`
|
||||
- `sql/loan_pricing_workflow.sql`
|
||||
- `sql/loan_pricing_schema_20260328.sql`
|
||||
- `sql/loan_pricing_prod_init_20260331.sql`
|
||||
- `sql/fix_comments.sql`
|
||||
- `sql/fix_all_comments.sql`
|
||||
- `sql/update_org_code_default_20260409.sql`
|
||||
- `doc/2026-04-09-shangyu-retail-input-params-design.md`
|
||||
- `doc/2026-04-09-shangyu-retail-input-params-frontend-plan.md`
|
||||
- `doc/implementation-report-2026-04-09-shangyu-retail-input-params.md`
|
||||
|
||||
## 数据库处理
|
||||
1. 执行 `sql/update_org_code_default_20260409.sql`
|
||||
2. 将 `loan_pricing_workflow.org_code` 默认值修改为 `892000`
|
||||
3. 将存量 `loan_pricing_workflow.org_code` 非 `892000` 的记录统一更新为 `892000`
|
||||
|
||||
## 验证方式
|
||||
1. 前端源码断言:
|
||||
- `npm --prefix ruoyi-ui run test:personal-create-input-params`
|
||||
- `npm --prefix ruoyi-ui run test:retail-display-fields`
|
||||
2. 后端单元测试:
|
||||
- `mvn -pl ruoyi-loan-pricing -Dtest=LoanPricingModelServiceTest,LoanPricingModelServicePersonalParamsTest test`
|
||||
3. 前端构建:
|
||||
- `npm --prefix ruoyi-ui run build:prod`
|
||||
4. 数据库验证:
|
||||
- 查询 `loan_pricing_workflow.org_code` 字段默认值
|
||||
- 查询存量数据中是否仍存在非 `892000` 记录
|
||||
5. 接口验证:
|
||||
- `/login/test` 获取 token
|
||||
- `POST /loanPricing/workflow/create/personal` 正常场景
|
||||
- `POST /loanPricing/workflow/create/personal` 缺少 `loanPurpose` 场景
|
||||
- `POST /loanPricing/workflow/create/personal` 分支值场景
|
||||
- `GET /loanPricing/workflow/{serialNum}` 验证回显
|
||||
6. 页面验证:
|
||||
- 启动前端 dev server
|
||||
- 使用浏览器打开流程列表页
|
||||
- 校验新增弹窗下拉选项
|
||||
- 页面创建个人流程并打开详情页确认回显
|
||||
|
||||
## 验证结果
|
||||
- `npm --prefix ruoyi-ui run test:personal-create-input-params` 通过
|
||||
- `npm --prefix ruoyi-ui run test:retail-display-fields` 通过
|
||||
- `mvn -pl ruoyi-loan-pricing -Dtest=LoanPricingModelServiceTest,LoanPricingModelServicePersonalParamsTest test` 通过
|
||||
- `npm --prefix ruoyi-ui run build:prod` 通过,输出 `Build complete.`
|
||||
- 数据库验证结果:
|
||||
- `loan_pricing_workflow.org_code` 默认值为 `892000`
|
||||
- 存量非 `892000` 记录数为 `0`
|
||||
- 接口验证结果:
|
||||
- 正常场景创建成功,返回 `orgCode=892000`,并持久化 `loanPurpose`、`loanTerm`
|
||||
- 缺少 `loanPurpose` 时返回 `贷款用途不能为空`
|
||||
- 分支场景详情回显 `bizProof=0`、`loanLoop=1`、`collThirdParty=0`
|
||||
- 页面验证结果:
|
||||
- 新增弹窗显示 `贷款用途`
|
||||
- 借款期限下拉仅包含 `1-6`
|
||||
- 抵质押类型下拉为 `一类/二类/三类`
|
||||
- 页面创建流程成功后,详情页展示 `贷款用途=经营`、`借款期限=6`
|
||||
|
||||
## 说明
|
||||
- 浏览器验证使用系统 `Google Chrome.app`
|
||||
- 本次验证期间启动的后端、前端和浏览器进程已在任务结束前关闭
|
||||
26
doc/implementation-report-2026-04-09-start-script-ps-ef.md
Normal file
26
doc/implementation-report-2026-04-09-start-script-ps-ef.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# 启动脚本进程判断改为 ps -ef 实施记录
|
||||
|
||||
## 修改内容
|
||||
|
||||
- 将 `bin/prod/restart_java.sh` 中的后端进程收集逻辑由 `pgrep -f` 改为 `ps -ef | awk`
|
||||
- 将 `bin/restart_java_backend.sh` 中的后端进程收集逻辑由 `pgrep -f` 改为 `ps -ef | awk`
|
||||
- 删除 `bin/restart_java_backend.sh` 中对 `pgrep` 命令的依赖校验
|
||||
- 更新 `bin/prod/restart_java_test.sh`,补充 `ps -ef` / `pgrep` 约束校验,并修正测试夹具中的 JDK 目录
|
||||
- 新增 `bin/restart_java_backend_test.sh`,校验本地后端重启脚本已改用 `ps -ef`
|
||||
|
||||
## 实现说明
|
||||
|
||||
- 两份脚本都只在 `ps -ef` 结果中匹配同时满足“包含脚本标记参数”和“`-jar` 指向目标 jar”这两个条件的 Java 进程
|
||||
- 进程筛选时继续忽略 `<defunct>` 记录,避免误判僵尸进程
|
||||
- 现有 PID 文件校验逻辑保持不变,本次只收敛“扫描当前是否已有进程”的实现方式
|
||||
|
||||
## 路径检查
|
||||
|
||||
- 已确认本次实施记录保存路径为 `doc/implementation-report-2026-04-09-start-script-ps-ef.md`
|
||||
|
||||
## 验证结果
|
||||
|
||||
- 已执行 `sh bin/prod/restart_java_test.sh`
|
||||
- 已执行 `sh bin/restart_java_backend_test.sh`
|
||||
- 已执行 `sh -n bin/prod/restart_java.sh && sh -n bin/restart_java_backend.sh`
|
||||
- 已确认测试中拉起的假 Java 进程在脚本收尾阶段自动停止并清理
|
||||
@@ -0,0 +1,37 @@
|
||||
# 2026-04-10 登录 Shell 默认使用 Node 25 实施记录
|
||||
|
||||
## 变更内容
|
||||
- 保持 `nvm` 默认别名为 `25`
|
||||
- 在 `~/.zprofile` 中补充 `nvm` 初始化,并在登录 shell 启动时自动执行 `nvm use default`
|
||||
|
||||
## 根因分析
|
||||
- `nvm alias default 25` 已经存在,但仅在交互式 shell 中可用
|
||||
- `zsh -lc` 启动的是登录非交互 shell,不会读取 `~/.zshrc`
|
||||
- 因此这类场景下 `node`、`npm`、`npx` 未进入 PATH,表现为 `npx` 启动失败
|
||||
|
||||
## 修改文件
|
||||
- `~/.zprofile`
|
||||
- `doc/implementation-report-2026-04-10-login-shell-default-node25.md`
|
||||
|
||||
## 验证项
|
||||
- 验证登录 shell 在不手动执行 `nvm use` 的情况下可直接识别 `node`
|
||||
- 验证登录 shell 在不手动执行 `nvm use` 的情况下可直接识别 `npx`
|
||||
- 验证 `nvm` 默认别名仍然指向 `25`
|
||||
|
||||
## 执行命令
|
||||
- `zsh -lc 'nvm alias default 25'`
|
||||
- `zsh -lc 'echo NODE=$(node -v); echo NPM=$(npm -v); echo NPX=$(npx -v); echo NODE_PATH=$(command -v node); echo NPX_PATH=$(command -v npx); echo NVM_CURRENT=$(nvm current); echo NVM_ALIAS=$(nvm alias default | tail -n 1)'`
|
||||
|
||||
## 验证结果
|
||||
- `nvm` 默认别名输出为 `default -> 25 (-> v25.9.0 *)`
|
||||
- 登录 shell 输出 `NODE=v25.9.0`
|
||||
- 登录 shell 输出 `NPM=11.12.1`
|
||||
- 登录 shell 输出 `NPX=11.12.1`
|
||||
- 登录 shell 输出 `NODE_PATH=/Users/wkc/.nvm/versions/node/v25.9.0/bin/node`
|
||||
- 登录 shell 输出 `NPX_PATH=/Users/wkc/.nvm/versions/node/v25.9.0/bin/npx`
|
||||
- 登录 shell 输出 `NVM_CURRENT=v25.9.0`
|
||||
- 登录 shell 输出 `NVM_ALIAS=default -> 25 (-> v25.9.0 *)`
|
||||
|
||||
## 结论
|
||||
- `zsh -lc` 场景下已默认切换到 Node `25.9.0`
|
||||
- `npx` 在登录 shell 中已可直接使用,无需先手动执行 `nvm use 25`
|
||||
BIN
doc/~$上虞利率测算接口文档.xlsx
Normal file
BIN
doc/~$上虞利率测算接口文档.xlsx
Normal file
Binary file not shown.
BIN
doc/上虞利率测算接口文档.xlsx
Normal file
BIN
doc/上虞利率测算接口文档.xlsx
Normal file
Binary file not shown.
@@ -0,0 +1,110 @@
|
||||
# Personal Pricing Collateral Optional Frontend Implementation Plan
|
||||
|
||||
> **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:** 维持现有个人新增弹窗的数据结构、字段名称和提交报文不变,只移除前端表单对 `collType` 的必填限制。通过前端源码断言测试和页面联调共同验证“字段可空提交”的行为,避免扩大到企业流程或后端接口。
|
||||
|
||||
**Tech Stack:** Vue 2、Element UI、npm、Node.js 断言脚本
|
||||
|
||||
---
|
||||
|
||||
### Task 1: 固化个人新增流程“抵质押类型非必填”的前端测试
|
||||
|
||||
**Files:**
|
||||
- Modify: `ruoyi-ui/tests/personal-create-input-params.test.js`
|
||||
- Inspect: `ruoyi-ui/src/views/loanPricing/workflow/components/PersonalCreateDialog.vue`
|
||||
|
||||
- [ ] **Step 1: 核对当前个人新增弹窗中的 `collType` 规则**
|
||||
|
||||
Run: `sed -n '150,220p' ruoyi-ui/src/views/loanPricing/workflow/components/PersonalCreateDialog.vue`
|
||||
Expected: 能看到 `rules.collType` 里仍有 `required: true`。
|
||||
|
||||
- [ ] **Step 2: 先写失败断言**
|
||||
|
||||
在 `ruoyi-ui/tests/personal-create-input-params.test.js` 中增加断言,明确个人新增弹窗不应再包含:
|
||||
|
||||
```js
|
||||
required: true, message: "请选择抵质押类型"
|
||||
```
|
||||
|
||||
- [ ] **Step 3: 运行测试确认红灯**
|
||||
|
||||
Run: `npm --prefix ruoyi-ui run test:personal-create-input-params`
|
||||
Expected: FAIL,提示个人新增弹窗仍将抵质押类型设为必填。
|
||||
|
||||
### Task 2: 移除个人新增弹窗中 `collType` 的必填限制
|
||||
|
||||
**Files:**
|
||||
- Modify: `ruoyi-ui/src/views/loanPricing/workflow/components/PersonalCreateDialog.vue`
|
||||
|
||||
- [ ] **Step 1: 删除 `collType` 的必填校验**
|
||||
|
||||
把:
|
||||
|
||||
```js
|
||||
collType: [
|
||||
{required: true, message: "请选择抵质押类型", trigger: "change"}
|
||||
]
|
||||
```
|
||||
|
||||
移除,使个人表单规则中不再声明 `collType` 为必填。
|
||||
|
||||
- [ ] **Step 2: 保持其它字段与提交逻辑不变**
|
||||
|
||||
确认以下内容不改动:
|
||||
|
||||
```js
|
||||
collType: undefined,
|
||||
collThirdParty: false
|
||||
```
|
||||
|
||||
以及提交时的:
|
||||
|
||||
```js
|
||||
collThirdParty: this.form.collThirdParty ? '1' : '0'
|
||||
```
|
||||
|
||||
- [ ] **Step 3: 重新运行测试确认转绿**
|
||||
|
||||
Run: `npm --prefix ruoyi-ui run test:personal-create-input-params`
|
||||
Expected: PASS,输出包含 `personal create input params assertions passed`。
|
||||
|
||||
### Task 3: 页面联调并补实施记录
|
||||
|
||||
**Files:**
|
||||
- Create: `docs/implementation-reports/2026-04-10-personal-pricing-collateral-optional-frontend.md`
|
||||
|
||||
- [ ] **Step 1: 启动前端页面**
|
||||
|
||||
Run: `npm --prefix ruoyi-ui run dev`
|
||||
Expected: 前端本地开发服务启动成功,可访问新增个人利率定价流程页面。
|
||||
|
||||
- [ ] **Step 2: 浏览器确认页面行为**
|
||||
|
||||
联调确认:
|
||||
- 个人新增弹窗“抵质押类型”字段可为空
|
||||
- 不选择“抵质押类型”时其余必填项填完整仍可点击提交
|
||||
- 企业新增弹窗规则不受影响
|
||||
|
||||
- [ ] **Step 3: 停止本次测试启动的前端进程**
|
||||
|
||||
Run: `ps -ef | rg 'vue-cli-service serve|npm --prefix ruoyi-ui run dev'`
|
||||
Expected: 仅停止本次联调启动的前端进程。
|
||||
|
||||
- [ ] **Step 4: 编写实施记录**
|
||||
|
||||
实施记录至少包含:
|
||||
|
||||
```markdown
|
||||
- 本次仅调整个人利率定价新增流程
|
||||
- 个人新增弹窗已移除抵质押类型必填校验
|
||||
- 企业新增流程未改动
|
||||
- 已执行前端断言测试与页面联调验证
|
||||
```
|
||||
|
||||
- [ ] **Step 5: 核对实施记录保存路径**
|
||||
|
||||
Run: `ls docs/implementation-reports/2026-04-10-personal-pricing-collateral-optional-frontend.md`
|
||||
Expected: 文件位于仓库 `docs/implementation-reports` 目录。
|
||||
BIN
ruoyi-admin/.DS_Store
vendored
Normal file
BIN
ruoyi-admin/.DS_Store
vendored
Normal file
Binary file not shown.
@@ -16,7 +16,7 @@ public class ModelInvokeDTO {
|
||||
|
||||
/**
|
||||
* 机构编码(必填)
|
||||
* 固定值:931000
|
||||
* 固定值:892000
|
||||
*/
|
||||
private String orgCode;
|
||||
|
||||
@@ -73,6 +73,12 @@ public class ModelInvokeDTO {
|
||||
*/
|
||||
private String applyAmt;
|
||||
|
||||
/**
|
||||
* 贷款期限(必填)
|
||||
* 单位:年
|
||||
*/
|
||||
private String loanTerm;
|
||||
|
||||
/**
|
||||
* 净身企业(非必填)
|
||||
* 可选值:true/false
|
||||
@@ -119,19 +125,25 @@ public class ModelInvokeDTO {
|
||||
|
||||
/**
|
||||
* 是否有经营佐证(非必填)
|
||||
* 可选值:true/false
|
||||
* 可选值:0/1
|
||||
*/
|
||||
private String bizProof;
|
||||
|
||||
/**
|
||||
* 循环功能(非必填)
|
||||
* 可选值:0/1
|
||||
*/
|
||||
private String loanLoop;
|
||||
|
||||
/**
|
||||
* 抵质押类型(非必填)
|
||||
* 可选值:抵押/质押
|
||||
* 可选值:一类/二类/三类
|
||||
*/
|
||||
private String collType;
|
||||
|
||||
/**
|
||||
* 抵质押物是否三方所有(非必填)
|
||||
* 可选值:true/false
|
||||
* 可选值:0/1
|
||||
*/
|
||||
private String collThirdParty;
|
||||
|
||||
|
||||
@@ -41,15 +41,24 @@ public class PersonalLoanPricingCreateDTO implements Serializable {
|
||||
@NotBlank(message = "申请金额不能为空")
|
||||
private String applyAmt;
|
||||
|
||||
@Schema(description = "是否有经营佐证", example = "true")
|
||||
@Schema(description = "贷款用途", requiredMode = Schema.RequiredMode.REQUIRED, example = "business", allowableValues = {"consumer", "business"})
|
||||
@NotBlank(message = "贷款用途不能为空")
|
||||
@Pattern(regexp = "^(consumer|business)$", message = "贷款用途必须是:consumer、business之一")
|
||||
private String loanPurpose;
|
||||
|
||||
@Schema(description = "借款期限(年)", requiredMode = Schema.RequiredMode.REQUIRED, example = "3")
|
||||
@NotBlank(message = "借款期限不能为空")
|
||||
private String loanTerm;
|
||||
|
||||
@Schema(description = "是否有经营佐证", example = "1")
|
||||
private String bizProof;
|
||||
|
||||
@Schema(description = "循环功能", example = "false")
|
||||
@Schema(description = "循环功能", example = "0")
|
||||
private String loanLoop;
|
||||
|
||||
@Schema(description = "抵质押类型", example = "一类")
|
||||
private String collType;
|
||||
|
||||
@Schema(description = "抵质押物是否三方所有", example = "false")
|
||||
@Schema(description = "抵质押物是否三方所有", example = "0")
|
||||
private String collThirdParty;
|
||||
}
|
||||
|
||||
@@ -60,6 +60,10 @@ public class LoanPricingModelService {
|
||||
}
|
||||
ModelInvokeDTO modelInvokeDTO = new ModelInvokeDTO();
|
||||
BeanUtils.copyProperties(loanPricingWorkflow, modelInvokeDTO);
|
||||
if ("个人".equals(loanPricingWorkflow.getCustType()))
|
||||
{
|
||||
normalizePersonalModelInvokeDTO(modelInvokeDTO);
|
||||
}
|
||||
JSONObject response = modelService.invokeModel(modelInvokeDTO);
|
||||
if (loanPricingWorkflow.getCustType().equals("个人")){
|
||||
// 个人模型
|
||||
@@ -83,4 +87,24 @@ public class LoanPricingModelService {
|
||||
log.info("更新流程信息成功");
|
||||
}
|
||||
}
|
||||
|
||||
private void normalizePersonalModelInvokeDTO(ModelInvokeDTO modelInvokeDTO)
|
||||
{
|
||||
modelInvokeDTO.setBizProof(toZeroOne(modelInvokeDTO.getBizProof()));
|
||||
modelInvokeDTO.setLoanLoop(toZeroOne(modelInvokeDTO.getLoanLoop()));
|
||||
modelInvokeDTO.setCollThirdParty(toZeroOne(modelInvokeDTO.getCollThirdParty()));
|
||||
}
|
||||
|
||||
private String toZeroOne(String value)
|
||||
{
|
||||
if ("true".equals(value) || "1".equals(value))
|
||||
{
|
||||
return "1";
|
||||
}
|
||||
if ("false".equals(value) || "0".equals(value))
|
||||
{
|
||||
return "0";
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@ public class LoanPricingConverter {
|
||||
entity.setIdNum(dto.getIdNum());
|
||||
entity.setGuarType(dto.getGuarType());
|
||||
entity.setApplyAmt(dto.getApplyAmt());
|
||||
entity.setLoanPurpose(dto.getLoanPurpose());
|
||||
entity.setLoanTerm(dto.getLoanTerm());
|
||||
entity.setCollType(dto.getCollType());
|
||||
entity.setCollThirdParty(dto.getCollThirdParty());
|
||||
// 映射个人特有字段
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
package com.ruoyi.loanpricing.service;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.ruoyi.loanpricing.domain.dto.ModelInvokeDTO;
|
||||
import com.ruoyi.loanpricing.domain.dto.PersonalLoanPricingCreateDTO;
|
||||
import com.ruoyi.loanpricing.domain.entity.LoanPricingWorkflow;
|
||||
import com.ruoyi.loanpricing.mapper.LoanPricingWorkflowMapper;
|
||||
import com.ruoyi.loanpricing.mapper.ModelCorpOutputFieldsMapper;
|
||||
import com.ruoyi.loanpricing.mapper.ModelRetailOutputFieldsMapper;
|
||||
import com.ruoyi.loanpricing.util.LoanPricingConverter;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class LoanPricingModelServicePersonalParamsTest {
|
||||
|
||||
@Mock
|
||||
private ModelService modelService;
|
||||
|
||||
@Mock
|
||||
private LoanPricingWorkflowMapper loanPricingWorkflowMapper;
|
||||
|
||||
@Mock
|
||||
private ModelRetailOutputFieldsMapper modelRetailOutputFieldsMapper;
|
||||
|
||||
@Mock
|
||||
private ModelCorpOutputFieldsMapper modelCorpOutputFieldsMapper;
|
||||
|
||||
@Mock
|
||||
private SensitiveFieldCryptoService sensitiveFieldCryptoService;
|
||||
|
||||
@InjectMocks
|
||||
private LoanPricingModelService loanPricingModelService;
|
||||
|
||||
@Test
|
||||
void shouldContainLoanPurposeAndLoanTermInPersonalCreateDto() throws NoSuchFieldException {
|
||||
assertNotNull(PersonalLoanPricingCreateDTO.class.getDeclaredField("loanPurpose"));
|
||||
assertNotNull(PersonalLoanPricingCreateDTO.class.getDeclaredField("loanTerm"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldMapLoanPurposeAndLoanTermFromPersonalDto() {
|
||||
PersonalLoanPricingCreateDTO dto = new PersonalLoanPricingCreateDTO();
|
||||
dto.setCustIsn("CUST001");
|
||||
dto.setCustName("张三");
|
||||
dto.setGuarType("信用");
|
||||
dto.setApplyAmt("100000");
|
||||
dto.setLoanPurpose("business");
|
||||
dto.setLoanTerm("3");
|
||||
|
||||
LoanPricingWorkflow workflow = LoanPricingConverter.toEntity(dto);
|
||||
|
||||
assertEquals("business", workflow.getLoanPurpose());
|
||||
assertEquals("3", workflow.getLoanTerm());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldContainLoanTermAndLoanLoopInModelInvokeDto() throws NoSuchFieldException {
|
||||
assertNotNull(ModelInvokeDTO.class.getDeclaredField("loanTerm"));
|
||||
assertNotNull(ModelInvokeDTO.class.getDeclaredField("loanLoop"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldInvokePersonalModelWithExpectedParams() {
|
||||
LoanPricingWorkflow workflow = new LoanPricingWorkflow();
|
||||
workflow.setId(1L);
|
||||
workflow.setSerialNum("202604090001");
|
||||
workflow.setOrgCode("892000");
|
||||
workflow.setRunType("1");
|
||||
workflow.setCustIsn("CUST001");
|
||||
workflow.setCustType("个人");
|
||||
workflow.setCustName("cipher-name");
|
||||
workflow.setIdType("身份证");
|
||||
workflow.setIdNum("cipher-id");
|
||||
workflow.setGuarType("信用");
|
||||
workflow.setApplyAmt("100000");
|
||||
workflow.setLoanPurpose("business");
|
||||
workflow.setLoanTerm("3");
|
||||
workflow.setBizProof("true");
|
||||
workflow.setLoanLoop("false");
|
||||
workflow.setCollThirdParty("true");
|
||||
workflow.setCollType("一类");
|
||||
|
||||
JSONObject response = new JSONObject();
|
||||
response.put("calculateRate", "6.15");
|
||||
|
||||
when(loanPricingWorkflowMapper.selectById(1L)).thenReturn(workflow);
|
||||
when(sensitiveFieldCryptoService.decrypt("cipher-name")).thenReturn("张三");
|
||||
when(sensitiveFieldCryptoService.decrypt("cipher-id")).thenReturn("110101199001011234");
|
||||
when(modelService.invokeModel(any())).thenReturn(response);
|
||||
|
||||
loanPricingModelService.invokeModelAsync(1L);
|
||||
|
||||
verify(modelService).invokeModel(argThat((ModelInvokeDTO dto) ->
|
||||
Objects.equals("202604090001", dto.getSerialNum())
|
||||
&& Objects.equals("892000", dto.getOrgCode())
|
||||
&& Objects.equals("1", dto.getRunType())
|
||||
&& Objects.equals("CUST001", dto.getCustIsn())
|
||||
&& Objects.equals("个人", dto.getCustType())
|
||||
&& Objects.equals("张三", dto.getCustName())
|
||||
&& Objects.equals("身份证", dto.getIdType())
|
||||
&& Objects.equals("110101199001011234", dto.getIdNum())
|
||||
&& Objects.equals("信用", dto.getGuarType())
|
||||
&& Objects.equals("100000", dto.getApplyAmt())
|
||||
&& Objects.equals("business", dto.getLoanPurpose())
|
||||
&& Objects.equals("3", dto.getLoanTerm())
|
||||
&& Objects.equals("1", dto.getBizProof())
|
||||
&& Objects.equals("0", dto.getLoanLoop())
|
||||
&& Objects.equals("1", dto.getCollThirdParty())
|
||||
&& Objects.equals("一类", dto.getCollType())));
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -10,7 +10,9 @@
|
||||
"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:retail-display-fields": "node tests/retail-display-fields.test.js"
|
||||
"test:retail-display-fields": "node tests/retail-display-fields.test.js",
|
||||
"test:personal-create-input-params": "node tests/personal-create-input-params.test.js",
|
||||
"test:id-number-validation-removal": "node tests/id-number-validation-removal.test.js"
|
||||
},
|
||||
"keywords": [
|
||||
"vue",
|
||||
|
||||
@@ -124,22 +124,6 @@ export default {
|
||||
}
|
||||
},
|
||||
data() {
|
||||
// 统一社会信用代码验证
|
||||
const validateIdNum = (rule, value, callback) => {
|
||||
if (!value) {
|
||||
callback(new Error('请输入证件号码'))
|
||||
} else if (this.form.idType === '统一社会信用代码') {
|
||||
const reg = /^[0-9A-HJ-NPQRTUWXY]{2}\d{6}[0-9A-HJ-NPQRTUWXY]{10}$/
|
||||
if (!reg.test(value)) {
|
||||
callback(new Error('请输入正确的统一社会信用代码'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
// 金额验证
|
||||
const validateApplyAmt = (rule, value, callback) => {
|
||||
if (!value) {
|
||||
@@ -175,7 +159,7 @@ export default {
|
||||
return {
|
||||
submitting: false,
|
||||
form: {
|
||||
orgCode: '',
|
||||
orgCode: '892000',
|
||||
runType: '1',
|
||||
custIsn: undefined,
|
||||
custName: undefined,
|
||||
@@ -204,7 +188,7 @@ export default {
|
||||
{required: true, message: "请选择证件类型", trigger: "change"}
|
||||
],
|
||||
idNum: [
|
||||
{required: true, validator: validateIdNum, trigger: "blur"}
|
||||
{required: true, message: "证件号码不能为空", trigger: "blur"}
|
||||
],
|
||||
guarType: [
|
||||
{required: true, message: "请选择担保方式", trigger: "change"}
|
||||
@@ -242,7 +226,7 @@ export default {
|
||||
/** 表单重置 */
|
||||
reset() {
|
||||
this.form = {
|
||||
orgCode: '',
|
||||
orgCode: '892000',
|
||||
runType: '1',
|
||||
custIsn: undefined,
|
||||
custName: undefined,
|
||||
|
||||
@@ -150,8 +150,8 @@ export default {
|
||||
methods: {
|
||||
/** 格式化布尔值为中文 */
|
||||
formatBoolean(value) {
|
||||
if (value === 'true' || value === true) return '是'
|
||||
if (value === 'false' || value === false) return '否'
|
||||
if (value === 'true' || value === true || value === '1' || value === 1) return '是'
|
||||
if (value === 'false' || value === false || value === '0' || value === 0) return '否'
|
||||
return value || '-'
|
||||
},
|
||||
/** 获取基准利率 */
|
||||
|
||||
@@ -242,8 +242,8 @@ export default {
|
||||
methods: {
|
||||
/** 格式化布尔值为中文 */
|
||||
formatBoolean(value) {
|
||||
if (value === 'true' || value === true) return '是'
|
||||
if (value === 'false' || value === false) return '否'
|
||||
if (value === 'true' || value === true || value === '1' || value === 1) return '是'
|
||||
if (value === 'false' || value === false || value === '0' || value === 0) return '否'
|
||||
return value || '-'
|
||||
},
|
||||
/** 格式化贷款用途 */
|
||||
|
||||
@@ -51,6 +51,23 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="贷款用途" prop="loanPurpose">
|
||||
<el-select v-model="form.loanPurpose" placeholder="请选择贷款用途" style="width: 100%">
|
||||
<el-option label="消费" value="consumer"/>
|
||||
<el-option label="经营" value="business"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="借款期限(年)" prop="loanTerm">
|
||||
<el-select v-model="form.loanTerm" placeholder="请选择借款期限" style="width: 100%">
|
||||
<el-option v-for="item in loanTermOptions" :key="item" :label="item" :value="item"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="是否有经营佐证" prop="bizProof">
|
||||
@@ -70,9 +87,9 @@
|
||||
<el-col :span="12">
|
||||
<el-form-item label="抵质押类型" prop="collType">
|
||||
<el-select v-model="form.collType" placeholder="请选择抵质押类型" style="width: 100%">
|
||||
<el-option label="一线" value="一线"/>
|
||||
<el-option label="一类" value="一类"/>
|
||||
<el-option label="二类" value="二类"/>
|
||||
<el-option label="三类" value="三类"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -102,22 +119,6 @@ export default {
|
||||
}
|
||||
},
|
||||
data() {
|
||||
// 身份证验证
|
||||
const validateIdNum = (rule, value, callback) => {
|
||||
if (!value) {
|
||||
callback(new Error('请输入证件号码'))
|
||||
} else if (this.form.idType === '身份证') {
|
||||
const reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/
|
||||
if (!reg.test(value)) {
|
||||
callback(new Error('请输入正确的身份证号码'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
// 金额验证
|
||||
const validateApplyAmt = (rule, value, callback) => {
|
||||
if (!value) {
|
||||
@@ -135,9 +136,12 @@ export default {
|
||||
}
|
||||
|
||||
return {
|
||||
loanTermOptions: [
|
||||
'1', '2', '3', '4', '5', '6'
|
||||
],
|
||||
submitting: false,
|
||||
form: {
|
||||
orgCode: '',
|
||||
orgCode: '892000',
|
||||
runType: '1',
|
||||
custIsn: undefined,
|
||||
custName: undefined,
|
||||
@@ -145,6 +149,8 @@ export default {
|
||||
idNum: undefined,
|
||||
guarType: undefined,
|
||||
applyAmt: undefined,
|
||||
loanPurpose: undefined,
|
||||
loanTerm: undefined,
|
||||
bizProof: false,
|
||||
loanLoop: false,
|
||||
collType: undefined,
|
||||
@@ -163,7 +169,7 @@ export default {
|
||||
{required: true, message: "请选择证件类型", trigger: "change"}
|
||||
],
|
||||
idNum: [
|
||||
{required: true, validator: validateIdNum, trigger: "blur"}
|
||||
{required: true, message: "证件号码不能为空", trigger: "blur"}
|
||||
],
|
||||
guarType: [
|
||||
{required: true, message: "请选择担保方式", trigger: "change"}
|
||||
@@ -171,8 +177,11 @@ export default {
|
||||
applyAmt: [
|
||||
{required: true, validator: validateApplyAmt, trigger: "blur"}
|
||||
],
|
||||
collType: [
|
||||
{required: true, message: "请选择抵质押类型", trigger: "change"}
|
||||
loanPurpose: [
|
||||
{required: true, message: "请选择贷款用途", trigger: "change"}
|
||||
],
|
||||
loanTerm: [
|
||||
{required: true, message: "请选择借款期限", trigger: "change"}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -198,7 +207,7 @@ export default {
|
||||
/** 表单重置 */
|
||||
reset() {
|
||||
this.form = {
|
||||
orgCode: '',
|
||||
orgCode: '892000',
|
||||
runType: '1',
|
||||
custIsn: undefined,
|
||||
custName: undefined,
|
||||
@@ -206,6 +215,8 @@ export default {
|
||||
idNum: undefined,
|
||||
guarType: undefined,
|
||||
applyAmt: undefined,
|
||||
loanPurpose: undefined,
|
||||
loanTerm: undefined,
|
||||
bizProof: false,
|
||||
loanLoop: false,
|
||||
collType: undefined,
|
||||
@@ -231,9 +242,9 @@ export default {
|
||||
// 转换开关值为字符串
|
||||
const data = {
|
||||
...this.form,
|
||||
bizProof: this.form.bizProof ? 'true' : 'false',
|
||||
loanLoop: this.form.loanLoop ? 'true' : 'false',
|
||||
collThirdParty: this.form.collThirdParty ? 'true' : 'false'
|
||||
bizProof: this.form.bizProof ? '1' : '0',
|
||||
loanLoop: this.form.loanLoop ? '1' : '0',
|
||||
collThirdParty: this.form.collThirdParty ? '1' : '0'
|
||||
}
|
||||
|
||||
createPersonalWorkflow(data).then(response => {
|
||||
|
||||
@@ -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="贷款用途">{{ formatLoanPurpose(detailData.loanPurpose) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="借款期限">{{ detailData.loanTerm || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="是否有经营佐证">{{
|
||||
formatBoolean(detailData.bizProof)
|
||||
@@ -149,8 +150,14 @@ export default {
|
||||
methods: {
|
||||
/** 格式化布尔值为中文 */
|
||||
formatBoolean(value) {
|
||||
if (value === 'true' || value === true) return '是'
|
||||
if (value === 'false' || value === false) return '否'
|
||||
if (value === 'true' || value === true || value === '1' || value === 1) return '是'
|
||||
if (value === 'false' || value === false || value === '0' || value === 0) return '否'
|
||||
return value || '-'
|
||||
},
|
||||
/** 格式化贷款用途 */
|
||||
formatLoanPurpose(value) {
|
||||
if (value === 'consumer') return '消费'
|
||||
if (value === 'business') return '经营'
|
||||
return value || '-'
|
||||
},
|
||||
/** 获取基准利率 */
|
||||
|
||||
34
ruoyi-ui/tests/id-number-validation-removal.test.js
Normal file
34
ruoyi-ui/tests/id-number-validation-removal.test.js
Normal file
@@ -0,0 +1,34 @@
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const assert = require('assert')
|
||||
|
||||
function read(relativePath) {
|
||||
return fs.readFileSync(path.join(__dirname, '..', relativePath), 'utf8')
|
||||
}
|
||||
|
||||
const personalCreateDialog = read('src/views/loanPricing/workflow/components/PersonalCreateDialog.vue')
|
||||
const corporateCreateDialog = read('src/views/loanPricing/workflow/components/CorporateCreateDialog.vue')
|
||||
|
||||
assert(
|
||||
!personalCreateDialog.includes('const validateIdNum ='),
|
||||
'个人新增弹窗仍包含证件号码格式校验函数'
|
||||
)
|
||||
|
||||
assert(
|
||||
!corporateCreateDialog.includes('const validateIdNum ='),
|
||||
'企业新增弹窗仍包含证件号码格式校验函数'
|
||||
)
|
||||
|
||||
assert(
|
||||
personalCreateDialog.includes("idNum: [") &&
|
||||
personalCreateDialog.includes('{required: true, message: "证件号码不能为空", trigger: "blur"}'),
|
||||
'个人新增弹窗证件号码规则应仅保留必填'
|
||||
)
|
||||
|
||||
assert(
|
||||
corporateCreateDialog.includes("idNum: [") &&
|
||||
corporateCreateDialog.includes('{required: true, message: "证件号码不能为空", trigger: "blur"}'),
|
||||
'企业新增弹窗证件号码规则应仅保留必填'
|
||||
)
|
||||
|
||||
console.log('id number validation removal assertions passed')
|
||||
65
ruoyi-ui/tests/personal-create-input-params.test.js
Normal file
65
ruoyi-ui/tests/personal-create-input-params.test.js
Normal file
@@ -0,0 +1,65 @@
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const assert = require('assert')
|
||||
|
||||
function read(relativePath) {
|
||||
return fs.readFileSync(path.join(__dirname, '..', relativePath), 'utf8')
|
||||
}
|
||||
|
||||
const personalCreateDialog = read('src/views/loanPricing/workflow/components/PersonalCreateDialog.vue')
|
||||
const personalDetail = read('src/views/loanPricing/workflow/components/PersonalWorkflowDetail.vue')
|
||||
|
||||
assert(
|
||||
personalCreateDialog.includes('label="贷款用途"') && personalCreateDialog.includes('prop="loanPurpose"'),
|
||||
'个人新增弹窗缺少贷款用途字段'
|
||||
)
|
||||
|
||||
assert(
|
||||
personalCreateDialog.includes('label="借款期限(年)"') && personalCreateDialog.includes('prop="loanTerm"'),
|
||||
'个人新增弹窗缺少借款期限字段'
|
||||
)
|
||||
|
||||
assert(
|
||||
personalCreateDialog.includes("value=\"consumer\"") && personalCreateDialog.includes("value=\"business\""),
|
||||
'个人新增弹窗缺少贷款用途选项'
|
||||
)
|
||||
|
||||
assert(
|
||||
personalCreateDialog.includes('loanTermOptions') &&
|
||||
personalCreateDialog.includes("'1'") &&
|
||||
personalCreateDialog.includes("'6'") &&
|
||||
!personalCreateDialog.includes("'7'"),
|
||||
'个人新增弹窗借款期限选项应限制为 1-6 年'
|
||||
)
|
||||
|
||||
assert(
|
||||
personalCreateDialog.includes('label="一类"') &&
|
||||
personalCreateDialog.includes('label="二类"') &&
|
||||
personalCreateDialog.includes('label="三类"') &&
|
||||
!personalCreateDialog.includes('label="一线"'),
|
||||
'个人新增弹窗抵质押类型选项未按 Excel 对齐'
|
||||
)
|
||||
|
||||
assert(
|
||||
!personalCreateDialog.includes('{required: true, message: "请选择抵质押类型", trigger: "change"}'),
|
||||
'个人新增弹窗仍将抵质押类型设为必填'
|
||||
)
|
||||
|
||||
assert(
|
||||
personalCreateDialog.includes("bizProof: this.form.bizProof ? '1' : '0'") &&
|
||||
personalCreateDialog.includes("loanLoop: this.form.loanLoop ? '1' : '0'") &&
|
||||
personalCreateDialog.includes("collThirdParty: this.form.collThirdParty ? '1' : '0'"),
|
||||
'个人新增弹窗开关字段未按 1/0 提交'
|
||||
)
|
||||
|
||||
assert(
|
||||
personalDetail.includes('label="贷款用途"') && personalDetail.includes('detailData.loanPurpose'),
|
||||
'个人详情页缺少贷款用途展示'
|
||||
)
|
||||
|
||||
assert(
|
||||
personalDetail.includes("value === '1'") && personalDetail.includes("value === '0'"),
|
||||
'个人详情页布尔格式化未兼容 1/0'
|
||||
)
|
||||
|
||||
console.log('personal create input params assertions passed')
|
||||
@@ -8,7 +8,7 @@ ALTER TABLE loan_pricing_workflow
|
||||
MODIFY COLUMN `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||
MODIFY COLUMN `serial_num` varchar(50) NOT NULL COMMENT '业务方流水号',
|
||||
MODIFY COLUMN `model_output_id` bigint(20) DEFAULT NULL COMMENT '模型输出ID',
|
||||
MODIFY COLUMN `org_code` varchar(20) NOT NULL DEFAULT '' COMMENT '机构编码',
|
||||
MODIFY COLUMN `org_code` varchar(20) NOT NULL DEFAULT '892000' COMMENT '机构编码(统一值892000)',
|
||||
MODIFY COLUMN `run_type` varchar(10) NOT NULL DEFAULT '1' COMMENT '运行模式: 1-同步',
|
||||
MODIFY COLUMN `cust_isn` varchar(50) NOT NULL COMMENT '客户内码',
|
||||
MODIFY COLUMN `cust_type` varchar(20) NOT NULL COMMENT '客户类型: 个人/企业',
|
||||
|
||||
@@ -14,7 +14,7 @@ ALTER TABLE loan_pricing_workflow
|
||||
MODIFY COLUMN `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||
MODIFY COLUMN `serial_num` varchar(50) NOT NULL COMMENT '业务方流水号',
|
||||
MODIFY COLUMN `model_output_id` bigint(20) DEFAULT NULL COMMENT '模型输出ID',
|
||||
MODIFY COLUMN `org_code` varchar(20) NOT NULL DEFAULT '' COMMENT '机构编码',
|
||||
MODIFY COLUMN `org_code` varchar(20) NOT NULL DEFAULT '892000' COMMENT '机构编码(统一值892000)',
|
||||
MODIFY COLUMN `run_type` varchar(10) NOT NULL DEFAULT '1' COMMENT '运行模式: 1-同步',
|
||||
MODIFY COLUMN `cust_isn` varchar(50) NOT NULL COMMENT '客户内码',
|
||||
MODIFY COLUMN `cust_type` varchar(20) NOT NULL COMMENT '客户类型: 个人/企业',
|
||||
|
||||
@@ -741,7 +741,7 @@ CREATE TABLE `loan_pricing_workflow` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||
`serial_num` varchar(50) NOT NULL COMMENT '业务方流水号',
|
||||
`model_output_id` bigint(20) DEFAULT NULL COMMENT '模型输出ID',
|
||||
`org_code` varchar(20) NOT NULL DEFAULT '' COMMENT '机构编码',
|
||||
`org_code` varchar(20) NOT NULL DEFAULT '892000' COMMENT '机构编码(统一值892000)',
|
||||
`run_type` varchar(10) NOT NULL DEFAULT '1' COMMENT '运行模式: 1-同步',
|
||||
`cust_isn` varchar(50) NOT NULL COMMENT '客户内码',
|
||||
`cust_type` varchar(20) NOT NULL COMMENT '客户类型: 个人/企业',
|
||||
|
||||
@@ -323,7 +323,7 @@ CREATE TABLE `loan_pricing_workflow` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||
`serial_num` varchar(50) NOT NULL COMMENT '业务方流水号',
|
||||
`model_output_id` bigint(20) DEFAULT NULL COMMENT '模型输出ID',
|
||||
`org_code` varchar(20) NOT NULL DEFAULT '' COMMENT '机构编码',
|
||||
`org_code` varchar(20) NOT NULL DEFAULT '892000' COMMENT '机构编码(统一值892000)',
|
||||
`run_type` varchar(10) NOT NULL DEFAULT '1' COMMENT '运行模式: 1-同步',
|
||||
`cust_isn` varchar(50) NOT NULL COMMENT '客户内码',
|
||||
`cust_type` varchar(20) NOT NULL COMMENT '客户类型: 个人/企业',
|
||||
|
||||
@@ -4,7 +4,7 @@ CREATE TABLE `loan_pricing_workflow` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||
`serial_num` varchar(50) NOT NULL COMMENT '业务方流水号',
|
||||
`model_output_id` bigint(20) NULL COMMENT '模型输出id',
|
||||
`org_code` varchar(20) NOT NULL DEFAULT '' COMMENT '机构编码',
|
||||
`org_code` varchar(20) NOT NULL DEFAULT '892000' COMMENT '机构编码(统一值892000)',
|
||||
`run_type` varchar(10) NOT NULL DEFAULT '1' COMMENT '运行模式: 1-同步',
|
||||
`cust_isn` varchar(50) NOT NULL COMMENT '客户内码',
|
||||
`cust_type` varchar(20) NOT NULL COMMENT '客户类型: 个人/企业',
|
||||
|
||||
10
sql/update_org_code_default_20260409.sql
Normal file
10
sql/update_org_code_default_20260409.sql
Normal file
@@ -0,0 +1,10 @@
|
||||
-- 统一 loan_pricing_workflow 表 org_code 默认值与存量数据
|
||||
|
||||
ALTER TABLE `loan_pricing_workflow`
|
||||
MODIFY COLUMN `org_code` varchar(20) NOT NULL DEFAULT '892000' COMMENT '机构编码(统一值892000)';
|
||||
|
||||
UPDATE `loan_pricing_workflow`
|
||||
SET `org_code` = '892000'
|
||||
WHERE `org_code` IS NULL
|
||||
OR `org_code` = ''
|
||||
OR `org_code` <> '892000';
|
||||
Reference in New Issue
Block a user