diff --git a/src/api/credit.js b/src/api/credit.js new file mode 100644 index 0000000..719f29a --- /dev/null +++ b/src/api/credit.js @@ -0,0 +1,21 @@ +import request from './request' + +// ---------------- 贷款申请(/api/credit-apply/*) ---------------- +// 说明:swagger 中同时存在 /api/loan-application/* (create-personal/create-enterprise/detail/page) +// 与本文件采用的 /api/credit-apply/* 两组平行接口。本项目统一采用 credit-apply 组,因其 +// 描述明确标注为"银行柜员录入/查询"场景且遵循与阶段4一致的"create草稿(DRAFT)+柜员update+ +// 客户端扫码confirm"三段式流程,与本管理后台定位一致;/api/loan-application/* 组用途存疑, +// 已登记于《缺失的后端接口.md》。 +export const fetchLoanApplicationListApi = (data) => request.post('/api/credit-apply/loan-application/list', data) +export const fetchLoanApplicationDetailApi = (data) => request.post('/api/credit-apply/loan-application/detail', data) +export const createPersonalLoanApplicationApi = (data) => + request.post('/api/credit-apply/personal-loan-application/create', data) +export const updatePersonalLoanApplicationApi = (data) => + request.post('/api/credit-apply/personal-loan-application/update', data) +export const createEnterpriseLoanApplicationApi = (data) => + request.post('/api/credit-apply/enterprise-loan-application/create', data) +export const updateEnterpriseLoanApplicationApi = (data) => + request.post('/api/credit-apply/enterprise-loan-application/update', data) + +// 注:confirm 接口(/api/credit-apply/loan-application/confirm)语义为"申请人微信扫码确认", +// 需短信验证码+人脸识别,属移动端客户操作流程,不在本管理后台前端实现范围,不在此导出。 diff --git a/src/constants/creditEnums.js b/src/constants/creditEnums.js new file mode 100644 index 0000000..7e813bd --- /dev/null +++ b/src/constants/creditEnums.js @@ -0,0 +1,125 @@ +// src/constants/creditEnums.js +// 授信管理(贷款申请)相关枚举字典,全部取值与中文标签均从 swagger 组件 schema 的 +// description 字段程序化提取,未做任何人工编造。 + +export const ETHNICITY_OPTIONS = [ + { value: "HAN", label: "汉族" }, + { value: "ZHUANG", label: "壮族" }, + { value: "MANCHU", label: "满族" }, + { value: "HUI", label: "回族" }, + { value: "MIAO", label: "苗族" }, + { value: "UYGHUR", label: "维吾尔族" }, + { value: "TUJIA", label: "土家族" }, + { value: "YI", label: "彝族" }, + { value: "MONGOL", label: "蒙古族" }, + { value: "TIBETAN", label: "藏族" }, + { value: "BUYI", label: "布依族" }, + { value: "DONG", label: "侗族" }, + { value: "YAO", label: "瑶族" }, + { value: "KOREAN", label: "朝鲜族" }, + { value: "BAI", label: "白族" }, + { value: "HANI", label: "哈尼族" }, + { value: "LI", label: "黎族" }, + { value: "KAZAKH", label: "哈萨克族" }, + { value: "DAI", label: "傣族" }, + { value: "SHE", label: "畲族" }, + { value: "LISU", label: "傈僳族" }, + { value: "GELAO", label: "仡佬族" }, + { value: "DONGXIANG", label: "东乡族" }, + { value: "LAHU", label: "拉祜族" }, + { value: "WA", label: "佤族" }, + { value: "SHUI", label: "水族" }, + { value: "NAXI", label: "纳西族" }, + { value: "QIANG", label: "羌族" }, + { value: "TU", label: "土族" }, + { value: "XIBE", label: "锡伯族" }, + { value: "KYRGYZ", label: "柯尔克孜族" }, + { value: "JINGPO", label: "景颇族" }, + { value: "DAUR", label: "达斡尔族" }, + { value: "MULAM", label: "仫佬族" }, + { value: "BLANG", label: "布朗族" }, + { value: "SALAR", label: "撒拉族" }, + { value: "MAONAN", label: "毛南族" }, + { value: "GILIM", label: "吉尔吉斯族" }, + { value: "TAO", label: "塔吉克族" }, + { value: "PUMI", label: "普米族" }, + { value: "ACHANG", label: "阿昌族" }, + { value: "NU", label: "怒族" }, + { value: "EWE", label: "鄂温克族" }, + { value: "DEANG", label: "德昂族" }, + { value: "BONAN", label: "保安族" }, + { value: "RUSSIAN", label: "俄罗斯族" }, + { value: "YUGUR", label: "裕固族" }, + { value: "UZBEK", label: "乌兹别克族" }, + { value: "MONBA", label: "门巴族" }, + { value: "OROCHEN", label: "鄂伦春族" }, + { value: "DERUNG", label: "独龙族" }, + { value: "HEZHENG", label: "赫哲族" }, + { value: "GAOSHAN", label: "高山族" }, + { value: "LOP", label: "珞巴族" }, + { value: "JINO", label: "基诺族" }, + { value: "OTHER", label: "其他" } +] + +export const EDUCATION_LEVEL_OPTIONS = [ + { value: "PRIMARY_SCHOOL", label: "小学" }, + { value: "JUNIOR_HIGH", label: "初中" }, + { value: "SENIOR_HIGH", label: "高中" }, + { value: "TECHNICAL_SECONDARY", label: "中专" }, + { value: "JUNIOR_COLLEGE", label: "大专" }, + { value: "BACHELOR", label: "本科" }, + { value: "MASTER", label: "硕士" }, + { value: "DOCTOR", label: "博士" }, + { value: "OTHER", label: "其他" } +] + +export const MARITAL_STATUS_OPTIONS = [ + { value: "UNMARRIED", label: "未婚" }, + { value: "MARRIED", label: "已婚" }, + { value: "DIVORCED", label: "离异" }, + { value: "WIDOWED", label: "丧偶" } +] + +export const GOODS_CATEGORY_OPTIONS = [ + { value: "SPECIAL_GOODS", label: "特殊商品" }, + { value: "GENERAL_GOODS", label: "一般商品" }, + { value: "BIG_ECOMMERCE", label: "大型电商" }, + { value: "HEAD_GOODS", label: "头部商品" }, + { value: "FUNDS", label: "资金类" }, + { value: "CONSIGNMENT", label: "寄售" }, + { value: "EQUITY", label: "权益" }, + { value: "LOGISTICS", label: "物流" } +] + +export const PAYMENT_CYCLE_OPTIONS = [ + { value: "DAY_22", label: "22天" }, + { value: "DAY_25", label: "25天" }, + { value: "DAY_30", label: "30天" }, + { value: "DAY_180", label: "180天" }, + { value: "DAY_270", label: "270天" }, + { value: "MANUAL", label: "手动" } +] + +export const EMERGENCY_CONTACT_RELATION_OPTIONS = [ + { value: "SPOUSE", label: "配偶" }, + { value: "PARENT", label: "父母" }, + { value: "CHILD", label: "子女" }, + { value: "SIBLING", label: "兄弟姐妹" }, + { value: "RELATIVE", label: "其他亲属" }, + { value: "FRIEND", label: "朋友" }, + { value: "COLLEAGUE", label: "同事" }, + { value: "OTHER", label: "其他" } +] + +export const APPLICATION_TYPE_OPTIONS = [ + { value: "PERSONAL", label: "个人贷款" }, + { value: "BUSINESS", label: "企业贷款" } +] + +export const LOAN_APPLICATION_STATUS_OPTIONS = [ + { value: "DRAFT", label: "待确认" }, + { value: "CONFIRMED", label: "已确认" }, + { value: "SUBMITTED", label: "已申请" }, + { value: "APPLY_FAILED", label: "申请失败" } +] + diff --git a/src/router/componentRegistry.js b/src/router/componentRegistry.js index c9c6e75..bb5e901 100644 --- a/src/router/componentRegistry.js +++ b/src/router/componentRegistry.js @@ -10,7 +10,8 @@ export const routePathComponentMap = { '/customer/personal': 'customer/personal/PersonalList', '/customer/enterprise': 'customer/enterprise/EnterpriseList', '/wallet/account': 'wallet/account/AccountList', - '/wallet/enterprise-open': 'wallet/enterprise-open/EnterpriseOpenList' + '/wallet/enterprise-open': 'wallet/enterprise-open/EnterpriseOpenList', + '/credit/loan-application': 'credit/loan-application/LoanApplicationList' } // 新增/编辑/查看等表单页不是后端菜单节点(不出现在侧边栏),但仍需要注册为 @@ -26,5 +27,11 @@ export const extraChildRoutes = [ { path: 'wallet/personal-open', name: 'wallet-personal-open', component: 'wallet/personal-open/PersonalOpenForm' }, { path: 'wallet/enterprise-open/create', name: 'wallet-enterprise-open-create', component: 'wallet/enterprise-open/EnterpriseOpenForm' }, { path: 'wallet/enterprise-open/edit', name: 'wallet-enterprise-open-edit', component: 'wallet/enterprise-open/EnterpriseOpenForm' }, - { path: 'wallet/enterprise-open/detail', name: 'wallet-enterprise-open-detail', component: 'wallet/enterprise-open/EnterpriseOpenForm' } + { path: 'wallet/enterprise-open/detail', name: 'wallet-enterprise-open-detail', component: 'wallet/enterprise-open/EnterpriseOpenForm' }, + { path: 'credit/loan-application/personal/create', name: 'credit-loan-personal-create', component: 'credit/loan-application/PersonalLoanForm' }, + { path: 'credit/loan-application/personal/edit', name: 'credit-loan-personal-edit', component: 'credit/loan-application/PersonalLoanForm' }, + { path: 'credit/loan-application/personal/detail', name: 'credit-loan-personal-detail', component: 'credit/loan-application/PersonalLoanForm' }, + { path: 'credit/loan-application/enterprise/create', name: 'credit-loan-enterprise-create', component: 'credit/loan-application/EnterpriseLoanForm' }, + { path: 'credit/loan-application/enterprise/edit', name: 'credit-loan-enterprise-edit', component: 'credit/loan-application/EnterpriseLoanForm' }, + { path: 'credit/loan-application/enterprise/detail', name: 'credit-loan-enterprise-detail', component: 'credit/loan-application/EnterpriseLoanForm' } ] diff --git a/src/views/credit/loan-application/EnterpriseLoanForm.vue b/src/views/credit/loan-application/EnterpriseLoanForm.vue new file mode 100644 index 0000000..2be5f49 --- /dev/null +++ b/src/views/credit/loan-application/EnterpriseLoanForm.vue @@ -0,0 +1,700 @@ + + + + + + + diff --git a/src/views/credit/loan-application/LoanApplicationList.vue b/src/views/credit/loan-application/LoanApplicationList.vue new file mode 100644 index 0000000..4acfd31 --- /dev/null +++ b/src/views/credit/loan-application/LoanApplicationList.vue @@ -0,0 +1,135 @@ + + + + + diff --git a/src/views/credit/loan-application/PersonalLoanForm.vue b/src/views/credit/loan-application/PersonalLoanForm.vue new file mode 100644 index 0000000..2f413d9 --- /dev/null +++ b/src/views/credit/loan-application/PersonalLoanForm.vue @@ -0,0 +1,493 @@ + + + + + + + diff --git a/缺失的后端接口.md b/缺失的后端接口.md index f141039..0b43745 100644 --- a/缺失的后端接口.md +++ b/缺失的后端接口.md @@ -151,6 +151,16 @@ | `POST enterprise-open-application/update` | `UpdateEnterpriseAccountOpenApplicationBto`,**要求 `id`(int64)** | | `POST enterprise-bank-card/list` / `bind` / `unbind` | 企业绑卡管理三件套,字段结构同个人绑卡但用 `primaryAccount`/`accountProperty` | +### 1.12 授信管理 —— 贷款申请(`/api/credit-apply/*`) + +| 接口 | 说明 | +| --- | --- | +| `POST credit-apply/loan-application/list` | 柜员分页查询,入参仅支持 `loanApplicationId/applicationStatus/applicationType/customerName/createDateStart/createDateEnd`,响应 `records: LoanApplicationVo[]` | +| `POST credit-apply/loan-application/detail` | `{loanApplicationId}`,响应 `LoanApplicationDetailVo`(个人/企业字段混合于同一模型,约60余字段) | +| `POST credit-apply/personal-loan-application/create` / `update` | 个人贷款申请草稿创建/修改(仅 DRAFT 可改),响应 `data` 为 `loanApplicationId` 字符串 | +| `POST credit-apply/enterprise-loan-application/create` / `update` | 企业贷款申请草稿创建/修改,响应 `CreateEnterpriseLoanDraftResultVo` | +| `POST credit-apply/loan-application/confirm` | 申请人微信扫码确认(短验+人脸识别),移动端流程,不在本项目前端范围 | + --- ## Part 2:待后端确认 / 建议补充事项 @@ -213,3 +223,24 @@ 25. **企业开户申请受益人信息 `enterpriseAccountOpenApplicationBeneficiaryBtoList` 是否支持多条受益人 在 `update` 时的增删语义(全量替换 vs 增量)未在 swagger 说明**:前端当前只支持维护单条受益人信息, 提交时整体覆盖该数组,若产品侧需要多受益人管理,需后端明确该数组的更新语义。 +26. **贷款申请存在两组平行接口 `/api/loan-application/*` 与 `/api/credit-apply/*`**:前者(`create-personal` + `create-enterprise`/`detail`/`page`)与后者(`personal-loan-application/create`等)字段结构不同、 + 用途描述均不完整,前端已选用后者(`credit-apply` 组,描述明确标注"银行柜员"场景且具备 + DRAFT→CONFIRMED→SUBMITTED 状态机,与阶段4风格一致),前者暂未使用,建议后端确认是否为废弃接口或 + 说明二者分工,避免维护两套语义重叠的接口。 +27. **个人贷款申请草稿 `CreatePersonalLoanApplicationDraftBto` 不含 `customerId`/账户号(钱包账号)字段**: + 与企业贷款草稿 `CreateEnterpriseLoanDraftBto`(含 `customerId`+`accountNo`)不对称,个人贷款申请无法 + 与具体客户ID、具体钱包账号建立强关联,选择客户仅能回填 `customerName`/`phoneNo`/`permanentAddress` + 三个文本字段,不产生外键关系,与需求文档"贷款钱包仅展示申请人已开立的钱包"的描述存在能力缺口, + 建议后端为个人贷款草稿补充 `customerId`/`accountNo` 字段。 +28. **贷款产品(`loanProductCode`)无独立的列表/字典查询接口**:前端改为柜员手动输入产品编号文本框, + 无法做下拉选择与合法性校验,建议后端补充贷款产品字典查询接口。 +29. **企业贷款草稿字段 `customerType` 无 enum 约束说明**:前端按项目既有命名习惯猜测传值 `'ENTERPRISE'`, + 需后端确认合法取值(可能是 `'ENTERPRISE'`/`'BUSINESS'`/`'企业'` 等其他形式)。 +30. **贷款申请没有"按企业客户查询其已开立钱包账号"的专用接口**:前端改为选定企业客户后,调用通用的 + `wallet-account/page` 按 `accountName`(企业名称文本)模糊匹配钱包账户列表供人工选择,若同名不同企业 + 或企业名称与钱包账户名称不完全一致,可能匹配不到或匹配错误,建议后端补充按 `customerId` 精确查询 + 钱包账号的专用接口。 +31. **法定代表人/配偶相关字段(`legalPersonEducation`/`legalPersonMarital`/`legalPersonNationality`/ + `legalPersonGender`/`spouseGender` 等)均为无枚举约束的纯字符串**:前端为提升可用性复用个人贷款 + 对应枚举的取值域渲染下拉框,但后端未做强校验,实际入库是否要求严格匹配以实测为准。