Compare commits

...

51 Commits

Author SHA1 Message Date
hz
43b31ca8ca Merge branch 'dev-local' into dev-new 2025-12-19 18:08:45 +08:00
hz
b01ea6a0bf feat(underwriting): 新增数据收集基础信息和险种信息组件
- 新增 DataCollectionBaseInformation 组件用于收集用户基础信息
- 新增 DataCollectionRiskInformation 组件用于选择险种信息
- 重构 UnderwritingDataCollection 页面,将基础信息和险种信息抽离为独立组件
- 更新 UnderwritingCollectionMedias 组件权限控制逻辑
- 移除页面内冗余的字段选择器和相关方法
- 添加险种信息类型定义文件
2025-12-19 18:08:27 +08:00
hz
a41708e473 feat(underwriting): 新增数据收集基础信息和险种信息组件
- 新增 DataCollectionBaseInformation 组件用于收集用户基础信息
- 新增 DataCollectionRiskInformation 组件用于选择险种信息
- 重构 UnderwritingDataCollection 页面,将基础信息和险种信息抽离为独立组件
- 更新 UnderwritingCollectionMedias 组件权限控制逻辑
- 移除页面内冗余的字段选择器和相关方法
- 添加险种信息类型定义文件
2025-12-19 18:08:26 +08:00
hz
f0c0236976 feat(underwriting): 添加签名确认页面功能
- 新增 getOrderDetail API 接口定义
- 添加订单详情相关类型定义文件
- 在 SignContract.vue 中集成订单详情获取逻辑
- 引入订单详情展示相关组件
- 实现订单信息的数据绑定和计算属性
- 添加订单号路由参数处理
- 集成 Toast 提示组件用于用户体验优化
2025-12-19 18:08:26 +08:00
hz
2aa3000d00 fix(underwriting): 修复组件名称异常导致无限递归的问题 2025-12-19 18:08:25 +08:00
hz
806724d559 style(SignContractDialog): 调整对话框样式以提升视觉效果
- 修改段落缩进并增加对话框圆角样式
- 添加全局对话框边框半径设置以统一UI风格
2025-12-19 18:08:24 +08:00
hz
750d842030 feat(underwriting): 添加签署合同弹窗组件
- 引入并注册 SignContractDialog 组件
- 在模板中添加 SignContractDialog 弹窗展示逻辑
- 新增弹窗组件文件,包含标题、内容及确认按钮
- 实现弹窗关闭方法 handleEnsure
- 添加相关样式以优化弹窗显示效果
2025-12-19 18:08:24 +08:00
hz
4d684c2797 refactor(navigate): 重构路由查找逻辑以支持任意深度嵌套
- 实现递归查找路由函数,支持多层嵌套路由的定位
- 新增通过路径和名称两种方式查找路由的功能
- 添加构建完整路由路径的工具函数
- 完善路由查找相关单元测试覆盖
- 优化路径规范化处理,去除多余斜杠
- 改进错误处理逻辑,提升代码健壮性
2025-12-19 18:08:23 +08:00
hz
43596c8003 feat(underwriting): 添加信息收集页面组件权限控制
- 为 UnderwritingCollectionMedias 组件新增 disabled 属性
- 根据订单状态动态控制表单和上传组件的可操作性
- 更新 Uploader 组件最大上传数量逻辑
- 调整提交按钮显示与禁用状态判断依据
- 移除旧版 actionDisabled 属性及相关逻辑
- 新增 executePermission 方法统一管理权限配置
- 优化组件间状态传递与冻结防止篡改
2025-12-19 18:08:23 +08:00
hz
ec3475150d fix(OrderListCard): 修正订单导航逻辑与时间判断条件
- 将 handleNavigate 方法直接作为默认处理器传递
- 优化时间差计算表达式为秒数常量相乘形式
- 在路由跳转时增加传递订单状态参数
2025-12-19 18:08:23 +08:00
hz
98a4a46148 fix(underwriting card): 修复列表卡片内容是展示预制内容问题
- 修改 OrderListCard 组件,从接收 type 属性改为接收完整的 order 对象作为 info 属性
- 更新订单状态计算逻辑,使用 info.orderStatus 替代原有的 type 属性
- 调整执行按钮的状态判断逻辑,基于 info.orderStatus 进行判断
- 优化卡片底部按钮布局结构,将按钮包裹在额外的 div 容器中以改善样式控制
2025-12-19 18:08:23 +08:00
hz
263d077e01 feat(underwriting): 预添加预核保资料和签名确认页面
- 新增 DocumentInfo.vue 页面用于展示预核保资料
- 新增 SignContract.vue 页面用于签名确认
- 在路由配置中注册两个新页面路径及元信息
- 页面组件采用异步加载方式引入对应模块
- 模板中预留容器结构并默认隐藏具体内容组件
- 添加基础样式作用域防止样式污染其他组件
2025-12-19 18:08:23 +08:00
hz
9ae5edf3ee feat(ebiz/underwriting): 补充资料部分增加反显的功能
- 修改补充资料接口名称及URL路径
- 增强获取预核保订单信息的参数校验
- 扩展被保险人信息类型定义
- 调整补充资料页面数据绑定逻辑
- 优化界面布局与样式适配
- 移除不必要的粘性组件包裹结构
- 修复数据集合组件高度设置问题
2025-12-19 18:08:23 +08:00
hz
193dfdd245 fix(underwriting): 修复订单列表加载状态更新问题
- 将 this.loading 替换为 this.listState.loading 以正确更新加载状态
- 确保分页加载完成后正确设置加载完成标志
- 优化加载状态更新逻辑,避免状态错乱
2025-12-19 18:08:22 +08:00
hz
a8ec123486 fix(underwriting): 介入接口内容(待后端调整)
- 更正 fetchUnderwritingOrderInfomation 拼写为 fetchUnderwritingOrderInformation
- 将路由参数 orderNo 获取方式从 params 改为 query
- 更新组件中对返回数据结构的引用,使用 content 替代 cont
- 添加 insured 计算属性以支持双向绑定
- 调整模板结构保持代码整洁性
2025-12-19 18:08:22 +08:00
dong.ai
0faa46e909 feat: 被保人启用税收居民身份字段并修复相关逻辑 2025-12-18 16:41:53 +08:00
dong.ai
9a9e181693 fix: 调整投保人信息页面字段显示逻辑 2025-12-18 15:20:28 +08:00
dong.ai
4a6e3e55fa fix(ebiz/sale): 修改投保资料按钮显示条件并优化初始化逻辑 2025-12-17 14:23:45 +08:00
dong.ai
7274b57dea fix(ebiz/sale): 根据分支类型控制按钮显示逻辑 2025-12-17 11:07:42 +08:00
dong.ai
8511dfc162 fix(List.vue): 添加分支类型14的处理逻辑 2025-12-17 10:20:05 +08:00
hz
b4763cc5f3 feat(underwriting): 新增预核保订单删除功能并优化列表操作逻辑
- 添加删除预核保订单的 API 接口函数 deleteUnderwritingOrderByOrderNo
- 在 OrderListCard 组件中引入删除功能并实现对应的处理方法
- 根据不同订单状态动态设置操作按钮的行为和跳转路径
- 修改订单列表卡片点击事件绑定方式,提升交互体验
- 更新样式以适配新的布局结构和按钮行为
- 移除冗余的 navigateDataCollection 方法调用逻辑
- 引入 Toast 模块用于展示删除操作的结果提示
2025-12-16 15:21:31 +08:00
hz
f75d3e1dd6 fix(underwriting): 更新核保状态值为数字类型
- 将待核保状态值从 'pending' 更改为 '67'
- 将标准体状态值从 'standard' 更改为 '68'
2025-12-16 15:21:30 +08:00
hz
591e5b9a9d fix(underwriting list): 修复订单状态异常的问题,优化接口名称
- 将 API 接口 list 方法重命名为 fetchUnderwritingList
- 统一导入和调用新的接口名称
- 调整分页参数 pageSize 从 5 改为 10
- 优化 loadMore 方法中的数据解构逻辑
2025-12-16 15:21:30 +08:00
hz
4663eb8bd1 feat(underwriting): 优化影像资料上传功能
- 新增文件映射对象 filesDTOMap 管理上传文件
- 监听 filesDTOMap 变化并同步更新 medias 数据
- 修改 handleMediaUpload 方法支持传递原始文件和新文件名
- 调整 uploadIMG 方法参数以接收文件及重命名信息
- 更新模板中 Uploader 组件绑定的属性名
- 修复部分代码格式问题提升可读性
2025-12-16 15:21:29 +08:00
hz
97f94485e5 feat(underwriting): 新增预核保补充资料功能
- 新增预核保订单信息查询接口
- 新增补充额外资料提交接口
- 补充资料页面增加订单信息获取逻辑
- 路由配置支持订单号参数传递
- 数据收集组件支持补充资料模式
- 新增保险订单数据类型定义文件
- 优化数据提交流程和表单校验逻辑
- 调整组件间通信方式以支持不同场景
2025-12-16 15:21:28 +08:00
hz
63339c5d1e fix(underwriting): 修复信息填写步骤中订单号为空的问题
- 在风险信息提交时添加空字符串作为默认订单号
- 确保在信息填写阶段不会因为缺少订单号导致数据异常
2025-12-16 15:21:28 +08:00
hz
b6dd661425 feat(underwriting): 优化核保数据收集功能
- 引入 idToData 工具函数替代原有身份证校验逻辑
- 移除对 getRelatedData 和 idNoCheck 的依赖
- 重构数据提交流程,分离提交与导航逻辑
- 增强证件号码校验,支持生日与性别匹配检查
- 更新险种选择组件绑定值为标签字段
- 添加详细的函数注释与返回类型说明
- 修复提交失败后未正确返回状态的问题
2025-12-16 15:21:28 +08:00
hz
4b20bd678d feat(unwriting): 完善预核保信息收集功能
- 新增险种选择功能,支持从接口获取主险列表
- 实现影像资料上传功能,支持文件重命名及表单提交
- 优化性别选择组件默认状态及事件触发逻辑
- 添加身份证号码校验工具函数
- 引入 saveOrder 接口用于保存预核保订单信息
- 调整字段选择器组件结构与数据绑定方式
- 修复字段选择器中风险类型选项的映射问题
- 更新出生日期选择器使用方式并移除旧确认方法
- 优化表单提交流程,增加数据验证与错误提示
- 修改证件类型选择器双向绑定逻辑以提升交互体验
2025-12-16 15:21:28 +08:00
hz
0ac3fc5405 feat(ebiz/underwriting): 更新订单列表接口并优化列表展示逻辑
- 修改订单列表接口地址与请求方式(从 GET 改为 POST)
- 重构订单列表组件的数据结构与状态管理
- 新增订单搜索功能,支持按投保人姓名查询
- 优化列表分页加载逻辑与错误处理机制
- 调整列表卡片渲染方式,绑定真实订单数据
- 移除调试用 console.log 与无用代码
- 更新模板结构以适配新数据格式与交互逻辑
2025-12-16 15:21:28 +08:00
hz
dafba738de feat(underwriting): 添加表单组件禁用状态控制
- 为 FieldSelect 组件添加 disabled 属性以控制禁用状态
- 为 SexRadio 组件添加 disabled 属性以控制禁用状态
- 在 UnderwritingDataCollection 页面中实现 actionDisabled 计算属性
- 将 disabled 属性传递给相关的表单字段组件
- 添加 handleActivePopup 方法以处理禁用状态下的弹窗激活逻辑
2025-12-16 15:21:28 +08:00
hz
ddd1bee126 feat(underwriting): 新增待核保状态并优化路由跳转逻辑
- 在 ORDER_STATUS 常量中新增 pending(待核保)状态
- 修复 navigateRouter 中 routerInfo 被覆盖的问题,使用对象展开保留原有属性
- 在 OrderList 组件中引入 ORDER_STATUS 并优化 navigateDataCollection 方法支持传递订单状态
- 更新 SupplementaryInformation 页面结构,引入 Sticky 组件优化提示信息展示
- 在 UnderwritingDataCollection 页面根据订单状态动态显示不同操作按钮及文案
- 调整页面样式确保组件布局适配新功能需求
2025-12-12 17:21:15 +08:00
hz
0d5e2b24cb feat(underwriting): 添加预核保订单列表导航功能
- 引入 navigateRouter 方法用于页面跳转
- 新增 handleNavigateToList 方法跳转至订单列表页
- 为确定按钮添加点击事件触发导航跳转
2025-12-12 17:21:15 +08:00
hz
0caaf79345 feat(ebiz/underwriting): 实现订单列表数据获取功能
- 新增 LIST_TYPE 常量定义未审核和已审核状态
- 添加 list API 接口用于获取订单预核保列表数据
- 在 OrderList 组件中引入并使用新的 list 接口
- 使用 LIST_TYPE 替换原有的字符串类型标识
- 实现 fetchListData 方法异步获取列表数据
- 更新 tabs 组件绑定值为 LIST_TYPE 对象属性
- 移除旧的 branchType 相关逻辑
- 调整组件初始化时的数据加载时机到 data 函数中
2025-12-12 14:52:34 +08:00
hz
fac7ec78df feat(underwriting): 重构订单列表页面逻辑与组件
- 移除旧的订单列表获取逻辑,替换为静态数据展示
- 更新搜索框绑定字段从 searchName 到 searchText
- 引入 ORDER_STATUS 常量用于模拟订单状态显示
- 修改 OrderListCard 组件以支持接收 type 属性并据此渲染不同状态
- 调整样式类名和结构以优化界面布局
- 删除不再使用的数据处理函数及导入模块
- 简化分页加载逻辑,目前使用定时器模拟加载效果
- 更新模板中 van-list 的循环方式以适配新数据源
2025-12-12 14:52:34 +08:00
hz
a7c5ed519a style(ebiz/underwriting): 调整页面样式和布局
- 移除 PreliminaryUnderwritingContainer 中 router-view 的 mt10 类
- 为 SupplementaryInformation 页面容器添加 mt10 类
- UnderwritingDataCollection 页面容器增加内边距类 ph15
- 基本信息标题添加上边距类 pt20
- 优化表单字段布局结构
- 为 UnderwritingDataCollection 添加自定义样式
- 设置页面容器高度为 100vh 并添加白色背景
2025-12-12 14:52:33 +08:00
hz
5d084256af fix(underwriting): 移除冗余else分支并添加卡片圆角样式
- 移除了OrderList.vue中created钩子内的冗余else分支
- 为OrderListCard.vue添加了6px的圆角样式
- 优化了条件判断逻辑,提升代码可读性
2025-12-11 15:26:14 +08:00
hz
1ad3d29cd1 feat(ebiz): 添加承保结果页面UI展示
- 引入 vant 组件库的 Image 和 Button 组件
- 添加错误提示图片和文案显示
- 实现页面布局居中对齐
- 设置背景色为白色并占满全屏
- 添加确定按钮并设置样式
- 引入评估结果图片资源
2025-12-11 15:26:13 +08:00
hz
f3a852cbc2 style(underwriting): 调整提交按钮样式
- 将提交按钮的样式从单独的组件移至容器组件
- 统一设置按钮底部距离为10px
- 设置按钮宽度为90%
- 添加水平居中变换
- 移除重复的样式定义
- 优化样式作用域穿透写法
2025-12-11 15:26:13 +08:00
hz
42088c8e81 feat(underwriting): 新增预核保订单列表卡片组件
- 添加 ORDER_STATUS 常量定义,包含标准体、问题件、拒保和延期状态
- 创建 OrderListCard 组件用于展示预核保订单信息
- 在 OrderList.vue 中引入并使用 OrderListCard 组件
- 移除 OrderList.vue 中冗余的 getAgentInfo 方法调用
- 调整 PreliminaryUnderwritingContainer.vue 样式类名
- 新增 UnderwritingResult.vue 空页面组件
- 更新 SupplementaryInformation.vue 页面样式
- 在路由配置中添加预核保结果页路由
2025-12-11 15:26:13 +08:00
hz
a8d13be189 feat(underwriting): 新增路由跳转工具函数并优化跳转逻辑
- 引入 jump 工具函数并调整其内部路由调用方式
- 新增 navigateRouter 函数用于统一管理路由跳转
- 替换原有 add 方法为 navigateDataCollection 并使用新跳转逻辑
- 移除旧有的手动清理 localStorage 的逻辑
- 优化路由查找逻辑,支持多层级 children 路由匹配
- 添加 URL 参数处理函数 processJson 以适配查询字符串拼接
2025-12-11 15:26:13 +08:00
hz
5af2c7f6bf feat(underwriting): 新增字段选择组件并优化预核保流程
- 新增 FieldSelect 组件,支持证件类型和险种类型选择
- 在预核保数据收集页面集成 FieldSelect 组件
- 移除旧的字段选择弹窗逻辑
- 更新订单列表页面样式和结构
- 调整预核保容器背景色和提交按钮样式
- 添加 UNDERWRITING_STATUS 和 FIELD_SELECT_TYPE 常量定义
- 移除冗余的权限检查和短信验证相关代码
- 简化订单列表展示逻辑
- 优化组件导入和注册方式
2025-12-11 15:26:13 +08:00
hz
b8c99ffed1 feat(ebiz): 新增预核保订单列表功能
- 添加预核保路由配置及引入相关组件
- 实现订单列表展示、搜索、分页加载功能
- 支持未审核和已审核订单的标签切换
- 实现订单详情查看、编辑、删除操作
- 添加撤单、重新支付、修改卡号等功能按钮
- 集成短信验证码验证撤单流程
- 实现获取投保资料并发送至邮箱功能
- 添加权限校验及无权限提示页面
- 优化订单状态展示及双录提示逻辑
2025-12-11 15:25:26 +08:00
勾通
5859857ddc 【FIX】修改输入框校验规则,取消提交置灰更换为提示
(cherry picked from commit 370be6db5d)
2025-12-10 15:39:36 +08:00
hz
ea2b8984d2 Merge branch 'feature/FCRS-1048投保流程优化需求' into dev-new 2025-12-05 16:22:07 +08:00
hz
8f1f3c13fc feat(sale): 新增新产品流程判断逻辑
- 添加新产品流程标识判断
- 根据标识跳转至新投保告知页面或原有页面
- 更新附件管理页面跳转逻辑
- 优化订单状态为37时的页面跳转条件判断
2025-12-05 16:21:50 +08:00
xuxinxiang
ed565ffb80 Merge branch 'feature/FCRS-1048投保流程优化需求' into dev-new 2025-12-05 13:59:40 +08:00
xuxinxiang
b8ea811ad6 修改签名后页面样式问题 2025-12-05 13:58:14 +08:00
xuxinxiang
dfb9546422 Merge branch 'feature/FCRS-1048投保流程优化需求' into dev-new 2025-12-05 11:16:44 +08:00
xuxinxiang
0edabc67cf 抄录提交和签字确定回跳页面 2025-12-05 11:15:31 +08:00
xuxinxiang
5ca5d913d4 Merge branch 'feature/FCRS-1048投保流程优化需求' into dev-new 2025-12-05 09:43:23 +08:00
xuxinxiang
46ae4f590d 修改文件为已阅读状态后,二次阅读页面的展示问题。修改投被不同人被保人无法阅读文件的问题 2025-12-05 09:42:05 +08:00
41 changed files with 3326 additions and 71 deletions

