Compare commits

...

33 Commits

Author SHA1 Message Date
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
xuxinxiang
beba5a9e69 Merge branch 'feature/FCRS-1048投保流程优化需求' into dev-new 2025-12-04 21:17:24 +08:00
xuxinxiang
27311ca621 修复部分问题 2025-12-04 21:16:34 +08:00
25 changed files with 1652 additions and 63 deletions

View File

@@ -0,0 +1,49 @@
import request from '@/assets/js/utils/request'
import getUrl from '@/assets/js/utils/get-url'
// 获取培训系统中心页面
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 postSupplementaryInformation(data) {
return request({
url: getUrl('/sale/orderPreUW/orderPreUWDetail', 1),
method: 'post',
data
})
}
// 预核保查询接口
export function fetchUnderwritingOrderInfomation(orderNo) {
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 }
})
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,37 @@
/**
* 预核保路由信息
* @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/:orderNo',
name: 'UnderwritingSupplementaryInformation',
meta: { title: '补传资料' },
component: () => import('@/views/ebiz/underwriting/SupplementaryInformation.vue')
},
{
path: 'result',
name: 'UnderwritingResult',
meta: { title: '预核保结果' },
component: () => import('@/views/ebiz/underwriting/Result.vue')
}
]
}
]

View File

@@ -583,7 +583,8 @@ export default {
localStorage.orderNo = orderNo
localStorage.isFrom = 'sale'
localStorage.removeItem('changeCard')
// 是否进入新流程的标识
const recordedNewProd = order.orderInfoDTO.newSaleFlag === '0'
if (orderStatus == '01') {
//已签名待客户确认, 跳到签名确认页面
url = '/sale/SignatureConfirmation?edit=1&orderNo=' + orderNo
@@ -597,11 +598,11 @@ export default {
//被保险人保存成功, 跳到已选产品列表
url = processURL('/common/selectedProduct?edit=1&orderNo=' + orderNo)
} 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') {
//账户信息保存成功, 跳到附件管理--
if (order.orderInfoDTO.activeType == 'KMH') {
if (order.orderInfoDTO.activeType === 'KMH') {
let params = {
orderNo: order.orderInfoDTO.orderNo
}
@@ -628,7 +629,7 @@ export default {
}
})
} else {
url = '/sale/AttachmentManagement?edit=1&orderNo=' + orderNo
url = processURL('/sale/AttachmentManagement?edit=1&orderNo=' + orderNo)
}
} else if (orderStatus == '39') {
//险种信息保存成功, 跳到已选产品列表

View File

@@ -92,14 +92,14 @@
class="budget-input"
>
</template>
<div class="fs12 c-gray-base">请填写0-10000之间的整数</div>
<div class="fs12 c-gray-base">请填写大于等于0的整数或保留两位小数点的非整数</div>
</p>
</div>
</div>
</div>
</div>
<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>
<PopupQuesResult
@reTestHandler="reTest"
@@ -641,6 +641,9 @@ export default {
this.getDetailInfo()
},
submitAnswer(){
if( this.disabled ){
return this.$toast('请填写完整信息')
}
if(this.answerList.length !=this.questionList.length){
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)})
|| !regex.test(this.answerList[4][0])){
return this.$toast('请填写0-10000之间的整数')
return this.$toast('请填写大于等于0的整数或保留两位小数点的非整数')
}
this.checkDataChanged()
this.getEvaluateResult()

View File

@@ -1219,6 +1219,8 @@ export default {
}).then(() => {
this.isNoWXInsureReadClick(val)
})
} else {
this.isNoWXInsureReadClick(val)
}
// 若被保险人为未成年人时,非微信环境点击【立即阅读签名】按钮进行弹窗提示 结束
}
@@ -2123,7 +2125,7 @@ export default {
window.localStorage.setItem('insuredSignFile', JSON.stringify(this.insuredSign))
window.localStorage.setItem('sign-val', val)
this.$router.push({
path: 'flow-improve/sale/readDocuments',
path: '/flow-improve/sale/readDocuments',
query: {
orderNo: this.$route.query.orderNo,
currentIndex: currentIndex + 1

View File

@@ -1,7 +1,7 @@
<template>
<div class='insuranceInformation-container redRadioCheckbox' :class="[isGuanhuaiBiaozhun === 0 ? '' : 'active1']">
<!--文件导航 开始-->
<div class="xxx-fileList" v-if="!isPreview">
<div class="xxx-fileList" v-if="!isPreview" ref="xxx1">
<p :key="index" v-for="(item, index) in fileList" :class="{ active: index+1 == current }"
@click="fileListClick(item,index)"
style="white-space: nowrap;display: flex;align-items: center;">
@@ -12,7 +12,7 @@
<!--文件导航 结束-->
<!-- 顶部提示 开始 -->
<p v-if='branchType != "14"' class="xxx-notice-bar">文件滑动至底部完成阅读</p>
<p v-if='branchType != "14" && !isPreview' class="xxx-notice-bar" ref="xxx2">文件滑动至底部完成阅读</p>
<!-- 顶部提示 结束 -->
<!-- 一键置底 开始 -->
@@ -22,32 +22,32 @@
<!-- 一键置底 结束 -->
<!--文件内容 开始-->
<div id="pdf" ref="scrollableContent" @scroll="updateScrollProgress">
<div id="pdfH5ID"></div>
<div id="pdf" :class="[isPreview ? 'active' : '']" ref="scrollableContent" @scroll="updateScrollProgress">
<div ref="xxx8" id="pdfH5ID"></div>
<div ref="activeButtonEle"></div>
</div>
<!--文件内容 结束-->
<!--底部提示和按钮 开始-->
<div class="xxx-bottom">
<p class="xxx-isread">
<div class="xxx-bottom" v-if="!isPreview">
<p class="xxx-isread" ref="xxx3">
本人已阅读确认理解并同意<span>{{documentName}}</span>各项内容
</p>
<div class='bg-white bottom-btn' v-if="current != '1'">
<div class='bg-white bottom-btn' v-if="current != '1'" ref="xxx4">
<van-button style="width: 30%;font-size: 16px;" plain type='danger' size='large' v-no-more-click='1000' @click="prevStep">上一步
</van-button>
<van-button style="width: 70%;font-size: 16px;" type='danger' size='large' :disabled='scrollProgress < 70' @click='goNext' v-no-more-click='1000'>
<van-button style="width: 70%;font-size: 16px;" type='danger' size='large' :disabled='isyiye ? false : scrollProgress < 70' @click='goNext' v-no-more-click='1000'>
我已阅读确认并理解继续
</van-button>
</div>
<div class='bg-white bottom-btn' v-if="current == '1'">
<van-button class="fs20" type='danger' size='large' :disabled='scrollProgress < 70' @click='goNext' v-no-more-click='1000'>我已阅读确认并理解继续
<div class='bg-white bottom-btn' v-if="current == '1'" ref="xxx5">
<van-button class="fs20" type='danger' size='large' :disabled='isyiye ? false : scrollProgress < 70' @click='goNext' v-no-more-click='1000'>我已阅读确认并理解继续
</van-button>
</div>
</div>
<!--底部提示和按钮 结束-->
<!--关怀标准切换 开始-->
<oldVersionSwitch @onFloatBtnClicked="onFloatBtnClicked" />
<oldVersionSwitch v-if="!isPreview" @onFloatBtnClicked="onFloatBtnClicked" />
<!--关怀标准切换 结束-->
</div>
</template>
@@ -80,7 +80,8 @@
scrollTimer: null,
pdfStatus: void 0,
scrollProgress: 0,
isGuanhuaiBiaozhun: Number(sessionStorage.getItem('oldVersionSwitch'))
isGuanhuaiBiaozhun: Number(sessionStorage.getItem('oldVersionSwitch')),
isyiye: false
}
},
components: {
@@ -116,6 +117,7 @@
})
}, 100)
window.appCallBack = this.appCallBack
console.log(this.isPreview)
},
mounted() {
document.body.style.backgroundColor = '#fff'
@@ -287,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=>{
if(res.result == 0) {
window.sessionStorage.removeItem('currentFile')
@@ -371,6 +402,12 @@
}).on("complete", (status, msg, time)=> { //监听完成事件
this.pdfStatus = status
console.log("状态:" + status + ",信息:" + msg + ",耗时:" + time + "毫秒,总页数:" + this.totalNum)
if (this.current!= '1') {
this.isyiye = (window.innerHeight - (this.$refs.xxx1.clientHeight + this.$refs.xxx2.clientHeight + this.$refs.xxx3.clientHeight + this.$refs.xxx4.clientHeight)) > this.$refs.xxx8.clientHeight
} else {
this.isyiye = (window.innerHeight - (this.$refs.xxx1.clientHeight + this.$refs.xxx2.clientHeight + this.$refs.xxx3.clientHeight + this.$refs.xxx5.clientHeight)) > this.$refs.xxx8.clientHeight
}
console.log(this.isyiye)
})
},
fileListClick(item,index) {
@@ -667,6 +704,10 @@
height: calc(100vh - 170px) !important;
position: relative;
top: 66px;
&.active{
height: 100vh !important;
top: 0;
}
//
}
.xxx-bottom{
@@ -704,6 +745,10 @@
#pdf{
height: calc(100vh - 240px) !important;
top: 84px;
&.active{
height: 100vh;
top: 0;
}
}
.xxx-isread{
font-size: 18px;

View File

@@ -1,5 +1,6 @@
<template>
<div class='insuranceInformation-container' :class="[isGuanhuaiBiaozhun === 0 ? '' : 'active']">
<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 v-if="signVal == '0' || signVal == '2'" style="margin-left: 5px;">
@@ -56,6 +57,7 @@
<div>
<img v-if="signstatus" :src="signImgUrl" style="height: 34px;margin-left: 20px;width: auto;"/>
</div>
</div>
<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">
完成阅读并签署
@@ -160,6 +162,9 @@
if(JSON.parse(window.sessionStorage.getItem('signH5Img')).type == '签名' && JSON.parse(window.sessionStorage.getItem('signH5Img')).val)
this.signstatus = true
this.signImgUrl = this.signImgUrl + JSON.parse(window.sessionStorage.getItem('signH5Img')).val
this.chaoLuObj.btnText = '抄录完成'
this.chaoLuObj.btnText1 = '已抄录'
}
if(window.sessionStorage.getItem('signH5Val')){
this.nextDisabled = false
@@ -231,12 +236,27 @@
signInfo.text = this.guardianName
}
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'
}
},
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 = {
orderType: 'SIGN_MERGED_ORDER',
orderDTO: {
@@ -434,6 +454,9 @@
box-sizing: border-box;
width: 100%;
overflow: auto;
.big-box{
margin-bottom: 140px;
}
}
.insuranceInformation-container.active{
.div1{
@@ -459,7 +482,7 @@
}
}
.div4{
margin-bottom: 160px;
// margin-bottom: 160px;
span{
font-size: 20px !important;
}

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, ORDER_STATUS } 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.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" :type="order.orderStatus" />
</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,81 @@
<script>
import { fetchUnderwritingOrderInfomation, postSupplementaryInformation } 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 } = (
/** @type {{ result: string, resultMessage: string, cont: InsuranceOrderDTO }} */
(await fetchUnderwritingOrderInfomation(this.orderNo))
)
if (result !== '0') {
Toast(`error: ${resultMessage}`)
return false
}
this.information = result.cont
},
data() {
const { orderNo } = this.$route.params
return {
/**
* 订单信息
* @type {InsuranceOrderDTO}
*/
information: undefined,
orderNo
}
},
methods: {
/**
* 提交数据
* @param fn {Function} 用来执行补充额外资料的接口
*/
handleSubmit(fn) {
postSupplementaryInformation({
orderNo: this.orderNo,
mediaDTOS: this.mediaDTOS
})
fn(false)
}
}
}
</script>
<template>
<div class="supplementary-document-container ph20">
<Sticky>
<div aria-live="polite" class="alert alert-warning" role="alert">
请您补充关于处方明细的影像资料
</div>
</Sticky>
<UnderwritingDataCollection ref="dataCollection" class="supplementary-document-content"
type="SupplementaryInformation" @submit="handleSubmit" />
</div>
</template>
<style lang="scss" scoped>
.supplementary-document-container {
background-color: #fff;
height: 100vh;
.alert {
padding: 10px 20px;
margin: 0 -20px;
}
.alert-warning {
background-color: #fef2d3;
}
.supplementary-document-content {
height: unset !important;
width: unset !important;
padding: unset !important;
}
}
</style>

