From bfe1b346d9182b4185353eeed06c2ae838cd59ff Mon Sep 17 00:00:00 2001 From: wkc <978997012@qq.com> Date: Fri, 17 Apr 2026 09:21:43 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=B5=81=E7=A8=8B=E8=AF=A6?= =?UTF-8?q?=E6=83=85=E4=B8=8E=E5=AF=B9=E5=85=AC=E6=96=B0=E5=A2=9E=E5=BC=B9?= =?UTF-8?q?=E7=AA=97=E5=B1=95=E7=A4=BA=E5=B9=B6=E8=A1=A5=E5=85=85=E6=B5=8B?= =?UTF-8?q?=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .DS_Store | Bin 20484 -> 26628 bytes ...hangyu-corporate-alignment-backend-plan.md | 52 +++ ...angyu-corporate-alignment-frontend-plan.md | 48 ++ ...-2026-04-16-shangyu-corporate-alignment.md | 38 ++ ...rkflow-detail-model-output-flat-display.md | 21 + ...$上虞对公利率测算_上传字段与展示字段 .xlsx | Bin 0 -> 165 bytes doc/上虞对公利率测算_上传字段与展示字段 .xlsx | Bin 0 -> 17170 bytes .../2026-04-16-tongweb-access-backend-plan.md | 27 ++ ruoyi-admin/pom.xml | 32 ++ .../src/main/resources/application.yml | 5 + ruoyi-admin/src/main/resources/license.dat | 1 + .../dto/CorporateLoanPricingCreateDTO.java | 26 +- .../domain/dto/ModelInvokeDTO.java | 20 +- .../domain/entity/LoanPricingWorkflow.java | 18 +- .../domain/entity/ModelCorpOutputFields.java | 20 +- .../service/LoanPricingModelService.java | 11 + .../impl/LoanPricingWorkflowServiceImpl.java | 2 +- .../util/LoanPricingConverter.java | 6 +- .../src/main/resources/data/corp_output.json | 108 ++--- .../service/LoanPricingModelServiceTest.java | 30 ++ .../LoanPricingWorkflowServiceImplTest.java | 4 +- ruoyi-ui/package.json | 5 +- .../components/CorporateCreateDialog.vue | 61 ++- .../components/CorporateWorkflowDetail.vue | 13 +- .../components/ModelOutputDisplay.vue | 165 ++++--- ...2026-04-16-shangyu-corporate-alignment.sql | 13 + sql/loan_pricing_prod_init_20260331.sql | 12 +- sql/loan_pricing_schema_20260328.sql | 12 +- sql/loan_pricing_workflow.sql | 11 +- sql/model_corp.sql | 115 ++--- .../2026-04-16-TongWeb接入全流程通用指南.md | 410 ++++++++++++++++++ tongweb/license.dat | 1 + tongweb_63310.properties | 15 + 33 files changed, 1026 insertions(+), 276 deletions(-) create mode 100644 doc/2026-04-16-shangyu-corporate-alignment-backend-plan.md create mode 100644 doc/2026-04-16-shangyu-corporate-alignment-frontend-plan.md create mode 100644 doc/implementation-report-2026-04-16-shangyu-corporate-alignment.md create mode 100644 doc/implementation-report-2026-04-16-workflow-detail-model-output-flat-display.md create mode 100644 doc/~$上虞对公利率测算_上传字段与展示字段 .xlsx create mode 100644 doc/上虞对公利率测算_上传字段与展示字段 .xlsx create mode 100644 docs/superpowers/plans/2026-04-16-tongweb-access-backend-plan.md create mode 100755 ruoyi-admin/src/main/resources/license.dat create mode 100644 sql/2026-04-16-shangyu-corporate-alignment.sql create mode 100644 tongweb/2026-04-16-TongWeb接入全流程通用指南.md create mode 100755 tongweb/license.dat create mode 100644 tongweb_63310.properties diff --git a/.DS_Store b/.DS_Store index 43b5d80a8fb4900e4ffda25f404a4bf68a1e8abe..201926ebce30dbb088f48e1c86fd1cbb5ad26b7e 100644 GIT binary patch delta 1288 zcma)6YfM~46rOK(p>xZ%JD`QT4`Gqj)w^9XD;H*w{Q_c&^4n52pKn)%$Rw}WkLq!1y`uVWBipY4lUWRQ@`x|g*tbT zEJ>0CIYH)#Mq;tKOe!{+j2WW#nbB+ zz05th3;#`3OHryYzmWc0l=*`q>sc26_}6Nkc84NACU;8ZSd%zeRqPIDx38v#Gh@_s zoVSXb0hbu7^NK5#m7+J;?_9zs_!P_d0xS3u*YOor@e_WzLA$Qo(DmL7e zrONPAhei$yciRWDtM>jqk2HkayB_Zw5N|hxa%+;bTEWY0id}IsUdKjeV)67$Jp1gX zR<2gu62HWbs?n^rKdHu_j%%ukuU0&ajpp^;)0*)$)v{N4Na9g8l!-s5nI?SlUWsR< zp_B1Mff|rQjH}Y{WHgr3CQWlqatq^q(xF*xIulPOOl6z=C@Y6g8Zj>Nl$OY5wp@2I zb}a9@Kbpx7q_o6VP!VMx<16e)W+FPR4a_C9X_FCAdKnwzwoQGW)T73;Nn_KMKYF$D z1Y?Ku_BvJ7FlFQA6@v#9MT~bj=Vfy81>kTHbl^aeRvY1IErH! zgNi96kU|=>$l)|z!pnFSXCd$=&fzUw#yfZq@8d&!hR<;o-{5E-_)_*{uW;dJ26O1@+cNvkCU(tDGJCJw2 Gf`0*6j!M1& delta 934 zcmZ`&TWk$M7@lwHGTXD!ZHcyL54IYb$PuTfQi{-vs$2DTT0O1Xsa-7X9?tG*O#Z${=o>(Y z5Q56IUQEbRv1DR;sK|tr2l_)LqrD5G24h#UAaTqKy3@f9 z>c{c9MQK)A771%5kvaUdwy59v%ma}qKbm`ke~mmV$jc9^3m3_CK0Yq*XZxQij&!+ku!Fkay;-s1xwjMn-}(c-W+J35ztt6AV) zEg8t5uS;J_?k}_4&M^C3mda8gFZt*YabzXZc7)W^YCH@>Pw)SxR<}JVBng zy4$qPj!vVw$JCuI@r1q6uyoVf+-B;A<(QjHBPDs6$E-w`;botrhSbUbi(*P4YfX2U zJJP1J)7L0a3nk?YTcal&qc*9Vy@FEzd88JoMU1t32URIUSl=zrP{WdvU@_a=W%wMk z4m@|kMXTE^BZSwH<=P_=G4 z$&~*j1!@ChagVM-*9B8felV{ormE`|#k9IjC*g>Ungpb6NqO?;=c{_3lGo%d`9Qt^ zpcsuY2w(z2n2IoFViqDOLnW$EjU{Np8mz@SY=sR6-RQv{?8gBd#33BTah$+OoWdEL z!+Bi5MO?;B+`?_#!9zU5bG*PijNl_a;WNHdMkSi5(GZ/dev/null && npm --prefix ruoyi-ui run test:corporate-create-input-params'` + - `zsh -lic 'nvm use default >/dev/null && npm --prefix ruoyi-ui run test:corporate-display-fields'` + - 结果:两个脚本均通过 +- 前端构建: + - `zsh -lic 'nvm use default >/dev/null && npm --prefix ruoyi-ui run build:prod'` + - 结果:构建成功,仅有体积告警 +- 接口联调: + - 使用 `/login/test` 获取 token + - 验证了对公创建正常场景、缺少 `repayMethod` 的参数错误场景、`分期/不分期` 与 `1/0` 分支场景 + - 详情接口确认返回新增字段,且 `loanPricingWorkflow.loanRate = modelCorpOutputFields.finalCalculateRate` +- 浏览器联调: + - 启动前端开发服务并打开流程列表 + - 验证对公新增弹窗字段、选项、提交流程 + - 验证创建后列表新增记录 + - 验证企业详情页出现 `最终测算利率`、`还款方式`、`贸易和建筑业企业`、`历史利率`、`产品最低利率下限`、`平滑幅度`、`参考利率` diff --git a/doc/implementation-report-2026-04-16-workflow-detail-model-output-flat-display.md b/doc/implementation-report-2026-04-16-workflow-detail-model-output-flat-display.md new file mode 100644 index 0000000..d3b6762 --- /dev/null +++ b/doc/implementation-report-2026-04-16-workflow-detail-model-output-flat-display.md @@ -0,0 +1,21 @@ +# 流程详情页模型输出平铺展示实施记录 + +## 改动日期 +- 2026-04-16 + +## 改动范围 +- 前端:`ruoyi-ui/src/views/loanPricing/workflow/components/ModelOutputDisplay.vue` +- 前端测试:`ruoyi-ui/tests/model-output-flat-display.test.js` +- 前端脚本:`ruoyi-ui/package.json` + +## 改动内容 +- 取消流程详情页“模型输出”区域的 Tab 切换结构。 +- 保留原有分组顺序与字段内容,将“基本信息”“忠诚度分析”“贡献度分析”等分组改为自上而下平铺展示。 +- 按最新要求,将“测算结果”分组前移到“基本信息”下方,优先展示最终测算相关结果。 +- 按最新要求,将“测算结果”中的“最终测算利率”调整到最后一行展示。 +- 移除组件内仅用于 Tab 默认选中的 `activeTab` 和相关监听逻辑。 +- 新增最小回归测试,校验模型输出组件不再包含 `el-tabs`、`el-tab-pane`,并具备平铺分组区块,同时校验“基本信息”后紧跟“测算结果”。 + +## 验证计划 +- 使用 `nvm` 显式切换前端 Node 版本后执行 `npm run test:model-output-flat-display`。 +- 启动前端页面,在浏览器中打开流程详情页,确认模型输出区域已按分组平铺展示,且不再出现 Tab 切换。 diff --git a/doc/~$上虞对公利率测算_上传字段与展示字段 .xlsx b/doc/~$上虞对公利率测算_上传字段与展示字段 .xlsx new file mode 100644 index 0000000000000000000000000000000000000000..3c3a794080821fc614a37e537889505a44d8e2ae GIT binary patch literal 165 ZcmZQB&rVh#9WXPLGh{O)Gbqpn0sshg4^aRB literal 0 HcmV?d00001 diff --git a/doc/上虞对公利率测算_上传字段与展示字段 .xlsx b/doc/上虞对公利率测算_上传字段与展示字段 .xlsx new file mode 100644 index 0000000000000000000000000000000000000000..679fcd96dc409d386a783ac443e57faa3a1205df GIT binary patch literal 17170 zcmeHu1D9mmvUSQ5ZEc*4ZJcz!yW1H% zYSXz{TM-n108!)t0Day6f8+n-6_`lcvgl(#8M*}b3{6;@6~T>StkOB3J|LUm6^s!(uF%MYg9b?W^W`sbU zOR=OWu{y@sYA|eA{JaEc8tzhJcZAw_Xu6w@C8=#mU=VBJU_mFsz3~%S!X?-G!7u~`W@qXJ%AaT?KW~hPP zZj04N;@#I82RLN~lZt2r_FCQ?7JM{A$`Y4K0vLAHN5`~wzL10vTDU^R(oVe`kDoi< zZx+sUh58=aBJs@i0s;W=`3Vdl|8ExBq|88k_oa3+Uj_*MWudwb##WB>bblQG&oci% zHphSY=~W4`-})I~LM|oVLPs7KH{uY4q+JCiItah}_(`tAH$@kcU~lx0;~;#;3IrDS z?ecjWTif7?J{=)^*k!4TL_*;vZg#B>Nqw<*2B#u(ND;HI+8ID}S-f9-NEerKr*P?t zrK)T#%a5 zyPQ&T0?Qx9DRVxTjymFKVEU`ZYs8B1{uxVI$&Ayy&LGEui^yHq$m-{S--o3BJ50>lkZ1(|n$o|TatI>c+{Iboj&FVjm1d{8Sp9L5IKpGqX z0RC%b+^pzbZ5=EPY;7(7*utum1#RaUP`Zh)@rkyWhs`sZXXnf2Zm z+;Bh`iY`M|z!5!rJ=?t|7Q^;K!i)?Wuh6k(R_^h-@OS$6#P}p+Z~!RW!i6-ZKDEZA zqwlt(3FzCH(#cA|C0v8;-?PZL4%YWEA9(2pI8i}02t-c#FdTT$q8>>z4?7v45eAtp z{JP~t%PoIoZGh92S}@USlieZ_h!G(lb^?jYO%(*r3sG^65u9_Hb2)}rH(vmzDm#AP37S6yEt^h5=x#tQ`K*dV?SV9C$ ze+{%tyskawUiQ;(_0lAyG5~8cF&MCXL(#Xait1d4N^oGx@xz1)C3F)IQjmi|5p6ae zPce~8DR~eA-!cq-nhfT#EeAt=S7xq{Hd${b-!kNtE4|gIG8%dGDuUz0g#0a-hqCck zZ(Ka++2DKbFTfkB3Q`W1G5^=V55lA!P~N}-ffIk_#YS+pvuIUNB}8{;M2~7dNUvQs z335AEZvUeT&<^01`Cqm!8reD$9>1j_#DWnMoh;_oJT#9nK;_qAmzB6`c?Tj(h}sJ6 zcQ$ltvOh5_wu)g_a;(S$rth+us!k?!BZ%S~F`6>@K%Bc-c}D(*c^lUoE;Cmf zIx~;plS_I0E0!7xEAZd$_+z#z9t&O~P1H-irxT0*0%)!vrM`z-+#g|hax(w_J zob|R(urW^J>WUJq)qDgXQ`nsuU`u%*x8+Y1ZWkD(%SR6+dGqF$0e5POp~I z9?v>!f$lED5EJXf*?kFij7PSG>21-^poB6eIl!)pjX*9icIwlzquoZ@%l^PLHl~{FlrF>v3MTqK;e9XT0p}Ye{e>arunF=Y)xy!|6C1cGmJu8B?n)E^0XwK~xfBCgTdYGB)#SZ5iG*k|7Ri z8C>fo!=}%as=sB8f3vDqi)ReEm18joMuR}8!R|Il-RMS+!SiHvNVxdIO=gK`O-*EHBoJTWt|%jyK9gt zto*t9=t3hQY+ytcAFd_cRd-Np?hH)gw&YLx;Lj>o!}FNZ2*h4e`tKkU_LaY2eKF|` zWx&YTKU8P))M<``Pk>^+pIk}`-TG7Gjy7zOjDs^})75h|_LIG_pL|?wN8J%(!oN3u z_WgeOnb*fvAuwZr+$~&*n-P5NVvTjoU8w5ri2K&>e$U?9u5#>y7xS3w44#s$?D{+B zR=n#CxlHnBd=V*WyDtz-DfGrH(l)#qWcKI$)6()b2OiIs&Lb6Hn%pN*0B?%Z@HqZ? zp4>LtW*IQ;RonMMdqmm>mQi^qp^i}B>of7O7;;eQ!&U4ZQu%(yvNRvoeB$dwPF?Op zo`8dW8q``3(~UkC$fOw>f5#pp#C)%m{ng7)njnYtV7m*nDHDZ{o4(dXi@94o>P~HF zAK1KH!5>z2IdEp6Mr5rxigI`Tt}iEKAkGMlAZNyzReR9;DNbSF=>8>P*^v_9A}~~7 zl-q}5QuKnF(G!9~CX#lD%+f-!Gq?_Ch(Hf+3rpqVMu>cF1k&TB;0XsGKTUNoSGkho zS4STO&d*!oSeR{xtswJn!6Yw)3`e1kWdFg|Mx zUE#az;%i!ztI5_z4@_}M_U18!B%3VZpWn+|YH4Yf3!bQ6(GJ3Gk8GXgoXrC-sT9;K z#X8UEfT$Gez|$|)g;$N0Hq3d^S`~fNr_twz2Q%JV zKkDVUof>9Fk|ljM#d8qHlA_^<$D3KNiHJQWn^vOzFc0GiwAx7;18#Rk+5;q|CmrHP z*7w|*BKPF*6kHM)w*8JnCN9&FZPt@I3F)#Nfw;nl(y8KM33Od{1lG*Vx^>;YR&XY` zwoUww97$YhEI$YILK&{780K=TSA%LBg(`NCL%o83=Ssffr}XqdhB$+sRrw*-qu!t5 z^ZJi=EnQ5$1_%iNphfk++BMUkcCDdlyT^v?O+WLgcg)-DoEpFp+0=D{W)@knwpLj% zQeW46AT?Gk`so?U9?4wPdJ3e=Z#z)9vvXx za@Ts}^Ll?lb!(!nn}ru4>{y|)sk!KWY18w5cvx)C@A_JCYO1%hP~GXhm0OD*S+lM> zT#(6rbP7V-QNoMH`}T{EuH8`+75=SwPalycb#zy4f&80Vt4-;OnM+4|RkQ4~QHmA>d7yf57`?XdSE>yP?`NlE4%3Pru#i zUOpV=hhUl%W;89@9CSU_@(!*+aQ)tD>~8)1j$6@Cn}@uWc|Z9aYO!ov z(eK}d^@Jxw>n}A7%SlTJbzEadfcdM>M#ISz28tH9gC6=m2aM^R`ScZ?IUhG7W8&zV=Rpf1pinOXvC1@tzy ztB1y5@qi&)+0baF@0M36xgRJ+>J3AWRn7;!5_%b2ZZBTgLF|#Hak`X*me3@9anYa- zf;4`^!7%gh9GFY(H-7uUFehfT2zg2VHZrXc5@XI|A+4zJX)tv3&*S=WVfbn;SBBMT zx!A_8xA~+Mfmw@~!zz0f!3Y6d|3<1-JFkm<_ z8dWAZ$Rki7iULUWX$XiW>`}wO=bw5V?7jd+Kt%#A0R`z~Aq4?vAtJ!%A%qC*5sa#X z2(ldk1wojFyGfBrf5nB1Ak9(+8!;`fgXD`CCJzuu{i+jSB$eiaD)di~zzs`?$EC#} z=7oxqqr@>Z8WpJLXFv)EWGt{;Ytb{ii^mu+iz9i6C+#_o64@4yf+0;$8<9`=sYe>E z;6RR`Qqb50jfD>dDJ;bnmrn|L<8EJr&eY8oq3>y?{bSkM?zk!lxl>mrQU!QFfEzm$jC3e7e18R!dSTqMSU<_8K% zTooa#B?(z$600coL?jCsJPWd_&+UmkT~7hr(+IhWn~HEnl`@2)>xVPyir}o-kyaCg zEX)=on0`u z4QlI{m#09E^6@w`9kTdQU$eg_TW>%!&f(CO`HePOlVxo#*kJ#@= z5p)oms-`)l(zN)4V?4L$jY&alkPUDZ!HcYfKf-#Vi)*$Qxawp6DH$^34y)l#` z{CKPb{~sbtHzQ<3bGImJrlwYy9YBQL%(o_X9df)3DbX^5T=zfK*qDG%7T!rG>l^r8 zXc)bA@-TM-g-(vr>@0zNh1wen!xDNL3n6M_T^7Q=8S?r{vjh~lS3ciXF@1nK<_6tv(h^YoJIKJ%2_&Xhb zIFNh{d+;^Mr>Y|;lnNcPQ8-f>K?0qgOGQ6PSpU)kD-^jucPGryO3|Wm4Gt^6rqm8_ zBA@4-64MZp8T2d?A@q65(-|ONAzl=yBG=)>qkXzIDR8l_C1NFhEH>i^Sp|hK7o%3# z|1N>BG%%|>ZD69n8qc`2^Ca6KPI%!imVzu<=I;BYngPN zc8#?(XG6!ZW3z>MJ(r6$^N{4yovAn{a`<$(z`N?(#yP;_{&v9{j)NApP0F=zKP=Y= zN~gotot?YPdsC=p7V7$_`c&^*jk(7?c*mf_b- zyrx&<+jrMWc9pIrbSZ3bUX=UQE*9CgyH2jQ8J?Qbsv=MgxvH@}upSlDS~_Yh{J}h) z+ptS<9lX+DYF?Vk=_kEXrHmO~=^9R2tdpVw^>w|sds5o7juxKhs1BYQo!SEuefMxW zIP(-X{J!$D{n4AVHa%sp5r#`wh`j;#+AI9to^3f|AAE)bbH)0M>9an+jfrhp|xKK{GFs3Ue`J9e%l}SnQ2im>q5;{ew@^)@M_a z2fT^*=|>73k>XD+&d}Bp?v(d*yiDjh1999F%5D?c$G!PGN&+7M5Mb-*p1Kx%GmmZ- z4x^!8NGbW2Z(E~En;B~H*Bx%%lG8?vgFB;5HflcPmf&NAtw9D5e3!y~c=g64HK`ck z(=H@WS?2<0holFD8sYse9DE&Wg%o$hIdvQ1DgJ2;x(25CHS^UBXU4g}%dkF0RU!GwE`mr!cfB!y^A& z24dA0I|QK~5gMxIN>7`0B?QlZsV5O2&L z1TZlfJm`9V-Px+VHVXe;WWPQhx92MZyvg5L=DGN3$X&UJRJFYT?N*In>+%A=eR&MlIJ?7O)68 zrN-Dd6F~Hhs;{NRDC~BZI+!U~X2pV`*o}1-)76KGQsieD612pSFKTfu3!Y!b1TOrJ z7_G2{_0x}tVJ@nOo=sRxA8#ROGnx#=Ki-DKyNi*b*`rWpXWPj@01@LCfTXS+OjLEs z9j56E6BPc7NL)?uLZj-}he6fb6qHkUhXiEbSsM7`yLT}#G#M2z3I$`pP%zg{o++OQ zIl;sd_eI+GA;?#&5;hr?vKPDeF)(BkkevR4o$HP z&~f%f-7fOCiU)3*p_ak}%>@^in5p8-S%eF%WDl=$vikW&Wvv2rY(q4r>}aXlBSVag zbR(|Zi={aWX>ZFA5D>3{ZC+Vt6HajDcZZN6fOy=Fk9T(Jr=WYaEEYlPY<{aUdx`|~ zxqPO$HWuo2sWQ`zyIym~%sq*9X*De2Khj-Y)epey>8PleoEeQRu62seQkm6 z{wQ$Mye~ce7*KQk?9-*=(J8b3_{tFdr?Zsh_oE2{0|4;D`lCwyXL{es%-GtP{?Fr| zX`^%XY1=h6ly3Nyue8yHMlR$Fgpan_^B3EXf)_#J7n~K7{MNV|G1K)-NwnKvEsubq zTFSQ@^o1IcPq47jptyOfB|&tr!%U_y3vkh2(i?6OeQ2~oiRiWkhwm41H8*;6L_LEM zQMs*HJMv$s&!GZO%(d^+CxyYbM}3f!Gx#{I`|G?ObkKMdf@QMf8KC`?Uav?IsQt6z=Dv! zZvkQtPy;GyMJq;L=-v;X5OGZ+r>Y@52HOrWJ;!h?s~5%5rm-!t*R82&3&^^@^gXQx z2{|3o!Q$3E2xC6p+XZWoLS2nBk!7h~_ezOEVSnAY4~*aB5S!?d5T0Tq{Q?{W`=nb7 z;v%r>G-(Vd{#!~qX)1VH`sH546oLvBaD{D{yU?6;@_RrDIKIaG?^7>O3mexrKCaEl zuzPE+&b-YIyHCN%i$Y@$^nS|*UQ_Rc^KS{iKQ2i0Y{0t2&8$2Hh9k#&<0@rBOM#w$=>o>RFgdxwz=7njJeRS{OJD>+CQ#Szvy7QSd??A zc^I|?ntQO8Fw0IS!9qitbS5_1aVA+9sRnkALs8wp3+9g8~uueo(W8$ovIc@dN zy?ocl4yMQ%<2e`xI6EKP*D^101x-9f1vm?J22D!0k*?tmB^OUkUBxz9CCE?CloX=w z$B?yG$bQiuRX%LjE?LMU7q0igmcp7`3LR-eiHBYlP|~I}JI!)kuS5Llz5+tabpiA6 zVwX;n=hCWmO2ick+!#J`gZ`nNWE^ilE6y_oTq8oR8W;qT#hFBcs|x3<1k0j~RnWS4 zN&taR+r~CBHY^60U_*vEZQ@3B_rsEwY3`Yp!m9>#sdVgZqjxTWmT-go`feR_-q;0R zFdTF;17-IjsSY+-B)#v;Y-$ss_k zmRfnIG8Xsc5rWMJWOp_+af=jHs~D-9%?JX``}vnW9rjfO585CWVojE@7}o_d{qc(e zZy1#hHOBY1kV|C^!4`!RFu_7L2n(GaRbMFN$go6>IA1f&K1394)LhN)uS?{qM&4sC z)_n<7O1a-FB3fVe6)P`4_ID8wvdQ(mS8RTG>KAVu!%_S6ELZ#}tW!M+RcPct7Zm`7NUlQ@MdiOEc~|L}yF0tD**b3q^LaF{kMfT{x=|Pa>Z^47{rQiH z(WeMJ)q<}GzX}%s0QSE&Ek`GJD`Uq$!ukdE$(S`Zgl_a>ZisfzdqYWT%#;APE-;`X z0sjr4t~n&*#$u7cf)WwDD;RlbsNLj`HbX${= z9lI4@1(WX`{hb6f@Xlv_3#?hgG=$G23q2jU&R*KoAY;fP>M_FJ{?PBDclWCALNpZJ z=>{|`dhzJ_e5eLX%uz%+yD+HeRw0g02~0VJfZBYF5tzdil>0?dSk2}hVj&VWsyH6% zozRIe*Z4<`auW@hNJcUgh|q)5%MGoM775HTLnwJEDS-ynKX_~`No|A5X2l(tkQ`O& zzH0&K1{PC>UmLdiBVthK*aJ_sp z!%{RLWwU@UT_Ki~aZ9Oyzxn=gx#i1)vZxGE8irn1M>V5;6kk+~a@)62GRL?NqBz1v zZ5`CT;n1OJ-4z%^_5$hr*134?13w$iplN3nMLXvn2GS%PmPUV&XBR`FGw7>+n zHFGXs{pXu-#6c77W#w)_QaK=aHPu|^yo1^;W85vY=yl* z3L>WvQ^hWrh&4jww|^Dv7I1dp*#l4%q*uaq^cCb?h`>i+ce9VF50=hUs3FNB z8H?E!+b-veH)!PRWtzNlqM5FtT)2#inP$y0>ITnDj0-D>t(Ol~u5IdrF`D3Yt7TGw z*zy|yx4FKfkwo5G!A_buF#@p~Eh*oFS#(vs&{L-GW7bF%@L9C4CfVPBm5kBQgi? z<56w3$4@so3KX7Y6nZ~X#hNj~lBz+d=dxlbQfbOO&j2Ns(p{Hl#s$^iwst~?nCr=w z6}F?e$PuDtwX3zpqGLBjFci3*ba_D_pQ~Ak@}JKhc9<}=;x5DN;6B4A1}(^~f%?PF zHDLWa6b#n4r>RTxtAOy9r=$oqBq{UM6g)lG8o#jKCM{?dG_#?)D^!5b*&cpAOr+Kr zyNGGepK{>caCa{|a}zH&gyt}}x`^9AcXS*9XPK+1+$WLucJK-^$w+QKRb0z^qGW+= ze5253$zf2LuA2S)$8<$1YXmte0ssJoIRF64e>*cXeFtMBB_{`S8`D31+PSu-61F&+ zk8AR0pp^12sU^5wq|RSegvMD$%gSx?>dg-dtP;RwDiRvzS9Gr=GIaof0NB`>(lFPs z!x&-F(QyoKsYV_qcl$kcx~{Q9(JUCuy!KgCZ4_%6nD<$HrLXHR+@X!RA1(ZNtz{+5 z^+pA>D+@CiFlFHqOjy!)&7hyN_k*GM;J}!&k|N1&O!>{A;EOU>^ACySQzlFr09&#~ zs{!5_DK8`_V=D$sa@7mpB zWxi#=vsqqjOk#dht*jLTV_FTCDLCA@$B&w|c5oli!mH?B=FThX08_HKcitNd>+UgH zUm@&JT6|3UPQ~X|qieXVj zR|9)(X{ousS#@eM$yY4_Gx`d%y@4trYPjRY;KZynVF}Fgkn>|=RfBcNb+SHmXcCsm zTbDjce|1Q0Ne#!7wuNUZYu@7HJJFV|J#ro~Z0w#Uwy?)Z+w0RCUixZH6-ex5n5c1i zlxPp$aVmNngKVr)zUQH3ajq=@Wjqx3BK@p8jyOFJo6Ww!w`ejq9@8p*$2LL>xLTRC zRSMH#375x%i_Y#IgQ=RF5U}0|ZtE!ielYIIM|D`qmPiuU^e8@-Th8?RnQEg2`b4Q+ zP0_@JVn!~*YMG?VEkB!G&8Cc9wZlj?uEN>WQS+b5b>ZvY5Ww>95qP8}_ueIT)&~lB zxY_!Ak*B>KN_;c9HvE|v1G*dXXX&4ybX4|fD<&2D`L>BCeqe!+&@&>nMLmA{+p%e} z!xOuFT`Prm!@GfR7SOLcxd~Hc500|5__LN17Zq>$A8JJDCMrQ)YL-Wl=c(rix+e0V zYVKYQNnDvfw?a5h`MnY(DG{##;Dp3vb-xGxjti}C7D7{fCfZw?&iah0ZA|Sz_SlJN z;(Svm)Oo5eM9zV@g$Npb3t1l`^J(Lb;C*v&jmj8z4PO&yNO5dRcU;^l-!|8;6hJ%Z zy0mB+Ytt!F?zFvo5p(}d=dwkig(YTQ9DHu2AIPEEk4D6&`3sUMo1Lv>WW&8HZqQL{ zqT1?m8_}7E^*Pk9{$bt7@q^P{U9?@i6lxAx4#;l>e z`-JP!7^5TpoL&?Aw#co=L)b!6Hr%zSTLzBGel7j+w1%fUd3ayqL^+rBNxU3}5$yr6*4 zD8;#GL=Y@ACT}FZtEtIAt_q*dGbl-eYl&CDJSiSF1@mqH2Ip>w2UE9P`CWIgfN8Hs zV}kfwb^fohARanZnl}>d=dB9+dm`<0rlR=KvzJIoH)$iIR*%hfw7IgkP*QY4C&Nqq z*@yY>Auy13LEV?6osEt0F~FUAuT-4<(Dew-R^~ze1BC zGg3U?BcldcGYH2oFe6(kT`j3_rM&`SG@S&b2v^!M{YQ7P3Uo1$hDssL2;=3U`Hi?Mh7Cd zsG+s9Drn=5QgD49(Z)xfTNOcZJp#ZAGAEZ3#|x|qgHIA7dr{PlAY4yDU|BPn0S(H; zOPB*aGZE~x8M9BHSWbSkC$F2~aBEv1l_Dc;Jf+7t(nL6+?Hhj-L>NJ{m64)8FruSy z$~8ZFEFdyw5|>>nW*%}LCE<~j{$Zqe_NpRzH+CS6-e_XJP#ZmqEKPBJ+xDV4F59~uQ6#+h)KHTZnuoF1JH5Wkz}OA zkIH_r2X?ig1<~SXef+wP)1zy-c^h(Z25=O@G)-vhXBb2Z9*PvGP9HUvuq=~sy`gMs zpeE5&L7Zp~TM;_>3V$%;8}Ug^hU?>9Uu$;<&0xr`v!!wJRexC}vRc4Y-NWFuaf3HJ z^_+&Te{ZsfD(RB~4IhpXfsb zZRI6HF>;Q^*;T~38b7LGm@nyF(c$1C0q^@r@NfH@bF@-gmrB3?RR{ZbnytE9j#hJRTbXN1R zyxRmGLfv7;?|DDbreo((J2)z%ju^q>E!SZ2D!27kTi9SghuJ<9W zGM4%2HhB+H@%N1i5DuSZ8QioEaBvA;y_s&Z4hd>wgnTX+5?%!4)MJPVWqr?sf`^Mm zqCGgM+;gUvqq4W-VpK3B&Errm5@VSS((T|yk%CUj6uSZD?_@%k`m=zP_J6yD;KysJ=D_NS6pn38bz7A3!>(V3l)z#BUc zls00*EYiEa2sJk9M_44Jqfgd^B;K4XO5M!I))Pr_oep#8G492~&jZKJKb;_jHb@P! z>RUpwhH41m2WtqM`b=#O$7YG*)JJ;_4%WjW^;h@ZUjOPz zEpT>)ATPKfwyQ(VC68+w61iAZXXVy4>pKYu3=TK~9Uw3&?r9B96hEb6;%eQZI!IhX zg5fW|+++z!bf&WJ-Y_wnwDSx)Pn1}i>yg`aX_AT^$DrqJ^e zM9?sQ%KR1b*JMiLEzweeO`0yeow!^|p*rTRu#Pf6`cFZYO?;20o*zv>Bfr$p!?ZiE zz{1pYL2q`k27~(mnBUB`VS3^*tjdr<teda2IqS+u+Vitf`o9-4~^ek?jGo(mW z1e^D>l0G2%MaexKc)g!8VOBpN>I?An<4sU68Af)aTn>LFXpB6OBo4* ztyn0fos74Jj5Gk?%(-e)Dq~!F3*U&iTCt2y>t5rkIg=G%o3JI)Z!)vk(ob1k^D&>$ zm`yV`;kl#2+#WSN`^D$AiE3km7kytz>%cv4we6y&v%W)!Q7N=xVc6Tu8Z|0&d1Mh% zkt!or!GN3I@@~_gXO&wU!3AU3f7I|)dGmxt`gLgq`C@OBlb!-e5qYj!6vQEF7W*&| z(~u|9Mc6B!utJ~pmcl&ED!KBa982BiRNJEH+nDwIYPk|M4)*+oKw<2@mZm(3X4t7> z>H=CB6@ST*R{{SN-zyhtX`L#b^>n14@%2NeO15}N)n)kcv72Zv-6cli8ByLkp!lu% zIMA3n(>P$oYBr)8D@lQ-;R)X0E|WaCIP=v5-=zxC>_#?+`|jiNw_$Th!L=Z}s8M@S zV2r?x={`YA?nzM*M69Y=3FtE~eco1>ARgbgdGDeaTMoExf7>i70fbAo-S$AOfqm10 zvT{U!gyGM%Z4ZstAXwP)!g?6sI)R61iW0wl1swTBKQPQvvM2#+))jWYisi`Ikp-L= z!Cmf7gLL>n(}_~jMyItgz{1#og3Pc11~YMT1`IWkrCY=VYNmj({z{`ere!rFBiL*V zb4yk+8F5qWkPl+*#`FGHu{4VMR$4_3cd}932A|zd>$`D9DIg}dsOfQp(jwQey9R*UD4N!shZMW`7^U6* zd$qeQN$KEyt%2=kjj6-L&--emBRs3+hb!|+sp*wg+fsP!cdfO!V~UO&mjk;AlB+e+ zizga!eq4qP^S2>>yg3x9zCjXbXr7t9I%KpTGZovbRfIf)tLi@qTQ1;t1Y%`kmo(rg zxBC#YNrdvWn)3(vtotb6QUGJQ7^;EFu9GY7NsBeuBD$Cn+=&e_3cTS~K8rXgoy>Qs zG^`3i>bWAL9ve%^;_mIYIi=H(YT7wTjqYmf_v%4-LkaTL%=w^WfzM+lgsA5TP+{OT zBz|)^(@b%p17I=3arU zMT!+sKnZUI>LZ|)i;ih^U!nIgrBO?biwQ)@8O)M5Hc6_;s^+c=DzSc`>hXvxhSYJ1 za$8yk)a!G{Er3krXSG)UC|bgG_O~2+_yNH4)mN6HM_HP(i*~#WjF=st1v~PRHxBm` zGX#l*!qN^!rpfoB=aYgAjSN2}audMssZ9XhUjLZ_q40H7UgV?L#!{?^T zQ|QHu2*5F*7XFx?rTC(}$$(_&J;Uq9L30z80XTeo9L?PbwT)RLGBNF017N zQ{YD}y1ABCip%-oQm^O+NsK`sj>mqESTquigp>0|?>CF?$zQr7jzPZR$f23f3R$79 zBsvLpGMxYobdUF2Bi;X~i6)4EIK5vpT3-ccgn!jUeLK7VQ^YR~{O^&K*lV-EfbhjF z>=fSjTsB8nHaln)(v*k)UiD*bGn)CA8b`D7w?b{5Jfz)K>`)@qaB6aSP}@dY9x%Cr z67@0;yUg^@<)_=INjQ~cIg2Yn^~CrM1t}zkxx+CUW`_p1`r9NDz~Ir~W-z9P5COQS zJ#nkUYT#HXAtcSTxOk*lSqj*OAgLgQB-!s!XVm_T_tF-TLXsRmZmNI+o#kqdT31FsX0S|a8F zj!V#XB7qU>8J;DuEz#v2vFq|%`*=OwUo#gfTv}Lj{D3pO4~o?khG~wL4U8d%S_^^> z#_FpyAmiZ!;K2iGfx)#2ZG3*PxqZKRcz^zV@Eq50)b;FeeS7+%8*&yIYO^v$)9@k4 z-js}Nf*Z`|Q9hArw~O{5Pq6;muw&$~_$qD~_2Kmt`kbPs@2q6>2Z{;gbM}#KzPoto zhUrenYoSxtP$**=qsJ%hlkL|7{I5<5Kp@($ob5j|{{QDO|Ihg!`2X_K{|@l)gyjDb z{Nwxwz2{%($$uC8J4y2|(c!P&j=xbh|1SLR1hl_Izf#gre+vIEbhN+Y{GEpM7m~#n zG3md*#D9>I{*Ll@(!*aULSISpe?a+@0`Yg0zxM$Ch2oC+k0^h31pXc6@69oPp_JhL ziSqYWnZE=4y-@iVfF|jm0DqM&|1SFXvcO-W6kl|ZuXS+zdy(Mp2>%`t{3Q|F=_@mj?aPGynjYKVDzTdd2_8yZ;Bl<0k(A literal 0 HcmV?d00001 diff --git a/docs/superpowers/plans/2026-04-16-tongweb-access-backend-plan.md b/docs/superpowers/plans/2026-04-16-tongweb-access-backend-plan.md new file mode 100644 index 0000000..bbd638b --- /dev/null +++ b/docs/superpowers/plans/2026-04-16-tongweb-access-backend-plan.md @@ -0,0 +1,27 @@ +# TongWeb 接入后端实施文档 + +## 目标 + +按照 `tongweb/2026-04-16-TongWeb接入全流程通用指南.md` 在当前后端工程中接入东方通 TongWeb,替换默认内嵌 Tomcat,并将 license 文件随 `ruoyi-admin` 启动模块一起打包。 + +## 实施内容 + +1. 在 `ruoyi-admin/pom.xml` 增加 TongWeb Maven 仓库。 +2. 在 `ruoyi-admin/pom.xml` 对 `ruoyi-framework`、`ruoyi-loan-pricing` 依赖排除 `spring-boot-starter-tomcat`。 +3. 在 `ruoyi-admin/pom.xml` 引入 `com.tongweb.springboot:tongweb-spring-boot-starter-3.x:7.0.E.7`。 +4. 将 TongWeb license 复制到 `ruoyi-admin/src/main/resources/license.dat`,并在 `application.yml` 中配置 `server.tongweb.license.path=classpath:license.dat`。 +5. 增加资源存在性测试,验证 `license.dat` 可从 classpath 加载。 +6. 执行后端构建、依赖树、打包产物和测试验证,确认 TongWeb 依赖与 license 已正确接入。 + +## 变更说明 + +- 当前项目基于 Spring Boot 3.5.x,因此实际接入使用 `tongweb-spring-boot-starter-3.x`,版本号延续指南中的 `7.0.E.7`。 +- license 按本次要求保持文件名为 `license.dat`,不改名为 `Tongweb_license.dat`。 +- 现有 `application-dev.yml`、`application-pro.yml`、`application-uat.yml` 中的 `server.tomcat` 参数暂时保留,后续以 TongWeb 实际启动结果为准决定是否继续清理。 + +## 验证步骤 + +1. `mvn -pl ruoyi-admin -Dtest=TongWebLicenseResourceTest test` +2. `mvn -pl ruoyi-admin -am package -DskipTests` +3. `jar tf ruoyi-admin/target/ruoyi-admin.jar | rg 'license.dat|tongweb'` +4. `mvn -pl ruoyi-admin dependency:tree '-Dincludes=com.tongweb.springboot:*,com.tongweb:*,org.springframework.boot:spring-boot-starter-tomcat,org.apache.tomcat.embed:*'` diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml index 84c510f..13fe9d6 100644 --- a/ruoyi-admin/pom.xml +++ b/ruoyi-admin/pom.xml @@ -15,6 +15,20 @@ web服务入口 + + + tongweb-releases + TongWeb Maven Releases + https://mvn.elitescloud.com/nexus/repository/maven-releases/ + + true + + + false + + + + @@ -40,6 +54,12 @@ com.ruoyi ruoyi-framework + + + org.springframework.boot + spring-boot-starter-tomcat + + @@ -58,6 +78,18 @@ com.ruoyi ruoyi-loan-pricing + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + + com.tongweb.springboot + tongweb-spring-boot-starter-3.x + 7.0.E.7 diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index 7ec4567..be8f1b0 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -1,4 +1,9 @@ # 项目相关配置 +server: + tongweb: + license: + path: classpath:license.dat + ruoyi: # 名称 name: RuoYi diff --git a/ruoyi-admin/src/main/resources/license.dat b/ruoyi-admin/src/main/resources/license.dat new file mode 100755 index 0000000..76964cd --- /dev/null +++ b/ruoyi-admin/src/main/resources/license.dat @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/CorporateLoanPricingCreateDTO.java b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/CorporateLoanPricingCreateDTO.java index 875b8e0..8164ec1 100644 --- a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/CorporateLoanPricingCreateDTO.java +++ b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/CorporateLoanPricingCreateDTO.java @@ -41,24 +41,26 @@ public class CorporateLoanPricingCreateDTO implements Serializable { @NotBlank(message = "申请金额不能为空") private String applyAmt; - @Schema(description = "贷款期限", example = "36") + @Schema(description = "还款方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "分期", allowableValues = {"分期", "不分期"}) + @NotBlank(message = "还款方式不能为空") + @Pattern(regexp = "^(分期|不分期)$", message = "还款方式必须是:分期、不分期之一") + private String repayMethod; + + @Schema(description = "借款期限(年)", requiredMode = Schema.RequiredMode.REQUIRED, example = "3") + @NotBlank(message = "贷款期限不能为空") private String loanTerm; - @Schema(description = "省农担担保贷款", example = "false") - private String isAgriGuar; - - @Schema(description = "绿色贷款", example = "true") + @Schema(description = "绿色贷款", example = "0") private String isGreenLoan; - @Schema(description = "科技型企业", example = "true") - private String isTechEnt; + @Schema(description = "贸易和建筑业企业标识", example = "0") + private String isTradeBuildEnt; - @Schema(description = "贸易和建筑业企业标识", example = "false") - private String isTradeConstruction; - - @Schema(description = "抵质押类型", example = "一类") + @Schema(description = "抵质押类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "一类", allowableValues = {"一类", "二类", "三类", "四类"}) + @NotBlank(message = "抵质押类型不能为空") + @Pattern(regexp = "^(一类|二类|三类|四类)$", message = "抵质押类型必须是:一类、二类、三类、四类之一") private String collType; - @Schema(description = "抵质押物是否三方所有", example = "false") + @Schema(description = "抵质押物是否三方所有", example = "0") private String collThirdParty; } diff --git a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/ModelInvokeDTO.java b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/ModelInvokeDTO.java index d65bbfb..a77d866 100644 --- a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/ModelInvokeDTO.java +++ b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/ModelInvokeDTO.java @@ -79,6 +79,12 @@ public class ModelInvokeDTO { */ private String loanTerm; + /** + * 还款方式(非必填) + * 可选值:分期/不分期 + */ + private String repayMethod; + /** * 净身企业(非必填) * 可选值:true/false @@ -98,10 +104,10 @@ public class ModelInvokeDTO { private String isManufacturing; /** - * 省农担担保贷款(非必填) - * 可选值:true/false + * 绿色贷款(非必填) + * 可选值:0/1 */ - private String isAgriGuar; + private String isGreenLoan; /** * 是否纳税信用等级A级(非必填) @@ -137,7 +143,7 @@ public class ModelInvokeDTO { /** * 抵质押类型(非必填) - * 可选值:一类/二类/三类 + * 可选值:一类/二类/三类/四类 */ private String collType; @@ -167,4 +173,10 @@ public class ModelInvokeDTO { */ private String idNum; + /** + * 贸易和建筑业企业(非必填) + * 可选值:0/1 + */ + private String isTradeBuildEnt; + } diff --git a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/entity/LoanPricingWorkflow.java b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/entity/LoanPricingWorkflow.java index 8046e3c..64d47f4 100644 --- a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/entity/LoanPricingWorkflow.java +++ b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/entity/LoanPricingWorkflow.java @@ -69,6 +69,11 @@ public class LoanPricingWorkflow implements Serializable */ private String loanTerm; + /** + * 还款方式: 分期/不分期 + */ + private String repayMethod; + /** 净身企业: true/false */ private String isCleanEnt; @@ -78,24 +83,17 @@ public class LoanPricingWorkflow implements Serializable /** 制造业企业: true/false */ private String isManufacturing; - /** 省农担担保贷款: true/false */ - private String isAgriGuar; - /** * 贸易和建筑业企业标识: true/false */ - private String isTradeConstruction; + @TableField("is_trade_construction") + private String isTradeBuildEnt; /** * 绿色贷款: true/false */ private String isGreenLoan; - /** - * 科技型企业: true/false - */ - private String isTechEnt; - /** 是否纳税信用等级A级: true/false */ private String isTaxA; @@ -111,7 +109,7 @@ public class LoanPricingWorkflow implements Serializable /** 循环功能: true/false */ private String loanLoop; - /** 抵质押类型: 一线/一类/二类 */ + /** 抵质押类型: 一类/二类/三类/四类 */ private String collType; /** 抵质押物是否三方所有: true/false */ diff --git a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/entity/ModelCorpOutputFields.java b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/entity/ModelCorpOutputFields.java index c7ec5ad..f5b33d2 100644 --- a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/entity/ModelCorpOutputFields.java +++ b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/entity/ModelCorpOutputFields.java @@ -31,6 +31,8 @@ public class ModelCorpOutputFields { private String idType; // 证件号码 private String idNum; + // 还款方式 + private String repayMethod; // 基准利率 private String baseLoanRate; // 我行首贷客户 @@ -65,8 +67,6 @@ public class ModelCorpOutputFields { private String midEntEleDdc; // 中间业务_企业_水费代扣 private String midEntWaterDdc; - // 中间业务_企业_税务代扣 - private String midEntTax; // BP_中间业务 private String bpMid; // 代发工资户数 @@ -79,12 +79,12 @@ public class ModelCorpOutputFields { private String isCleanEnt; // 开立基本结算账户 private String hasSettleAcct; - // 省农担担保贷款 - private String isAgriGuar; // 绿色贷款 private String isGreenLoan; // 科技型企业 private String isTechEnt; + // 贸易和建筑业企业 + private String isTradeBuildEnt; // BP_企业客户类别 private String bpEntType; // TOTAL_BP_关联度 @@ -109,8 +109,6 @@ public class ModelCorpOutputFields { private String prinOverdue; // 利息逾期 private String interestOverdue; - // 信用卡逾期 - private String cardOverdue; // BP_灰名单与逾期 private String bpGreyOverdue; // TOTAL_BP_风险度 @@ -119,6 +117,16 @@ public class ModelCorpOutputFields { private String totalBp; // 测算利率 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; diff --git a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/LoanPricingModelService.java b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/LoanPricingModelService.java index 05517d9..e987db3 100644 --- a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/LoanPricingModelService.java +++ b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/LoanPricingModelService.java @@ -64,6 +64,10 @@ public class LoanPricingModelService { { normalizePersonalModelInvokeDTO(modelInvokeDTO); } + if ("企业".equals(loanPricingWorkflow.getCustType())) + { + normalizeCorporateModelInvokeDTO(modelInvokeDTO); + } JSONObject response = modelService.invokeModel(modelInvokeDTO); if (loanPricingWorkflow.getCustType().equals("个人")){ // 个人模型 @@ -95,6 +99,13 @@ public class LoanPricingModelService { modelInvokeDTO.setCollThirdParty(toZeroOne(modelInvokeDTO.getCollThirdParty())); } + private void normalizeCorporateModelInvokeDTO(ModelInvokeDTO modelInvokeDTO) + { + modelInvokeDTO.setCollThirdParty(toZeroOne(modelInvokeDTO.getCollThirdParty())); + modelInvokeDTO.setIsGreenLoan(toZeroOne(modelInvokeDTO.getIsGreenLoan())); + modelInvokeDTO.setIsTradeBuildEnt(toZeroOne(modelInvokeDTO.getIsTradeBuildEnt())); + } + private String toZeroOne(String value) { if ("true".equals(value) || "1".equals(value)) diff --git a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/impl/LoanPricingWorkflowServiceImpl.java b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/impl/LoanPricingWorkflowServiceImpl.java index 7c2f9a7..2a145da 100644 --- a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/impl/LoanPricingWorkflowServiceImpl.java +++ b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/impl/LoanPricingWorkflowServiceImpl.java @@ -181,7 +181,7 @@ public class LoanPricingWorkflowServiceImpl implements ILoanPricingWorkflowServi if (Objects.nonNull(modelCorpOutputFields)) { maskModelCorpOutputBasicInfo(modelCorpOutputFields); - loanPricingWorkflow.setLoanRate(modelCorpOutputFields.getCalculateRate()); + loanPricingWorkflow.setLoanRate(modelCorpOutputFields.getFinalCalculateRate()); } loanPricingWorkflowVO.setModelCorpOutputFields(modelCorpOutputFields); } diff --git a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/util/LoanPricingConverter.java b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/util/LoanPricingConverter.java index ca0715e..e463dc6 100644 --- a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/util/LoanPricingConverter.java +++ b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/util/LoanPricingConverter.java @@ -54,13 +54,11 @@ public class LoanPricingConverter { entity.setIdNum(dto.getIdNum()); entity.setGuarType(dto.getGuarType()); entity.setApplyAmt(dto.getApplyAmt()); + entity.setRepayMethod(dto.getRepayMethod()); entity.setCollType(dto.getCollType()); entity.setCollThirdParty(dto.getCollThirdParty()); - // 映射企业特有字段 - entity.setIsAgriGuar(dto.getIsAgriGuar()); entity.setIsGreenLoan(dto.getIsGreenLoan()); - entity.setIsTechEnt(dto.getIsTechEnt()); - entity.setIsTradeConstruction(dto.getIsTradeConstruction()); + entity.setIsTradeBuildEnt(dto.getIsTradeBuildEnt()); entity.setLoanTerm(dto.getLoanTerm()); return entity; } diff --git a/ruoyi-loan-pricing/src/main/resources/data/corp_output.json b/ruoyi-loan-pricing/src/main/resources/data/corp_output.json index 5752edc..080ea2d 100644 --- a/ruoyi-loan-pricing/src/main/resources/data/corp_output.json +++ b/ruoyi-loan-pricing/src/main/resources/data/corp_output.json @@ -3,66 +3,70 @@ "cost": 2267, "tokenId": "17364055486305E7F4722M8IPFWNL8TOBEB", "mappingOutputFields": { - "custIsn": "CUST20260121001", - "custType": "企业客户", - "guarType": "抵押担保", - "custName": "北京智联科技有限公司", - "idType": "营业执照", - "idNum": "91110108MA00XXXXXX", - "baseLoanRate": "3.45", - "isFirstLoan": "N", - "faithDay": "730", - "bpFirstLoan": "0", - "bpAgeLoan": "5.2", - "totalBpLoyalty": "8.5", - "balanceAvg": "5000000.00", - "loanAvg": "3000000.00", - "derivationRate": "1.8", - "totalBpContribution": "12.3", - "midEntConnect": "100000.00", - "midEntEffect": "50000.00", - "midEntInter": "80000.00", - "midEntAccept": "200000.00", - "midEntDiscount": "150000.00", - "midEntEleDdc": "30000.00", - "midEntWaterDdc": "10000.00", - "midEntTax": "40000.00", - "bpMid": "6.8", - "payroll": "200", - "invLoanAmount": "2500000.00", - "bpPayroll": "4.1", - "isCleanEnt": "Y", - "hasSettleAcct": "Y", - "isAgriGuar": "N", - "isGreenLoan": "Y", - "isTechEnt": "Y", - "bpEntType": "7.5", - "totoalBpRelevance": "9.2", - "loanTerm": "36", - "bpLoanTerm": "3.3", - "applyAmt": "5000000.00", - "bpLoanAmount": "5.8", - "collType": "房产抵押", - "collThirdParty": "N", - "bpCollateral": "4.5", - "greyCust": "N", - "prinOverdue": "N", - "interestOverdue": "N", - "cardOverdue": "N", - "bpGreyOverdue": "0", - "totoalBpRisk": "1.2", - "totalBp": "48.2", - "calculateRate": "3.932" + "custIsn": "CUST20260121001", + "custType": "企业", + "guarType": "抵押", + "custName": "北京智联科技有限公司", + "idType": "统一社会信用代码", + "idNum": "91110108MA00XXXXXX", + "repayMethod": "分期", + "loanTerm": "3", + "isFirstLoan": "0", + "faithDay": "730", + "bpFirstLoan": "0", + "bpAgeLoan": "5.2", + "totalBpLoyalty": "8.5", + "balanceAvg": "5000000.00", + "loanAvg": "3000000.00", + "derivationRate": "1.8", + "totalBpContribution": "12.3", + "midEntConnect": "1", + "midEntEffect": "1", + "midEntInter": "1", + "midEntAccept": "1", + "midEntDiscount": "1", + "midEntEleDdc": "1", + "midEntWaterDdc": "1", + "bpMid": "6.8", + "payroll": "200", + "invLoanAmount": "2500000.00", + "bpPayroll": "4.1", + "isCleanEnt": "1", + "hasSettleAcct": "1", + "isTradeBuildEnt": "0", + "isGreenLoan": "1", + "isTechEnt": "1", + "bpEntType": "7.5", + "totoalBpRelevance": "9.2", + "bpLoanTerm": "3.3", + "applyAmt": "5000000.00", + "bpLoanAmount": "5.8", + "collType": "一类", + "collThirdParty": "0", + "bpCollateral": "4.5", + "greyCust": "0", + "prinOverdue": "0", + "interestOverdue": "0", + "bpGreyOverdue": "0", + "totoalBpRisk": "1.2", + "totalBp": "48.2", + "baseLoanRate": "3.45", + "calculateRate": "3.932", + "loanRateHistory": "4.20", + "minRateProduct": "3.10", + "smoothRange": "-0.20", + "finalCalculateRate": "3.732", + "referenceRate": "3.432" }, "extensionMap": {}, "reasonMessage": "Running successfully", "bizTime": 1736405548630, "outputFields": {}, "workflowCode": "TBKH", - "orgCode": "802000", + "orgCode": "892000", "bizId": "2025010914345", "reasonCode": 200, "workflowVersion": 14, "callTime": 1736405548630, "status": 1 -} \ No newline at end of file +} diff --git a/ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/LoanPricingModelServiceTest.java b/ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/LoanPricingModelServiceTest.java index e983273..a76133b 100644 --- a/ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/LoanPricingModelServiceTest.java +++ b/ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/LoanPricingModelServiceTest.java @@ -87,4 +87,34 @@ class LoanPricingModelServiceTest !Objects.equals("张三", entity.getCustName()) && !Objects.equals("110101199001011234", entity.getIdNum()))); } + + @Test + void shouldNormalizeCorporateUploadParamsBeforeInvokeModel() + { + LoanPricingWorkflow workflow = new LoanPricingWorkflow(); + workflow.setId(3L); + workflow.setCustType("企业"); + workflow.setCustName("cipher-name"); + workflow.setIdNum("cipher-id"); + workflow.setRepayMethod("分期"); + workflow.setIsGreenLoan("true"); + workflow.setIsTradeBuildEnt("false"); + workflow.setCollThirdParty("true"); + + JSONObject response = new JSONObject(); + response.put("calculateRate", "4.15"); + + when(loanPricingWorkflowMapper.selectById(3L)).thenReturn(workflow); + when(sensitiveFieldCryptoService.decrypt("cipher-name")).thenReturn("测试公司"); + when(sensitiveFieldCryptoService.decrypt("cipher-id")).thenReturn("91330000123456789X"); + when(modelService.invokeModel(any())).thenReturn(response); + + loanPricingModelService.invokeModelAsync(3L); + + verify(modelService).invokeModel(argThat((ModelInvokeDTO dto) -> + Objects.equals("分期", dto.getRepayMethod()) + && Objects.equals("1", dto.getIsGreenLoan()) + && Objects.equals("0", dto.getIsTradeBuildEnt()) + && Objects.equals("1", dto.getCollThirdParty()))); + } } diff --git a/ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/impl/LoanPricingWorkflowServiceImplTest.java b/ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/impl/LoanPricingWorkflowServiceImplTest.java index 542fade..dac8aa5 100644 --- a/ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/impl/LoanPricingWorkflowServiceImplTest.java +++ b/ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/impl/LoanPricingWorkflowServiceImplTest.java @@ -216,14 +216,16 @@ class LoanPricingWorkflowServiceImplTest ModelCorpOutputFields corpOutputFields = new ModelCorpOutputFields(); corpOutputFields.setCalculateRate("3.932"); + corpOutputFields.setFinalCalculateRate("3.652"); when(loanPricingWorkflowMapper.selectOne(any())).thenReturn(workflow); when(modelCorpOutputFieldsMapper.selectById(22L)).thenReturn(corpOutputFields); LoanPricingWorkflowVO result = loanPricingWorkflowService.selectLoanPricingBySerialNum("C20260328001"); - assertEquals("3.932", result.getLoanPricingWorkflow().getLoanRate()); + assertEquals("3.652", result.getLoanPricingWorkflow().getLoanRate()); assertEquals("3.932", result.getModelCorpOutputFields().getCalculateRate()); + assertEquals("3.652", result.getModelCorpOutputFields().getFinalCalculateRate()); } @Test diff --git a/ruoyi-ui/package.json b/ruoyi-ui/package.json index 5fbcc8a..c857296 100644 --- a/ruoyi-ui/package.json +++ b/ruoyi-ui/package.json @@ -11,8 +11,11 @@ "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:model-output-flat-display": "node tests/model-output-flat-display.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" + "test:id-number-validation-removal": "node tests/id-number-validation-removal.test.js", + "test:corporate-create-input-params": "node tests/corporate-create-input-params.test.js", + "test:corporate-display-fields": "node tests/corporate-display-fields.test.js" }, "keywords": [ "vue", diff --git a/ruoyi-ui/src/views/loanPricing/workflow/components/CorporateCreateDialog.vue b/ruoyi-ui/src/views/loanPricing/workflow/components/CorporateCreateDialog.vue index 44f906c..4a07d18 100644 --- a/ruoyi-ui/src/views/loanPricing/workflow/components/CorporateCreateDialog.vue +++ b/ruoyi-ui/src/views/loanPricing/workflow/components/CorporateCreateDialog.vue @@ -53,8 +53,18 @@ - - + + + + + + + + + + + + @@ -62,26 +72,14 @@ 企业标识 - - - - - - - - - - - - - - + + @@ -92,9 +90,10 @@ - + + @@ -148,8 +147,6 @@ export default { const num = parseInt(value) if (isNaN(num) || num <= 0) { callback(new Error('请输入有效的贷款期限')) - } else if (num > 360) { - callback(new Error('贷款期限不能超过 360 个月')) } else { callback() } @@ -157,6 +154,9 @@ export default { } return { + loanTermOptions: [ + '1', '2', '3', '4', '5', '6', '7', '8', '9', '10' + ], submitting: false, form: { orgCode: '892000', @@ -168,10 +168,9 @@ export default { guarType: undefined, applyAmt: undefined, loanTerm: undefined, - isAgriGuar: false, + repayMethod: undefined, isGreenLoan: false, - isTechEnt: false, - isTradeConstruction: false, + isTradeBuildEnt: false, collType: undefined, collThirdParty: false }, @@ -197,7 +196,10 @@ export default { {required: true, validator: validateApplyAmt, trigger: "blur"} ], loanTerm: [ - {required: true, validator: validateLoanTerm, trigger: "blur"} + {required: true, validator: validateLoanTerm, trigger: "change"} + ], + repayMethod: [ + {required: true, message: "请选择还款方式", trigger: "change"} ], collType: [ {required: true, message: "请选择抵质押类型", trigger: "change"} @@ -235,10 +237,9 @@ export default { guarType: undefined, applyAmt: undefined, loanTerm: undefined, - isAgriGuar: false, + repayMethod: undefined, isGreenLoan: false, - isTechEnt: false, - isTradeConstruction: false, + isTradeBuildEnt: false, collType: undefined, collThirdParty: false } @@ -262,11 +263,9 @@ export default { // 转换开关值为字符串 const data = { ...this.form, - isAgriGuar: this.form.isAgriGuar ? 'true' : 'false', - isGreenLoan: this.form.isGreenLoan ? 'true' : 'false', - isTechEnt: this.form.isTechEnt ? 'true' : 'false', - isTradeConstruction: this.form.isTradeConstruction ? 'true' : 'false', - collThirdParty: this.form.collThirdParty ? 'true' : 'false' + isGreenLoan: this.form.isGreenLoan ? '1' : '0', + isTradeBuildEnt: this.form.isTradeBuildEnt ? '1' : '0', + collThirdParty: this.form.collThirdParty ? '1' : '0' } createCorporateWorkflow(data).then(response => { diff --git a/ruoyi-ui/src/views/loanPricing/workflow/components/CorporateWorkflowDetail.vue b/ruoyi-ui/src/views/loanPricing/workflow/components/CorporateWorkflowDetail.vue index fe17473..68b9ffb 100644 --- a/ruoyi-ui/src/views/loanPricing/workflow/components/CorporateWorkflowDetail.vue +++ b/ruoyi-ui/src/views/loanPricing/workflow/components/CorporateWorkflowDetail.vue @@ -19,7 +19,7 @@ {{ getTotalBp() }} - + {{ getCalculateRate() }} % @@ -80,12 +80,9 @@ {{ detailData.guarType }} {{ detailData.applyAmt }} 元 - {{ - formatBoolean(detailData.isAgriGuar) - }} - + {{ detailData.repayMethod || '-' }} {{ formatBoolean(detailData.isGreenLoan) }} - {{ formatBoolean(detailData.isTechEnt) }} + {{ formatBoolean(detailData.isTradeBuildEnt) }} {{ detailData.collType || '-' }} {{ formatBoolean(detailData.collThirdParty) @@ -162,9 +159,9 @@ export default { getTotalBp() { return this.corpOutput?.totalBp || '-' }, - /** 获取测算利率 */ + /** 获取最终测算利率 */ getCalculateRate() { - return this.corpOutput?.calculateRate || '-' + return this.corpOutput?.finalCalculateRate || '-' }, /** 设定执行利率 */ handleSetExecuteRate() { diff --git a/ruoyi-ui/src/views/loanPricing/workflow/components/ModelOutputDisplay.vue b/ruoyi-ui/src/views/loanPricing/workflow/components/ModelOutputDisplay.vue index 4aa649d..25edb02 100644 --- a/ruoyi-ui/src/views/loanPricing/workflow/components/ModelOutputDisplay.vue +++ b/ruoyi-ui/src/views/loanPricing/workflow/components/ModelOutputDisplay.vue @@ -3,11 +3,11 @@
模型输出
- +
- +
@@ -221,24 +225,6 @@ export default { default: null } }, - data() { - return { - activeTab: '' - } - }, - watch: { - custType: { - immediate: true, - handler(val) { - // 根据客户类型设置默认 tab - if (val === '个人') { - this.activeTab = 'retail-basic' - } else if (val === '企业') { - this.activeTab = 'corp-basic' - } - } - } - }, methods: { /** 格式化布尔值为中文 */ formatBoolean(value) { @@ -279,8 +265,15 @@ export default { padding: 20px; } - ::v-deep .el-tabs__header { - margin-bottom: 20px; + .output-section + .output-section { + margin-top: 24px; + } + + .section-title { + margin: 0 0 12px; + font-size: 15px; + font-weight: 500; + color: #303133; } // BP 值样式 diff --git a/sql/2026-04-16-shangyu-corporate-alignment.sql b/sql/2026-04-16-shangyu-corporate-alignment.sql new file mode 100644 index 0000000..41eb101 --- /dev/null +++ b/sql/2026-04-16-shangyu-corporate-alignment.sql @@ -0,0 +1,13 @@ +-- 上虞对公利率测算字段对齐 + +ALTER TABLE `loan_pricing_workflow` + ADD COLUMN `repay_method` varchar(20) DEFAULT NULL COMMENT '还款方式: 分期/不分期' AFTER `loan_term`; + +ALTER TABLE `model_corp_output_fields` + ADD COLUMN `repay_method` varchar(100) DEFAULT NULL COMMENT '还款方式' AFTER `id_num`, + ADD COLUMN `is_trade_build_ent` varchar(100) DEFAULT NULL COMMENT '贸易和建筑业企业' AFTER `is_tech_ent`, + ADD COLUMN `loan_rate_history` varchar(100) DEFAULT NULL COMMENT '历史利率' AFTER `calculate_rate`, + ADD COLUMN `min_rate_product` varchar(100) DEFAULT NULL COMMENT '产品最低利率下限' AFTER `loan_rate_history`, + ADD COLUMN `smooth_range` varchar(100) DEFAULT NULL COMMENT '平滑幅度' AFTER `min_rate_product`, + ADD COLUMN `final_calculate_rate` varchar(100) DEFAULT NULL COMMENT '最终测算利率' AFTER `smooth_range`, + ADD COLUMN `reference_rate` varchar(100) DEFAULT NULL COMMENT '参考利率' AFTER `final_calculate_rate`; diff --git a/sql/loan_pricing_prod_init_20260331.sql b/sql/loan_pricing_prod_init_20260331.sql index 7468d21..3ca837b 100644 --- a/sql/loan_pricing_prod_init_20260331.sql +++ b/sql/loan_pricing_prod_init_20260331.sql @@ -751,7 +751,8 @@ CREATE TABLE `loan_pricing_workflow` ( `mid_ent_ele_ddc` varchar(10) DEFAULT NULL COMMENT '中间业务_企业_电费代扣: true/false', `mid_ent_water_ddc` varchar(10) DEFAULT NULL COMMENT '中间业务_企业_水费代扣: true/false', `apply_amt` varchar(50) NOT NULL COMMENT '申请金额(元)', - `loan_term` varchar(50) DEFAULT NULL COMMENT '贷款期限', + `loan_term` varchar(50) DEFAULT NULL COMMENT '借款期限(年)', + `repay_method` varchar(20) DEFAULT NULL COMMENT '还款方式: 分期/不分期', `is_clean_ent` varchar(10) DEFAULT NULL COMMENT '净身企业: true/false', `has_settle_acct` varchar(10) DEFAULT NULL COMMENT '开立基本结算账户: true/false', `is_manufacturing` varchar(10) DEFAULT NULL COMMENT '制造业企业: true/false', @@ -764,7 +765,7 @@ CREATE TABLE `loan_pricing_workflow` ( `loan_purpose` varchar(20) DEFAULT NULL COMMENT '贷款用途: consumer-消费/business-经营', `biz_proof` varchar(10) DEFAULT NULL COMMENT '是否有经营佐证: true/false', `loan_loop` varchar(10) DEFAULT NULL COMMENT '循环功能: true/false(贷款合同是否开通循环功能)', - `coll_type` varchar(20) DEFAULT NULL COMMENT '抵质押类型: 一线/一类/二类', + `coll_type` varchar(20) DEFAULT NULL COMMENT '抵质押类型: 一类/二类/三类/四类', `coll_third_party` varchar(10) DEFAULT NULL COMMENT '抵质押物是否三方所有: true/false', `loan_rate` varchar(20) DEFAULT NULL COMMENT '贷款利率', `execute_rate` varchar(20) DEFAULT NULL COMMENT '执行利率(%)', @@ -800,6 +801,7 @@ CREATE TABLE `model_corp_output_fields` ( `cust_name` varchar(100) DEFAULT NULL COMMENT '客户名称', `id_type` varchar(100) DEFAULT NULL COMMENT '证件类型', `id_num` varchar(100) DEFAULT NULL COMMENT '证件号码', + `repay_method` varchar(100) DEFAULT NULL COMMENT '还款方式', `base_loan_rate` varchar(100) DEFAULT NULL COMMENT '基准利率', `is_first_loan` varchar(100) DEFAULT NULL COMMENT '我行首贷客户', `faith_day` varchar(100) DEFAULT NULL COMMENT '用信天数', @@ -827,6 +829,7 @@ CREATE TABLE `model_corp_output_fields` ( `is_agri_guar` varchar(100) DEFAULT NULL COMMENT '省农担担保贷款', `is_green_loan` varchar(100) DEFAULT NULL COMMENT '绿色贷款', `is_tech_ent` varchar(100) DEFAULT NULL COMMENT '科技型企业', + `is_trade_build_ent` varchar(100) DEFAULT NULL COMMENT '贸易和建筑业企业', `bp_ent_type` varchar(100) DEFAULT NULL COMMENT 'BP_企业客户类别', `totoal_bp_relevance` varchar(100) DEFAULT NULL COMMENT 'TOTAL_BP_关联度', `loan_term` varchar(100) DEFAULT NULL COMMENT '贷款期限', @@ -844,6 +847,11 @@ CREATE TABLE `model_corp_output_fields` ( `totoal_bp_risk` varchar(100) DEFAULT NULL COMMENT 'TOTAL_BP_风险度', `total_bp` varchar(100) DEFAULT NULL COMMENT '浮动BP', `calculate_rate` varchar(100) DEFAULT NULL COMMENT '测算利率', + `loan_rate_history` varchar(100) DEFAULT NULL COMMENT '历史利率', + `min_rate_product` varchar(100) DEFAULT NULL COMMENT '产品最低利率下限', + `smooth_range` varchar(100) DEFAULT NULL COMMENT '平滑幅度', + `final_calculate_rate` varchar(100) DEFAULT NULL COMMENT '最终测算利率', + `reference_rate` varchar(100) DEFAULT NULL COMMENT '参考利率', `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='客户贷款利率测算表'; diff --git a/sql/loan_pricing_schema_20260328.sql b/sql/loan_pricing_schema_20260328.sql index f02f608..8b33745 100644 --- a/sql/loan_pricing_schema_20260328.sql +++ b/sql/loan_pricing_schema_20260328.sql @@ -333,7 +333,8 @@ CREATE TABLE `loan_pricing_workflow` ( `mid_ent_ele_ddc` varchar(10) DEFAULT NULL COMMENT '中间业务_企业_电费代扣: true/false', `mid_ent_water_ddc` varchar(10) DEFAULT NULL COMMENT '中间业务_企业_水费代扣: true/false', `apply_amt` varchar(50) NOT NULL COMMENT '申请金额(元)', - `loan_term` varchar(50) DEFAULT NULL COMMENT '贷款期限', + `loan_term` varchar(50) DEFAULT NULL COMMENT '借款期限(年)', + `repay_method` varchar(20) DEFAULT NULL COMMENT '还款方式: 分期/不分期', `is_clean_ent` varchar(10) DEFAULT NULL COMMENT '净身企业: true/false', `has_settle_acct` varchar(10) DEFAULT NULL COMMENT '开立基本结算账户: true/false', `is_manufacturing` varchar(10) DEFAULT NULL COMMENT '制造业企业: true/false', @@ -346,7 +347,7 @@ CREATE TABLE `loan_pricing_workflow` ( `loan_purpose` varchar(20) DEFAULT NULL COMMENT '贷款用途: consumer-消费/business-经营', `biz_proof` varchar(10) DEFAULT NULL COMMENT '是否有经营佐证: true/false', `loan_loop` varchar(10) DEFAULT NULL COMMENT '循环功能: true/false(贷款合同是否开通循环功能)', - `coll_type` varchar(20) DEFAULT NULL COMMENT '抵质押类型: 一线/一类/二类', + `coll_type` varchar(20) DEFAULT NULL COMMENT '抵质押类型: 一类/二类/三类/四类', `coll_third_party` varchar(10) DEFAULT NULL COMMENT '抵质押物是否三方所有: true/false', `loan_rate` varchar(20) DEFAULT NULL COMMENT '贷款利率', `execute_rate` varchar(20) DEFAULT NULL COMMENT '执行利率(%)', @@ -382,6 +383,7 @@ CREATE TABLE `model_corp_output_fields` ( `cust_name` varchar(100) DEFAULT NULL COMMENT '客户名称', `id_type` varchar(100) DEFAULT NULL COMMENT '证件类型', `id_num` varchar(100) DEFAULT NULL COMMENT '证件号码', + `repay_method` varchar(100) DEFAULT NULL COMMENT '还款方式', `base_loan_rate` varchar(100) DEFAULT NULL COMMENT '基准利率', `is_first_loan` varchar(100) DEFAULT NULL COMMENT '我行首贷客户', `faith_day` varchar(100) DEFAULT NULL COMMENT '用信天数', @@ -409,6 +411,7 @@ CREATE TABLE `model_corp_output_fields` ( `is_agri_guar` varchar(100) DEFAULT NULL COMMENT '省农担担保贷款', `is_green_loan` varchar(100) DEFAULT NULL COMMENT '绿色贷款', `is_tech_ent` varchar(100) DEFAULT NULL COMMENT '科技型企业', + `is_trade_build_ent` varchar(100) DEFAULT NULL COMMENT '贸易和建筑业企业', `bp_ent_type` varchar(100) DEFAULT NULL COMMENT 'BP_企业客户类别', `totoal_bp_relevance` varchar(100) DEFAULT NULL COMMENT 'TOTAL_BP_关联度', `loan_term` varchar(100) DEFAULT NULL COMMENT '贷款期限', @@ -426,6 +429,11 @@ CREATE TABLE `model_corp_output_fields` ( `totoal_bp_risk` varchar(100) DEFAULT NULL COMMENT 'TOTAL_BP_风险度', `total_bp` varchar(100) DEFAULT NULL COMMENT '浮动BP', `calculate_rate` varchar(100) DEFAULT NULL COMMENT '测算利率', + `loan_rate_history` varchar(100) DEFAULT NULL COMMENT '历史利率', + `min_rate_product` varchar(100) DEFAULT NULL COMMENT '产品最低利率下限', + `smooth_range` varchar(100) DEFAULT NULL COMMENT '平滑幅度', + `final_calculate_rate` varchar(100) DEFAULT NULL COMMENT '最终测算利率', + `reference_rate` varchar(100) DEFAULT NULL COMMENT '参考利率', `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='客户贷款利率测算表'; diff --git a/sql/loan_pricing_workflow.sql b/sql/loan_pricing_workflow.sql index b81fa25..08c6956 100644 --- a/sql/loan_pricing_workflow.sql +++ b/sql/loan_pricing_workflow.sql @@ -14,20 +14,27 @@ CREATE TABLE `loan_pricing_workflow` ( `mid_ent_ele_ddc` varchar(10) DEFAULT NULL COMMENT '中间业务_企业_电费代扣: true/false', `mid_ent_water_ddc` varchar(10) DEFAULT NULL COMMENT '中间业务_企业_水费代扣: true/false', `apply_amt` varchar(50) NOT NULL COMMENT '申请金额(元)', + `loan_term` varchar(50) DEFAULT NULL COMMENT '借款期限(年)', + `repay_method` varchar(20) DEFAULT NULL COMMENT '还款方式: 分期/不分期', `is_clean_ent` varchar(10) DEFAULT NULL COMMENT '净身企业: true/false', `has_settle_acct` varchar(10) DEFAULT NULL COMMENT '开立基本结算账户: true/false', `is_manufacturing` varchar(10) DEFAULT NULL COMMENT '制造业企业: true/false', `is_agri_guar` varchar(10) DEFAULT NULL COMMENT '省农担担保贷款: true/false', + `is_tech_ent` varchar(10) DEFAULT NULL COMMENT '科技型企业: true/false(科技型企业最多下降5BP)', + `is_green_loan` varchar(10) DEFAULT NULL COMMENT '绿色贷款: true/false(绿色贷款最多下降5BP)', + `is_trade_construction` varchar(10) DEFAULT NULL COMMENT '贸易和建筑业企业标识: true/false(抵质押类上调20BP)', `is_tax_a` varchar(10) DEFAULT NULL COMMENT '是否纳税信用等级A级: true/false', `is_agri_leading` varchar(10) DEFAULT NULL COMMENT '是否县级及以上农业龙头企业: true/false', `loan_purpose` varchar(20) DEFAULT NULL COMMENT '贷款用途: consumer-消费/business-经营', `biz_proof` varchar(10) DEFAULT NULL COMMENT '是否有经营佐证: true/false', - `coll_type` varchar(20) DEFAULT NULL COMMENT '抵质押类型: 一线/一类/二类', + `loan_loop` varchar(10) DEFAULT NULL COMMENT '循环功能: true/false(贷款合同是否开通循环功能)', + `coll_type` varchar(20) DEFAULT NULL COMMENT '抵质押类型: 一类/二类/三类/四类', `coll_third_party` varchar(10) DEFAULT NULL COMMENT '抵质押物是否三方所有: true/false', - `loan_rate` varchar(20) NOT NULL COMMENT '贷款利率', + `loan_rate` varchar(20) DEFAULT NULL COMMENT '贷款利率', `execute_rate` varchar(20) DEFAULT NULL COMMENT '执行利率(%)', `cust_name` varchar(100) DEFAULT NULL COMMENT '客户名称', `id_type` varchar(50) DEFAULT NULL COMMENT '证件类型', + `id_num` varchar(100) DEFAULT NULL COMMENT '证件号码', `is_inclusive_finance` varchar(10) DEFAULT NULL COMMENT '是否普惠小微借款人: true/false', `create_by` varchar(64) DEFAULT '' COMMENT '创建者', `create_time` datetime DEFAULT NULL COMMENT '创建时间', diff --git a/sql/model_corp.sql b/sql/model_corp.sql index 07ec0ca..c19d7db 100644 --- a/sql/model_corp.sql +++ b/sql/model_corp.sql @@ -3,57 +3,64 @@ */ DROP TABLE IF EXISTS model_corp_output_fields; CREATE TABLE `model_corp_output_fields` ( - `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '自增主键ID', - `cust_isn` VARCHAR(100) COMMENT '客户内码', - `cust_type` VARCHAR(100) COMMENT '客户类型', - `guar_type` VARCHAR(100) COMMENT '担保方式', - `cust_name` VARCHAR(100) COMMENT '客户名称', - `id_type` VARCHAR(100) COMMENT '证件类型', - `id_num` VARCHAR(100) COMMENT '证件号码', - `base_loan_rate` VARCHAR(100) COMMENT '基准利率', - `is_first_loan` VARCHAR(100) COMMENT '我行首贷客户', - `faith_day` VARCHAR(100) COMMENT '用信天数', - `bp_first_loan` VARCHAR(100) COMMENT 'BP_首贷', - `bp_age_loan` VARCHAR(100) COMMENT 'BP_贷龄', - `total_bp_loyalty` VARCHAR(100) COMMENT 'TOTAL_BP_忠诚度', - `balance_avg` VARCHAR(100) COMMENT '存款年日均', - `loan_avg` VARCHAR(100) COMMENT '贷款年日均', - `derivation_rate` VARCHAR(100) COMMENT '派生率', - `total_bp_contribution` VARCHAR(100) COMMENT 'TOTAL_BP_贡献度', - `mid_ent_connect` VARCHAR(100) COMMENT '中间业务_企业_企业互联', - `mid_ent_effect` VARCHAR(100) COMMENT '中间业务_企业_有效价值客户', - `mid_ent_inter` VARCHAR(100) COMMENT '中间业务_企业_国际业务', - `mid_ent_accept` VARCHAR(100) COMMENT '中间业务_企业_承兑', - `mid_ent_discount` VARCHAR(100) COMMENT '中间业务_企业_贴现', - `mid_ent_ele_ddc` VARCHAR(100) COMMENT '中间业务_企业_电费代扣', - `mid_ent_water_ddc` VARCHAR(100) COMMENT '中间业务_企业_水费代扣', - `mid_ent_tax` VARCHAR(100) COMMENT '中间业务_企业_税务代扣', - `bp_mid` VARCHAR(100) COMMENT 'BP_中间业务', - `payroll` VARCHAR(100) COMMENT '代发工资户数', - `inv_loan_amount` VARCHAR(100) COMMENT '存量贷款余额', - `bp_payroll` VARCHAR(100) COMMENT 'BP_代发工资', - `is_clean_ent` VARCHAR(100) COMMENT '净身企业', - `has_settle_acct` VARCHAR(100) COMMENT '开立基本结算账户', - `is_agri_guar` VARCHAR(100) COMMENT '省农担担保贷款', - `is_green_loan` VARCHAR(100) COMMENT '绿色贷款', - `is_tech_ent` VARCHAR(100) COMMENT '科技型企业', - `bp_ent_type` VARCHAR(100) COMMENT 'BP_企业客户类别', - `totoal_bp_relevance` VARCHAR(100) COMMENT 'TOTAL_BP_关联度', - `loan_term` VARCHAR(100) COMMENT '贷款期限', - `bp_loan_term` VARCHAR(100) COMMENT 'BP_贷款期限', - `apply_amt` VARCHAR(100) COMMENT '申请金额', - `bp_loan_amount` VARCHAR(100) COMMENT 'BP_贷款额度', - `coll_type` VARCHAR(100) COMMENT '抵质押类型', - `coll_third_party` VARCHAR(100) COMMENT '抵质押物是否三方所有', - `bp_collateral` VARCHAR(100) COMMENT 'BP_抵押物', - `grey_cust` VARCHAR(100) COMMENT '灰名单客户', - `prin_overdue` VARCHAR(100) COMMENT '本金逾期', - `interest_overdue` VARCHAR(100) COMMENT '利息逾期', - `card_overdue` VARCHAR(100) COMMENT '信用卡逾期', - `bp_grey_overdue` VARCHAR(100) COMMENT 'BP_灰名单与逾期', - `totoal_bp_risk` VARCHAR(100) COMMENT 'TOTAL_BP_风险度', - `total_bp` VARCHAR(100) COMMENT '浮动BP', - `calculate_rate` VARCHAR(100) COMMENT '测算利率', - `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='客户贷款利率测算表'; \ No newline at end of file + `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '自增主键ID', + `cust_isn` VARCHAR(100) COMMENT '客户内码', + `cust_type` VARCHAR(100) COMMENT '客户类型', + `guar_type` VARCHAR(100) COMMENT '担保方式', + `cust_name` VARCHAR(100) COMMENT '客户名称', + `id_type` VARCHAR(100) COMMENT '证件类型', + `id_num` VARCHAR(100) COMMENT '证件号码', + `repay_method` VARCHAR(100) COMMENT '还款方式', + `base_loan_rate` VARCHAR(100) COMMENT '基准利率', + `is_first_loan` VARCHAR(100) COMMENT '我行首贷客户', + `faith_day` VARCHAR(100) COMMENT '用信天数', + `bp_first_loan` VARCHAR(100) COMMENT 'BP_首贷', + `bp_age_loan` VARCHAR(100) COMMENT 'BP_贷龄', + `total_bp_loyalty` VARCHAR(100) COMMENT 'TOTAL_BP_忠诚度', + `balance_avg` VARCHAR(100) COMMENT '存款年日均', + `loan_avg` VARCHAR(100) COMMENT '贷款年日均', + `derivation_rate` VARCHAR(100) COMMENT '派生率', + `total_bp_contribution` VARCHAR(100) COMMENT 'TOTAL_BP_贡献度', + `mid_ent_connect` VARCHAR(100) COMMENT '中间业务_企业_企业互联', + `mid_ent_effect` VARCHAR(100) COMMENT '中间业务_企业_有效价值客户', + `mid_ent_inter` VARCHAR(100) COMMENT '中间业务_企业_国际业务', + `mid_ent_accept` VARCHAR(100) COMMENT '中间业务_企业_承兑', + `mid_ent_discount` VARCHAR(100) COMMENT '中间业务_企业_贴现', + `mid_ent_ele_ddc` VARCHAR(100) COMMENT '中间业务_企业_电费代扣', + `mid_ent_water_ddc` VARCHAR(100) COMMENT '中间业务_企业_水费代扣', + `mid_ent_tax` VARCHAR(100) COMMENT '中间业务_企业_税务代扣', + `bp_mid` VARCHAR(100) COMMENT 'BP_中间业务', + `payroll` VARCHAR(100) COMMENT '代发工资户数', + `inv_loan_amount` VARCHAR(100) COMMENT '存量贷款余额', + `bp_payroll` VARCHAR(100) COMMENT 'BP_代发工资', + `is_clean_ent` VARCHAR(100) COMMENT '净身企业', + `has_settle_acct` VARCHAR(100) COMMENT '开立基本结算账户', + `is_agri_guar` VARCHAR(100) COMMENT '省农担担保贷款', + `is_green_loan` VARCHAR(100) COMMENT '绿色贷款', + `is_tech_ent` VARCHAR(100) COMMENT '科技型企业', + `is_trade_build_ent` VARCHAR(100) COMMENT '贸易和建筑业企业', + `bp_ent_type` VARCHAR(100) COMMENT 'BP_企业客户类别', + `totoal_bp_relevance` VARCHAR(100) COMMENT 'TOTAL_BP_关联度', + `loan_term` VARCHAR(100) COMMENT '借款期限', + `bp_loan_term` VARCHAR(100) COMMENT 'BP_贷款期限', + `apply_amt` VARCHAR(100) COMMENT '申请金额', + `bp_loan_amount` VARCHAR(100) COMMENT 'BP_贷款额度', + `coll_type` VARCHAR(100) COMMENT '抵质押类型', + `coll_third_party` VARCHAR(100) COMMENT '抵质押物是否三方所有', + `bp_collateral` VARCHAR(100) COMMENT 'BP_抵押物', + `grey_cust` VARCHAR(100) COMMENT '灰名单客户', + `prin_overdue` VARCHAR(100) COMMENT '本金逾期', + `interest_overdue` VARCHAR(100) COMMENT '利息逾期', + `card_overdue` VARCHAR(100) COMMENT '信用卡逾期', + `bp_grey_overdue` VARCHAR(100) COMMENT 'BP_灰名单与逾期', + `totoal_bp_risk` VARCHAR(100) COMMENT 'TOTAL_BP_风险度', + `total_bp` VARCHAR(100) COMMENT '浮动BP', + `calculate_rate` VARCHAR(100) COMMENT '测算利率', + `loan_rate_history` VARCHAR(100) COMMENT '历史利率', + `min_rate_product` VARCHAR(100) COMMENT '产品最低利率下限', + `smooth_range` VARCHAR(100) COMMENT '平滑幅度', + `final_calculate_rate` VARCHAR(100) COMMENT '最终测算利率', + `reference_rate` VARCHAR(100) COMMENT '参考利率', + `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='客户贷款利率测算表'; diff --git a/tongweb/2026-04-16-TongWeb接入全流程通用指南.md b/tongweb/2026-04-16-TongWeb接入全流程通用指南.md new file mode 100644 index 0000000..1c7d131 --- /dev/null +++ b/tongweb/2026-04-16-TongWeb接入全流程通用指南.md @@ -0,0 +1,410 @@ +# TongWeb接入全流程通用指南 + +## 1. 适用场景 + +本文档用于指导 Spring Boot 2.x 项目接入东方通 TongWeb 内嵌容器,适用于以下场景: + +- 现有项目默认使用 Spring Boot 内嵌 Tomcat。 +- 需要切换为 TongWeb 自启动运行。 +- 需要将 TongWeb license 文件随应用一起打包。 +- 需要沉淀一套可以迁移到其他项目的标准接入步骤。 + +本文以本仓库的接入经验为基础,输出的是一套可复用流程,而不是只面向当前项目的零散记录。 + +## 2. 前置准备 + +接入前需要准备以下信息: + +### 2.1 TongWeb Starter 依赖 + +当前使用的依赖坐标: + +```xml + + com.tongweb.springboot + tongweb-spring-boot-starter-2.x + 7.0.E.7 + +``` + +### 2.2 Maven 仓库 + +如果项目默认只配了 Maven Central 或阿里云公共仓库,TongWeb 依赖通常无法直接解析,需要补充 TongWeb 仓库: + +```xml + + + tongweb-releases + TongWeb Maven Releases + https://mvn.elitescloud.com/nexus/repository/maven-releases/ + + true + + + false + + + +``` + +### 2.3 License 文件 + +需要一份可用的 TongWeb license 文件,例如: + +- `Tongweb_license.dat` + +建议确认以下信息: + +- 许可证版本是否与目标 TongWeb 版本一致。 +- 许可证是否仍在有效期内。 +- 许可证是否允许当前部署规模使用。 + +## 3. 接入总流程 + +TongWeb 接入建议按下面顺序执行: + +1. 确认项目里是谁引入了默认 Tomcat。 +2. 排除默认 Tomcat 依赖。 +3. 引入 TongWeb Starter。 +4. 把 license 文件放入 `resources`。 +5. 在 `application.yml` 中增加 TongWeb 配置。 +6. 执行构建、依赖树、产物检查和启动验证。 +7. 根据日志处理依赖解析、license 不匹配、配置冲突等问题。 + +## 4. 依赖改造 + +### 4.1 找出默认 Tomcat 来源 + +很多项目不是在启动模块直接声明 `spring-boot-starter-web`,而是通过公共框架模块间接引入。因此第一步必须先查清默认 Tomcat 的入口来源。 + +例如: + +```xml + + org.springframework.boot + spring-boot-starter-web + +``` + +如果它出现在公共框架模块里,实际排除 Tomcat 时通常要在应用启动模块对该依赖做 `exclusion`。 + +### 4.2 排除默认 Tomcat + +推荐在最终启动模块中对上游框架模块做排除,避免默认内嵌 Tomcat 和 TongWeb 同时进入运行时: + +```xml + + com.xxx + project-framework + + + org.springframework.boot + spring-boot-starter-tomcat + + + +``` + +### 4.3 引入 TongWeb Starter + +在最终启动模块增加 TongWeb Starter: + +```xml + + com.tongweb.springboot + tongweb-spring-boot-starter-2.x + 7.0.E.7 + +``` + +### 4.4 资源打包 + +如果项目资源打包规则比较严格,建议显式保留 `resources` 配置,避免 `.dat` 文件没有进入产物: + +```xml + + + + src/main/resources + false + + **/* + + + + +``` + +## 5. License 文件接入 + +### 5.1 放置路径 + +将 TongWeb license 文件放到: + +```text +src/main/resources/Tongweb_license.dat +``` + +建议直接随项目源码管理,便于构建产物统一携带。 + +### 5.2 命名原则 + +配置中的文件名必须与实际资源名完全一致。例如资源名是: + +```text +Tongweb_license.dat +``` + +那么配置里也必须写: + +```text +classpath:Tongweb_license.dat +``` + +不要一个地方写 `license.dat`,另一个地方写 `Tongweb_license.dat`,否则运行时会直接出现 license 读取失败。 + +## 6. 配置接入 + +建议把 TongWeb 配置统一放到 `application.yml` 中,便于其他项目直接复用,而不是散落到多个环境文件。 + +推荐配置如下: + +```yml +server: + tongweb: + license: + path: classpath:Tongweb_license.dat +``` + +如果项目本身已经有 `server` 节点,直接挂到其下即可,不需要额外拆配置文件。 + +## 7. 构建与验证 + +接入完成后,至少执行下面几类验证。 + +### 7.1 依赖解析验证 + +```bash +mvn -pl ruoyi-admin -am package -DskipTests +``` + +预期: + +- TongWeb 依赖能够正常下载。 +- 项目可以正常构建。 + +### 7.2 产物检查 + +```bash +jar tf ruoyi-admin/target/ruoyi-admin.jar | rg 'Tongweb_license.dat|tongweb' +``` + +预期: + +- `Tongweb_license.dat` 已进入 `BOOT-INF/classes/` +- TongWeb 相关 jar 已进入 `BOOT-INF/lib/` + +### 7.3 依赖树检查 + +```bash +mvn -pl ruoyi-admin dependency:tree '-Dincludes=com.tongweb.springboot:*,com.tongweb:*,org.apache.tomcat.embed:*' +``` + +预期: + +- 能看到 TongWeb Starter 及相关依赖。 +- 默认 `spring-boot-starter-tomcat` 不应再作为主依赖链出现。 + +注意: + +- 某些项目中仍可能看到 `tomcat-embed-el`,它可能来自 `spring-boot-starter-validation` 等其他依赖。 +- 是否需要继续清理,最终以实际启动结果为准。 + +### 7.4 启动验证 + +建议从应用模块目录直接执行: + +```bash +mvn -f ruoyi-admin/pom.xml spring-boot:run -Dspring-boot.run.profiles=dev +``` + +这样可以避免从聚合工程根目录调用时,Maven 把插件错误落到父 `pom` 上。 + +验证重点: + +- 应用是否成功启动。 +- TongWeb License SDK 日志是否出现。 +- 端口是否成功监听。 +- 是否出现 TongWeb 与 Tomcat 的容器冲突报错。 + +### 7.5 启动后进程清理 + +如果是本地验证,结束测试后需要手动关闭 Java 进程,避免残留服务继续占用端口。 + +例如: + +```bash +lsof -nP -iTCP:63310 -sTCP:LISTEN +kill +``` + +## 8. 推荐自动化测试 + +如果项目有测试体系,建议至少补两类测试。 + +### 8.1 资源存在性测试 + +验证 license 文件能否从 classpath 读取: + +```java +assertNotNull( + TongWebLicenseResourceTest.class.getClassLoader().getResource("Tongweb_license.dat")); +``` + +### 8.2 配置存在性测试 + +验证 `application.yml` 中是否存在: + +```text +server.tongweb.license.path +``` + +这样可以避免后续重构时把 TongWeb 配置误删。 + +## 9. 常见问题 + +### 9.1 TongWeb 依赖下载失败 + +典型现象: + +- Maven 提示找不到 `tongweb-spring-boot-starter-2.x` + +原因: + +- 项目只配置了公共仓库,没有配置 TongWeb 专用仓库。 + +处理方式: + +- 补充 TongWeb Maven 仓库。 + +### 9.2 `spring-boot:run` 找不到插件 + +典型现象: + +- `No plugin found for prefix 'spring-boot'` + +处理方式: + +- 改为从子模块目录执行,或者用 `-f ruoyi-admin/pom.xml` 指向具体模块。 + +### 9.3 `spring-boot:run` 落到父工程 + +典型现象: + +- `Unable to find a suitable main class` + +原因: + +- Spring Boot 插件被执行在聚合父 `pom` 上。 + +处理方式: + +- 使用: + +```bash +mvn -f ruoyi-admin/pom.xml spring-boot:run +``` + +### 9.4 License 不匹配或已过期 + +典型现象: + +- 版本号不匹配告警 +- 有效期已过期 + +这类问题说明 TongWeb 配置链路通常已经生效,真正的问题是授权文件本身不适配当前环境。 + +处理方式: + +- 更换与目标 TongWeb 版本一致、且仍在有效期内的 license 文件。 + +### 9.5 项目里仍保留 `server.tomcat.*` + +如果项目原先已有: + +```yml +server: + tomcat: + ... +``` + +建议先不要大规模重构。 + +处理策略: + +- 若 TongWeb 启动时仅忽略这些配置,则先保留。 +- 只有当日志明确指出这些配置导致启动失败时,再做最小必要调整。 + +## 10. 可复制模板 + +### 10.1 `pom.xml` 最小改造模板 + +```xml + + com.xxx + project-framework + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + + com.tongweb.springboot + tongweb-spring-boot-starter-2.x + 7.0.E.7 + +``` + +### 10.2 `application.yml` 模板 + +```yml +server: + tongweb: + license: + path: classpath:Tongweb_license.dat +``` + +### 10.3 目录模板 + +```text +src/main/resources/Tongweb_license.dat +``` + +## 11. 最终检查清单 + +在其他项目复用时,可以按下面清单逐项确认: + +- 是否已确认默认 Tomcat 的引入来源 +- 是否已排除 `spring-boot-starter-tomcat` +- 是否已引入 TongWeb Starter +- 是否已配置 TongWeb Maven 仓库 +- 是否已将 `Tongweb_license.dat` 放入 `src/main/resources` +- 是否已在 `application.yml` 中加入 `server.tongweb.license.path` +- 是否已通过构建验证 +- 是否已确认产物中包含 TongWeb 相关 jar 与 license 文件 +- 是否已完成启动验证 +- 是否已确认 license 版本、有效期和授权范围可用 + +## 12. 结论 + +TongWeb 接入本质上只包含四件事: + +- 替换默认内嵌容器依赖 +- 接入 TongWeb 仓库与 Starter +- 让 license 文件进入 classpath +- 用启动日志验证 TongWeb 是否真正接管运行 + +只要按这个顺序执行,TongWeb 接入通常可以用最短路径完成,且这套流程可以直接迁移到其他 Spring Boot 项目中。 diff --git a/tongweb/license.dat b/tongweb/license.dat new file mode 100755 index 0000000..76964cd --- /dev/null +++ b/tongweb/license.dat @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/tongweb_63310.properties b/tongweb_63310.properties new file mode 100644 index 0000000..2ee39c0 --- /dev/null +++ b/tongweb_63310.properties @@ -0,0 +1,15 @@ +#TongTech License properties +#Thu Apr 16 16:56:43 CST 2026 +application.location=/Users/wkc/Desktop/loan-pricing/loan-pricing +license.create.date=2024-12-10 +license.customer.name=\u6D59\u6C5F\u519C\u6751\u5546\u4E1A\u8054\u5408\u94F6\u884C\u80A1\u4EFD\u6709\u9650\u516C\u53F8 +license.end.date=-1 +license.extern.properties.name=validateType,order_number,license_info +license.extern.properties.value=file,2024-2121,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 +license.file.content=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 +license.file.path=classpath\:license.dat +license.max.number=-1 +license.project.name=\u6D59\u6C5F\u519C\u6751\u5546\u4E1A\u8054\u5408\u94F6\u884C\u80A1\u4EFD\u6709\u9650\u516C\u53F8\u5173\u4E8E\u56FD\u4EA7\u5316\u5E94\u7528\u670D\u52A1\u5668\u4E2D\u95F4\u4EF6\u91C7\u8D2D +license.type=release +license.validate.type=file +server.number=7.0.E.7