View File

@@ -84,7 +84,12 @@ export function saveInformation(data) {
}) })
} }
// 获取订单详情 /**
* 获取订单详情
* @param {{orderNo: string, [key: String] : String}} data
* @return {Promise<ApiContent>}
*/
export function getOrderDetail(data) { export function getOrderDetail(data) {
return request({ return request({
url: getUrl('/sale/order/orderDetail', 1), url: getUrl('/sale/order/orderDetail', 1),

View File

@@ -0,0 +1,64 @@
import getUrl from '@/assets/js/utils/get-url'
import request from '@/assets/js/utils/request'
// 获取培训系统中心页面
export function fetchUnderwritingList(data) {
return request({
url: getUrl('/sale/orderPreUW/orderList', 1),
method: 'post',
data
})
}
// 预核保信息保存接口
export function saveOrder(data) {
return request({
url: getUrl('/sale/orderPreUW/orderPreUW', 1),
method: 'post',
data
})
}
// 补充额外资料
export function saveSupplementaryInformation(data) {
return request({
url: getUrl('/sale/orderPreUW/orderSupplyPreUW', 1),
method: 'post',
data
})
}
// 预核保查询接口
export function fetchUnderwritingOrderInformation(orderNo) {
if (!orderNo) {
return Promise.reject('orderNo is null')
}
return request({
url: getUrl('/sale/orderPreUW/orderPreUWDetail', 1),
method: 'post',
data: { orderNo }
})
}
// 删除预核保订单
export function deleteUnderwritingOrderByOrderNo(orderNo) {
if (!orderNo) {
return Promise.reject('orderNo is null')
}
return request({
url: getUrl('/sale/orderPreUW/orderPreUWCancel', 1),
method: 'post',
data: { orderNo }
})
}
/**
* 删除预核保订单
* @param {{platform: "app"}} data
* @return {Promise<OrderRiskListResponse>}
*/
export function fetchUnderwritingOrderRiskList(data) {
return request({
url: getUrl('/sale/product/getMainRiskPreUWList', 1),
method: 'post',
data
})
}

View File

@@ -1,13 +1,17 @@
/* eslint-disable no-undef */ /* eslint-disable no-undef */
import router from '@/router'
export default function jump(options) { export default function jump(options) {
// eslint-disable // eslint-disable
if (window.WebViewJavascriptBridge && options.flag) { if (window.WebViewJavascriptBridge && options.flag) {
if (options.flag == 'h5' || if (
options.flag == 'service' || options.flag == 'h5' ||
options.flag == 'home' || options.flag == 'service' ||
options.flag == 'mine' || options.flag == 'home' ||
options.flag == 'message' || options.flag == 'mine' ||
options.flag == 'setting' ) { options.flag == 'message' ||
options.flag == 'setting'
) {
EWebBridge.webCallAppInJs('bridge', { EWebBridge.webCallAppInJs('bridge', {
flag: options.flag, flag: options.flag,
extra: options.extra extra: options.extra
@@ -23,11 +27,11 @@ export default function jump(options) {
} else { } else {
// 1:replace 2:go 默认为push // 1:replace 2:go 默认为push
if (options.routerInfo && options.routerInfo.type == '1') { if (options.routerInfo && options.routerInfo.type == '1') {
this.$router.replace(options.routerInfo) router.replace(options.routerInfo)
} else if (options.routerInfo && options.routerInfo.type == '2') { } else if (options.routerInfo && options.routerInfo.type == '2') {
this.$router.go(options.routerInfo.index || -1) router.go(options.routerInfo.index || -1)
} else if (options.routerInfo) { } else if (options.routerInfo) {
this.$router.push(options.routerInfo) router.push(options.routerInfo)
} }
} }
} }

View File

@@ -148,6 +148,20 @@
flex-direction: column; flex-direction: column;
} }
.column {
flex-direction: column;
}
.row {
flex-direction: row;
}
@for $i from 1 through 300 {
.gap-#{$i} {
gap: #{$i * 1px};
}
}
// 字体颜色 // 字体颜色
.green { .green {
color: $green !important; color: $green !important;
@@ -156,9 +170,11 @@
.red { .red {
color: $red !important; color: $red !important;
} }
.red1 { .red1 {
color: $red1 !important; color: $red1 !important;
} }
.yellow { .yellow {
color: $yellow !important; color: $yellow !important;
} }
@@ -182,8 +198,9 @@
.black { .black {
color: $black !important; color: $black !important;
} }
.ffcb6b{
color:#ffcb6b; .ffcb6b {
color: #ffcb6b;
} }
// 常用文字颜色 // 常用文字颜色
@@ -266,9 +283,11 @@
.bg-red { .bg-red {
background: $red !important; background: $red !important;
} }
.bg-red1 { .bg-red1 {
background: $red1 !important; background: $red1 !important;
} }
.bg-green-base { .bg-green-base {
background: #ddf2ef !important; background: #ddf2ef !important;
} }
@@ -335,12 +354,15 @@
.van-checkbox__icon .van-icon { .van-checkbox__icon .van-icon {
border-color: #e9332e; border-color: #e9332e;
} }
.van-checkbox__label { .van-checkbox__label {
color: #e9332e; color: #e9332e;
} }
.van-radio__icon .van-icon { .van-radio__icon .van-icon {
border-color: #e9332e; border-color: #e9332e;
} }
.van-radio__label { .van-radio__label {
color: #e9332e; color: #e9332e;
} }
@@ -350,12 +372,15 @@
.van-checkbox__icon .van-icon { .van-checkbox__icon .van-icon {
border-color: #2E4591; border-color: #2E4591;
} }
.van-checkbox__label { .van-checkbox__label {
color: #2E4591; color: #2E4591;
} }
.van-radio__icon .van-icon { .van-radio__icon .van-icon {
border-color: #2E4591; border-color: #2E4591;
} }
.van-radio__label { .van-radio__label {
color: #2E4591; color: #2E4591;
} }

View File

@@ -16,38 +16,21 @@
</div> </div>
</template> </template>
<script> <script>
import { SEX } from '@/views/ebiz/underwriting/js/const'
import { RadioGroup, Radio } from 'vant' import { RadioGroup, Radio } from 'vant'
export default { export default {
name: 'select-radio', name: 'select-radio',
props: { props: {
value: { value: {
type: String | Boolean,
default: '0'
},
label: {
type: String, type: String,
default: '' default: SEX.male
}, },
color: { label: { type: String, default: '' },
type: String, color: { type: String, default: '' },
default: '' type: { type: String, default: 'danger' },
}, radios: { type: Array, default: () => [] },
type: { required: { type: Boolean, default: true },
type: String, disabled: { type: Boolean, default: false }
default: 'danger'
},
radios: {
type: Array,
default: []
},
required: {
type: Boolean,
default: true
},
disabled: {
type: Boolean,
default: false
}
}, },
data() { data() {
return {} return {}
@@ -76,7 +59,6 @@ export default {
} }
} }
</script> </script>
<style lang="scss"></style>
<style lang="scss" scoped> <style lang="scss" scoped>
.sex-radio { .sex-radio {
.radio-area { .radio-area {

View File

@@ -58,6 +58,7 @@ import saleFlowImprove from './saleFlowImprove'
// // 产品流程优化 // // 产品流程优化
import {improveProduct as productFlowImprove} from './productFlowImprove' import {improveProduct as productFlowImprove} from './productFlowImprove'
import { underwriting } from '@/router/ebiz/underwriting'
export default [ export default [
...proposal, ...proposal,
...sale, ...sale,
@@ -99,5 +100,7 @@ export default [
...GBC, ...GBC,
...healthInsuranceRenewal, ...healthInsuranceRenewal,
...saleFlowImprove, ...saleFlowImprove,
...productFlowImprove ...productFlowImprove,
// 预核保信息
...underwriting
] //根据需要进行删减 ] //根据需要进行删减

View File

@@ -0,0 +1,49 @@
/**
* 预核保路由信息
* @type {import("vue-router").RouteRecord[]}
* */
export const underwriting = [
{
path: '/underwriting',
// 布局组件
component: () => import('@/views/ebiz/underwriting/PreliminaryUnderwritingContainer.vue'),
children: [
{
path: 'list',
name: 'UnderwritingOrderList',
meta: { title: '预核保订单列表' },
component: () => import('@/views/ebiz/underwriting/OrderList.vue')
},
{
path: 'data-collection',
name: 'UnderwritingDataCollection',
meta: { title: '信息录入' },
component: () => import('@/views/ebiz/underwriting/UnderwritingDataCollection.vue')
},
{
path: 'supplementary-information',
name: 'UnderwritingSupplementaryInformation',
meta: { title: '补传资料' },
component: () => import('@/views/ebiz/underwriting/SupplementaryInformation.vue')
},
{
path: 'result',
name: 'UnderwritingResult',
meta: { title: '预核保结果' },
component: () => import('@/views/ebiz/underwriting/Result.vue')
},
{
path: 'contract-sign',
name: 'UnderwritingContractSign',
meta: { title: '签名确认' },
component: () => import('@/views/ebiz/underwriting/SignContract.vue')
},
{
path: 'document-info',
name: 'UnderwritingDocumentInfo',
meta: { title: '预核保资料' },
component: () => import('@/views/ebiz/underwriting/DocumentInfo.vue')
}
]
}
]

View File

@@ -167,7 +167,7 @@
maxlength="5" maxlength="5"
/> />
<van-field <van-field
v-if="Number(branchType)!==14" v-if="Number(branchType)!==14"
v-model="userInfo.avoirdupois" v-model="userInfo.avoirdupois"
label="体重(kg)" label="体重(kg)"
name="体重" name="体重"
@@ -652,7 +652,7 @@
avoirdupois: '', //体重 avoirdupois: '', //体重
// degree: '', //文化程度 // degree: '', //文化程度
medical: '1', //有无社保 medical: '1', //有无社保
taxResidentId: '', //税收居民身份 taxResidentId: '1', //税收居民身份
averageAnnualIncome: '', //平均年收入 averageAnnualIncome: '', //平均年收入
workcompany: '', //工作单位 workcompany: '', //工作单位
isAsync: 0, //是否协同工作单位 0否 1是 isAsync: 0, //是否协同工作单位 0否 1是

View File

@@ -242,7 +242,7 @@
:value.sync="userInfo.medical" :value.sync="userInfo.medical"
:disabled="isAppnt" :disabled="isAppnt"
></select-radio> ></select-radio>
<!-- <van-field <van-field
:value="userInfo.taxResidentId | idToText('taxIdentity')" :value="userInfo.taxResidentId | idToText('taxIdentity')"
readonly readonly
label="税收居民身份" label="税收居民身份"
@@ -252,7 +252,7 @@
placeholder="请选择" placeholder="请选择"
v-validate="'required'" v-validate="'required'"
@click="toSelect('5')" @click="toSelect('5')"
/> --> />
<occupation-picker <occupation-picker
:value.sync="userInfo.occupationCode" :value.sync="userInfo.occupationCode"
@@ -610,7 +610,7 @@
// authCode: '', //验证码 // authCode: '', //验证码
// degree: '', //文化程度 // degree: '', //文化程度
medical: '1', //有无社保 medical: '1', //有无社保
// taxResidentId: '', //税收居民身份 taxResidentId: '1', //税收居民身份
averageAnnualIncome: '', //平均年收入 averageAnnualIncome: '', //平均年收入
liabilitiesMoney: '', //负债金额 liabilitiesMoney: '', //负债金额
workcompany: '', //工作单位 workcompany: '', //工作单位
@@ -1035,9 +1035,10 @@
this.userInfo.degree = value.id this.userInfo.degree = value.id
}*/ else if (this.pickerType == '4') { }*/ else if (this.pickerType == '4') {
this.userInfo.socialSecurity = value.id this.userInfo.socialSecurity = value.id
} /*else if (this.pickerType == '5') { }
else if (this.pickerType == '5') {
this.userInfo.taxResidentId = value.id this.userInfo.taxResidentId = value.id
} else if (this.pickerType == '6') { } /*else if (this.pickerType == '6') {
this.userInfo.marriage = value.id this.userInfo.marriage = value.id
} */ else if ( } */ else if (
this.pickerType == '7' this.pickerType == '7'
@@ -1326,7 +1327,7 @@
this.userInfo.avoirdupois = data.weight //体重 this.userInfo.avoirdupois = data.weight //体重
// this.userInfo.degree = data.educationLevel //教育水平 // this.userInfo.degree = data.educationLevel //教育水平
this.userInfo.medical = data.socialSecurity //有无社保 this.userInfo.medical = data.socialSecurity //有无社保
// this.userInfo.taxResidentId = data.residentStatus //税收居民身份 this.userInfo.taxResidentId = data.residentStatus //税收居民身份
this.userInfo.averageAnnualIncome = data.averageYearlyIncome //平均年收入 this.userInfo.averageAnnualIncome = data.averageYearlyIncome //平均年收入
this.userInfo.workcompany = data.workUnits //工作单位 this.userInfo.workcompany = data.workUnits //工作单位
// this.userInfo.jobStatus = data.jobStatus //工作情况 // this.userInfo.jobStatus = data.jobStatus //工作情况

View File

@@ -88,7 +88,7 @@
</div> </div>
<div class="text-right mt15 "> <div class="text-right mt15 ">
<van-button round @click="goInsuredInform(order)" size="small" v-if="buttonShow == '14'" <van-button round @click="goInsuredInform(order)" size="small" v-if="branchType == '14'"
:disabled="order.emailStatus == 'disable'" class="mr5" type="danger" v-no-more-click="1000"> :disabled="order.emailStatus == 'disable'" class="mr5" type="danger" v-no-more-click="1000">
获取投保资料 获取投保资料
</van-button> </van-button>
@@ -293,16 +293,14 @@ export default {
emailForm: { email: '' }, emailForm: { email: '' },
inputShow: true, inputShow: true,
contentShow: false, contentShow: false,
buttonShow: '',
emailContent: '系统将会将投保资料发送至您录入邮箱,解压密码为投保人身份证号的后六位,请您稍后进行查看', emailContent: '系统将会将投保资料发送至您录入邮箱,解压密码为投保人身份证号的后六位,请您稍后进行查看',
} }
}, },
created() { created() {
if(this.$CacheUtils.getLocItem('branchType')) { if(this.$CacheUtils.getLocItem('branchType')) {
this.branchType = this.$CacheUtils.getLocItem('branchType') this.branchType = this.$CacheUtils.getLocItem('branchType')
}else{ }else{
this.getAgentInfo() this.getAgentInfo()
} }
}, },
mounted() { mounted() {
@@ -316,9 +314,6 @@ export default {
funcPermCheck({}).then(res => { funcPermCheck({}).then(res => {
this.isCheck = res.result this.isCheck = res.result
}) })
if (window.localStorage.getItem('branchType') == '14') {
this.buttonShow = localStorage.getItem('branchType')
}
}, },
methods: { methods: {
async getAgentInfo() { async getAgentInfo() {
@@ -564,6 +559,9 @@ export default {
if (this.$CacheUtils.getLocItem('branchType') == '13') { if (this.$CacheUtils.getLocItem('branchType') == '13') {
thisbranchType = this.$CacheUtils.getLocItem('branchType') thisbranchType = this.$CacheUtils.getLocItem('branchType')
} }
if (this.$CacheUtils.getLocItem('branchType') == '14') {
thisbranchType = this.$CacheUtils.getLocItem('branchType')
}
window.localStorage.clear() window.localStorage.clear()
this.$CacheUtils.setLocItem('token', thisToken) this.$CacheUtils.setLocItem('token', thisToken)
if (thisbranchType) { if (thisbranchType) {
@@ -583,7 +581,8 @@ export default {
localStorage.orderNo = orderNo localStorage.orderNo = orderNo
localStorage.isFrom = 'sale' localStorage.isFrom = 'sale'
localStorage.removeItem('changeCard') localStorage.removeItem('changeCard')
// 是否进入新流程的标识
const recordedNewProd = order.orderInfoDTO.newSaleFlag === '0'
if (orderStatus == '01') { if (orderStatus == '01') {
//已签名待客户确认, 跳到签名确认页面 //已签名待客户确认, 跳到签名确认页面
url = '/sale/SignatureConfirmation?edit=1&orderNo=' + orderNo url = '/sale/SignatureConfirmation?edit=1&orderNo=' + orderNo
@@ -597,11 +596,11 @@ export default {
//被保险人保存成功, 跳到已选产品列表 //被保险人保存成功, 跳到已选产品列表
url = processURL('/common/selectedProduct?edit=1&orderNo=' + orderNo) url = processURL('/common/selectedProduct?edit=1&orderNo=' + orderNo)
} else if (orderStatus == '37') { } else if (orderStatus == '37') {
//受益人保存成功, 跳到告知信息-- // 新流程的新产品检测, 如果是新产品,则跳转到新投保告知页面
url = '/sale/NotifyingMessage?edit=1&orderNo=' + orderNo url = (recordedNewProd ? '/flow-improve/sale/insureNotifyReplenishImag?orderNo=' : '/sale/newProduct?edit=1&orderNo=') + orderNo
} else if (orderStatus == '38') { } else if (orderStatus == '38') {
//账户信息保存成功, 跳到附件管理-- //账户信息保存成功, 跳到附件管理--
if (order.orderInfoDTO.activeType == 'KMH') { if (order.orderInfoDTO.activeType === 'KMH') {
let params = { let params = {
orderNo: order.orderInfoDTO.orderNo orderNo: order.orderInfoDTO.orderNo
} }
@@ -628,7 +627,7 @@ export default {
} }
}) })
} else { } else {
url = '/sale/AttachmentManagement?edit=1&orderNo=' + orderNo url = processURL('/sale/AttachmentManagement?edit=1&orderNo=' + orderNo)
} }
} else if (orderStatus == '39') { } else if (orderStatus == '39') {
//险种信息保存成功, 跳到已选产品列表 //险种信息保存成功, 跳到已选产品列表

View File

@@ -92,14 +92,14 @@
class="budget-input" class="budget-input"
> >
</template> </template>
<div class="fs12 c-gray-base">请填写0-10000之间的整数</div> <div class="fs12 c-gray-base">请填写大于等于0的整数或保留两位小数点的非整数</div>
</p> </p>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="question-btn bottom-btn bg-white"> <div class="question-btn bottom-btn bg-white">
<van-button type="danger" size="large" :disabled="disabled" class="bottom-btn" @click="submitAnswer" v-no-more-click="1000">提交</van-button> <van-button type="danger" size="large" class="bottom-btn" @click="submitAnswer" v-no-more-click="1000">提交</van-button>
</div> </div>
<PopupQuesResult <PopupQuesResult
@reTestHandler="reTest" @reTestHandler="reTest"
@@ -641,6 +641,9 @@ export default {
this.getDetailInfo() this.getDetailInfo()
}, },
submitAnswer(){ submitAnswer(){
if( this.disabled ){
return this.$toast('请填写完整信息')
}
if(this.answerList.length !=this.questionList.length){ if(this.answerList.length !=this.questionList.length){
return this.$toast('请填写完整信息') return this.$toast('请填写完整信息')
@@ -661,10 +664,10 @@ export default {
} }
} }
let regex = /^(0|[1-9]\d{0,3}|10000)$/; let regex =/^(?!0\d)(?!.*\.$)(0|[1-9]\d{0,14})(?:\.\d{1,2})?$/;
if(Array.from(this.answerList[3]).some(item=>{return !regex.test(item)}) if(Array.from(this.answerList[3]).some(item=>{return !regex.test(item)})
|| !regex.test(this.answerList[4][0])){ || !regex.test(this.answerList[4][0])){
return this.$toast('请填写0-10000之间的整数') return this.$toast('请填写大于等于0的整数或保留两位小数点的非整数')
} }
this.checkDataChanged() this.checkDataChanged()
this.getEvaluateResult() this.getEvaluateResult()

View File

@@ -1219,6 +1219,8 @@ export default {
}).then(() => { }).then(() => {
this.isNoWXInsureReadClick(val) this.isNoWXInsureReadClick(val)
}) })
} else {
this.isNoWXInsureReadClick(val)
} }
// 若被保险人为未成年人时,非微信环境点击【立即阅读签名】按钮进行弹窗提示 结束 // 若被保险人为未成年人时,非微信环境点击【立即阅读签名】按钮进行弹窗提示 结束
} }

View File

@@ -12,7 +12,7 @@
<!--文件导航 结束--> <!--文件导航 结束-->
<!-- 顶部提示 开始 --> <!-- 顶部提示 开始 -->
<p v-if='branchType != "14"' class="xxx-notice-bar" ref="xxx2">文件滑动至底部完成阅读</p> <p v-if='branchType != "14" && !isPreview' class="xxx-notice-bar" ref="xxx2">文件滑动至底部完成阅读</p>
<!-- 顶部提示 结束 --> <!-- 顶部提示 结束 -->
<!-- 一键置底 开始 --> <!-- 一键置底 开始 -->
@@ -22,14 +22,14 @@
<!-- 一键置底 结束 --> <!-- 一键置底 结束 -->
<!--文件内容 开始--> <!--文件内容 开始-->
<div id="pdf" ref="scrollableContent" @scroll="updateScrollProgress"> <div id="pdf" :class="[isPreview ? 'active' : '']" ref="scrollableContent" @scroll="updateScrollProgress">
<div ref="xxx8" id="pdfH5ID"></div> <div ref="xxx8" id="pdfH5ID"></div>
<div ref="activeButtonEle"></div> <div ref="activeButtonEle"></div>
</div> </div>
<!--文件内容 结束--> <!--文件内容 结束-->
<!--底部提示和按钮 开始--> <!--底部提示和按钮 开始-->
<div class="xxx-bottom"> <div class="xxx-bottom" v-if="!isPreview">
<p class="xxx-isread" ref="xxx3"> <p class="xxx-isread" ref="xxx3">
本人已阅读确认理解并同意<span>{{documentName}}</span>各项内容 本人已阅读确认理解并同意<span>{{documentName}}</span>各项内容
</p> </p>
@@ -47,7 +47,7 @@
</div> </div>
<!--底部提示和按钮 结束--> <!--底部提示和按钮 结束-->
<!--关怀标准切换 开始--> <!--关怀标准切换 开始-->
<oldVersionSwitch @onFloatBtnClicked="onFloatBtnClicked" /> <oldVersionSwitch v-if="!isPreview" @onFloatBtnClicked="onFloatBtnClicked" />
<!--关怀标准切换 结束--> <!--关怀标准切换 结束-->
</div> </div>
</template> </template>
@@ -117,6 +117,7 @@
}) })
}, 100) }, 100)
window.appCallBack = this.appCallBack window.appCallBack = this.appCallBack
console.log(this.isPreview)
}, },
mounted() { mounted() {
document.body.style.backgroundColor = '#fff' document.body.style.backgroundColor = '#fff'
@@ -288,6 +289,35 @@
] ]
} }
} }
/**
* @Author: LiuXiaoFeng
* @Description: documentCode为2 代表的是人身保险电子投保单
* 人身保险电子投保单文件需要抄录 保存时修改入参数据 copyValue是抄录的base64字符串 signOrRead需要变更为sign
* @Date: 2023/11/20
**/
if(this.fileList[this.current - 1].documentCode == '2' && this.signVal == '2' && (this.productType == '1' || this.productType == '2')){
window.localStorage.setItem('chaoluSubmitObj',JSON.stringify({
orderType: 'SIGN_COPY',
orderDTO: {
orderInfoDTO: {
orderNo: this.$route.query.orderNo
},
ebizSignDTOS: [
{
copyValue: '',
caType: 'copy',
signOrRead: 'sign',
signId: this.fileList[this.current - 1].signId,
orderNo: this.$route.query.orderNo,
documentCode: this.fileList[this.current - 1].documentCode,
documentStatus: '1',
documentType: this.fileList[this.current - 1].documentType,
signType: window.localStorage.getItem('sign-val')
}
]
}
}))
}
saveInformation(params).then(res=>{ saveInformation(params).then(res=>{
if(res.result == 0) { if(res.result == 0) {
window.sessionStorage.removeItem('currentFile') window.sessionStorage.removeItem('currentFile')
@@ -674,6 +704,10 @@
height: calc(100vh - 170px) !important; height: calc(100vh - 170px) !important;
position: relative; position: relative;
top: 66px; top: 66px;
&.active{
height: 100vh !important;
top: 0;
}
// //
} }
.xxx-bottom{ .xxx-bottom{
@@ -711,6 +745,10 @@
#pdf{ #pdf{
height: calc(100vh - 240px) !important; height: calc(100vh - 240px) !important;
top: 84px; top: 84px;
&.active{
height: 100vh;
top: 0;
}
} }
.xxx-isread{ .xxx-isread{
font-size: 18px; font-size: 18px;

View File

@@ -1,6 +1,7 @@
<template> <template>
<div class='insuranceInformation-container' :class="[isGuanhuaiBiaozhun === 0 ? '' : 'active']"> <div class='insuranceInformation-container' :class="[isGuanhuaiBiaozhun === 0 ? '' : 'active']">
<div style="display: flex;align-items: center;font-weight: bold;" class="fs20 div1"> <div class="big-box">
<div style="display: flex;align-items: center;font-weight: bold;" class="fs20 div1">
<span class="span1" style="width: 3px;background: red;height: 25px;"></span> <span class="span1" style="width: 3px;background: red;height: 25px;"></span>
<span v-if="signVal == '0' || signVal == '2'" style="margin-left: 5px;"> <span v-if="signVal == '0' || signVal == '2'" style="margin-left: 5px;">
投保人{{signName}} 投保人{{signName}}
@@ -56,6 +57,7 @@
<div> <div>
<img v-if="signstatus" :src="signImgUrl" style="height: 34px;margin-left: 20px;width: auto;"/> <img v-if="signstatus" :src="signImgUrl" style="height: 34px;margin-left: 20px;width: auto;"/>
</div> </div>
</div>
<div class='bg-white bottom-btn'> <div class='bg-white bottom-btn'>
<van-button :disabled="nextDisabled" type='danger' size='normal' style="font-size: 16px;" block v-no-more-click='1000' @click="gonext"> <van-button :disabled="nextDisabled" type='danger' size='normal' style="font-size: 16px;" block v-no-more-click='1000' @click="gonext">
完成阅读并签署 完成阅读并签署
@@ -160,6 +162,9 @@
if(JSON.parse(window.sessionStorage.getItem('signH5Img')).type == '签名' && JSON.parse(window.sessionStorage.getItem('signH5Img')).val) if(JSON.parse(window.sessionStorage.getItem('signH5Img')).type == '签名' && JSON.parse(window.sessionStorage.getItem('signH5Img')).val)
this.signstatus = true this.signstatus = true
this.signImgUrl = this.signImgUrl + JSON.parse(window.sessionStorage.getItem('signH5Img')).val this.signImgUrl = this.signImgUrl + JSON.parse(window.sessionStorage.getItem('signH5Img')).val
this.chaoLuObj.btnText = '抄录完成'
this.chaoLuObj.btnText1 = '已抄录'
} }
if(window.sessionStorage.getItem('signH5Val')){ if(window.sessionStorage.getItem('signH5Val')){
this.nextDisabled = false this.nextDisabled = false
@@ -231,12 +236,27 @@
signInfo.text = this.guardianName signInfo.text = this.guardianName
} }
window.sessionStorage.setItem('signInfo',JSON.stringify(signInfo)) window.sessionStorage.setItem('signInfo',JSON.stringify(signInfo))
window.location.href = this.$mainUrl + '/signH5/1.html' window.location.href = this.$mainUrl + '/signH5/2.html'
// window.location.href = 'http://'+window.location.host + '/signH5/1.html' // window.location.href = 'http://'+window.location.host + '/signH5/1.html'
} }
}, },
gonext(){ gonext(){
// 抄录提交 开始
if ((this.signVal == '0' || this.signVal == '2') && (this.productType == '1' || this.productType == '2')) {
saveInformation(JSON.parse(window.localStorage.getItem('chaoluSubmitObj'))).then(res => {
if(res.result == '0') {
this.publicSubmit()
} else {
this.$toast(res.resultMessage)
}
})
} else {
this.publicSubmit()
}
// 抄录提交 结束
},
publicSubmit() {
let params = { let params = {
orderType: 'SIGN_MERGED_ORDER', orderType: 'SIGN_MERGED_ORDER',
orderDTO: { orderDTO: {
@@ -434,6 +454,9 @@
box-sizing: border-box; box-sizing: border-box;
width: 100%; width: 100%;
overflow: auto; overflow: auto;
.big-box{
margin-bottom: 140px;
}
} }
.insuranceInformation-container.active{ .insuranceInformation-container.active{
.div1{ .div1{
@@ -459,7 +482,7 @@
} }
} }
.div4{ .div4{
margin-bottom: 160px; // margin-bottom: 160px;
span{ span{
font-size: 20px !important; font-size: 20px !important;
} }

View File

@@ -0,0 +1,16 @@
<script>
export default {
name: 'DocumentInfo',
components: {
SaleDocumentInfo: () => import('@/views/ebiz/sale/readDocuments.vue')
}
}
</script>
<template>
<div class="document-info-container">
<SaleDocumentInfo />
</div>
</template>
<style lang="scss" scoped></style>

View File

@@ -0,0 +1,159 @@
<script>
import { fetchUnderwritingList } from '@/api/ebiz/underwriting'
import OrderListCard from '@/views/ebiz/underwriting/components/OrderList/OrderListCard.vue'
import { LIST_TYPE } from '@/views/ebiz/underwriting/js/const'
import { navigateRouter } from '@/views/ebiz/underwriting/js/navigate'
import { Search, Tabs, Tab, List, Sticky, Button } from 'vant'
/**
* 保单订单信息
* @typedef {Object} Order
* @property {string} orderNo - 订单号
* @property {string} name - 投保人姓名
* @property {'1'|'2'} sex - 性别('1' 为男,'2' 为女)
* @property {string|null} birthday - 出生日期(格式如 'YYYY-MM-DD',若未知则为 null
* @property {string} idType - 证件类型('1' 通常表示身份证)
* @property {string} idNo - 证件号码
* @property {string} riskCode - 险种代码
* @property {string} riskName - 险种名称
* @property {string} orderStatus - 订单状态(具体值待定)
*/
export default {
name: 'saleList',
created() {
this.loadMore()
},
components: {
OrderListCard,
Button,
VanSearch: Search,
VanTabs: Tabs,
VanTab: Tab,
VanList: List,
VanSticky: Sticky
},
computed: {
LIST_TYPE() {
return LIST_TYPE
},
finishText() {
return this.listState.finished ? '没有更多了' : '正在加载...'
}
},
data() {
return {
searchText: '',
type: LIST_TYPE.unreviewed, //uncommit 表示未提交 commit表示已提交
/**
* @description 订单列表
* @type {Order[]}
*/
orders: [],
isSuccess: false,
branchType: '',
listState: {
loading: false,
finished: false,
error: false,
errorText: '请求失败,点击重新加载'
},
pagesInfo: {
currentPage: 1, //当前页数
pageSize: 10 //每页数据条数
}
}
},
methods: {
/**
* 初始化列表数据
* @returns {Promise<void>}
*/
async fetchListData() {
const params = {
pageNum: this.pagesInfo.currentPage,
pageSize: this.pagesInfo.pageSize,
orderType: this.type,
name: this.searchText
}
const res = await fetchUnderwritingList(params)
const { orderDTOPageInfo } = res
if (orderDTOPageInfo === null) return
;[this.orders] = [orderDTOPageInfo.list]
return orderDTOPageInfo
},
//分页用
loadMore() {
setTimeout(async () => {
const pagesInfo = await this.fetchListData()
/** 此刻没有任何数据内容 */
if (!pagesInfo) {
;[this.listState.loading, this.listState.finished] = [false, true]
return
}
const { total } = pagesInfo
if (this.pagesInfo.currentPage >= total) this.listState.finished = true
this.listState.loading = false
}, 400)
},
tabChange() {
this.resetListState()
},
/**搜索*/
handleSearch() {
this.resetListState()
},
/**重置列表状态*/
resetListState() {
this.orders = []
this.pagesInfo.currentPage = 1
;[this.listState.loading, this.listState.finished] = [true, false]
this.loadMore()
},
//新增
navigateDataCollection(orderStatus) {
const pathName = 'UnderwritingDataCollection'
navigateRouter({
name: pathName,
params: { orderStatus }
})
}
}
}
</script>
<template>
<div class="sale-list-container mb50">
<van-sticky>
<van-search v-model="searchText" placeholder="请输入投保人姓名" @search="handleSearch" />
<van-tabs v-model="type" :line-width="45" sticky @change="tabChange">
<van-tab :name="LIST_TYPE.unreviewed" title="未审核"></van-tab>
<van-tab :name="LIST_TYPE.reviewed" title="已审核"></van-tab>
</van-tabs>
</van-sticky>
<van-list
v-model="listState.loading"
:error-text="listState.errorText"
:error.sync="listState.error"
:finished="listState.finished"
:finished-text="finishText"
:immediate-check="false"
@load="loadMore"
>
<OrderListCard v-for="order in orders" :key="order.orderNo" :info="order" />
</van-list>
<Button v-no-more-click="1000" class="submit-btn bottom-btn mt20" type="danger" @click="navigateDataCollection()">点我新增</Button>
</div>
</template>
<style lang="scss" scoped>
.sale-list-container {
background-color: #f5f5f5;
}
</style>

View File

@@ -0,0 +1,26 @@
<template>
<div class="container">
<router-view />
</div>
</template>
<script>
export default {
name: 'PreliminaryUnderwritingContainer'
}
</script>
<style lang="scss" scoped>
.container {
width: 100vw;
height: 100vh;
background: #f5f5f5;
overflow-x: hidden;
::v-deep .submit-btn {
bottom: 10px;
width: 90%;
transform: translateX(5%);
}
}
</style>

View File

@@ -0,0 +1,43 @@
<script>
import { Image as VanImage, Button } from 'vant'
import { navigateRouter } from '@/views/ebiz/underwriting//js/navigate'
export default {
name: 'UnderwritingResult',
components: { Button, VanImage },
data() {
return {
errorMsg: '根据您的信息,不符合本产品承保要求',
image: require('@/assets/images/ebiz/evalImg.png')
}
},
methods: {
handleNavigateToList() {
navigateRouter({ name: 'UnderwritingOrderList', title: '预核保订单列表' })
}
}
}
</script>
<template>
<div class="underwriting-result-container flex justify-content-c align-items-c">
<div class="error-msg flex column align-items-c">
<VanImage :src="image" alt="error-result-image" width="80%" />
<div class="mt40">{{ errorMsg }}</div>
</div>
<Button class="submit-btn bottom-btn mt20" color="#E9322E" @click="handleNavigateToList">确定</Button>
</div>
</template>
<style lang="scss" scoped>
.underwriting-result-container {
background-color: #ffffff;
margin-top: 0 !important;
height: 100vh;
width: 100vw;
overflow: hidden;
.error-msg {
height: fit-content;
}
}
</style>

View File

@@ -0,0 +1,57 @@
<script>
import { getOrderDetail } from '@/api/ebiz/sale/sale'
import { Toast } from 'vant'
export default {
name: 'SignContract',
components: {
SignContractDialog: () => import('@/views/ebiz/underwriting/components/SignContract/SignContractDialog.vue'),
SaleSignContract: () => import('@/views/ebiz/sale/SignatureConfirmation.vue'),
SignContractOrderInfo: () => import('@/views/ebiz/underwriting/components/SignContract/SignContractOrderInfo.vue'),
SignContractApplicantDocument: () => import('@/views/ebiz/underwriting/components/SignContract/SignContractApplicantDocument.vue'),
SignContractInsuredDocument: () => import('@/views/ebiz/underwriting/components/SignContract/SignContractInsuredDocument.vue')
},
created() {
this.fetchOrderInfo()
},
data() {
return { orderNO: this.$route.query.orderNo, orderInfo: void 0 }
},
computed: {
agent: {
get() {
if (!this.orderInfo) return
return this.orderInfo.recmdDTO
}
}
},
methods: {
async fetchOrderInfo() {
const { result, resultMessage, orderDTO } = getOrderDetail({ orderNo: this.orderNO, getOtherType: 'RID' })
if (result !== '0') {
Toast({ message: resultMessage })
return false
}
this.orderInfo = orderDTO
}
}
}
</script>
<template>
<div class="sign-contract-container">
<div class="container">
<SignContractOrderInfo />
<SignContractApplicantDocument />
<SignContractInsuredDocument />
</div>
<!-- 签名正文 -->
<SaleSignContract />
<!-- 确认提示 -->
<SignContractDialog />
</div>
</template>
<style lang="scss" scoped></style>

View File

@@ -0,0 +1,107 @@
<script>
import { fetchUnderwritingOrderInformation, saveSupplementaryInformation } from '@/api/ebiz/underwriting'
import UnderwritingDataCollection from '@/views/ebiz/underwriting/UnderwritingDataCollection.vue'
import { Sticky, Toast } from 'vant'
export default {
name: 'supplementaryInformation',
components: { UnderwritingDataCollection, Sticky },
async created() {
const { result, resultMessage, content } =
/** @type {{ result: string, resultMessage: string, content: InsuranceOrderDTO }} */
(await fetchUnderwritingOrderInformation(this.orderNo))
if (result !== '0') {
Toast(`error: ${resultMessage}`)
return false
}
this.information = content
},
watch: {
insured: {
deep: true,
handler() {
this.$nextTick(() => {
const dcThis = this.$refs.dataCollection
dcThis.user = this.insured
})
}
}
},
data() {
const { orderNo } = this.$route.query
return {
/**
* 订单信息
* @type {InsuranceOrderDTO}
*/
information: void 0,
orderNo
}
},
computed: {
/**@type {InsuredDTO | undefined}*/
insured: {
get() {
if (!this.information) return void 0
return this.information.data.cont.insuredDTO
},
set(value) {}
},
risk: {
get() {
if (!this.information) return void 0
return this.information.data.cont.riskList[0]
},
set(value) {}
}
},
methods: {
/**
* 提交数据
* @param fn {Function} 用来执行补充额外资料的接口
*/
handleSubmit(fn) {
saveSupplementaryInformation({
orderNo: this.orderNo,
mediaDTOS: this.mediaDTOS
})
fn(false)
}
}
}
</script>
<template>
<div class="supplementary-document-container ph20">
<div aria-live="polite" class="alert alert-warning" role="alert">
请您补充关于处方明细的影像资料
</div>
<UnderwritingDataCollection ref="dataCollection" class="supplementary-document-content" type="SupplementaryInformation" @submit="handleSubmit" />
</div>
</template>
<style lang="scss" scoped>
.supplementary-document-container {
background-color: #fff;
min-height: 100vh;
.alert {
position: sticky;
top: 0;
padding: 10px 20px;
margin: 0 -20px;
}
.alert-warning {
background-color: #fef2d3;
}
.supplementary-document-content {
min-height: unset !important;
cheight: unset !important;
width: unset !important;
padding: unset !important;
}
}
</style>

View File

@@ -0,0 +1,214 @@
<script>
/**
* mediaDTO 媒体信息列表
* @typedef {Object} MediaDTO 媒体文件类型
* @property {string} businessNo - 业务编号
* @property {string} businessType - 业务类型(可能为空)
* @property {string} fileName - 文件名
* @property {string} imageInfoType - 图片信息类型("png" 等字符串形式)
* @property {string} rgssUrl - 加密或编码后的文件 URL可能经过 Base64 或其他编码)
* @property {string} subBusinessType - 子业务类型(如 "0"
*/
import { saveOrder } from '@/api/ebiz/underwriting'
import { idToData } from '@/assets/js/utils/verification'
import DataCollectionBaseInformation
from '@/views/ebiz/underwriting/components/DataCollection/DataCollectionBaseInformation.vue'
import DataCollectionRiskInformation
from '@/views/ebiz/underwriting/components/DataCollection/DataCollectionRiskInformation.vue'
import UnderwritingCollectionMedias
from '@/views/ebiz/underwriting/components/UnderwritingCollection/UnderwritingCollectionMedias.vue'
import { ORDER_STATUS, SEX } from '@/views/ebiz/underwriting/js/const'
import { navigateRouter } from '@/views/ebiz/underwriting/js/navigate'
import { Button, Toast } from 'vant'
const type = Object.freeze({ SupplementaryInformation: 'SupplementaryInformation', DataCollection: 'DataCollection' })
export default {
name: 'CollectionUnderwritingData',
components: { DataCollectionRiskInformation, DataCollectionBaseInformation, UnderwritingCollectionMedias, Button },
computed: {
/** 各个组件执行权限 */
executePermission() {
const orderStatus = this.$route.query.orderStatus
const isShow = orderStatus !== ORDER_STATUS.pending.value
const permission = {
uploader: { disabled: true },
form: { disabled: true },
riskForm: { disabled: true },
submit: { disabled: false, show: isShow }
}
if (!orderStatus) {
permission.form.disabled = false
permission.uploader.disabled = false
permission.riskForm.disabled = false
} else if (ORDER_STATUS.referred.value === orderStatus) {
console.log(typeof orderStatus, orderStatus, ORDER_STATUS.referred.value === orderStatus)
permission.uploader.disabled = false
}
// 防止被意外篡改
return Object.freeze(permission)
},
/** 执行的按钮根据不同状态,切换不同效果和提示语 */
executeBtn() {
const orderStatus = this.$route.query.orderStatus
switch (orderStatus) {
case ORDER_STATUS.standard.value:
return {
label: '去投保',
fn: () => console.log('去投保')
}
case ORDER_STATUS.declined.value:
case ORDER_STATUS.postponed.value: {
return {
label: '查看结果',
fn: () => console.log('查看结果')
}
}
}
return {
label: this.type === type.DataCollection ? '提交预核保' : '提交',
fn: this.handleDataSubmit
}
}
},
props: {
type: { type: String, default: type.DataCollection }
},
data() {
return {
// 险种名称
riskName: {
value: '',
label: ''
},
// 用户相关信息
user: {
name: '',
idType: '',
idNo: '',
sex: SEX.male,
birthday: ''
},
/**
* 媒体信息列表
* @type {MediaDTO[]}
*/
mediaDTOS: []
}
},
methods: {
/**
* 准备提交数据控制器
*/
async handleDataSubmit() {
const hadSent = await this.postSubmit()
if (!hadSent) return false
this.navigateToList()
},
/**
* 提交数据
* @returns {Promise<boolean>}
*/
async postSubmit() {
const validate = await this.$validator.validateAll()
if (!validate || !this.checkIdNo()) {
console.log(this.$validator.errors.items[0])
Toast(`error: ${this.$validator.errors.items[0].msg}`)
return false
}
/**
* 针对补充信息步骤,进行相应处理
*/
if (this.type === type.SupplementaryInformation) {
let res
this.$emit('submit', value => (res = value))
console.log(res)
return res
}
const params = {
...this.user,
...{
riskCode: this.riskName.value,
riskName: this.riskName.label,
// 在信息填写步骤的时候, oderNo 为空
orderNo: ''
},
mediaDTOS: this.mediaDTOS
}
const { result, resultMessage } = await saveOrder(params)
if (result !== '0') {
Toast(`error: ${resultMessage}`)
return false
}
return true
},
/**
* 导航到订单列表
* @returns {void}
*/
navigateToList() {
navigateRouter({
name: 'UnderwritingOrderList'
})
},
/**
* 检查证件号码是否合法
* @returns {boolean}
*/
checkIdNo() {
switch (Number(this.user.idType)) {
case 1: {
const { text = '', birthday = '', sex = '' } = idToData(this.user.idNo)
/* text 只包含错误信息 **/
if (text) {
this.$validator.errors.items.unshift({ msg: text })
return false
}
/**检测 生日 和 性别*/
if (this.user.birthday !== birthday || this.user.sex !== sex) {
this.$validator.errors.items.unshift({ msg: '证件号码与出生日期或性别不匹配,请重新检查' })
return false
}
}
}
return true
}
}
}
</script>
<template>
<div class="underwriting-data-collection-container ph15">
<!-- 基本信息 -->
<DataCollectionBaseInformation :executePermission="executePermission.form" :riskName="riskName" :user="user" />
<!-- 险种信息 -->
<DataCollectionRiskInformation :executePermission="executePermission.riskForm" :riskName="riskName" />
<!-- 影像信息 -->
<UnderwritingCollectionMedias :disabled="executePermission.uploader.disabled" :medias="mediaDTOS" class="medias" />
<Button
v-if="executePermission.submit.show"
:disabled="executePermission.submit.disabled"
block
class="bottom-btn submit-btn mt20"
color="#E9322E"
@click="executeBtn.fn"
>
{{ executeBtn.label }}
</Button>
</div>
</template>
<style>
.underwriting-data-collection-container {
min-height: 100vh;
background-color: #fff;
}
</style>

View File

@@ -0,0 +1,84 @@
<script>
import filter from '@/filters'
import FieldPicker from '@/views/ebiz/underwriting/components/FieldPicker.vue'
import FieldSelect from '@/views/ebiz/underwriting/components/FieldSelect.vue'
import GField from '@/views/ebiz/underwriting/components/GField.vue'
import SexRadio from '@/views/ebiz/underwriting/components/SexRadio.vue'
import { FIELD_SELECT_TYPE, SEX } from '@/views/ebiz/underwriting/js/const'
export default {
name: 'DataCollectionBaseInformation',
components: { FieldPicker, GField, SexRadio, FieldSelect },
props: {
/**@type {{ name: String, idType: String, idNo: String, sex: String, birthday: String }}*/
user: {
type: Object,
default: () => ({ name: '', idType: '', idNo: '', sex: SEX.male, birthday: '' })
},
/**@type {{ disabled: Boolean }}*/
executePermission: { type: Object, default: () => ({ disabled: false }) }
},
computed: {
FIELD_SELECT_TYPE: () => FIELD_SELECT_TYPE,
_idType: {
get() {
return filter.idToText(this.user.idType, 'insuredIdType')
},
set(val) {
// 如何 id 类型 改变,则清空 id 值
this.user.idNo = void 0
this.user.idType = val
}
}
},
methods: {
/**
* 改变证件类型
* @param type {Object} 证件类型
* @returns {void}
*/
handleChangeIdType(type) {
// console.log(type)
this._idType = type.id
}
}
}
</script>
<template>
<div class="base-information-container">
<h4 class="pt20">基本信息</h4>
<GField v-model="user.name" v-validate="'required'" :disabled="executePermission.disabled" label="姓名" name="姓名" />
<SexRadio :disabled="executePermission.disabled" :hairline="true" :sex.sync="user.sex"></SexRadio>
<FieldPicker
ref="birthday"
v-validate="'required'"
:disabled="executePermission.disabled"
:flag="true"
:maxDate="new Date()"
:value.sync="user.birthday"
label="出生日期"
name="出生日期"
required
type="date"
/>
<FieldSelect
v-model="_idType"
v-validate="'required'"
:disabled="executePermission.disabled"
:type="FIELD_SELECT_TYPE.idType"
:value.sync="_idType"
label="证件类型"
name="证件类型"
placeholder="请选择"
readonly
required
right-icon="arrow"
@submit="handleChangeIdType"
/>
<GField v-model="user.idNo" :disabled="executePermission.disabled" clearable label="证件号码" maxlength="18" placeholder="请输入" required />
</div>
</template>
<style lang="scss" scoped></style>

View File

@@ -0,0 +1,51 @@
<script>
import FieldSelect from '@/views/ebiz/underwriting/components/FieldSelect.vue'
import { FIELD_SELECT_TYPE } from '@/views/ebiz/underwriting/js/const'
export default {
name: 'DataCollectionRiskInformation',
components: { FieldSelect },
props: {
/**@type {RiskType} */
riskName: { type: Object, default: () => ({ value: '', label: '' }) },
/**@type {{disabled: Boolean}} */
executePermission: { type: Object, default: () => ({ disabled: false }) }
},
computed: {
FIELD_SELECT_TYPE: () => FIELD_SELECT_TYPE
},
methods: {
/**
* 确定主险
* @param riskInfo {Object} 险种信息
* @returns {void}
*/
handleEnsureMainRisk(riskInfo) {
console.log(riskInfo)
;[this.riskName.label, this.riskName.value] = [riskInfo.riskName, riskInfo.riskProductCode]
}
}
}
</script>
<template>
<section class="risk-information-container">
<h4 class="pt20">险种信息</h4>
<FieldSelect
v-model="riskName.label"
v-validate="'required'"
:disabled="executePermission.disabled"
:type="FIELD_SELECT_TYPE.underwritingRiskType"
:value.sync="riskName.value"
label="险种名称"
name="险种名称"
placeholder="请选择"
readonly
required
right-icon="arrow"
@submit="handleEnsureMainRisk"
/>
</section>
</template>
<style lang="scss" scoped></style>

View File

@@ -0,0 +1,197 @@
<template>
<div class="date-picter mb1" id="date-picter">
<div v-if="defaultStyle == 'style02'" @click="DatePickerShow(flag)" class="fs12 red ml15">
<span v-if="value">{{ value }} </span>
<span v-else>{{ placeholder }} </span>
<img src="@/assets/images/u79.png" alt class="absolute mt5 ml5" />
</div>
<div v-else-if="defaultStyle == 'style03'" @click="DatePickerShow(flag)" class="fs12 mr15">
<span v-if="value">{{ value }} </span>
<span v-else>{{ placeholder }} </span>
<img src="@/assets/images/u80.png" alt class="absolute ml5" />
</div>
<van-field
v-else
readonly
clickable
:label="label"
:value="date"
:placeholder="placeholder"
@click="DatePickerShow(flag)"
:required="required"
:name="label"
right-icon="arrow"
/>
<van-popup v-model="showDataPicker" position="bottom" style="z-index9999">
<van-datetime-picker :type="type" v-model="data" @confirm="onConfirmDate" @cancel="cancel" :max-date="maxDate" :min-date="minDate" />
</van-popup>
</div>
</template>
<script>
import { Field, Popup, DatetimePicker } from 'vant'
import utils from '@/assets/js/business-common'
import beforeDate from '@/assets/js/utils/getBeforeDate.js'
export default {
name: 'FieldDatePicter',
props: {
// defaultStyle :style02 时,显示红字红三角的样式,不写的话展示默认样式
defaultStyle: {
type: String,
default: ''
},
isDefault: {
type: Boolean,
default: false
},
maxDate: {
type: Date,
default: () => {
return beforeDate.getBeforeYear(-20)
}
},
minDate: {
type: Date,
default: () => {
return new Date('1900-01-01')
}
},
disabled: {
type: Boolean,
default: false
},
label: {
type: String,
default: '11'
},
value: {
type: String,
default: ''
},
placeholder: {
type: String,
default: '请选择'
},
type: {
type: String,
default: 'date'
},
defaultDate: {
type: Date,
default: () => {
return new Date()
}
},
defaulTime: {
type: String,
default: ''
},
required: {
type: Boolean,
default: false
},
flag: {
type: Boolean,
default: false
},
readonly: {
type: Boolean,
default: false
}
},
data() {
return {
currentDate: beforeDate.getBeforeYear(30), //当前时间的30年前
showDataPicker: false,
data: '', //时间插件绑定的值
date: '' //field显示的值
//minDate: new Date('1900-01-01') //因为VANT组件默认是十年前
}
},
components: {
[DatetimePicker.name]: DatetimePicker,
[Field.name]: () => import('@/views/ebiz/underwriting/components/GField.vue'),
[Popup.name]: Popup
},
created() {
// this.DatePickerShow(this.flag)
this.init()
// setTimeout(() => {
// this.showDataPicker = false
// }, 0)
},
mounted() {},
watch: {
value() {
this.init()
}
},
methods: {
/**
* 初始化
*/
init() {
if (this.type == 'time') {
this.data = this.value
} else if (this.value) {
this.data = new Date(this.value)
} else {
this.data = this.currentDate
}
if (this.required) {
this.rules = 'required'
}
if (this.isDefault) {
this.data = beforeDate.getBeforeYear(0)
}
this.date = this.value
},
onConfirmDate(value) {
let result = ''
if (this.type == 'time') {
result = value
} else {
let dateType = {
date: 'yyyy-MM-dd',
datetime: 'yyyy-MM-dd HH:mm:ss',
'year-month': 'yyyy-MM',
time: 'mm:ss'
}
result = utils.formatDate(value, dateType[this.type])
}
this.$emit('update:value', result)
this.date = result
this.$emit('confirm', result)
this.showDataPicker = false
},
cancel() {
this.showDataPicker = false
this.$emit('cancel', '')
},
DatePickerShow(flag) {
if (this.readonly || this.disabled) {
return
}
this.showDataPicker = flag
this.$emit('showUp', flag)
}
}
}
</script>
<style lang="scss" scoped>
.nav-bar {
.van-nav-bar {
&__text {
color: white;
}
&__title {
color: white;
}
}
.van-icon {
color: white;
}
}
</style>

View File

@@ -0,0 +1,74 @@
<script>
import { mainRiskList } from '@/api/ebiz/common/common'
import { fetchUnderwritingOrderRiskList } from '@/api/ebiz/underwriting'
import DataDictionary from '@/assets/js/utils/data-dictionary'
import GField from '@/views/ebiz/underwriting/components/GField.vue'
import { FIELD_SELECT_TYPE } from '@/views/ebiz/underwriting/js/const'
import { Picker, Popup } from 'vant'
export default {
name: 'FieldSelect',
components: { GField, Popup, Picker },
async created() {
switch (this.type) {
case FIELD_SELECT_TYPE.riskType: {
const res = await mainRiskList({ platform: 'app' })
;[this.mainRisks] = [res.mainRiskDTOS]
break
}
case FIELD_SELECT_TYPE.underwritingRiskType: {
const res = await fetchUnderwritingOrderRiskList({ platform: 'app' })
;[this.mainRisks] = [res.mainRiskDTOS]
break
}
}
},
props: {
type: { type: Number, default: FIELD_SELECT_TYPE.other },
disabled: { type: Boolean, default: false }
},
data() {
return {
show: false,
mainRisks: []
}
},
computed: {
// eslint-disable-next-line vue/return-in-computed-property
columns() {
if (this.type === FIELD_SELECT_TYPE.other) return ['没有对应列表内容,请检查类型']
switch (Number(this.type)) {
case FIELD_SELECT_TYPE.idType:
return DataDictionary.insuredIdType
case FIELD_SELECT_TYPE.underwritingRiskType:
case FIELD_SELECT_TYPE.riskType:
console.log(this.mainRisks, '----')
return this.mainRisks.map(item => ({ text: item.riskName, detail: item }))
}
}
},
methods: {
handlePopupSubmit(value) {
this.show = false
if (this.type === FIELD_SELECT_TYPE.other) return
this.$emit('submit', value)
},
handleActivePopup() {
if (this.disabled) return
this.show = true
}
}
}
</script>
<template>
<div class="field-select-container">
<GField v-bind="{ ...$attrs, disabled: disabled }" @click="handleActivePopup" />
<Popup v-model="show" position="bottom">
<Picker :columns="columns" show-toolbar @cancel="show = false" @confirm="handlePopupSubmit" />
</Popup>
</div>
</template>
<style lang="scss" scoped></style>

View File

@@ -0,0 +1,44 @@
<script>
import { Field } from 'vant'
export default {
components: { Field },
inheritAttrs: false,
name: 'GField',
props: {
feetLine: { type: Boolean, default: true },
hairLine: { type: Boolean, default: true },
required: { type: Boolean, default: true },
label: { type: String, default: '' },
value: { type: String, default: '' },
placeholder: { type: String, default: '' },
type: { type: String, default: 'text' },
clearable: { type: Boolean, default: true },
password: { type: Boolean, default: false },
errorMessage: { type: String, default: '' },
error: { type: Boolean, default: false }
}
}
</script>
<template>
<div class="g-field">
<Field ref="field" class="hairline" required v-bind="{ ...$attrs, ...$props }" v-on="$listeners">
<template v-for="(_, slot) of $slots" v-slot:[slot]>
<slot :name="slot" />
</template>
</Field>
</div>
</template>
<style lang="scss" scoped>
::v-deep .van-field {
&.hairline::after {
border-bottom: 1px solid #f5f5f5 !important;
content: ' ';
width: 90%;
position: absolute;
left: 3%;
bottom: 0;
}
}
</style>

View File

@@ -0,0 +1,178 @@
<script>
import { deleteUnderwritingOrderByOrderNo } from '@/api/ebiz/underwriting'
import filter from '@/filters'
import { ORDER_STATUS } from '@/views/ebiz/underwriting/js/const'
import { navigateRouter } from '@/views/ebiz/underwriting/js/navigate'
import { Button, Tag, Toast } from 'vant'
export default {
name: 'OrderListCard',
components: { Tag, Button },
props: {
info: {
type: Object,
default: () => {
return {
orderNo: '8186270000130107',
name: '王飞',
sex: '1',
birthday: null,
idType: '1',
idNo: '522530199208180048',
riskCode: 'GFRS_M0109',
riskName: '国富人寿富贵年年终身寿险 ',
orderStatus: ORDER_STATUS.declined.value,
createdDate: '2029-07-09 10:05:05'
}
}
}
},
computed: {
idType: {
get() {
return filter.idToText(this.info.idType, 'insuredIdType')
}
},
orderStatus() {
const status = Object.values(ORDER_STATUS).find(item => item.value === /* this.info.orderStatus */ this.info.orderStatus)
if (!status) {
console.error('未定义的订单状态, 请重新检查相应代码内容')
return
}
return status.label
},
executeBtn() {
const status = this./* info.orderStatus */ info.orderStatus
const date = this.info.createdDate
let label, pathname, handler
switch (status) {
case ORDER_STATUS.standard.value:
label = '去投保'
pathname = 'UnderwritingDataCollection'
break
case ORDER_STATUS.referred.value:
label = '补充资料'
pathname = 'UnderwritingSupplementaryInformation'
break
case ORDER_STATUS.declined.value:
label = '查看结果'
pathname = 'UnderwritingResult'
break
case ORDER_STATUS.pending.value:
label = '删除'
pathname = 'UnderwritingDataCollection'
handler = this.handleDeleteOrderByOrderNo
break
default:
label = '未定义的状态,请重新检查相应枚举'
break
}
return {
label,
pathname,
handler: handler || this.handleNavigate,
// 如果这个是标准单且距今超过一个月了,则禁用当前按钮
disabled: status === ORDER_STATUS.standard.value && new Date() - new Date(date) > 3600 * 24 * 30 * 1000
}
}
},
methods: {
handleNavigate() {
navigateRouter({
name: this.executeBtn.pathname,
params: {
orderId: this.info.orderId,
orderStatus: this.info.orderStatus
}
})
},
async handleDeleteOrderByOrderNo() {
const { result, resultMessage } = await deleteUnderwritingOrderByOrderNo(this.info.orderNo)
if (result !== '0') {
this.$toast(resultMessage)
return false
}
Toast({ message: '删除成功', position: 'bottom' })
}
}
}
</script>
<template>
<div class="order-list-card-container mt10 fs12 mh10">
<div @click="handleNavigate">
<section class="flex align-items-c">
<div>
<Tag plain type="danger">险种</Tag>
<span>{{ info.riskName }}</span>
</div>
<div>{{ info.createdDate }}</div>
</section>
<section class="hairline">
<div>
<Tag plain type="warning">被保</Tag> <span>{{ info.name }}</span>
</div>
<div>
<Tag plain type="danger">类型</Tag> <span>{{ idType }}</span>
</div>
<div>
<Tag plain type="danger">证号</Tag> <span>{{ info.idNo }}</span>
</div>
</section>
<section class="hairline">
<div>
<Tag plain type="danger"><span class="mh15">状态</span></Tag> <span>{{ orderStatus }}</span>
</div>
</section>
</div>
<section class="flex hairline " style="flex-direction: row-reverse">
<div>
<Button
:class="{ disable: executeBtn.disabled }"
:disabled="executeBtn.disabled"
class="delete-btn ph30 pv5 "
color="#FF1113"
round
@click.self="executeBtn.handler"
>
{{ executeBtn.label }}
</Button>
</div>
</section>
</div>
</template>
<style lang="scss" scoped>
.order-list-card-container {
background-color: #fff;
border-radius: 6px;
.hairline {
border-top: 1px solid #eaeaea;
}
section {
div {
margin: 10px;
}
::v-deep .van-tag {
margin-right: 10px;
}
}
.delete-btn {
height: unset;
line-height: unset;
}
button.disable {
background-color: grey !important;
border-color: grey !important;
}
}
</style>

View File

@@ -0,0 +1,68 @@
<script>
import { SEX } from '@/views/ebiz/underwriting/js/const.js'
import SelectRadio from '@/components/ebiz/SelectRadio.vue'
export default {
components: { SelectRadio },
name: 'SexRadio',
props: {
required: { type: Boolean, default: true },
sex: { type: String, default: SEX.male },
hairline: { type: Boolean, default: true },
disabled: { type: Boolean, default: false }
},
data() {
return {
sexRadio: [
{ label: '男', value: '0' },
{ label: '女', value: '1' }
]
}
},
computed: {
_sex: {
get() {
return this.sex
},
set(value) {
this.$emit('update:sex', value)
this.radioChange(value)
}
}
},
methods: {
radioChange(value) {
this.$emit('changeSex', value)
}
}
}
</script>
<template>
<div class="sex-radio-container">
<SelectRadio
:class="{ hairline }"
:disabled="disabled"
:radios="sexRadio"
:required="required"
:value.sync="_sex"
label="性别"
name="性别"
@radio-change="radioChange"
></SelectRadio>
</div>
</template>
<style lang="scss">
.sex-radio-container {
.hairline {
&::after {
border-bottom: 1px solid #f5f5f5 !important;
content: ' ';
width: 90%;
position: absolute;
left: 3%;
//bottom: 10px;
}
}
}
</style>

View File

@@ -0,0 +1,11 @@
<script>
export default {
name: 'SignContractApplicantDocument'
}
</script>
<template>
<section class="application-document-info"></section>
</template>
<style lang="scss" scoped></style>

View File

@@ -0,0 +1,50 @@
<script>
import { Button, Dialog } from 'vant'
export default {
name: 'SignContractDialog',
components: { Dialog: Dialog.Component, Button },
data() {
return { canShowDialog: true }
},
methods: {
handleEnsure() {
this.canShowDialog = false
}
}
}
</script>
<template>
<section class="sign-contract-container">
<Dialog v-model="canShowDialog" :showConfirmButton="false">
<template #title>
<section class="dialog-header red">提示</section>
</template>
<section class="dialog-content ph20 pb20 gray fs13">
<p>
尊敬的客户您好
</p>
<p style="text-indent: 2em;dialog-border-radius:200px">
感谢您投保我公司爱心保/安心保产品在本保险合同生效后被保险人将获得一份专属的健康管理服务详情请登录公司官方微信公众号国富人寿保险>发现国富>新市民专区
查询或拨打公司客服热线400-694-6688咨询本服务为无偿提供
</p>
</section>
<Button block class="dialog-footer white fs16 bg-red1" @click="handleEnsure">确定</Button>
</Dialog>
</section>
</template>
<style lang="scss" scoped>
.sign-contract-container {
.dialog-content {
p {
margin: 5px 0;
}
}
::v-deep [role='dialog'] {
border-radius: 1em;
}
}
</style>

View File

@@ -0,0 +1,11 @@
<script>
export default {
name: 'SignContractInsuredDocument'
}
</script>
<template>
<section class="insured-document-info"></section>
</template>
<style lang="scss" scoped></style>

View File

@@ -0,0 +1,29 @@
<script>
import { CellGroup, Cell } from 'vant'
export default {
name: 'SignContractOrderInfo',
components: { CellGroup, Cell }
}
</script>
<template>
<section class="order-info">
<CellGroup class="mt10 fs20">
<Cell :value="recmd.agentCode" title="销售人员工号" />
<Cell :value="recmd.name" title="销售人员姓名" />
<Cell :value="orderInfo.orderNo" title="投保单号"></Cell>
<!-- 电投签名确认新增交费期间 start at 20240910 -->
<div v-if="riskInfo">
<Cell v-if="riskInfo.payEndYear == '1000'" title="交费期间" value="一次性交清" />
<Cell v-else :value="riskInfo.payEndYearFlag == 'Y' ? `${riskInfo.payEndYear}年` : `至${riskInfo.payEndYear}岁`" title="交费期间" />
</div>
<!-- 电投签名确认新增交费期间 end at 20240910 -->
<Cell :value="date" title="投保日期" />
<Cell :value="orderInfo.orderAmount == undefined ? '' : orderInfo.orderAmount | moneyFormat" title="保费合计(元)" />
<Cell v-if="cvalidateStr" :value="cvalidateStr" title="指定保单生效日" />
</CellGroup>
</section>
</template>
<style lang="scss" scoped></style>

View File

@@ -0,0 +1,94 @@
<script>
import { uploadImg } from '@/api/ebiz/sale/sale'
import { Toast, Uploader } from 'vant'
export default {
name: 'UnderwritingCollectionMedias',
components: { Uploader },
props: {
isSupplementary: { type: Boolean, default: false },
medias: { type: Array, default: () => [] },
/**@type {{disabled: Boolean}}*/
executePermission: { type: Object, default: () => ({ disabled: false }) }
},
data() {
return {
/**@type {{[key:String]:File}}*/
filesDTOMap: {},
/**@type {File[]}*/
files: []
}
},
watch: {
filesDTOMap: {
deep: true,
handler(value) {
const dto = this.files.map(({ file }) => value[file.name])
this.medias.length = 0
this.medias.push(...dto)
console.log(this.medias, 'medias')
}
}
},
methods: {
/**
* 媒体上传
* @param file {File} 文件
* @param content {string} 文件内容
*/
handleMediaUpload({ file }) {
// console.log(file, content)
const filename = `${btoa(Math.random() * 100)}.${Date.now()}.${file.name}`
const _file = this.renameFile(file, filename)
let formData = new FormData()
formData.append('imgPath', _file)
this.uploadIMG(formData, { file, newName: filename })
},
/**
* 上传图片
* @param formData {FormData} 表单数据
* @param file {File} 当前文件
* @param newName {string} 当前文件新文件名
* @returns {Promise<void>}
*/
async uploadIMG(formData, { file, newName }) {
const { result, path, resultMessage } = await uploadImg(formData)
if (result !== '0') {
Toast(`error: ${resultMessage}`)
return
}
// console.log(`upload res `, { result, path, resultMessage })
this.$set(this.filesDTOMap, file.name, {
fileName: newName,
rgssUrl: path,
imageInfoType: '30',
// 预核保专用 type
subBusinessType: '2'
})
},
/**
* 重新命名文件
* @param file {File} 文件
* @param filename {string} 文件名
* @returns {File}
*/
renameFile(file, filename) {
return new File([file], filename, { ...file })
}
}
}
</script>
<template>
<div class="underwriting-collection-medias-container mt10">
<h4>影像信息</h4>
<article class="mh15 mt15 flex column gap-20">
<p>
请您上传关于当前疾病的所有影像资料如等费用收据门诊病历出院小结处方明细等......
</p>
<Uploader v-model="files" :after-read="handleMediaUpload" :max-count="executePermission.disabled ? medias.length : 99999"></Uploader>
</article>
</div>
</template>

View File

@@ -0,0 +1,86 @@
export const SEX = Object.freeze({ male: '0', female: '1' })
export const UNDERWRITING_STATUS = Object.freeze({
standard: 'standard',
referred: 'referred',
declined: 'declined',
postponed: 'postponed'
})
export const FIELD_SELECT_TYPE = Object.freeze({
other: 0,
idType: 1,
riskType: 2,
underwritingRiskType: 3
})
export const ORDER_STATUS = Object.freeze({
/**
* 待核保
*/
pending: {
value: '67',
label: '待核保'
},
/* 标准体 */
standard: {
value: '68',
label: '标准体'
},
/* 问题件 */
referred: {
value: 'referred',
label: '问题件'
},
/* 拒保 */
declined: {
value: 'declined',
label: '拒保'
},
/* 延期 */
postponed: {
value: 'postponed',
label: '延期'
}
})
export const LIST_TYPE = {
unreviewed: 'unreviewed',
reviewed: 'reviewed'
}
// export const cardSide = Object.freeze({
// front: 1,
// back: 0
// })
// export const user = Object.freeze({
// applicant: '0',
// insured: '1',
// beneficiary: '3'
// })
// // user 别名
// export const subBusinessType = user
//
// export const OcrDocumentType = Object.freeze({
// ID_CARD_FRONT: 1, // 身份证头像面
// ID_CARD_BACK: 2, // 身份证国徽面
// BANK_CARD: 3, // 银行卡正面影像
// FACE_PHOTO: 4, // 人脸影像
// HOUSEHOLD_REGISTER_HEAD: 5, // 户口本户主页
// HOUSEHOLD_REGISTER_SELF: 6, // 户口本本人页
// BIRTH_CERTIFICATE: 7, // 出生证
// PASSPORT: 8, // 护照本人照片页
// HK_MACAO_PERMIT: 9, // 港澳居民通行证头像面
// TAIWAN_PERMIT: 10, // 台湾居民通行证头像面
// OTHER: 11 // 其他
// })
// // OcrDocumentType 别名
// export const imageType = OcrDocumentType
//
// /**受益人类型*/
// export const beneficiaryType = Object.freeze({
// /** 法人 */
// legalPerson: '0',
// /** 指定受益人 */
// designateBeneficiary: '1'
// })

View File

@@ -0,0 +1,194 @@
import jump from '@/assets/js/utils/jump'
import router from '@/router'
/**
* 路由跳转函数
* @param path { String}路径
* @param name
* @param title {String} 标题内容
* @param params { Object}参数
*/
export function navigateRouter({ path = '', name = '', title = '', params = {} } = {}) {
const routes = router.options.routes
let options = {
flag: 'h5',
extra: {
title,
// forbidSwipeBack: 1, //当前页面禁止右滑返回
url: ''
},
routerInfo: { query: params }
}
if (path) {
// 查找路由支持任意深度的嵌套
const routeInfo = findRouteByPath(routes, path)
if (!routeInfo) {
console.error('在 routers 中无法找到该路径,请检查路径是否正确')
return false
}
options.extra = {
title: routeInfo.route.meta && routeInfo.route.meta.title ? routeInfo.route.meta.title : '',
url: location.origin + '/#' + path + '?' + processJson(params)
}
options.routerInfo = { ...options.routerInfo, path }
} else if (name) {
// 通过名称查找路由也支持任意深度嵌套
const routeInfo = findRouteByName(routes, name)
if (!routeInfo) {
console.error('在 routers 中无法找到该名称,请检查名称是否正确')
return false
}
// 构建完整的路径
const fullPath = buildFullPath(routeInfo.routeStack)
options.extra = {
title: routeInfo.route.meta && routeInfo.route.meta.title ? routeInfo.route.meta.title : '',
url: location.origin + '/#' + fullPath + '?' + processJson(params)
}
options.routerInfo = { ...options.routerInfo, name }
}
jump(options)
}
/**
* 递归查找具有指定路径的路由(支持多层嵌套)
* @param routes {import("vue-router").RouteConfig[]} 路由数组
* @param targetPath {String}目标路径
* @param parentPath {String}父级路径
* @return {undefined| {
* route: import("vue-router").RouteConfig,
* fullPath: String
* }}
*/
function findRouteByPath(routes, targetPath, parentPath = '') {
if (!routes || !Array.isArray(routes)) return undefined
// 规范化目标路径,移除多余的斜杠
targetPath = targetPath.replace(/\/+/g, '/')
for (const route of routes) {
// 构造当前路由的完整路径
let currentPath = parentPath
if (currentPath && !currentPath.endsWith('/') && route.path && !route.path.startsWith('/')) {
currentPath += '/' + route.path
} else {
currentPath += route.path
}
// 移除多余的斜杠
currentPath = currentPath.replace(/\/+/g, '/')
// 检查当前路由是否匹配
if (currentPath === targetPath) {
return {
route: route,
fullPath: currentPath
}
}
// 递归检查子路由
if (route.children && route.children.length > 0) {
const matchedChild = findRouteByPath(route.children, targetPath, currentPath)
if (matchedChild) {
return matchedChild
}
}
}
return undefined
}
/**
* 递归查找具有指定名称的路由(支持多层嵌套)
* @param routes 路由数组
* @param targetName 目标名称
* @param routeStack 用于追踪路由层级的堆栈
* @return {undefined| {
* route: import("vue-router").RouteConfig,
* routeStack: import("vue-router").RouteConfig[]
* }}
*/
function findRouteByName(routes, targetName, routeStack = []) {
if (!routes || !Array.isArray(routes)) return undefined
for (const route of routes) {
// 创建当前路由的堆栈副本
const currentStack = [...routeStack, route]
// 检查当前路由是否匹配
if (route.name === targetName) {
return {
route: route,
routeStack: currentStack
}
}
// 递归检查子路由
if (route.children && route.children.length > 0) {
const matchedChild = findRouteByName(route.children, targetName, currentStack)
if (matchedChild) {
return matchedChild
}
}
}
return undefined
}
/**
* 根据路由堆栈构建完整路径
* @param routeStack 路由堆栈
* @returns string
*/
function buildFullPath(routeStack) {
if (!routeStack || routeStack.length === 0) return ''
// 提取所有路由的路径并正确拼接
let fullPath = ''
routeStack.forEach((route, index) => {
// 特殊处理第一个路由
if (index === 0) {
fullPath += route.path
} else {
if (fullPath && !fullPath.endsWith('/') && route.path && !route.path.startsWith('/')) {
fullPath += '/' + route.path
} else if (fullPath.endsWith('/') && route.path.startsWith('/')) {
// 如果fullPath以/结尾而route.path以/开头,则需要去掉一个/
fullPath += route.path.substring(1)
} else {
fullPath += route.path
}
}
})
// 移除多余的斜杠
fullPath = fullPath.replace(/\/+/g, '/')
// 确保不会在末尾留下斜杠(除非是根路径)
if (fullPath.length > 1 && fullPath.endsWith('/')) {
fullPath = fullPath.slice(0, -1)
}
return fullPath
}
/**
* 处理 json 键值对,到 url 中
*/
function processJson(json) {
if (typeof json !== 'object') return
if (window.URLSearchParams) return new URLSearchParams(json).toString()
let url = ''
for (const key in json) {
if (json.hasOwnProperty(key)) {
url += key + '=' + json[key] + '&'
}
}
return url.substring(0, url.length - 1)
}

View File

@@ -0,0 +1,16 @@
/**
* API响应根对象
* @typedef {Object} ApiResponse
* @property {number} code - 响应代码
* @property {string} message - 响应消息
* @property {ApiContent} content - 响应内容
*/
/**
* API内容
* @typedef {Object} ApiContent
* @property {string} result - 结果代码
* @property {string} resultMessage - 结果消息
* @property {*} content - 内容
* @property {OrderDTO} orderDTO - 订单DTO
*/

View File

@@ -0,0 +1,743 @@
/**
* 订单DTO
* @typedef {Object} OrderDTO
* @property {*} appntOrInsured - 投保人或被保险人
* @property {*} deleteFlag - 删除标志
* @property {ProductDTO} productDTO - 产品信息
* @property {OrderInfoDTO} orderInfoDTO - 订单信息
* @property {AppntDTO} appntDTO - 投保人信息
* @property {InsuredDTO[]} insuredDTOs - 被保险人信息数组
* @property {*} paymentDTO - 支付信息
* @property {OrderAccountDTO} orderAccountDTO - 订单账户信息
* @property {*} channelDTO - 渠道信息
* @property {*} orderExpandDTO - 订单扩展信息
* @property {*} thirdOrderDTO - 第三方订单信息
* @property {RecmdDTO} recmdDTO - 推荐信息
* @property {*} agentLaurelDTO - 代理人信息
* @property {*} smsCodeDTO - 短信验证码信息
* @property {MediaDTO[]} mediaDTOS - 媒体信息数组
* @property {EbizSignDTO[]} ebizSignDTOS - 电子签名信息数组
* @property {*} baseEncryp - 基础加密信息
* @property {*} signValue - 签名值
* @property {*} signType - 签名类型
* @property {*} signMap - 签名映射
* @property {*} cardOrder - 卡订单
* @property {*} xqPayDTO - 需求支付信息
* @property {string} prtType - 打印类型
* @property {*} reason - 原因
* @property {*} groupCardPlanList - 团体卡计划列表
* @property {*} ybOrderDTO - 医保订单信息
* @property {*} riskEvaluationDTO - 风险评估信息
* @property {UniversalRiskNotifyDTO} universalRiskNotifyDTO - 通用风险通知信息
* @property {EbizOrderGbcRelDTO} ebizOrderGbcRelDTO - 订单关联信息
* @property {*} userModel - 用户模型
* @property {*} orderType - 订单类型
* @property {*} emailStatus - 邮箱状态
* @property {*} assessCoreDto - 评估核心信息
*/
/**
* 产品信息DTO
* @typedef {Object} ProductDTO
* @property {*} productCode - 产品代码
* @property {*} productName - 产品名称
* @property {*} mainRiskCode - 主险代码
* @property {*} productChannel - 产品渠道
* @property {*} productDesc - 产品描述
* @property {*} productType - 产品类型
* @property {*} planCode - 计划代码
* @property {*} productFlag - 产品标志
* @property {*} insuranceFlag - 保险标志
* @property {*} channelCode - 渠道代码
* @property {*} itemStatus - 项目状态
* @property {*} isSpecial - 是否特殊产品
* @property {*} special - 特殊标识
*/
/**
* 订单信息DTO
* @typedef {Object} OrderInfoDTO
* @property {*} appntDateStr - 投保日期字符串
* @property {number} orderAmount - 订单金额
* @property {*} customerId - 客户ID
* @property {string} orderNo - 订单号
* @property {string} prtNo - 打印号
* @property {*} contNo - 合同号
* @property {*} prem - 保费
* @property {*} sumPrem - 累计保费
* @property {*} orderStandAmount - 订单标准金额
* @property {*} totalPremium - 总保费
* @property {*} totalAmnt - 总保额
* @property {*} amnt - 保额
* @property {*} contState - 合同状态
* @property {*} expiryDate - 到期日期
* @property {*} payIntv - 缴费间隔
* @property {*} nextPayDate - 下次缴费日期
* @property {*} bonusFlag - 红利标志
* @property {*} survivalFlag - 生存金标志
* @property {*} loanFlag - 贷款标志
* @property {*} elecUrl - 电子URL
* @property {string} productCode - 产品代码
* @property {*} rate - 费率
* @property {*} underLineIdentification - 线下标识
* @property {string} saleChannel - 销售渠道
* @property {*} policyNumber - 保单号
* @property {*} riskPlanCode - 风险计划代码
* @property {*} hesitateDays - 犹豫期天数
* @property {string} appntDate - 投保日期
* @property {string} appntDateLabel - 投保日期标签
* @property {*} bnfType - 受益人类型
* @property {*} checkStatus - 检查状态
* @property {*} commitDate - 提交日期
* @property {*} confirmAddress - 确认地址
* @property {*} confirmZip - 确认邮编
* @property {*} confirmTime - 确认时间
* @property {*} contPrintStatus - 合同打印状态
* @property {*} contSendStatus - 合同发送状态
* @property {*} elecContStatus - 电子合同状态
* @property {*} giftName - 礼品名称
* @property {*} invoicePrintStatus - 发票打印状态
* @property {string} isElecCont - 是否电子合同
* @property {*} isLockedOrg - 是否锁定机构
* @property {*} isUseAddress - 是否使用地址
* @property {string} manageOrg - 管理机构
* @property {*} needInvoice - 是否需要发票
* @property {*} needPrt - 是否需要打印
* @property {string} orderStatus - 订单状态
* @property {*} planCode - 计划代码
* @property {string} productChannel - 产品渠道
* @property {string} productType - 产品类型
* @property {*} smsSendStatus - 短信发送状态
* @property {*} productDTO - 产品信息
* @property {string} orderType - 订单类型
* @property {*} productPlat - 产品平台
* @property {*} createDate - 创建日期
* @property {*} productName - 产品名称
* @property {*} bankAccount - 银行账户
* @property {*} bankCode - 银行代码
* @property {*} cardBookCode - 存折代码
* @property {string} supportBank - 支持银行
* @property {*} skuCode - SKU代码
* @property {*} signDate - 签约日期
* @property {*} silentBatchFlag - 静默批处理标志
* @property {*} systemSubtype - 系统子类型
* @property {*} staffFlag - 员工标志
* @property {*} perfUserStatus - 绩效用户状态
* @property {*} isNewInterface - 是否新接口
* @property {*} orderExecStatus - 订单执行状态
* @property {*} freezeLisStatus - 冻结LIS状态
* @property {*} policySyncDate - 保单同步日期
* @property {*} actCode - 激活码
* @property {*} automaticFee - 自动费用
* @property {*} expireDate - 过期日期
* @property {*} loanInterestBeforeday - 前一日贷款利息
* @property {*} loanInterest - 贷款利息
* @property {*} loanMoney - 贷款金额
* @property {*} contValueDate - 合同价值日期
* @property {*} contValue - 合同价值
* @property {*} applyDate - 申请日期
* @property {*} policyChangeDate - 保单变更日期
* @property {*} importLisStatus - 导入LIS状态
* @property {*} policyValue - 保单价值
* @property {*} policyValueBeforeday - 前一日保单价值
* @property {*} lastHesitateDate - 最后犹豫期日期
* @property {*} freezePoint - 冻结积分
* @property {*} availablePoint - 可用积分
* @property {*} autoPayEnd - 自动付款结束
* @property {*} autoPayStart - 自动付款开始
* @property {*} isAutoPay - 是否自动付款
* @property {*} saleChannelDetail - 销售渠道详情
* @property {string} bnfFlag - 受益人标志
* @property {*} uwRes - 核保结果
* @property {*} idRejectReason - 身份拒绝原因
* @property {*} idRejectType - 身份拒绝类型
* @property {*} idCheckRes - 身份检查结果
* @property {*} contSendDate - 合同发送日期
* @property {*} receiptDate - 回执日期
* @property {string} doubleFlag - 双录标志
* @property {*} isDoubleMailRisk - 是否双录邮件风险
* @property {*} activeType - 激活类型
* @property {string} validateCustomerFlag - 验证客户标志
* @property {*} reInsuranceFlag - 再保险标志
* @property {*} oldPolicyContNo - 旧保单合同号
* @property {*} specInfos - 特殊信息
* @property {*} isDoubleRecords - 是否双录记录
* @property {*} doubleState - 双录状态
* @property {*} saleChnl - 销售渠道
* @property {*} grpContNo - 团体合同号
* @property {*} activityCode - 活动代码
* @property {*} activeEndDateStr - 活动结束日期字符串
* @property {*} activeCvalidateDateStr - 活动验证日期字符串
* @property {*} isGroupCard - 是否团体卡
* @property {*} insuredSize - 被保险人数量
* @property {*} riskControl - 风控
* @property {*} transContFlag - 转换合同标志
* @property {string} sugAppntTerminateFlag - 建议投保人终止标志
* @property {string} sugTerminateDesc - 建议终止描述
* @property {*} subSource - 子来源
* @property {*} agentType - 代理类型
* @property {*} payChnls - 支付渠道
* @property {*} newSaleFlag - 新销售标志
* @property {*} assessFlag - 评估标志
* @property {*} assessQuestionnaireDto - 评估问卷
* @property {string} resultRiskType - 结果风险类型
* @property {string} assessResult - 评估结果
* @property {*} assessResultDescMap - 评估结果描述映射
* @property {AssessQuestionnaireDto[]} assessQuestionnaireDtoList - 评估问卷列表
* @property {*} assessJump - 评估跳转
* @property {*} assessUpdateLimitFlag - 评估更新限制标志
* @property {*} cvaliDate - 有效日期
* @property {*} nyearCashValue - 多年现金价值
*/
/**
* 投保人信息DTO
* @typedef {Object} AppntDTO
* @property {*} customerNo - 客户号
* @property {string} orderNo - 订单号
* @property {number} appntId - 投保人ID
* @property {string} name - 姓名
* @property {string} sex - 性别
* @property {string} birthday - 生日
* @property {string} idType - 证件类型
* @property {string} idNo - 证件号码
* @property {*} idNoStar - 脱敏证件号码
* @property {string} certiexpiredate - 证件到期日期
* @property {string} certificateValidate - 证件验证
* @property {string} nativeplace - 籍贯
* @property {string} occupationCode - 职业代码
* @property {string} mobile - 手机号
* @property {*} mobileStar - 脱敏手机号
* @property {*} telephone - 电话
* @property {string} province - 省份
* @property {*} city - 城市
* @property {string} area - 地区
* @property {*} addressNo - 地址编号
* @property {*} zip - 邮编
* @property {string} email - 邮箱
* @property {*} emailStar - 脱敏邮箱
* @property {string} marriage - 婚姻状况
* @property {number} stature - 身高
* @property {number} avoirdupois - 体重
* @property {*} degree - 学历
* @property {*} income - 收入
* @property {*} residentType - 居民类型
* @property {string} relationToInsured - 与被保险人关系
* @property {string} effectiveDateType - 有效日期类型
* @property {string} medical - 医疗
* @property {*} isAsync - 是否异步
* @property {string} workcompany - 工作单位
* @property {*} postalAddress - 邮政地址
* @property {*} occupationType - 职业类型
* @property {string} occupationName - 职业名称
* @property {string} birthdayLabel - 生日标签
* @property {*} marriageDate - 结婚日期
* @property {*} health - 健康状况
* @property {*} joinCompanyDate - 入职日期
* @property {*} startWorkDate - 开始工作日期
* @property {*} position - 职位
* @property {*} salary - 薪资
* @property {*} smokeFlag - 吸烟标志
* @property {*} village - 村庄
* @property {string} taxResidentId - 税收居民ID
* @property {*} countyOfHospital - 医院所在县
* @property {*} hospitalName - 医院名称
* @property {*} hospitalType - 医院类型
* @property {*} stepNumber - 步骤编号
* @property {*} bmi - BMI
* @property {*} cityLevel - 城市等级
* @property {number} averageAnnualIncome - 平均年收入
* @property {*} familyAnnualIncome - 家庭年收入
* @property {ImpartDTO} impartDTO - 告知信息
* @property {FinanceImpartDTO} financeImpartDTO - 财务告知信息
* @property {JobImpartDTO} jobImpartDTO - 职业告知信息
* @property {*} mediaDTOS - 媒体信息
* @property {*} jobStatus - 工作状态
* @property {string} liabilitiesMoney - 负债金额
* @property {*} companyProvince - 公司省份
* @property {*} companyCity - 公司城市
* @property {*} companyArea - 公司地区
* @property {*} companyAddress - 公司地址
* @property {*} companyZip - 公司邮编
* @property {*} companyPhone - 公司电话
* @property {string} homeProvince - 家庭省份
* @property {string} homeCity - 家庭城市
* @property {string} homeArea - 家庭地区
* @property {*} homeProvinceName - 家庭省份名称
* @property {*} homeCityName - 家庭城市名称
* @property {*} homeAreaName - 家庭地区名称
* @property {string} homeAddress - 家庭地址
* @property {*} homeZip - 家庭邮编
* @property {*} homePhone - 家庭电话
* @property {*} signStatus - 签名状态
* @property {*} signDate - 签名日期
* @property {*} householdProvince - 户籍省份
* @property {*} householdCity - 户籍城市
* @property {*} addressStatus - 地址状态
* @property {string} lifeGrade - 寿险等级
* @property {string} healthGrade - 健康等级
* @property {string} salarySource - 薪资来源
* @property {string} otherSalarySource - 其他薪资来源
* @property {string} age - 年龄
* @property {*} totalPremAll - 总保费
* @property {*} proposalCoverUrl - 建议书封面URL
* @property {*} entryAge - 入职年龄
* @property {*} maritalStatus - 婚姻状态
* @property {*} ridStatus - RID状态
* @property {*} street - 街道
* @property {*} loadNo - 加载编号
* @property {*} schoolName - 学校名称
* @property {*} className - 班级名称
* @property {*} invTyp - 投资类型
* @property {string} npType - NP类型
* @property {string} isNewPeopleFlag - 是否新人标志
* @property {*} fincome - 家庭收入
* @property {*} faverageIncome - 家庭平均收入
*/
/**
* 被保险人信息DTO
* @typedef {Object} InsuredDTO
* @property {number} insuredId - 被保险人ID
* @property {string} orderNo - 订单号
* @property {*} occupationType - 职业类型
* @property {string} occupationName - 职业名称
* @property {string} nativeplace - 籍贯
* @property {*} insuredNo - 被保险人编号
* @property {*} socialSecurity - 社保
* @property {string} name - 姓名
* @property {string} sex - 性别
* @property {string} birthday - 生日
* @property {string} idType - 证件类型
* @property {string} idNo - 证件号码
* @property {*} idNoStar - 脱敏证件号码
* @property {string} certiexpiredate - 证件到期日期
* @property {string} certificateValidate - 证件验证
* @property {*} insuredAge - 被保险人年龄
* @property {string} occupationCode - 职业代码
* @property {*} insuredJobClass - 被保险人工作类别
* @property {string} mobile - 手机号
* @property {*} mobileStar - 脱敏手机号
* @property {*} telephone - 电话
* @property {string} province - 省份
* @property {*} city - 城市
* @property {string} area - 地区
* @property {*} addressNo - 地址编号
* @property {*} zip - 邮编
* @property {*} email - 邮箱
* @property {*} emailStar - 脱敏邮箱
* @property {string} marriage - 婚姻状况
* @property {*} health - 健康状况
* @property {number} stature - 身高
* @property {number} avoirdupois - 体重
* @property {*} degree - 学历
* @property {*} income - 收入
* @property {*} impartAmnt - 告知金额
* @property {string} effectiveDateType - 有效日期类型
* @property {*} postalAddress - 邮政地址
* @property {string} workcompany - 工作单位
* @property {*} isAsync - 是否异步
* @property {*} relationToMainInsured - 与主被保险人关系
* @property {string} relationToAppnt - 与投保人关系
* @property {*} bankCode - 银行代码
* @property {*} cardBookCode - 存折代码
* @property {*} cardBookType - 存折类型
* @property {*} countyOfHospital - 医院所在县
* @property {string} medical - 医疗
* @property {string} birthdayLabel - 生日标签
* @property {*} bnfDTOs - 受益人信息
* @property {RiskDTO[]} riskDTOLst - 险种信息列表
* @property {ImpartDTO} impartDTO - 告知信息
* @property {FinanceImpartDTO} financeImpartDTO - 财务告知信息
* @property {JobImpartDTO} jobImpartDTO - 职业告知信息
* @property {*} marriageDate - 结婚日期
* @property {*} joinCompanyDate - 入职日期
* @property {*} startWorkDate - 开始工作日期
* @property {*} position - 职位
* @property {*} salary - 薪资
* @property {*} smokeFlag - 吸烟标志
* @property {*} village - 村庄
* @property {string} taxResidentId - 税收居民ID
* @property {*} hospitalType - 医院类型
* @property {*} hospitalName - 医院名称
* @property {*} stepNumber - 步骤编号
* @property {*} bmi - BMI
* @property {*} cityLevel - 城市等级
* @property {number} averageAnnualIncome - 平均年收入
* @property {*} familyAnnualIncome - 家庭年收入
* @property {*} totalPrem - 总保费
* @property {*} totalAmt - 总保额
* @property {*} mediaDTOS - 媒体信息
* @property {*} jobStatus - 工作状态
* @property {string} liabilitiesMoney - 负债金额
* @property {*} companyProvince - 公司省份
* @property {*} companyCity - 公司城市
* @property {*} companyArea - 公司地区
* @property {*} companyAddress - 公司地址
* @property {*} companyZip - 公司邮编
* @property {*} companyPhone - 公司电话
* @property {string} homeProvince - 家庭省份
* @property {string} homeCity - 家庭城市
* @property {string} homeArea - 家庭地区
* @property {*} homeProvinceName - 家庭省份名称
* @property {*} homeCityName - 家庭城市名称
* @property {*} homeAreaName - 家庭地区名称
* @property {string} homeAddress - 家庭地址
* @property {*} homeZip - 家庭邮编
* @property {*} homePhone - 家庭电话
* @property {*} signStatus - 签名状态
* @property {*} signDate - 签名日期
* @property {*} householdProvince - 户籍省份
* @property {*} householdCity - 户籍城市
* @property {*} addressStatus - 地址状态
* @property {string} lifeGrade - 寿险等级
* @property {string} healthGrade - 健康等级
* @property {string} salarySource - 薪资来源
* @property {string} otherSalarySource - 其他薪资来源
* @property {*} dutySortResult - 职责分类结果
* @property {*} maritalStatus - 婚姻状态
* @property {*} ridStatus - RID状态
* @property {*} otherRiskDTOLst - 其他险种信息列表
* @property {*} street - 街道
* @property {*} loadNo - 加载编号
* @property {*} schoolName - 学校名称
* @property {*} className - 班级名称
* @property {*} contPlanCode - 合同计划代码
* @property {string} npType - NP类型
* @property {string} isNewPeopleFlag - 是否新人标志
* @property {*} fincome - 家庭收入
* @property {*} faverageIncome - 家庭平均收入
*/
/**
* 订单账户信息DTO
* @typedef {Object} OrderAccountDTO
* @property {string} orderNo - 订单号
* @property {string} accountName - 账户名称
* @property {number} accountId - 账户ID
* @property {string} bankName - 银行名称
* @property {string} bankCode - 银行代码
* @property {*} syBankCode - SY银行代码
* @property {*} syAreaCode - SY地区代码
* @property {*} syLocationCode - SY位置代码
* @property {*} otherBankCode - 其他银行代码
* @property {string} cardBookType - 存折类型
* @property {string} cardBookCode - 存折代码
* @property {*} expiredDate - 过期日期
* @property {*} cvv2Code - CVV2代码
* @property {string} createdDate - 创建日期
* @property {*} modifiedDate - 修改日期
* @property {*} createdUser - 创建用户
* @property {*} modifiedUser - 修改用户
* @property {number} isDelete - 是否删除
* @property {*} isAutoRenewal - 是否自动续期
* @property {*} isAutoPay - 是否自动支付
* @property {string} accountType - 账户类型
* @property {string} accBankProvince - 银行省份
* @property {string} accBankCity - 银行城市
* @property {*} cw2Code - CW2代码
*/
/**
* 推荐信息DTO
* @typedef {Object} RecmdDTO
* @property {*} agentChannel - 代理渠道
* @property {*} agentList - 代理列表
* @property {*} city - 城市
* @property {*} code - 代码
* @property {*} customerId - 客户ID
* @property {*} customerName - 客户名称
* @property {*} customerManager - 客户经理
* @property {*} hasRecommend - 是否推荐
* @property {*} manageOrgLabel - 管理机构标签
* @property {*} productChannel - 产品渠道
* @property {*} productCode - 产品代码
* @property {*} saleChannel - 销售渠道
* @property {*} saleChannelDetail - 销售渠道详情
* @property {string} orderNo - 订单号
* @property {string} recommendType - 推荐类型
* @property {string} agentCode - 代理代码
* @property {string} name - 姓名
* @property {*} agentGroup - 代理组
* @property {string} managerOrg - 管理机构
* @property {*} employeeId - 员工ID
* @property {string} createdDate - 创建日期
* @property {string} remark - 备注
* @property {*} remark2 - 备注2
* @property {*} remark3 - 备注3
* @property {string} remark4 - 备注4
* @property {*} shareId - 分享ID
* @property {string} manageComCode - 管理公司代码
* @property {*} mobile - 手机号
* @property {*} certificateNo - 证书编号
* @property {*} comAddress - 公司地址
* @property {*} sex - 性别
* @property {*} birthday - 生日
* @property {*} idType - 证件类型
* @property {*} idNo - 证件号码
* @property {*} source - 来源
* @property {string} virtualAgentCode - 虚拟代理代码
* @property {string} salesComCode - 销售公司代码
*/
/**
* 媒体信息DTO
* @typedef {Object} MediaDTO
* @property {string} businessNo - 业务号
* @property {string} businessType - 业务类型
* @property {string} imageInfoType - 图像信息类型
* @property {string} rgssUrl - RGSS URL
* @property {string} subBusinessType - 子业务类型
* @property {string} subBusinessNo - 子业务号
* @property {*} pageNum - 页码
* @property {*} imageUrl - 图像URL
* @property {*} pageCode - 页面代码
* @property {*} fileName - 文件名
* @property {*} pageList - 页面列表
*/
/**
* 电子签名信息DTO
* @typedef {Object} EbizSignDTO
* @property {number} signId - 签名ID
* @property {*} signOrRead - 签名或阅读
* @property {*} caType - CA类型
* @property {*} copyValue - 复制值
* @property {*} baseEncryp - 基础加密
* @property {string} orderNo - 订单号
* @property {*} riskCode - 险种代码
* @property {string} documentName - 文档名称
* @property {string} documentCode - 文档代码
* @property {string} policyUrl - 保单URL
* @property {string} originalUrl - 原始URL
* @property {string} documentType - 文档类型
* @property {string} documentStatus - 文档状态
* @property {string} signType - 签名类型
* @property {*} relationId - 关联ID
* @property {*} signDate - 签名日期
* @property {string} createdDate - 创建日期
* @property {*} modifiedDate - 修改日期
* @property {*} createdUser - 创建用户
* @property {*} modifiedUser - 修改用户
* @property {number} isDelete - 是否删除
* @property {*} isSigned - 是否已签名
* @property {*} caSignEnteringGinseng - CA签名录入人参
* @property {*} caSignExoticGinseng - CA签名异国人参
*/
/**
* 通用风险通知信息DTO
* @typedef {Object} UniversalRiskNotifyDTO
* @property {*} id - ID
* @property {*} orderNo - 订单号
* @property {*} agentCode - 代理代码
* @property {*} appntName - 投保人姓名
* @property {*} appntIdNo - 投保人证件号码
* @property {*} appntIdType - 投保人证件类型
* @property {*} quentionAnswer - 问题答案
* @property {*} totalScore - 总分
* @property {*} isNewProduct - 是否新产品
* @property {*} tipContent - 提示内容
* @property {*} statementContent - 声明内容
* @property {*} pdfUrl - PDF URL
* @property {*} signPdfUrl - 签名PDF URL
* @property {*} createdDate - 创建日期
* @property {*} createdUser - 创建用户
* @property {*} modifiedUser - 修改用户
* @property {*} modifiedDate - 修改日期
* @property {string} isUniversalRiskNotifyShowPoint - 是否显示通用风险通知点
* @property {*} isDelete - 是否删除
*/
/**
* 订单关联信息DTO
* @typedef {Object} EbizOrderGbcRelDTO
* @property {*} relId - 关联ID
* @property {*} orderNo - 订单号
* @property {*} projectCode - 项目代码
* @property {*} projectName - 项目名称
* @property {*} projectEndDate - 项目结束日期
* @property {*} platformCode - 平台代码
* @property {*} unitName - 单位名称
* @property {*} personCode - 人员代码
* @property {*} personName - 人员名称
* @property {*} teamCode - 团队代码
* @property {*} teamName - 团队名称
* @property {*} teamLeaderCode - 团队领导代码
* @property {*} departmentCode - 部门代码
* @property {*} departmentName - 部门名称
* @property {*} createdDate - 创建日期
* @property {*} createdUser - 创建用户
* @property {*} modifiedDate - 修改日期
* @property {*} modifiedUser - 修改用户
* @property {*} isDelete - 是否删除
*/
/**
* 评估问卷DTO
* @typedef {Object} AssessQuestionnaireDto
* @property {string} orderNo - 订单号
* @property {string} questionNo - 问题编号
* @property {string} questionContent - 问题内容
* @property {string} choose - 选择
* @property {string} chooseContent - 选择内容
* @property {*} subOption - 子选项
* @property {*} subOptionContent - 子选项内容
* @property {string} score - 分数
* @property {*} chooseDesc - 选择描述
* @property {string} appntIdNo - 投保人证件号码
* @property {string} appntName - 投保人姓名
* @property {string} appntIsFirst - 投保人是否首次
* @property {string} assessDate - 评估日期
*/
/**
* 告知信息DTO
* @typedef {Object} ImpartDTO
* @property {*} orderNo - 订单号
* @property {*} relationId - 关联ID
* @property {string} impartType - 告知类型
* @property {ImpartItemDTO[]} impartItemDTOS - 告知项目列表
*/
/**
* 财务告知信息DTO
* @typedef {Object} FinanceImpartDTO
* @property {*} orderNo - 订单号
* @property {*} relationId - 关联ID
* @property {string} impartType - 告知类型
* @property {ImpartItemDTO[]} impartItemDTOS - 告知项目列表
*/
/**
* 职业告知信息DTO
* @typedef {Object} JobImpartDTO
* @property {*} orderNo - 订单号
* @property {*} relationId - 关联ID
* @property {string} impartType - 告知类型
* @property {ImpartItemDTO[]} impartItemDTOS - 告知项目列表
*/
/**
* 告知项目DTO
* @typedef {Object} ImpartItemDTO
* @property {number} impartId - 告知ID
* @property {string} impartCode - 告知代码
* @property {string} impartContent - 告知内容
* @property {*} height - 身高
* @property {*} weight - 体重
* @property {string} impartAnswer - 告知答案
* @property {*} impartVersion - 告知版本
* @property {*} impartNo - 告知编号
* @property {*} impartConten - 告知内容
* @property {*} impartParam - 告知参数
* @property {*} impartParamName - 告知参数名称
* @property {*} impartSource - 告知来源
* @property {string} impartRemark - 告知备注
* @property {Question[]} questions - 问题列表
*/
/**
* 问题
* @typedef {Object} Question
* @property {string} questionContent - 问题内容
* @property {string} answer - 答案
* @property {string} questionType - 问题类型
*/
/**
* 险种信息DTO
* @typedef {Object} RiskDTO
* @property {*} bonusGetMode - 红利领取方式
* @property {string} mainRiskCode - 主险代码
* @property {number} insuredId - 被保险人ID
* @property {number} insuanceId - 保险ID
* @property {string} orderNo - 订单号
* @property {*} itemCode - 项目代码
* @property {*} productName - 产品名称
* @property {string} riskCode - 险种代码
* @property {string} riskName - 险种名称
* @property {*} planCode - 计划代码
* @property {*} planCodeLabel - 计划代码标签
* @property {*} planName - 计划名称
* @property {number} prem - 保费
* @property {number} showPrem - 显示保费
* @property {number} amt - 保额
* @property {number} standPrem - 标准保费
* @property {*} addPrem - 附加保费
* @property {*} mult - 倍数
* @property {string} insuYearFlag - 保险年限标志
* @property {number} insuYear - 保险年限
* @property {*} startInsureDate - 开始保险日期
* @property {*} stopInsureDate - 停止保险日期
* @property {number} payEndYear - 缴费终止年
* @property {string} payEndYearFlag - 缴费终止年标志
* @property {string} isMainRisk - 是否主险
* @property {string} riskType - 险种类型
* @property {Array} dutyLst - 责任列表
* @property {*} duty - 责任
* @property {number} payIntv - 缴费间隔
* @property {*} diseaseType - 疾病类型
* @property {*} cvaliDate - 有效日期
* @property {*} calFlag - 计算标志
* @property {*} getEndYear - 领取终止年
* @property {*} getEndYearFlag - 领取终止年标志
* @property {*} years - 年数
* @property {*} getYearFlag - 领取年标志
* @property {*} getYear - 领取年
* @property {*} riskGrade - 险种等级
* @property {*} acciYearFlag - 意外年标志
* @property {*} acciYear - 意外年
* @property {*} firstPremNum - 首期保费数
* @property {*} getStartDate - 领取开始日期
* @property {*} getEndDate - 领取结束日期
* @property {*} deadGetMode - 身故领取方式
* @property {*} liveGetMode - 生存领取方式
* @property {*} autoPayFlag - 自动支付标志
* @property {*} airNo - 航班号
* @property {*} flyDate - 飞行日期
* @property {*} claimScale - 理赔比例
* @property {*} deductAmt - 扣除金额
* @property {*} rnewFlag - 续保标志
* @property {*} protocolCode - 协议代码
* @property {string} thirdInsuraceNo - 第三方保险号
* @property {*} thirdInsuraceNos - 第三方保险号列表
* @property {*} contPlanCode - 合同计划代码
* @property {*} riskLevel - 险种等级
* @property {*} getIntv - 领取间隔
* @property {*} isDelete - 是否删除
* @property {string} createdDate - 创建日期
* @property {*} predictTransferPrem - 预估转移保费
* @property {number} intMult - 利率倍数
* @property {string} pdfRiskCode - PDF险种代码
* @property {*} getLimit - 领取限额
* @property {*} getRate - 领取费率
* @property {*} specInsuredFlag - 特殊被保险人标志
* @property {*} url - URL
* @property {*} clauseName - 条款名称
* @property {*} riskDutySortResult - 险种责任分类结果
* @property {*} isRotate - 是否轮换
* @property {*} lineNum - 行号
* @property {*} thead - 表头
* @property {*} tableFontSize - 表格字体大小
* @property {*} benefitPageCSS - 利益页面CSS
* @property {*} benefitDesc - 利益描述
* @property {*} proposalCoverUrl - 建议书封面URL
* @property {string} isRemit - 是否汇款
* @property {*} productLongtime - 产品长期
* @property {*} riderRiskList - 附加险列表
* @property {*} choFlag - 选择标志
* @property {*} isRenewal - 是否续保
* @property {*} proScheme - 产品方案
* @property {*} proSchemeCode - 产品方案代码
* @property {*} firstOr - 首期或
* @property {string} medical - 医疗
* @property {*} chooseKind - 选择种类
* @property {*} educationStage - 教育阶段
* @property {*} renewType - 续保类型
* @property {*} additionalInsuranceFlag - 附加保险标志
* @property {*} guaranteedYear - 保证年
* @property {*} pensionAge - 养老年龄
* @property {*} receivePensionWay - 领取养老金方式
* @property {*} productPlanCode - 产品计划代码
*/

View File

@@ -0,0 +1,24 @@
/**
* 险种列表响应数据结构
* @typedef {Object} OrderRiskListResponse
* @property {string} result - 请求结果代码,"0"表示成功
* @property {string} resultMessage - 请求结果消息
* @property {null} content - 内容主体在此接口中为null
* @property {OrderRiskListItem[]} mainRiskDTOS - 主险列表
*/
/**
* 主险信息
* @typedef {Object} OrderRiskListItem
* @property {string} riskName - 险种名称
* @property {string} riskProductCode - 险种产品代码
* @property {string} productType - 产品类型
* @property {string} mutexRisk - 互斥险种代码列表(逗号分隔)
* @property {string[]} channels - 销售渠道列表
* @property {null} activeLst - 活动列表在此接口中为null
* @property {null} saleStartTime - 销售开始时间在此接口中为null
* @property {null} saleEndTime - 销售结束时间在此接口中为null
* @property {null} agentComLst - 代理公司列表在此接口中为null
* @property {null} netPinComLst - 网络公司列表在此接口中为null
* @property {null} occupationCodeLst - 职业代码列表在此接口中为null
*/

View File

@@ -0,0 +1,146 @@
/**
* 投保人信息
* @typedef {Object} AppntDTO
* @property {string} name - 投保人姓名
* @property {string} sex - 性别("1" 表示男,"2" 表示女,具体编码依业务而定)
* @property {string} birthday - 出生日期格式YYYY-MM-DD
* @property {string} idType - 证件类型编码(如 "1" 表示身份证)
* @property {string} idNo - 证件号码
*/
/**
* 被保险人信息
* @typedef {Object} InsuredDTO
* @property {string|null} insuredId - 被保险人ID
* @property {string|null} orderNo - 订单号
* @property {string|null} occupationType - 职业类型
* @property {string|null} occupationName - 职业名称
* @property {string|null} nativeplace - 籍贯
* @property {string|null} insuredNo - 被保险人编号
* @property {string|null} socialSecurity - 社保情况
* @property {string} name - 被保险人姓名
* @property {string} sex - 性别("1" 表示男,"2" 表示女)
* @property {string} birthday - 出生日期格式YYYY-MM-DD
* @property {string} idType - 证件类型编码
* @property {string} idNo - 证件号码
* @property {string|null} idNoStar - 脱敏证件号码
* @property {string|null} certiexpiredate - 证件有效期
* @property {string|null} certificateValidate - 证件是否长期有效
* @property {string|null} insuredAge - 被保险人年龄
* @property {string|null} occupationCode - 职业编码
* @property {string|null} insuredJobClass - 被保险人工作类别
* @property {string|null} mobile - 手机号码
* @property {string|null} mobileStar - 脱敏手机号码
* @property {string|null} telephone - 固定电话
* @property {string|null} province - 省份
* @property {string|null} city - 城市
* @property {string|null} area - 地区
* @property {string|null} addressNo - 地址编号
* @property {string|null} zip - 邮编
* @property {string|null} email - 邮箱
* @property {string|null} emailStar - 脱敏邮箱
* @property {string|null} marriage - 婚姻状况
* @property {string|null} health - 健康状况
* @property {string|null} stature - 身高
* @property {string|null} avoirdupois - 体重
* @property {string|null} degree - 学历
* @property {string|null} income - 收入
* @property {string|null} impartAmnt - 告知金额
* @property {string|null} effectiveDateType - 生效日期类型
* @property {string|null} postalAddress - 通讯地址
* @property {string|null} workcompany - 工作单位
* @property {string|null} isAsync - 是否异步处理
* @property {string|null} relationToMainInsured - 与主被保险人关系
* @property {string|null} relationToAppnt - 与投保人关系
* @property {string|null} bankCode - 银行代码
* @property {string|null} cardBookCode - 存折号/银行卡号
* @property {string|null} cardBookType - 存折类型
* @property {string|null} countyOfHospital - 医院所在地区
* @property {string|null} medical - 医疗情况
* @property {string|null} birthdayLabel - 生日标签
* @property {Array|null} bnfDTOs - 受益人信息列表
* @property {Array|null} riskDTOLst - 险种信息列表
* @property {Object|null} impartDTO - 告知信息
* @property {Object|null} financeImpartDTO - 财务告知信息
* @property {Object|null} jobImpartDTO - 职业告知信息
* @property {string|null} marriageDate - 结婚日期
* @property {string|null} joinCompanyDate - 入职日期
* @property {string|null} startWorkDate - 开始工作日期
* @property {string|null} position - 职位
* @property {string|null} salary - 薪资
* @property {string|null} smokeFlag - 吸烟标志
* @property {string|null} village - 村庄
* @property {string|null} taxResidentId - 税收居民身份
* @property {string|null} hospitalType - 医院类型
* @property {string|null} hospitalName - 医院名称
* @property {string|null} stepNumber - 步骤编号
* @property {string|null} bmi - BMI指数
* @property {string|null} cityLevel - 城市等级
* @property {string|null} averageAnnualIncome - 平均年收入
* @property {string|null} familyAnnualIncome - 家庭年收入
* @property {string|null} totalPrem - 总保费
* @property {string|null} totalAmt - 总保额
* @property {Array|null} mediaDTOS - 媒体信息列表
* @property {string|null} jobStatus - 工作状态
* @property {string|null} liabilitiesMoney - 负债金额
* @property {string|null} companyProvince - 公司省份
* @property {string|null} companyCity - 公司城市
* @property {string|null} companyArea - 公司区域
* @property {string|null} companyAddress - 公司地址
* @property {string|null} companyZip - 公司邮编
* @property {string|null} companyPhone - 公司电话
* @property {string|null} homeProvince - 家庭住址省份
* @property {string|null} homeCity - 家庭住址城市
* @property {string|null} homeArea - 家庭住址区域
* @property {string|null} homeProvinceName - 家庭住址省份名称
* @property {string|null} homeCityName - 家庭住址城市名称
* @property {string|null} homeAreaName - 家庭住址区域名称
* @property {string|null} homeAddress - 家庭住址
* @property {string|null} homeZip - 家庭住址邮编
* @property {string|null} homePhone - 家庭电话
* @property {string|null} signStatus - 签约状态
* @property {string|null} signDate - 签约日期
* @property {string|null} householdProvince - 户籍省份
* @property {string|null} householdCity - 户籍城市
* @property {string|null} addressStatus - 地址状态
* @property {string|null} lifeGrade - 寿险等级
* @property {string|null} healthGrade - 健康等级
* @property {string|null} salarySource - 薪资来源
* @property {string|null} otherSalarySource - 其他薪资来源
* @property {string|null} dutySortResult - 职业分类结果
* @property {string|null} maritalStatus - 婚姻状态
* @property {string|null} ridStatus - RID状态
* @property {Array|null} otherRiskDTOLst - 其他险种信息列表
* @property {string|null} street - 街道
* @property {string|null} loadNo - 加载编号
* @property {string|null} schoolName - 学校名称
* @property {string|null} className - 班级名称
* @property {string|null} contPlanCode - 合同计划代码
* @property {string|null} npType - NP类型
* @property {string|null} isNewPeopleFlag - 是否新人标识
* @property {string|null} fincome - 家庭收入
* @property {string|null} faverageIncome - 家庭平均收入
*/
/**
* 险种信息
* @typedef {Object} RiskDTO
* @property {string} riskCode - 险种代码
* @property {string} mainRiskCode - 主险代码(若为空字符串,表示该险种为主险或无主险)
*/
/**
* 保险订单数据结构
* @typedef {Object} InsuranceOrderDTO
* @property {string} orderNo - 订单号
* @property {string} prtNo - 打印号(通常与订单号一致)
* @property {AppntDTO} appntDTO - 投保人信息
* @property {InsuredDTO[]} insuredDTO - 被保险人列表(支持多人)
* @property {RiskDTO[]} riskDTOLst - 险种列表
* @property {string} contState - 保单状态
* @property {string} preUWState - 预核保状态
* @property {string} preUWConClusion - 预核保结论
* @property {string} issueState - 预核保问题件状态
* @property {string} appFlag - 投保单标识
* @property {string} uwFlag - 核保标识
*/

View File

@@ -0,0 +1,6 @@
/**
* 险种信息
* @typedef {Object} RiskType
* @property {String} value - 险种代码
* @property {String} label - 展示中文的姓名
*/

View File

@@ -0,0 +1,329 @@
// 模拟路由配置数据,基于实际项目结构
const mockRoutes = [
{
path: '/underwriting',
name: 'PreliminaryUnderwriting',
component: () => import('@/views/ebiz/underwriting/PreliminaryUnderwritingContainer.vue'),
children: [
{
path: 'list',
name: 'UnderwritingOrderList',
meta: { title: '预核保订单列表' },
component: () => import('@/views/ebiz/underwriting/OrderList.vue')
},
{
path: 'data-collection',
name: 'UnderwritingDataCollection',
meta: { title: '信息录入' },
component: () => import('@/views/ebiz/underwriting/UnderwritingDataCollection.vue')
},
{
path: 'supplementary-information',
name: 'UnderwritingSupplementaryInformation',
meta: { title: '补传资料' },
component: () => import('@/views/ebiz/underwriting/SupplementaryInformation.vue')
},
{
path: 'result',
name: 'UnderwritingResult',
meta: { title: '预核保结果' },
component: () => import('@/views/ebiz/underwriting/Result.vue')
},
{
path: 'contract-sign',
name: 'UnderwritingContractSign',
meta: { title: '签名确认' },
component: () => import('@/views/ebiz/underwriting/SignContract.vue')
},
{
path: 'document-info',
name: 'UnderwritingDocumentInfo',
meta: { title: '预核保资料' },
component: () => import('@/views/ebiz/underwriting/DocumentInfo.vue')
}
]
},
{
path: '/other',
name: 'Other',
component: () => import('@/views/other/OtherContainer.vue'),
children: [
{
path: 'nested',
name: 'Nested',
component: () => import('@/views/other/Nested.vue'),
children: [
{
path: 'deep',
name: 'DeepNested',
meta: { title: '深层嵌套路由' },
component: () => import('@/views/other/DeepNested.vue')
}
]
}
]
},
{
path: '/',
name: 'Home',
component: () => import('@/views/Home.vue')
},
{
path: '/simple',
name: 'SimpleRoute',
meta: { title: '简单路由' },
component: () => import('@/views/Simple.vue')
}
];
/**
* 递归查找具有指定路径的路由(支持多层嵌套)
* @param routes 路由数组
* @param targetPath 目标路径
* @param parentPath 父级路径
* @returns 匹配的路由信息或undefined
*/
function findRouteByPath(routes, targetPath, parentPath = '') {
if (!routes || !Array.isArray(routes)) return undefined
// 规范化目标路径,移除多余的斜杠
targetPath = targetPath.replace(/\/+/g, '/')
for (const route of routes) {
// 构造当前路由的完整路径
let currentPath = parentPath
if (currentPath && !currentPath.endsWith('/') && route.path && !route.path.startsWith('/')) {
currentPath += '/' + route.path
} else {
currentPath += route.path
}
// 移除多余的斜杠
currentPath = currentPath.replace(/\/+/g, '/')
// 检查当前路由是否匹配
if (currentPath === targetPath) {
return {
route: route,
fullPath: currentPath
}
}
// 递归检查子路由
if (route.children && route.children.length > 0) {
const matchedChild = findRouteByPath(route.children, targetPath, currentPath)
if (matchedChild) {
return matchedChild
}
}
}
return undefined
}
/**
* 递归查找具有指定名称的路由(支持多层嵌套)
* @param routes 路由数组
* @param targetName 目标名称
* @param routeStack 用于追踪路由层级的堆栈
* @returns 包含路由和路由堆栈的对象或undefined
*/
function findRouteByName(routes, targetName, routeStack = []) {
if (!routes || !Array.isArray(routes)) return undefined
for (const route of routes) {
// 创建当前路由的堆栈副本
const currentStack = [...routeStack, route]
// 检查当前路由是否匹配
if (route.name === targetName) {
return {
route: route,
routeStack: currentStack
}
}
// 递归检查子路由
if (route.children && route.children.length > 0) {
const matchedChild = findRouteByName(route.children, targetName, currentStack)
if (matchedChild) {
return matchedChild
}
}
}
return undefined
}
/**
* 根据路由堆栈构建完整路径
* @param routeStack 路由堆栈
* @returns 完整路径字符串
*/
function buildFullPath(routeStack) {
if (!routeStack || routeStack.length === 0) return ''
// 提取所有路由的路径并正确拼接
let fullPath = ''
routeStack.forEach((route, index) => {
// 特殊处理第一个路由
if (index === 0) {
fullPath += route.path
} else {
if (fullPath && !fullPath.endsWith('/') && route.path && !route.path.startsWith('/')) {
fullPath += '/' + route.path
} else if (fullPath.endsWith('/') && route.path.startsWith('/')) {
// 如果fullPath以/结尾而route.path以/开头,则需要去掉一个/
fullPath += route.path.substring(1)
} else {
fullPath += route.path
}
}
})
// 移除多余的斜杠
fullPath = fullPath.replace(/\/+/g, '/')
// 确保不会在末尾留下斜杠(除非是根路径)
if (fullPath.length > 1 && fullPath.endsWith('/')) {
fullPath = fullPath.slice(0, -1)
}
return fullPath
}
describe('Underwriting Navigate Functions', () => {
describe('findRouteByPath', () => {
it('应该能找到根路径路由', () => {
const result = findRouteByPath(mockRoutes, '/')
expect(result).not.toBeUndefined()
expect(result.route.name).toBe('Home')
})
it('应该能找到简单路径路由', () => {
const result = findRouteByPath(mockRoutes, '/simple')
expect(result).not.toBeUndefined()
expect(result.route.name).toBe('SimpleRoute')
})
it('应该能找到一级嵌套路由', () => {
const result = findRouteByPath(mockRoutes, '/underwriting')
expect(result).not.toBeUndefined()
expect(result.route.name).toBe('PreliminaryUnderwriting')
})
it('应该能找到二级嵌套路由', () => {
const result = findRouteByPath(mockRoutes, '/underwriting/list')
expect(result).not.toBeUndefined()
expect(result.route.name).toBe('UnderwritingOrderList')
})
it('应该能找到三级嵌套路由', () => {
const result = findRouteByPath(mockRoutes, '/other/nested/deep')
expect(result).not.toBeUndefined()
expect(result.route.name).toBe('DeepNested')
})
it('应该返回undefined当找不到路由时', () => {
const result = findRouteByPath(mockRoutes, '/nonexistent')
expect(result).toBeUndefined()
})
it('应该正确处理带有多个斜杠的路径', () => {
// 实际上我们查找的是 /underwriting/list只是输入路径中有多余的斜杠
const result = findRouteByPath(mockRoutes, '/underwriting///list')
expect(result).not.toBeUndefined()
expect(result.route.name).toBe('UnderwritingOrderList')
})
})
describe('findRouteByName', () => {
it('应该通过名称找到根路径路由', () => {
const result = findRouteByName(mockRoutes, 'Home')
expect(result).not.toBeUndefined()
expect(result.route.name).toBe('Home')
})
it('应该通过名称找到简单路径路由', () => {
const result = findRouteByName(mockRoutes, 'SimpleRoute')
expect(result).not.toBeUndefined()
expect(result.route.name).toBe('SimpleRoute')
})
it('应该通过名称找到一级嵌套路由', () => {
const result = findRouteByName(mockRoutes, 'PreliminaryUnderwriting')
expect(result).not.toBeUndefined()
expect(result.route.name).toBe('PreliminaryUnderwriting')
})
it('应该通过名称找到二级嵌套路由', () => {
const result = findRouteByName(mockRoutes, 'UnderwritingOrderList')
expect(result).not.toBeUndefined()
expect(result.route.name).toBe('UnderwritingOrderList')
})
it('应该通过名称找到三级嵌套路由', () => {
const result = findRouteByName(mockRoutes, 'DeepNested')
expect(result).not.toBeUndefined()
expect(result.route.name).toBe('DeepNested')
})
it('应该返回undefined当找不到路由时', () => {
const result = findRouteByName(mockRoutes, 'NonExistent')
expect(result).toBeUndefined()
})
})
describe('buildFullPath', () => {
it('应该正确构建根路径', () => {
const routeStack = [{ path: '/' }]
const result = buildFullPath(routeStack)
expect(result).toBe('/')
})
it('应该正确构建简单路径', () => {
const routeStack = [
{ path: '/' },
{ path: 'simple' }
]
const result = buildFullPath(routeStack)
expect(result).toBe('/simple')
})
it('应该正确构建嵌套路径', () => {
const routeStack = [
{ path: '/underwriting' },
{ path: 'list' }
]
const result = buildFullPath(routeStack)
expect(result).toBe('/underwriting/list')
})
it('应该正确构建深层嵌套路径', () => {
const routeStack = [
{ path: '/other' },
{ path: 'nested' },
{ path: 'deep' }
]
const result = buildFullPath(routeStack)
expect(result).toBe('/other/nested/deep')
})
it('应该正确处理空路由堆栈', () => {
const result = buildFullPath([])
expect(result).toBe('')
})
it('应该正确处理多余的斜杠', () => {
const routeStack = [
{ path: '/underwriting/' },
{ path: '/list/' }
]
const result = buildFullPath(routeStack)
// 由于路径规范化处理,结果应该是 /underwriting/list 而不是 /underwriting//list
expect(result).toBe('/underwriting/list')
})
})
})