View File

@@ -0,0 +1,255 @@
<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 filter from '@/filters'
import FieldPicker from '@/views/ebiz/underwriting/components/FieldPicker.vue'
import FieldSelect from '@/views/ebiz/underwriting/components/FieldSelect.vue'
import SexRadio from '@/views/ebiz/underwriting/components/SexRadio.vue'
import UnderwritingCollectionMedias from '@/views/ebiz/underwriting/components/UnderwritingCollection/UnderwritingCollectionMedias.vue'
import { FIELD_SELECT_TYPE, ORDER_STATUS, SEX } from '@/views/ebiz/underwriting/js/const'
import { navigateRouter } from '@/views/ebiz/underwriting/js/navigate'
import { Button, Toast } from 'vant'
import GField from './components/GField.vue'
const type = Object.freeze({ SupplementaryInformation: 'SupplementaryInformation', DataCollection: 'DataCollection' })
export default {
name: 'CollectionUnderwritingData',
components: { FieldSelect, GField, SexRadio, FieldPicker, UnderwritingCollectionMedias, Button },
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
}
},
executeBtn() {
const orderStatus = this.$route.query.orderStatus
const isShow = orderStatus !== ORDER_STATUS.pending.value
switch (orderStatus) {
case ORDER_STATUS.standard.value:
return {
label: '去投保',
fn: () => console.log('去投保'),
isShow
}
case ORDER_STATUS.declined.value:
case ORDER_STATUS.postponed.value: {
return {
label: '查看结果',
fn: () => console.log('查看结果'),
isShow
}
}
}
return {
label: this.type === type.DataCollection ? '提交预核保' : '提交',
fn: this.handleDataSubmit,
isShow
}
}
},
props: {
type: { type: String, default: type.DataCollection },
actionDisabled: { type: Boolean, default: false }
},
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'
})
},
/**
* 确定主险
* @param riskInfo {Object} 险种信息
* @returns {void}
*/
handleEnsureMainRisk(riskInfo) {
// console.log(riskInfo)
;[this.riskName.label, this.riskName.value] = [riskInfo.riskName, riskInfo.riskProductCode]
},
/**
* 改变证件类型
* @param type {Object} 证件类型
* @returns {void}
*/
handleChangeIdType(type) {
// console.log(type)
this._idType = type.id
},
/**
* 检查证件号码是否合法
* @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">
<h4 class="pt20">基本信息</h4>
<div>
<FieldSelect
v-model="riskName.label"
v-validate="'required'"
:disabled="actionDisabled"
:type="FIELD_SELECT_TYPE.riskType"
:value.sync="riskName.value"
label="险种名称"
name="险种名称"
placeholder="请选择"
readonly
required
right-icon="arrow"
@submit="handleEnsureMainRisk"
/>
<GField v-model="user.name" v-validate="'required'" :disabled="actionDisabled" label="姓名" name="姓名" />
<SexRadio :hairline="true" :sex.sync="user.sex"></SexRadio>
<FieldPicker
ref="birthday"
v-validate="'required'"
:flag="true"
:maxDate="new Date()"
:value.sync="user.birthday"
label="出生日期"
name="出生日期"
required
type="date"
/>
<FieldSelect
v-model="_idType"
v-validate="'required'"
:type="FIELD_SELECT_TYPE.idType"
:value.sync="_idType"
label="证件类型"
name="证件类型"
placeholder="请选择"
readonly
required
right-icon="arrow"
@submit="handleChangeIdType"
/>
<GField v-model="user.idNo" clearable label="证件号码" maxlength="18" placeholder="请输入" required />
</div>
<UnderwritingCollectionMedias :medias="mediaDTOS" class="medias" />
<Button v-if="executeBtn.isShow" block class="bottom-btn submit-btn mt20" color="#E9322E" @click="executeBtn.fn">{{ executeBtn.label }}</Button>
</div>
</template>
<style>
.underwriting-data-collection-container {
height: 100vh;
background-color: #fff;
}
</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,65 @@
<script>
import { mainRiskList } from '@/api/ebiz/common/common'
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 { Popup, Picker } 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]
}
}
},
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.riskType:
return this.mainRisks.map(item => ({ ...item, text: item.riskName }))
}
}
},
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,176 @@
<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'
}
}
},
type: { type: String, default: '' }
},
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.type)
if (!status) {
console.error('未定义的订单状态, 请重新检查相应代码内容')
return
}
return status.label
},
executeBtn() {
const status = this./* info.orderStatus */ type
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(pathname)),
// 如果这个是标准单且距今超过一个月了,则禁用当前按钮
disabled: status === ORDER_STATUS.standard.value && new Date() - new Date(date) > 2592000000
}
}
},
methods: {
handleNavigate() {
navigateRouter({
name: this.executeBtn.pathname,
params: {
orderId: this.info.orderId
}
})
},
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>
<div class="flex hairline" style="flex-direction: row-reverse">
<Button
:class="{ disable: executeBtn.disabled }"
:disabled="executeBtn.disabled"
class="delete-btn ph30 pv5 mb10"
color="#FF1113"
round
@click.self="executeBtn.handler"
>
{{ executeBtn.label }}
</Button>
</div>
</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,92 @@
<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: () => [] }
},
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"></Uploader>
</article>
</div>
</template>

View File

@@ -0,0 +1,85 @@
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
})
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,82 @@
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 route = routes.find(item => {
if (item.children) {
// 可能后面 children 存在多个,目前暂时先判定一层。 待优化
return item.children.find(childItem => `${item.path}/${childItem.path}` === path)
}
return item.path === path
})
if (!route) {
console.error('在 routers 中无法找到该路径,请检查路径是否正确')
return
}
options.extra = {
title: route.meta && route.meta.title ? route.meta.title : '',
url: location.origin + '/#' + path + '?' + processJson(params)
}
options.routerInfo = { ...options.routerInfo, path }
} else if (name) {
const route = routes.find(item => {
if (item.children) {
// 可能后面 children 存在多个,目前暂时先判定一层。 待优化
return item.children.find(childItem => childItem.name === name)
}
return item.name === name
})
if (!route) {
console.error('在 routers 中无法找到该路径,请检查路径是否正确')
return
}
// 如何存在子元素, 需要重新更改 path 地址
if (route.children) {
route.path = `${route.path}/${route.children.find(childItem => childItem.name === name).path}`
}
console.log(route)
options.extra = {
title: route.meta && route.meta.title ? route.meta.title : '',
url: location.origin + '/#' + route.path + '?' + processJson(params)
}
options.routerInfo = { ...options.routerInfo, name }
}
jump(options)
}
/**
* 处理 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,42 @@
/**
* 投保人信息
* @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} name - 被保险人姓名
* @property {string} sex - 性别("1" 表示男,"2" 表示女)
* @property {string} birthday - 出生日期格式YYYY-MM-DD
* @property {string} idType - 证件类型编码
* @property {string} idNo - 证件号码
*/
/**
* 险种信息
* @typedef {Object} RiskDTO
* @property {string} riskCode - 险种代码
* @property {string} mainRiskCode - 主险代码(若为空字符串,表示该险种为主险或无主险)
*/
/**
* 保险订单数据结构
* @typedef {Object} InsuranceOrderDTO
* @property {string} orderNo - 订单号
* @property {string} prtNo - 打印号(通常与订单号一致)
* @property {AppntDTO} appntDTO - 投保人信息
* @property {InsuredDTO[]} insuredDTOs - 被保险人列表(支持多人)
* @property {RiskDTO[]} riskDTOLst - 险种列表
* @property {string} contState - 保单状态
* @property {string} preUWState - 预核保状态
* @property {string} preUWConClusion - 预核保结论
* @property {string} issueState - 预核保问题件状态
* @property {string} appFlag - 投保单标识
* @property {string} uwFlag - 核保标识
*/