Commit 621b7859 by Sweet Zhang

Merge branch 'feature-20250827wyz-写业务' into sw

parents df8d349a 3f5ee310
<template> <template>
<el-watermark :font="font" :content="content"> <el-watermark :font="font" :content="content">
<router-view /> <router-view />
</el-watermark> </el-watermark>
...@@ -10,10 +9,10 @@ import useSettingsStore from '@/store/modules/settings' ...@@ -10,10 +9,10 @@ import useSettingsStore from '@/store/modules/settings'
import { handleThemeStyle } from '@/utils/theme' import { handleThemeStyle } from '@/utils/theme'
import { reactive } from 'vue' import { reactive } from 'vue'
const font = reactive({ const font = reactive({
color: 'rgba(0, 0, 0, .15)', color: 'rgba(0, 0, 0, .15)'
}) })
const content = reactive('csf') const content = ref('')
onMounted(() => { onMounted(() => {
nextTick(() => { nextTick(() => {
......
...@@ -95,3 +95,51 @@ export function getClientUser(data) { ...@@ -95,3 +95,51 @@ export function getClientUser(data) {
data: data data: data
}) })
} }
// 银行列表
export function getBankList(data) {
return request({
url: '/base/api/bank/page',
method: 'post',
data: data
})
}
// 转介人列表
export function getUserSaleExpandList(data) {
return request({
url: '/insurance/base/api/userSaleExpand/page',
method: 'post',
data: data
})
}
// 第二个附加险列表
export function secondAdditonalList(data) {
return request({
url: '/product/api/relProjectProductLaunch/parameter/page',
method: 'post',
data: data
})
}
// 获取签单员列表
export function getAllSignList(data) {
return request({
url: '/insurance/base/api/userSignExpand/page',
method: 'post',
data: data
})
}
// 获取团队列表
export function getAllTeam(data) {
return request({
url: '/csf/api/team/page',
method: 'post',
data: data
})
}
// 获取保险公司列表
export function getInsuranceCompany(data) {
return request({
url: '/insurance/base/api/insuranceCompany/page',
data: data,
method: 'post'
})
}
...@@ -222,3 +222,4 @@ export function delSigleAppointment(appointmentBizId) { ...@@ -222,3 +222,4 @@ export function delSigleAppointment(appointmentBizId) {
method: 'delete' method: 'delete'
}) })
} }
...@@ -4,7 +4,10 @@ ...@@ -4,7 +4,10 @@
<template #header> <template #header>
<div class="cardOneheader"> <div class="cardOneheader">
<div class="cardOneLeft"> <div class="cardOneLeft">
<div class="mainTitle">{{ title }}</div> <div class="mainTitle">
{{ title }}
<slot name="mainTitCustom"></slot>
</div>
<slot name="headerRight"></slot> <slot name="headerRight"></slot>
</div> </div>
<div class="subTitle" v-if="desTitle">{{ desTitle }}</div> <div class="subTitle" v-if="desTitle">{{ desTitle }}</div>
...@@ -60,6 +63,7 @@ const props = defineProps({ ...@@ -60,6 +63,7 @@ const props = defineProps({
padding-left: 5px; padding-left: 5px;
display: flex; display: flex;
align-items: center; align-items: center;
margin-right: 20px;
/* border-top-left-radius: 2px; /* border-top-left-radius: 2px;
border-bottom-left-radius: 2px; border-bottom-left-radius: 2px;
...@@ -69,7 +73,7 @@ const props = defineProps({ ...@@ -69,7 +73,7 @@ const props = defineProps({
content: ''; content: '';
display: inline-block; display: inline-block;
width: 4px; width: 4px;
height: 22px; height: 18px;
background: #0052d9; background: #0052d9;
margin-right: 5px; margin-right: 5px;
border-radius: 4px; border-radius: 4px;
......
const appointmentInfo = [ const appointmentInfo = [
// 申请 // 申请
{ {
fatherTitle: '', fatherTitle: '行政信息',
type: 'object', keyType: 'object',
key: 'personInfo', key: 'administration',
anchorKey: 'administration',
showMoudle: true, //模块是否展示 showMoudle: true, //模块是否展示
data: [ data: [
{ {
...@@ -21,150 +22,37 @@ const appointmentInfo = [ ...@@ -21,150 +22,37 @@ const appointmentInfo = [
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
label: '预约时间', label: '意向签单日',
key: 'confirmAppointmentTime', key: 'intentionAppointmentTime',
domType: 'datetimePicker', domType: 'DatePicker',
required: false, required: true,
disabled: true,
placeholder: '请选择',
show: false,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: ' ',
key: 'newPolicyButton',
domType: 'button',
buttonTxt: '生成新单跟进记录',
buttonType: 'primary',
required: false,
maxLength: 10,
disabled: false,
show: false,
// labelPosition: 'top', //标签的位置
labelWidth: '0px', //标签宽度
sm: 12, //栅格布局份数
lg: 8 //栅格布局份数
}
]
},
// 业务信息
{
fatherTitle: '业务信息',
type: 'object',
key: 'business',
labelPosition: 'top', //标签的位置
showMoudle: true, //模块是否展示
// description: '证件信息至少填写一项',
data: [
{
label: '业务编号',
key: 'businessNo',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 20,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '签单员账号',
key: 'businessRepresentAccount1',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 20,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '签单员姓名',
key: 'businessRepresentName1',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 20,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '签单员电话号码',
key: 'businessRepresentMobile1',
domType: 'arrowRight',
required: false,
disabled: false,
placeholder: '请填写',
show: true,
drawerType: 'phone',
businessRepresentMobile1: {}, //带有区号得电话一定要有一个和key一样得对象用于收集区号和号码
code: 'businessRepresentMobile1Code',
maxLength: 20,
labelPosition: 'top', //标签的位置
labelWidth: '180px', //标签宽度
sm: 12, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '签单员邮箱',
key: 'businessRepresentEmail1',
domType: 'Input',
inputType: 'text',
maxLength: 30,
required: false,
disabled: false, disabled: false,
placeholder: '请输入', placeholder: '请选择',
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}
]
}, },
// 基础信息
{ {
fatherTitle: '基础信息', label: '转介人是否陪同',
type: 'object', key: 'isReferrerAccompany',
key: 'basic', domType: 'Select',
showMoudle: true, //模块是否展示
// description: '证件信息至少填写一项',
data: [
{
label: '意向预约时间',
key: 'intentionAppointmentTime',
domType: 'datetimePicker',
required: true, required: true,
disabled: false, disabled: false,
placeholder: '请选择', placeholder: '请选择',
dictType: 'sys_no_yes',
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
label: '转介人是否陪同', label: '是否需用车',
key: 'isAccompany', key: 'isUseCar',
domType: 'Select', domType: 'Select',
required: false, required: true,
disabled: false, disabled: false,
placeholder: '请选择', placeholder: '请选择',
dictType: 'sys_no_yes', dictType: 'sys_no_yes',
...@@ -175,10 +63,10 @@ const appointmentInfo = [ ...@@ -175,10 +63,10 @@ const appointmentInfo = [
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
label: '是否有用车需求', label: '是否开户',
key: 'isUseCar', key: 'isOpenAccount',
domType: 'Select', domType: 'Select',
required: false, required: true,
disabled: false, disabled: false,
placeholder: '请选择', placeholder: '请选择',
dictType: 'sys_no_yes', dictType: 'sys_no_yes',
...@@ -188,75 +76,76 @@ const appointmentInfo = [ ...@@ -188,75 +76,76 @@ const appointmentInfo = [
sm: 12, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
} }
// {
// label: '预约时间',
// key: 'confirmAppointmentTime',
// domType: 'datetimePicker',
// required: false,
// disabled: true,
// placeholder: '请选择',
// show: false,
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 12, //栅格布局份数
// lg: 8 //栅格布局份数
// },
// {
// label: ' ',
// key: 'newPolicyButton',
// domType: 'button',
// buttonTxt: '生成新单跟进记录',
// buttonType: 'primary',
// required: false,
// maxLength: 10,
// disabled: false,
// show: false,
// // labelPosition: 'top', //标签的位置
// labelWidth: '0px', //标签宽度
// sm: 12, //栅格布局份数
// lg: 8 //栅格布局份数
// }
] ]
}, },
// 陪同顾问信息 // 陪同转介人信息
{ {
fatherTitle: '转介人信息', fatherTitle: '陪同转介人',
type: 'object', keyType: 'Array', //用于表单收集值时,判断是数组还是对象
key: 'consult', key: 'referrerDtoList',
anchorKey: 'referrerDtoList',
moudleType: 'referrerDtoList',
dataLength: 1, //设置dataLength,用于控制子级dom的个数,子级保存一个样例数据,便于加子级数据
showTable: true,
showMoudle: false, //模块是否展示 showMoudle: false, //模块是否展示
addChildren: true, //是否可以新增子级dom
addChildrenTxt: '陪同转介人', //新增按钮得文本
fatherRequired: false, //父级必填,代表个人资料这个模块有必填项
isOpen: false, //dom是否展开
data: [ data: [
{ // {
label: '姓名', // id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识
key: 'accompanyName', // span: 24, //栅格布局份数
domType: 'Input', // email: '',
inputType: 'text', // phone: '',
required: false, // realName: ''
maxLength: 30, // }
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '手机',
key: 'accompanyMobile',
domType: 'arrowRight',
required: false,
disabled: false,
placeholder: '请填写',
show: true,
labelPosition: 'top', //标签的位置
drawerType: 'phone',
accompanyMobile: {}, //带有区号得电话一定要有一个和key一样得对象用于收集区号和号码
code: 'accompanyMobileCode',
maxLength: 20,
labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '邮箱',
key: 'accompanyEmail',
domType: 'Input',
inputType: 'text',
maxLength: 30,
required: false,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数
lg: 8 //栅格布局份数
}
] ]
}, },
// 到港信息 // 到港信息
{ {
fatherTitle: '到港信息', fatherTitle: '到港/离港信息',
type: 'object', keyType: 'object',
key: 'position', key: 'position',
anchorKey: 'position',
showMoudle: true, //模块是否展示 showMoudle: true, //模块是否展示
data: [ data: [
{ {
label: '到港时间', label: '到港时间',
key: 'arrivalTime', key: 'arrivalTime',
domType: 'datetimePicker', domType: 'datetimePicker',
dateValue: '', //YYYY-MM-DD
timeValue: '', //HH:mm
compositionTime: true, //是否组合时间
required: false, required: false,
disabled: false, disabled: false,
placeholder: '请选择', placeholder: '请选择',
...@@ -270,6 +159,9 @@ const appointmentInfo = [ ...@@ -270,6 +159,9 @@ const appointmentInfo = [
label: '离港时间(离港时间必须晚于到港时间)', label: '离港时间(离港时间必须晚于到港时间)',
key: 'departureTime', key: 'departureTime',
domType: 'datetimePicker', domType: 'datetimePicker',
dateValue: '', //YYYY-MM-DD
timeValue: '', //HH:mm
compositionTime: true, //是否组合时间
required: false, required: false,
disabled: false, disabled: false,
placeholder: '请选择', placeholder: '请选择',
...@@ -295,7 +187,7 @@ const appointmentInfo = [ ...@@ -295,7 +187,7 @@ const appointmentInfo = [
}, },
{ {
label: '签单地', label: '签单地',
key: 'signingAddress', key: 'signingAddress',
domType: 'Input', domType: 'Input',
inputType: 'text', inputType: 'text',
...@@ -310,7 +202,7 @@ const appointmentInfo = [ ...@@ -310,7 +202,7 @@ const appointmentInfo = [
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
label: '客户在港期间联络电话', label: '在港联系电话',
key: 'hkMobile', key: 'hkMobile',
domType: 'arrowRight', //带有区号得电话一定要有一个和key一样得对象用于收集区号和号码 domType: 'arrowRight', //带有区号得电话一定要有一个和key一样得对象用于收集区号和号码
required: false, required: false,
...@@ -328,27 +220,29 @@ const appointmentInfo = [ ...@@ -328,27 +220,29 @@ const appointmentInfo = [
} }
] ]
}, },
// 其他情况 // 陪同转介人信息
{ {
fatherTitle: '其他情况', fatherTitle: '签单员',
type: 'object', keyType: 'Array', //用于表单收集值时,判断是数组还是对象
key: 'other', key: 'userSignDtoList',
anchorKey: 'userSignDtoList',
moudleType: 'userSignDtoList',
dataLength: 1, //设置dataLength,用于控制子级dom的个数,子级保存一个样例数据,便于加子级数据
showTable: true,
showMoudle: true, //模块是否展示 showMoudle: true, //模块是否展示
addChildren: true, //是否可以新增子级dom
addChildrenTxt: '签单员', //新增按钮得文本
fatherRequired: false, //父级必填,代表个人资料这个模块有必填项
isOpen: false, //dom是否展开
data: [ data: [
{ // {
label: '是否开户', // name: '', //姓名
key: 'isOpenAccount', // practiceCode: '', //执业编码
domType: 'Select', // phone: '', //手机号
required: false, // cardType: '', //证件类型
disabled: false, // cardNo: '', //证件号码
placeholder: '请选择', // email: '' //邮箱
dictType: 'sys_no_yes', // }
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数
lg: 8 //栅格布局份数
}
] ]
}, },
// 开户信息 // 开户信息
...@@ -356,6 +250,7 @@ const appointmentInfo = [ ...@@ -356,6 +250,7 @@ const appointmentInfo = [
fatherTitle: '开户信息', fatherTitle: '开户信息',
type: 'object', type: 'object',
key: 'openAccount', key: 'openAccount',
anchorKey: 'openAccount',
showMoudle: false, //模块是否展示 showMoudle: false, //模块是否展示
data: [ data: [
{ {
...@@ -391,7 +286,7 @@ const appointmentInfo = [ ...@@ -391,7 +286,7 @@ const appointmentInfo = [
}, },
{ {
label: '开户时间段(开始)', label: '开户时间(起)',
key: 'openAccountStartTime', key: 'openAccountStartTime',
domType: 'DatePicker', domType: 'DatePicker',
timeType: 'date', timeType: 'date',
...@@ -405,7 +300,7 @@ const appointmentInfo = [ ...@@ -405,7 +300,7 @@ const appointmentInfo = [
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
label: '开户时间段(结束,先选择开始时间)', label: '开户时间(止)',
key: 'openAccountEndTime', key: 'openAccountEndTime',
domType: 'DatePicker', domType: 'DatePicker',
required: false, required: false,
...@@ -467,6 +362,7 @@ const appointmentInfo = [ ...@@ -467,6 +362,7 @@ const appointmentInfo = [
inputType: 'textarea', inputType: 'textarea',
required: false, required: false,
maxLength: 300, maxLength: 300,
rows: 5, //文本域行数
disabled: false, disabled: false,
placeholder: '请输入', placeholder: '请输入',
show: true, show: true,
...@@ -476,27 +372,234 @@ const appointmentInfo = [ ...@@ -476,27 +372,234 @@ const appointmentInfo = [
lg: 24 //栅格布局份数 lg: 24 //栅格布局份数
}, },
{ {
label: '', label: '所需资料',
title: '所需资料', key: 'materials',
key: 'information', domType: 'Input',
domType: 'Div', inputType: 'textarea',
required: false, required: false,
maxLength: 30, maxLength: 300,
rows: 5, //文本域行数
disabled: false, disabled: false,
placeholder: '请输入', placeholder: '请输入',
show: true, show: true,
informationList: [ labelPosition: 'top', //标签的位置
{ name: '1、身份证' },
{ name: '2、港澳通行证/护照' },
{ name: '3、出生证明(18岁以下受保人)' },
{ name: '4、结婚证(如夫妻为对方支付保费)' },
{ name: '5、通关小白条' }
],
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 24, //栅格布局份数 sm: 24, //栅格布局份数
lg: 24 //栅格布局份数 lg: 24 //栅格布局份数
} }
// {
// label: '',
// title: '所需资料',
// key: 'information',
// domType: 'Div',
// required: false,
// maxLength: 30,
// disabled: false,
// placeholder: '请输入',
// show: true,
// informationList: [
// { name: '1、身份证' },
// { name: '2、港澳通行证/护照' },
// { name: '3、出生证明(18岁以下受保人)' },
// { name: '4、结婚证(如夫妻为对方支付保费)' },
// { name: '5、通关小白条' }
// ],
// labelWidth: '120px', //标签宽度
// sm: 24, //栅格布局份数
// lg: 24 //栅格布局份数
// }
] ]
} }
// 业务信息
// {
// fatherTitle: '业务信息',
// type: 'object',
// key: 'business',
// labelPosition: 'top', //标签的位置
// showMoudle: true, //模块是否展示
// // description: '证件信息至少填写一项',
// data: [
// {
// label: '业务编号',
// key: 'businessNo',
// domType: 'Input',
// inputType: 'text',
// required: false,
// maxLength: 20,
// disabled: false,
// placeholder: '请输入',
// show: true,
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 12, //栅格布局份数
// lg: 8 //栅格布局份数
// },
// {
// label: '签单员账号',
// key: 'businessRepresentAccount1',
// domType: 'Input',
// inputType: 'text',
// required: false,
// maxLength: 20,
// disabled: false,
// placeholder: '请输入',
// show: true,
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 12, //栅格布局份数
// lg: 8 //栅格布局份数
// },
// {
// label: '签单员姓名',
// key: 'businessRepresentName1',
// domType: 'Input',
// inputType: 'text',
// required: false,
// maxLength: 20,
// disabled: false,
// placeholder: '请输入',
// show: true,
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 12, //栅格布局份数
// lg: 8 //栅格布局份数
// },
// {
// label: '签单员电话号码',
// key: 'businessRepresentMobile1',
// domType: 'arrowRight',
// required: false,
// disabled: false,
// placeholder: '请填写',
// show: true,
// drawerType: 'phone',
// businessRepresentMobile1: {}, //带有区号得电话一定要有一个和key一样得对象用于收集区号和号码
// code: 'businessRepresentMobile1Code',
// maxLength: 20,
// labelPosition: 'top', //标签的位置
// labelWidth: '180px', //标签宽度
// sm: 12, //栅格布局份数
// lg: 8 //栅格布局份数
// },
// {
// label: '签单员邮箱',
// key: 'businessRepresentEmail1',
// domType: 'Input',
// inputType: 'text',
// maxLength: 30,
// required: false,
// disabled: false,
// placeholder: '请输入',
// show: true,
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 12, //栅格布局份数
// lg: 8 //栅格布局份数
// }
// ]
// },
// 基础信息
// {
// fatherTitle: '基础信息',
// type: 'object',
// key: 'basic',
// showMoudle: true, //模块是否展示
// // description: '证件信息至少填写一项',
// data: [
// {
// label: '意向预约时间',
// key: 'intentionAppointmentTime',
// domType: 'datetimePicker',
// required: true,
// disabled: false,
// placeholder: '请选择',
// show: true,
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 12, //栅格布局份数
// lg: 8 //栅格布局份数
// },
// {
// label: '是否有用车需求',
// key: 'isUseCar',
// domType: 'Select',
// required: false,
// disabled: false,
// placeholder: '请选择',
// dictType: 'sys_no_yes',
// show: true,
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 12, //栅格布局份数
// lg: 8 //栅格布局份数
// }
// ]
// },
// 陪同顾问信息
// {
// fatherTitle: '转介人信息',
// type: 'object',
// key: 'consult',
// showMoudle: false, //模块是否展示
// data: [
// {
// label: '姓名',
// key: 'accompanyName',
// domType: 'Input',
// inputType: 'text',
// required: false,
// maxLength: 30,
// disabled: false,
// placeholder: '请输入',
// show: true,
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 12, //栅格布局份数
// lg: 8 //栅格布局份数
// },
// {
// label: '手机',
// key: 'accompanyMobile',
// domType: 'arrowRight',
// required: false,
// disabled: false,
// placeholder: '请填写',
// show: true,
// labelPosition: 'top', //标签的位置
// drawerType: 'phone',
// accompanyMobile: {}, //带有区号得电话一定要有一个和key一样得对象用于收集区号和号码
// code: 'accompanyMobileCode',
// maxLength: 20,
// labelWidth: '120px', //标签宽度
// sm: 12, //栅格布局份数
// lg: 8 //栅格布局份数
// },
// {
// label: '邮箱',
// key: 'accompanyEmail',
// domType: 'Input',
// inputType: 'text',
// maxLength: 30,
// required: false,
// disabled: false,
// placeholder: '请输入',
// show: true,
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 12, //栅格布局份数
// lg: 8 //栅格布局份数
// }
// ]
// },
// 其他情况
// {
// fatherTitle: '其他情况',
// type: 'object',
// key: 'other',
// showMoudle: true, //模块是否展示
// data: []
// },
] ]
export default appointmentInfo export default appointmentInfo
const customer = [ const customer = [
// 与投保人关系-在受保人中显示
{
fatherTitle: '与投保人关系',
type: 'object',
key: 'policyholderRel',
anchorKey: 'policyholderRel',
showTable: false,
showMoudle: false,
data: [
{
label: '与投保人关系',
key: 'policyholderRel',
domType: 'Select',
required: false,
disabled: false,
placeholder: '请选择',
dictType: 'csf_ap_rel',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数
lg: 8 //栅格布局份数
}
]
},
// 基础信息 // 基础信息
{ {
fatherTitle: '基础信息', fatherTitle: '基础信息',
...@@ -6,6 +31,7 @@ const customer = [ ...@@ -6,6 +31,7 @@ const customer = [
key: 'personInfo', key: 'personInfo',
anchorKey: 'personInfo', anchorKey: 'personInfo',
showTable: false, showTable: false,
showMoudle: true,
data: [ data: [
{ {
label: '名字(中文)', label: '名字(中文)',
...@@ -21,7 +47,7 @@ const customer = [ ...@@ -21,7 +47,7 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
...@@ -37,23 +63,10 @@ const customer = [ ...@@ -37,23 +63,10 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
// {
// label: '称谓',
// key: 'title',
// domType: 'Select',
// required: true,
// disabled: false,
// placeholder: '请选择',
// dictType: 'csf_customer_title',
// show: true,
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 8, //栅格布局份数
// lg: 8 //栅格布局份数
// },
{ {
label: '证件类型', label: '证件类型',
key: 'documentType', key: 'documentType',
...@@ -65,7 +78,7 @@ const customer = [ ...@@ -65,7 +78,7 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
...@@ -80,7 +93,7 @@ const customer = [ ...@@ -80,7 +93,7 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
...@@ -95,7 +108,7 @@ const customer = [ ...@@ -95,7 +108,7 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
...@@ -108,7 +121,7 @@ const customer = [ ...@@ -108,7 +121,7 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
...@@ -123,7 +136,7 @@ const customer = [ ...@@ -123,7 +136,7 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
...@@ -137,7 +150,7 @@ const customer = [ ...@@ -137,7 +150,7 @@ const customer = [
drawerType: 'country', drawerType: 'country',
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
...@@ -152,11 +165,11 @@ const customer = [ ...@@ -152,11 +165,11 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
label: '是否拥有其他国家公民身份(如美国、日本等)', label: '是否拥有其他国家公民身份',
key: 'isOtherCountry', key: 'isOtherCountry',
domType: 'Select', domType: 'Select',
required: false, required: false,
...@@ -166,7 +179,7 @@ const customer = [ ...@@ -166,7 +179,7 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
...@@ -180,24 +193,10 @@ const customer = [ ...@@ -180,24 +193,10 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
// {
// label: '吸烟数量(支/天)',
// key: 'smokeQuantity',
// domType: 'Input',
// inputType: 'number',
// maxLength: 30,
// required: false,
// disabled: false,
// placeholder: '请输入',
// show: false,
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 8, //栅格布局份数
// lg: 8 //栅格布局份数
// },
{ {
label: '婚姻状况', label: '婚姻状况',
key: 'maritalStatus', key: 'maritalStatus',
...@@ -209,7 +208,7 @@ const customer = [ ...@@ -209,7 +208,7 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
...@@ -223,7 +222,7 @@ const customer = [ ...@@ -223,7 +222,7 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
...@@ -237,7 +236,7 @@ const customer = [ ...@@ -237,7 +236,7 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
...@@ -252,7 +251,7 @@ const customer = [ ...@@ -252,7 +251,7 @@ const customer = [
show: false, show: false,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
...@@ -266,7 +265,7 @@ const customer = [ ...@@ -266,7 +265,7 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
...@@ -282,7 +281,7 @@ const customer = [ ...@@ -282,7 +281,7 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
...@@ -297,7 +296,7 @@ const customer = [ ...@@ -297,7 +296,7 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
...@@ -307,12 +306,12 @@ const customer = [ ...@@ -307,12 +306,12 @@ const customer = [
inputType: 'text', inputType: 'text',
required: false, required: false,
maxLength: 300, maxLength: 300,
disabled: false, disabled: true,
placeholder: '请输入', placeholder: '请输入',
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
} }
] ]
...@@ -325,6 +324,7 @@ const customer = [ ...@@ -325,6 +324,7 @@ const customer = [
anchorKey: 'apiTaxationDtoList', anchorKey: 'apiTaxationDtoList',
moudleType: 'apiTaxationDtoList', moudleType: 'apiTaxationDtoList',
dataLength: 1, //设置dataLength,用于控制子级dom的个数,子级保存一个样例数据,便于加子级数据 dataLength: 1, //设置dataLength,用于控制子级dom的个数,子级保存一个样例数据,便于加子级数据
showMoudle: true,
showTable: true, showTable: true,
addChildren: true, //是否可以新增子级dom addChildren: true, //是否可以新增子级dom
addChildrenTxt: '税务', //新增按钮得文本 addChildrenTxt: '税务', //新增按钮得文本
...@@ -335,7 +335,7 @@ const customer = [ ...@@ -335,7 +335,7 @@ const customer = [
// id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识 // id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识
// span: 24, //栅格布局份数 // span: 24, //栅格布局份数
// taxCountry: '', // taxCountry: '',
// taxNumber: '' // taxId: ''
// } // }
] ]
}, },
...@@ -346,6 +346,7 @@ const customer = [ ...@@ -346,6 +346,7 @@ const customer = [
key: 'contactInfo', key: 'contactInfo',
anchorKey: 'contactInfo', anchorKey: 'contactInfo',
showTable: false, showTable: false,
showMoudle: true,
data: [ data: [
{ {
label: '移动电话', label: '移动电话',
...@@ -361,7 +362,7 @@ const customer = [ ...@@ -361,7 +362,7 @@ const customer = [
value: '', value: '',
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
...@@ -379,7 +380,7 @@ const customer = [ ...@@ -379,7 +380,7 @@ const customer = [
maxLength: 20, maxLength: 20,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
...@@ -394,7 +395,7 @@ const customer = [ ...@@ -394,7 +395,7 @@ const customer = [
maxLength: 20, maxLength: 20,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
...@@ -403,13 +404,13 @@ const customer = [ ...@@ -403,13 +404,13 @@ const customer = [
domType: 'Input', domType: 'Input',
inputType: 'text', inputType: 'text',
maxLength: 30, maxLength: 30,
required: true, required: false,
disabled: false, disabled: false,
placeholder: '请输入', placeholder: '请输入',
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
...@@ -421,10 +422,10 @@ const customer = [ ...@@ -421,10 +422,10 @@ const customer = [
maxLength: 20, maxLength: 20,
disabled: false, disabled: false,
placeholder: '请输入', placeholder: '请输入',
show: false, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
...@@ -440,7 +441,7 @@ const customer = [ ...@@ -440,7 +441,7 @@ const customer = [
mailingAddress: {}, mailingAddress: {},
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
...@@ -455,7 +456,7 @@ const customer = [ ...@@ -455,7 +456,7 @@ const customer = [
residentialAddress: {}, residentialAddress: {},
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
...@@ -470,7 +471,7 @@ const customer = [ ...@@ -470,7 +471,7 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
} }
] ]
...@@ -483,6 +484,7 @@ const customer = [ ...@@ -483,6 +484,7 @@ const customer = [
key: 'companyInfo', key: 'companyInfo',
anchorKey: 'companyInfo', anchorKey: 'companyInfo',
showTable: false, showTable: false,
showMoudle: true,
data: [ data: [
{ {
label: '就业情况', label: '就业情况',
...@@ -495,7 +497,7 @@ const customer = [ ...@@ -495,7 +497,7 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
...@@ -510,7 +512,7 @@ const customer = [ ...@@ -510,7 +512,7 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
...@@ -525,7 +527,7 @@ const customer = [ ...@@ -525,7 +527,7 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
...@@ -541,7 +543,7 @@ const customer = [ ...@@ -541,7 +543,7 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
...@@ -556,7 +558,7 @@ const customer = [ ...@@ -556,7 +558,7 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
...@@ -571,7 +573,7 @@ const customer = [ ...@@ -571,7 +573,7 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
...@@ -586,7 +588,7 @@ const customer = [ ...@@ -586,7 +588,7 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
...@@ -606,7 +608,7 @@ const customer = [ ...@@ -606,7 +608,7 @@ const customer = [
maxLength: 20, maxLength: 20,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '180px', //标签宽度 labelWidth: '180px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
...@@ -622,7 +624,7 @@ const customer = [ ...@@ -622,7 +624,7 @@ const customer = [
companyAddress: {}, companyAddress: {},
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
...@@ -637,7 +639,7 @@ const customer = [ ...@@ -637,7 +639,7 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
} }
] ]
...@@ -649,6 +651,7 @@ const customer = [ ...@@ -649,6 +651,7 @@ const customer = [
key: 'financeInfo', key: 'financeInfo',
anchorKey: 'financeInfo', anchorKey: 'financeInfo',
showTable: false, showTable: false,
showMoudle: true,
data: [ data: [
{ {
label: '平均每月收入', label: '平均每月收入',
...@@ -663,7 +666,7 @@ const customer = [ ...@@ -663,7 +666,7 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
...@@ -679,7 +682,7 @@ const customer = [ ...@@ -679,7 +682,7 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
...@@ -695,7 +698,7 @@ const customer = [ ...@@ -695,7 +698,7 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
...@@ -711,7 +714,7 @@ const customer = [ ...@@ -711,7 +714,7 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
} }
] ]
...@@ -737,7 +740,7 @@ const customer = [ ...@@ -737,7 +740,7 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
...@@ -751,7 +754,7 @@ const customer = [ ...@@ -751,7 +754,7 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
...@@ -765,7 +768,7 @@ const customer = [ ...@@ -765,7 +768,7 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
...@@ -779,7 +782,7 @@ const customer = [ ...@@ -779,7 +782,7 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
...@@ -795,7 +798,7 @@ const customer = [ ...@@ -795,7 +798,7 @@ const customer = [
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
} }
] ]
......
/**
* 1.普通模块得数据格式,无子级:
* {
一些页面用到得属性,比如个人资料模块得数据格式
data:[] data主要是这个模块对应得表单dom数据
}
2. 有子级得模块得数据格式:
{
一些页面用到得属性,比如家庭状况模块得数据格式
data:[ data主要父级模块对应得表单
{
比如家庭状况中有父亲,母亲,配偶,这个对象就代表这些人
children:[],代表得是这些人对应得表单dom
}
]
}
以上两种格式说明了fnaForm页面得dom数据格式,如果有子级得dom请参照2格式添加,否则可能有未知错误
*/
const fnaForm = [ const fnaForm = [
{ // 介绍人信息
fatherTitle: '个人资料', {
keyType: 'Object', //用于表单收集值时,判断是数组还是对象 fatherTitle: '转介人信息',
key: 'personalData', keyType: 'Array',
child: 'no', //没有子级dom,直接展示 key: 'brokerList',
fatherRequired: true, //父级必填,代表个人资料这个模块有必填项 anchorKey: 'brokerList',
data: [ moudleType: 'brokerList',
{ dataLength: 1,
label: '转介人', showMoudle: true,
key: 'accountName', showTable: true,
domType: 'SearchSelect', addChildren: true,
required: true, addChildrenTxt: '转介人',
maxLength: 30, fatherRequired: false,
disabled: false, isOpen: false,
placeholder: '请输入', // 新增表格列配置
show: true, columns: [
labelPosition: 'top', //标签的位置 {
labelWidth: '120px', //标签宽度 label: '姓名',
sm: 8, //栅格布局份数 prop: 'brokerName',
lg: 8 //栅格布局份数 type: 'remoteSelect',
searchType: 'brokerName',
placeholder: '请输入关键词搜索',
required: false
}, },
// {
// label: '签单员注册编号',
// key: 'registrationNumber',
// domType: 'Input',
// inputType: 'text',
// required: true,
// maxLength: 30,
// disabled: false,
// placeholder: '请输入',
// show: true,
// labelPosition: 'top', //标签的位置
// labelWidth: '140px', //标签宽度
// sm: 8, //栅格布局份数
// lg: 8 //栅格布局份数
// },
// {
// label: '签单员内部编码',
// key: 'number',
// domType: 'Input',
// inputType: 'text',
// required: false,
// maxLength: 30,
// disabled: false,
// placeholder: '请输入',
// show: true,
// labelPosition: 'top', //标签的位置
// labelWidth: '130px', //标签宽度
// sm: 8, //栅格布局份数
// lg: 8 //栅格布局份数
// },
{ {
label: '客户姓名', label: '性别',
key: 'customerName', prop: 'brokerGender',
domType: 'Input', type: 'select',
inputType: 'text', dictType: 'sys_gender',
required: true, placeholder: '请选择',
maxLength: 30, required: false
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
}, },
// {
// label: '税务国家',
// key: 'taxCountry',
// domType: 'Input',
// inputType: 'text',
// required: true,
// maxLength: 30,
// disabled: false,
// placeholder: '请输入',
// show: true,
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 8, //栅格布局份数
// lg: 8 //栅格布局份数
// },
{ {
label: '就业情况', label: '内部编号',
key: 'employment', prop: 'brokerNumber',
domType: 'Select', type: 'input',
required: true,
maxLength: 30,
disabled: false,
placeholder: '请输入', placeholder: '请输入',
show: true, required: false
dictType: 'csf_employment',
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
}, },
{ {
label: '是否退休', label: '所属团队',
key: 'isRetired', prop: 'brokerTeam',
domType: 'Select', type: 'remoteSelect',
required: true, searchType: 'brokerTeam',
maxLength: 30, placeholder: '请输入关键词搜索',
disabled: false, required: false
placeholder: '请输入',
show: true,
dictType: 'sys_no_yes',
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
}, },
{ {
label: '退休年龄', label: '分配比例',
key: 'retiredAge', prop: 'brokerRatio',
domType: 'Input', type: 'inputNumber',
inputType: 'number',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入', placeholder: '请输入',
show: true, required: true
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
}, },
{ {
label: '其他就业情况', label: '备注',
key: 'otherEmployment', prop: 'remark',
domType: 'Input', type: 'input',
inputType: 'text',
required: false,
maxLength: 300,
disabled: false,
placeholder: '请输入', placeholder: '请输入',
show: false, required: false
labelPosition: 'top', //标签的位置 }
labelWidth: '120px', //标签宽度 ],
sm: 8, //栅格布局份数 data: [
lg: 8 //栅格布局份数 {
brokerName: '',
brokerGender: '',
brokerNumber: '',
brokerTeam: '',
brokerRatio: '',
remark: ''
} }
] ]
}, },
{ // 受供养人信息
fatherTitle: '家庭状况', {
keyType: 'Array', //用于表单收集值时,判断是数组还是对象 fatherTitle: '受供养人信息',
showTable: true, //以table的形式展示 keyType: 'Array',
key: 'familyMembers', key: 'dependantList',
moudleType: 'family', anchorKey: 'dependantList',
addChildren: true, //是否可以新增子级dom moudleType: 'dependantList',
dataLength: 1,
addChildrenTxt: '添加儿女', //新增按钮得文本 showMoudle: true,
fatherRequired: false, //父级必填,代表个人资料这个模块有必填项 showTable: true,
addChildren: true,
addChildrenTxt: '受供养人',
fatherRequired: false,
isOpen: false, isOpen: false,
openIcon: true, // 表格列配置
data: [ columns: [
{ {
type: '1', label: '与投保人关系',
childTitle: '父亲', prop: 'policyholderRel',
id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识 type: 'select',
age: '', dictType: 'csf_ap_rel',
needProvide: '', placeholder: '请选择',
disabled: false, required: false
dictType: 'sys_no_yes',
options: []
}, },
{ {
type: '2', label: '年龄',
childTitle: '母亲', prop: 'dependantAge',
id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识 type: 'inputNumber',
span: 24, //栅格布局份数 placeholder: '请输入年龄',
age: '', required: false
needProvide: '', }
disabled: false, ],
dictType: 'sys_no_yes', data: [
options: []
},
{ {
type: '3', policyholderRel: '',
childTitle: '配偶', dependantAge: ''
id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识
span: 24, //栅格布局份数
age: '',
needProvide: '',
disabled: false,
dictType: 'sys_no_yes',
options: []
} }
] ]
}, },
//财务需要分析 // 已生效仍在缴费期的保单情况
{ {
fatherTitle: '财务需要分析', fatherTitle: '已生效仍在缴费期的保单情况',
subTitle: '保单持有人个人已有保障', keyType: 'Array',
keyType: 'Array', //用于表单收集值时,判断是数组还是对象
key: 'existingSecurityOwner', key: 'existingSecurityOwner',
moudleType: 'finance', anchorKey: 'existingSecurityOwner',
addChildren: true, //是否可以新增子级dom moudleType: 'existingSecurityOwner',
addChildrenTxt: '保单持有人个人已有保障', //新增按钮得文本 dataLength: 1,
showMoudle: true,
showTable: true, showTable: true,
dataLength: 5, //设置dataLength,用于控制子级dom的个数,子级保存一个样例数据,便于加子级数据 addChildren: true,
addChildrenTxt: '保单',
fatherRequired: false,
isOpen: false, isOpen: false,
openIcon: true, // 表格列配置
fatherRequired: false, //父级必填,代表个人资料这个模块有必填项 columns: [
data: [ {
label: '保险公司',
prop: 'insurer',
type: 'remoteSelect',
searchType: 'insurer',
placeholder: '请搜索保险公司名称',
required: true
},
{ {
id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识 label: '保险种类',
span: 24, //栅格布局份数 prop: 'insuranceType',
childTitle: '保单持有人个人已有保障', type: 'remoteSelect',
insurer: '', searchType: 'insuranceType',
insuranceType: '', placeholder: '请选择',
sumInsured: '', required: true
policyIssueDate: '', },
currency: '', {
label: '保单币种',
prop: 'currency',
type: 'select',
dictType: 'bx_currency_type', dictType: 'bx_currency_type',
options: [] placeholder: '请选择',
} required: true
]
}, },
//受保人个人已有保障
{ {
keyType: 'Array', //用于表单收集值时,判断是数组还是对象 label: '投保日期',
subTitle: '受保人个人已有保障', prop: 'policyIssueDate',
key: 'existingSecurityInsured', type: 'datePicker',
moudleType: 'finance', placeholder: '请选择日期',
addChildren: true, //是否可以新增子级dom required: true
addChildrenTxt: '受保人个人已有保障', //新增按钮得文本 }
dataLength: 5, //设置dataLength,用于控制子级dom的个数,子级保存一个样例数据,便于加子级数据 // 有重疾险才让填写
showTable: true, // {
isOpen: false, //dom是否展开 // label: '保额',
fatherRequired: false, //父级必填,代表个人资料这个模块有必填项 // prop: 'sumInsured',
// type: 'inputNumber',
// placeholder: '请输入保额',
// required: true
// },
],
data: [ data: [
{ {
id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识
span: 24, //栅格布局份数
subTitle: '受保人个人已有保障',
insurer: '', insurer: '',
insuranceType: '', insuranceType: '',
sumInsured: '', sumInsured: '',
policyIssueDate: '',
currency: '',
dictType: 'bx_currency_type',
options: []
}
]
},
// 投资房地产
{
keyType: 'Array', //用于表单收集值时,判断是数组还是对象
key: 'investment',
moudleType: 'finance',
subTitle: '投资房地产',
showTable: true,
dataLength: 2, //设置dataLength,用于控制子级dom的个数,子级保存一个样例数据,便于加子级数据
addChildren: true, //是否可以新增子级dom
addChildrenTxt: '投资房地产', //新增按钮得文本
isOpen: false, //dom是否展开
fatherRequired: false, //父级必填,代表个人资料这个模块有必填项
data: [
{
childTitle: '投资房地产',
id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识
span: 24, //栅格布局份数
address: '',
currency: '', currency: '',
dictType: 'bx_currency_type', policyIssueDate: ''
marketValue: ''
} }
] ]
}, },
//保单持有人资产 // 不动产信息
{ {
keyType: 'Array', //用于表单收集值时,判断是数组还是对象 fatherTitle: '不动产信息',
keyType: 'Array',
key: 'primaryResidence', key: 'primaryResidence',
moudleType: 'finance', anchorKey: 'primaryResidence',
dataLength: 1, //设置dataLength,用于控制子级dom的个数,子级保存一个样例数据,便于加子级数据 moudleType: 'primaryResidence',
showTable: true, dataLength: 1,
subTitle: '保单持有人资产', showMoudle: true,
addChildren: true, //是否可以新增子级dom
addChildrenTxt: '保单持有人资产', //新增按钮得文本
isOpen: false, //dom是否展开
fatherRequired: false, //父级必填,代表个人资料这个模块有必填项
data: [
{
childTitle: '自住用途之房地产',
id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识
span: 24, //栅格布局份数
address: '',
currency: '',
dictType: 'bx_currency_type',
marketValue: ''
}
]
},
// 税务国家
{
keyType: 'Array', //用于表单收集值时,判断是数组还是对象
key: 'taxList',
moudleType: 'finance',
dataLength: 1, //设置dataLength,用于控制子级dom的个数,子级保存一个样例数据,便于加子级数据
showTable: true, showTable: true,
subTitle: '税务', addChildren: true,
addChildren: true, //是否可以新增子级dom addChildrenTxt: '不动产',
addChildrenTxt: '税务', //新增按钮得文本 fatherRequired: false,
fatherRequired: false, //父级必填,代表个人资料这个模块有必填项 isOpen: false,
isOpen: false, //dom是否展开 // 表格列配置
data: [ columns: [
{ {
id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识 label: '类型',
span: 24, //栅格布局份数 prop: 'propertyType',
taxCountry: '', type: 'select',
taxNumber: '' dictType: 'csf_property_type',
} placeholder: '请选择',
] required: true
}, },
//公司业务资料
{
keyType: 'Object', //用于表单收集值时,判断是数组还是对象
key: 'companyBusinessData',
child: 'no', //有子级dom,需要循环展示
isOpen: true, //是否展开
fatherRequired: false, //父级必填,代表个人资料这个模块有必填项
subTitle: '公司业务资料 (适用于公司老板跟股东)',
data: [
{ {
label: '公司過去兩年平均純利', label: '房地产地址',
key: 'averageNetProfit', prop: 'address',
domType: 'Input', type: 'input',
inputType: 'text', placeholder: '请输入地址',
required: false, required: false
maxLength: 300,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '220px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
}, },
{ {
label: '公司現時大約的總資產', label: '市值',
key: 'estimatedTotalAssets', prop: 'marketValue',
domType: 'Input', type: 'inputNumber',
inputType: 'text', placeholder: '请输入市场价值',
required: false, required: false
maxLength: 300,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '220px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
}, },
{ {
label: '币种', label: '币种',
key: 'currency', prop: 'currency',
domType: 'Select', type: 'select',
inputType: 'text',
required: false,
maxLength: 300,
disabled: false,
placeholder: '请输入',
show: true,
dictType: 'bx_currency_type', dictType: 'bx_currency_type',
labelPosition: 'top', //标签的位置 placeholder: '请选择',
labelWidth: '120px', //标签宽度 required: false
sm: 8, //栅格布局份数 }
lg: 8 //栅格布局份数 ],
}, data: [
{ {
label: '资产所佔百分比 (%)', propertyType: '',
key: 'assetPercentage', address: '',
domType: 'Input', marketValue: '',
inputType: 'text', currency: ''
required: false,
maxLength: 300,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '220px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
} }
] ]
}, },
//支出 // 保费负担能力评估
{ {
key: 'incomeExpense', fatherTitle: '保费负担能力评估',
keyType: 'Object', //用于表单收集值时,判断是数组还是对象 type: 'object',
child: 'no', key: 'premiumAffordability',
fatherRequired: false, //父级必填,代表个人资料这个模块有必填项 anchorKey: 'premiumAffordability',
showTable: false,
showMoudle: true,
data: [ data: [
{ {
label: label: '在过去12个月里你的平均每月收入',
'在过去12个月里,你从所有所得的收入来源所得的平均每月收入为(包括薪金、花红、佣金、其他薪酬红利、银行存款利息、债券利息及股息等。',
key: 'monthlyIncome', key: 'monthlyIncome',
value: '',
domType: 'Input', domType: 'Input',
inputType: 'text', unit: 'HKD',
required: false, showDes: true, //是否展示描述
inputType: 'number',
required: true,
maxLength: 300, maxLength: 300,
disabled: false, disabled: false,
placeholder: '请输入', placeholder: '请输入平均每月收入',
tooltip: '包括薪金、花红、佣金、其他薪酬红利、银行存款利息、债券利息及股息等',
show: true, show: true,
inputWidth: '300px', labelPosition: 'top', //标签的位置
labelWidth: '800px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 24, //栅格布局份数 sm: 24, //栅格布局份数
lg: 24, //栅格布局份数 lg: 8 //栅格布局份数
labelPosition: 'top' //标签的位置
}, },
{ {
label: '过去12个月每月里,你每月的平均开支为', label: '在过去12个月里你的平均每月开支',
key: 'monthlyExpense', key: 'monthlyExpense',
value: '',
domType: 'Input', domType: 'Input',
inputType: 'text', unit: 'HKD',
required: false, showDes: true, //是否展示描述
inputType: 'number',
required: true,
maxLength: 300, maxLength: 300,
disabled: false, disabled: false,
placeholder: '请输入', placeholder: '请输入平均每月开支',
show: true, show: true,
inputWidth: '300px', //输入框宽度 labelPosition: 'top', //标签的位置
labelWidth: '260px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 24, //栅格布局份数 sm: 24, //栅格布局份数
lg: 12, //栅格布局份数 lg: 8 //栅格布局份数
labelPosition: 'top' //标签的位置
}
]
}, },
{ {
key: 'liquidAssets',
keyType: 'Object', //用于表单收集值时,判断是数组还是对象
child: 'no',
fatherRequired: false, //父级必填,代表个人资料这个模块有必填项
data: [
{
label: '您现时的累积流动资产约有多少?', label: '您现时的累积流动资产约有多少?',
key: 'liquidAssets', key: 'liquidAssets',
value: '',
domType: 'Input', domType: 'Input',
inputType: 'text', unit: 'HKD',
required: false, inputType: 'number',
required: true,
maxLength: 300, maxLength: 300,
disabled: false, disabled: false,
placeholder: '请输入', placeholder: '请输入流动资产',
tooltip: '流動资産是指可以容易變為现金的資産。例如現金、存款、外幣及股票,不包括物業。',
show: true, show: true,
inputWidth: '300px', //输入框宽度 labelPosition: 'top', //标签的位置
labelWidth: '220px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 24, //栅格布局份数 sm: 24, //栅格布局份数
lg: 12, //栅格布局份数 lg: 8 //栅格布局份数
labelPosition: 'top' //标签的位置
}, },
{ {
label: '流动资产种类', label: '流动资产种类有?(多选)',
key: 'liquidAssetType', key: 'liquidAssetType',
value: [],
domType: 'Checkbox', domType: 'Checkbox',
required: false, dictType: 'csf_liquid_asset_type',
required: true,
maxLength: 300, maxLength: 300,
disabled: false, disabled: false,
placeholder: '请输入',
show: true, show: true,
labelWidth: '100px', //标签宽度
sm: 24, //栅格布局份数
lg: 24, //栅格布局份数
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
dictType: 'csf_liquid_asset_type' labelWidth: '120px', //标签宽度
}, sm: 12, //栅格布局份数
{ lg: 8 //栅格布局份数
label: '',
key: 'otherLiquidAsset',
inputType: 'Input',
required: false,
maxLength: 300,
disabled: false,
placeholder: '请输入',
show: false,
labelWidth: '0px', //标签宽度
sm: 24, //栅格布局份数
lg: 24, //栅格布局份数
labelPosition: 'top' //标签的位置
}
]
}, },
{
fatherTitle: '',
keyType: 'Object', //用于表单收集值时,判断是数组还是对象
child: 'no',
fatherRequired: false, //父级必填,代表个人资料这个模块有必填项
key: 'other',
data: [
{ {
label: '首期及续保保费的财富来源', label: '首期及续保保费的财富来源?(多选)',
key: 'premiumFundingSource', key: 'premiumFundingSource',
value: [],
domType: 'Checkbox', domType: 'Checkbox',
required: false, dictType: 'csf_premium_funding_source',
maxLength: 30, required: true,
maxLength: 300,
disabled: false, disabled: false,
placeholder: '请输入',
show: true, show: true,
labelWidth: '180px', //标签宽度
sm: 24, //栅格布局份数
lg: 24, //栅格布局份数
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
dictType: 'csf_premium_funding_source' labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数
lg: 8 //栅格布局份数
} }
] ]
} }
// 公司业务资料
// {
// fatherTitle: '公司业务资料',
// type: 'object',
// key: 'companyBusinessData',
// anchorKey: 'companyBusinessData',
// showTable: false,
// showMoudle: true,
// data: [
// {
// label: '公司过去两年平均纯利',
// key: 'averageNetProfit',
// value: '',
// domType: 'Input',
// unit: 'HKD',
// inputType: 'number',
// required: false,
// maxLength: 300,
// disabled: false,
// placeholder: '请输入',
// show: true,
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 12, //栅格布局份数
// lg: 8 //栅格布局份数
// },
// {
// label: '公司现时大约总资产',
// key: 'estimatedTotalAssets',
// value: '',
// domType: 'Input',
// unit: 'HKD',
// inputType: 'number',
// required: false,
// maxLength: 300,
// disabled: false,
// placeholder: '请输入',
// show: true,
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 12, //栅格布局份数
// lg: 8 //栅格布局份数
// },
// {
// label: '币种',
// key: 'currency',
// value: '',
// domType: 'Select',
// required: false,
// disabled: false,
// placeholder: '请选择',
// dictType: 'bx_currency_type',
// show: true,
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 12, //栅格布局份数
// lg: 8 //栅格布局份数
// },
// {
// label: '资产所占百分比(%)',
// key: 'assetPercentage',
// value: '',
// domType: 'Input',
// unit: 'HKD',
// inputType: 'number',
// required: false,
// maxLength: 300,
// disabled: false,
// placeholder: '请输入',
// show: true,
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 12, //栅格布局份数
// lg: 8 //栅格布局份数
// }
// ]
// }
] ]
export default fnaForm export default fnaForm
...@@ -10,7 +10,6 @@ const insured = [ ...@@ -10,7 +10,6 @@ const insured = [
{ {
label: '与投保人关系', label: '与投保人关系',
key: 'policyholderRel', key: 'policyholderRel',
// customerKey: 'customerType',
domType: 'Select', domType: 'Select',
required: true, required: true,
disabled: false, disabled: false,
......
import { anchorKey } from 'element-plus/es/components/anchor/src/constants.mjs'
const productPlan = [ const productPlan = [
{ {
fatherTitle: '', fatherTitle: '基础信息',
keyType: 'Object', //用于表单收集值时,判断是数组还是对象 keyType: 'Object', //用于表单收集值时,判断是数组还是对象
key: 'apiProductPlanMainInfoDto', key: 'apiProductPlanMainInfoDto',
child: 'no', //有子级dom,需要循环展示 anchorKey: 'apiProductPlanMainInfoDto',
showMoudle: true, //模块是否展示 showMoudle: true, //模块是否展示
showTable: false, //是否展示表格
fatherRequired: true, //父级必填,代表个人资料这个模块有必填项 fatherRequired: true, //父级必填,代表个人资料这个模块有必填项
data: [ data: [
{ {
label: '保险公司',
key: 'companyName',
domType: 'SearchSelect',
required: true,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数
labelPosition: 'top', //标签的位置
lg: 8 //栅格布局份数
},
{
label: '保险种类',
key: 'insuranceTypeName',
domType: 'SearchSelect',
required: true,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数
labelPosition: 'top', //标签的位置
lg: 8 //栅格布局份数
},
{
label: '产品名称', label: '产品名称',
key: 'productName', key: 'productLaunchName',
domType: 'SearchSelect', domType: 'SearchSelect',
required: true, required: true,
maxLength: 30, maxLength: 30,
...@@ -22,13 +53,27 @@ const productPlan = [ ...@@ -22,13 +53,27 @@ const productPlan = [
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
label: '地区', label: '供款期数',
key: 'region', key: 'issueNumber',
domType: 'Select',
required: true,
disabled: false,
placeholder: '请选择',
dictType: 'issueNumber',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '保障年期',
key: 'guaranteePeriod',
domType: 'Input', domType: 'Input',
inputType: 'text', inputType: 'number',
required: false, required: true,
maxLength: 20, maxLength: 20,
disabled: true, disabled: false,
placeholder: '请输入', placeholder: '请输入',
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
...@@ -37,8 +82,8 @@ const productPlan = [ ...@@ -37,8 +82,8 @@ const productPlan = [
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
label: '货币', label: '保单币种',
key: 'currency', key: 'policyCurrency',
domType: 'Select', domType: 'Select',
required: true, required: true,
disabled: false, disabled: false,
...@@ -51,14 +96,14 @@ const productPlan = [ ...@@ -51,14 +96,14 @@ const productPlan = [
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
label: '供款年期', label: '保单额度(重疾)',
key: 'paymentTerm', key: 'sumInsured',
domType: 'Select', domType: 'Input',
required: true, inputType: 'number',
required: false,
maxLength: 20,
disabled: false, disabled: false,
placeholder: '请选择', placeholder: '请输入',
dictType: 'paymentTerm',
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
...@@ -95,14 +140,13 @@ const productPlan = [ ...@@ -95,14 +140,13 @@ const productPlan = [
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
label: '保额', label: '首期付款方式',
key: 'sumInsured', key: 'initialPaymentMethod',
domType: 'Input', domType: 'Select',
inputType: 'number',
required: false, required: false,
maxLength: 20,
disabled: false, disabled: false,
placeholder: '请输入', placeholder: '请选择',
dictType: 'csf_ap_first_issue',
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
...@@ -110,13 +154,14 @@ const productPlan = [ ...@@ -110,13 +154,14 @@ const productPlan = [
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
label: '是否预缴保费', label: '保单征费',
key: 'isPrepay', key: 'policyLevy',
domType: 'Select', domType: 'Input',
inputType: 'number',
required: true, required: true,
maxLength: 20,
disabled: false, disabled: false,
placeholder: '请选择', placeholder: '请输入',
dictType: 'sys_no_yes',
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
...@@ -124,13 +169,13 @@ const productPlan = [ ...@@ -124,13 +169,13 @@ const productPlan = [
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
label: '首期付款方式', label: '是否预缴',
key: 'initialPaymentMethod', key: 'isPrepay',
domType: 'Select', domType: 'Select',
required: false, required: true,
disabled: false, disabled: false,
placeholder: '请选择', placeholder: '请选择',
dictType: 'csf_ap_first_issue', dictType: 'sys_no_yes',
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
...@@ -138,13 +183,13 @@ const productPlan = [ ...@@ -138,13 +183,13 @@ const productPlan = [
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
label: '续期付款方式', label: '是否追溯',
key: 'renewalPaymentMethod', key: 'isTraceable',
domType: 'Select', domType: 'Select',
required: false, required: false,
disabled: false, disabled: false,
placeholder: '请选择', placeholder: '请选择',
dictType: 'csf_ap_first_issue', dictType: 'sys_no_yes',
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
...@@ -152,13 +197,13 @@ const productPlan = [ ...@@ -152,13 +197,13 @@ const productPlan = [
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
label: '红利分配方式', label: '保单日期回溯',
key: 'dividendDistributionMethod', key: 'isBacktrack',
domType: 'Select', domType: 'Select',
required: false, required: false,
disabled: false, disabled: false,
placeholder: '请选择', placeholder: '请选择',
dictType: 'csf_ap_dividend', dictType: 'sys_no_yes',
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
...@@ -166,8 +211,8 @@ const productPlan = [ ...@@ -166,8 +211,8 @@ const productPlan = [
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
label: '保单日期回溯', label: '是否参加递增保障权益',
key: 'isBacktrack', key: 'isJoin',
domType: 'Select', domType: 'Select',
required: false, required: false,
disabled: false, disabled: false,
...@@ -180,44 +225,75 @@ const productPlan = [ ...@@ -180,44 +225,75 @@ const productPlan = [
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
label: '保单生效日', label: '红利分配方式',
key: 'policyEffectiveDate', key: 'dividendDistributionMethod',
domType: 'DatePicker', domType: 'Select',
required: false, required: false,
disabled: false, disabled: false,
placeholder: '请选择', placeholder: '请选择',
show: false, dictType: 'csf_ap_dividend',
show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
}, },
{ {
label: '是否参加递增保障权益', label: '续期付款方式',
key: 'isJoin', key: 'renewalPaymentMethod',
domType: 'Select', domType: 'Select',
required: false, required: false,
disabled: false, disabled: false,
placeholder: '请选择', placeholder: '请选择',
dictType: 'sys_no_yes', dictType: 'csf_ap_first_issue',
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度 labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数 sm: 12, //栅格布局份数
lg: 8 //栅格布局份数 lg: 8 //栅格布局份数
} }
// {
// label: '地区',
// key: 'region',
// domType: 'Input',
// inputType: 'text',
// required: false,
// maxLength: 20,
// disabled: true,
// placeholder: '请输入',
// show: true,
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 12, //栅格布局份数
// lg: 8 //栅格布局份数
// },
// {
// label: '保单生效日',
// key: 'policyEffectiveDate',
// domType: 'DatePicker',
// required: false,
// disabled: false,
// placeholder: '请选择',
// show: false,
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 12, //栅格布局份数
// lg: 8 //栅格布局份数
// }
] ]
}, },
//附加险 //附加险
{ {
showMoudle: true, //模块是否展示 showMoudle: true, //模块是否展示
fatherTitle: '附加', fatherTitle: '附加计划',
keyType: 'Array', //用于表单收集值时,判断是数组还是对象 keyType: 'Array', //用于表单收集值时,判断是数组还是对象
key: 'apiProductPlanAdditionalInfoDtoList', key: 'apiProductPlanAdditionalInfoDtoList',
child: 'yes', //有子级dom,需要循环展示 anchorKey: 'apiProductPlanAdditionalInfoDtoList',
fatherRequired: true, //父级必填,代表个人资料这个模块有必填项 fatherRequired: true, //父级必填,代表个人资料这个模块有必填项
addBtn: true, addChildren: true,
emptySpan: 24, //空状态得span addChildrenTxt: '新增附加险',
showTable: true, //是否展示表格
data: [ data: [
// { // {
// id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识 // id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识
...@@ -347,6 +423,169 @@ const productPlan = [ ...@@ -347,6 +423,169 @@ const productPlan = [
// } // }
// ] // ]
// } // }
],
// 弹窗表单的配置
formItem: [
{
label: '产品名称',
value: '',
key: 'productLaunchName',
domType: 'SearchSelect',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数
labelPosition: 'top', //标签的位置
lg: 8 //栅格布局份数
},
{
label: '供款期数',
key: 'issueNumber',
value: '',
domType: 'Select',
required: false,
disabled: false,
placeholder: '请选择',
dictType: 'issueNumber',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '保障年期(若是终身,输入999)',
key: 'guaranteePeriod',
value: '',
domType: 'Input',
inputType: 'number',
required: false,
maxLength: 300,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '保单币种',
key: 'policyCurrency',
value: '',
domType: 'Select',
inputType: 'text',
required: false,
maxLength: 300,
disabled: false,
placeholder: '请输入',
show: true,
dictType: 'bx_currency_type',
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '保单额度(重疾)',
key: 'sumInsured',
value: '',
domType: 'Input',
inputType: 'number',
required: false,
maxLength: 300,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '每期保费',
key: 'eachIssuePremium',
value: '',
domType: 'Input',
inputType: 'number',
required: false,
maxLength: 300,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '保障地区',
key: 'guaranteeRegion',
value: '',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 300,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '保障级别',
value: '',
key: 'protectionLevel',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 300,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '自付额',
value: '',
key: 'deductibles',
domType: 'Input',
inputType: 'number',
required: false,
maxLength: 300,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '附加保障',
value: '',
key: 'additionalSafeguards',
domType: 'Input',
inputType: 'textarea',
required: false,
maxLength: 300,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 24, //栅格布局份数
lg: 24 //栅格布局份数
}
] ]
} }
] ]
......
...@@ -9,7 +9,13 @@ const useDictStore = defineStore('dict', { ...@@ -9,7 +9,13 @@ const useDictStore = defineStore('dict', {
insureCompanyList: [], //保险公司数据 insureCompanyList: [], //保险公司数据
clientUserList: [], //用户数据,转介人 clientUserList: [], //用户数据,转介人
dictTypeLists: [], //字典列表,根据请求得不同会变化,所以使用之前需要使用useDictLists请求数据 dictTypeLists: [], //字典列表,根据请求得不同会变化,所以使用之前需要使用useDictLists请求数据
signNameList: [] signNameList: [],
bankList: [], //银行列表
userSaleExpandList: [], //最新转介人列表
productAdditionalList: [], //附加险产品列表对应的是产品计划
signPeopleList: [], //所有签单员
allTeaList: [], //所有团队
allInsuranceCompanyList: [] //最新的保险公司列表
}), }),
actions: { actions: {
// 获取字典 // 获取字典
...@@ -84,6 +90,30 @@ const useDictStore = defineStore('dict', { ...@@ -84,6 +90,30 @@ const useDictStore = defineStore('dict', {
// 设置签单人姓名列表 // 设置签单人姓名列表
setSignNameList(nameList) { setSignNameList(nameList) {
this.signNameList = nameList this.signNameList = nameList
},
//设置银行列表
setBankList(list) {
this.bankList = list
},
//设置最新转介人列表
setUserSaleExpandList(list) {
this.userSaleExpandList = list
},
//设置最新的附加险产品列表
setProductAdditionalList(list) {
this.productAdditionalList = list
},
//设置签单员列表
setSignPeopleList(list) {
this.signPeopleList = list
},
//设置团队列表
setAllTeaList(list) {
this.allTeaList = list
},
//设置最新的保险公司列表
setAllInsuranceCompanyList(list) {
this.allInsuranceCompanyList = list
} }
} }
}) })
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -153,6 +153,46 @@ export const validateEnglish = (rule, value, callback) => { ...@@ -153,6 +153,46 @@ export const validateEnglish = (rule, value, callback) => {
callback() callback()
} }
/**
* 英文姓名校验规则
*/
export const validateChinese = (rule, value, callback) => {
if (!value) {
callback(new Error('请输入中文姓名'))
return
}
// 验证是否只包含中文字符
const chineseRegex = /^[\u4e00-\u9fa5]+$/
if (!chineseRegex.test(value)) {
callback(new Error('只能输入中文'))
return
}
// 验证长度在2-6之间
if (value.length < 2 || value.length > 6) {
callback(new Error('长度应在2-6个字符之间'))
return
}
callback()
}
/**
* BMI校验规则
*/
export const validateBMI = (rule, value, callback) => {
if (!value) {
return
}
if (value < 19) {
return callback(new Error('BMI值不能小于19'))
}
if (value >= 23.5) {
return callback(new Error('BMI值不能大于23.5'))
}
callback()
}
/** /**
* 手机号校验规则 * 手机号校验规则
...@@ -169,7 +209,401 @@ export const validatePhone = (rule, value, callback) => { ...@@ -169,7 +209,401 @@ export const validatePhone = (rule, value, callback) => {
callback() callback()
} }
// 身份证验证相关方法
/**
* 验证身份证号码是否合法
* @param {string} idCard 身份证号码
* @returns {boolean} 是否合法
*/
export function validIDCard(idCard) {
if (!idCard) return false
const idCardStr = idCard.toString().trim()
// 长度验证
if (idCardStr.length !== 15 && idCardStr.length !== 18) {
return false
}
// 格式验证
if (idCardStr.length === 15) {
// 15位身份证:全部为数字
if (!/^\d{15}$/.test(idCardStr)) {
return false
}
// 验证出生日期
const birthDateStr = '19' + idCardStr.substr(6, 6) // 19yyMMdd
if (!validateBirthDate(birthDateStr)) {
return false
}
// 验证省份代码
const provinceCode = idCardStr.substr(0, 2)
if (!validateProvinceCode(provinceCode)) {
return false
}
} else if (idCardStr.length === 18) {
// 18位身份证:前17位为数字,最后一位为数字或X(大小写)
if (!/^\d{17}[\dXx]$/.test(idCardStr)) {
return false
}
// 验证出生日期
const birthDateStr = idCardStr.substr(6, 8) // yyyyMMdd
if (!validateBirthDate(birthDateStr)) {
return false
}
// 验证省份代码
const provinceCode = idCardStr.substr(0, 2)
if (!validateProvinceCode(provinceCode)) {
return false
}
// 验证校验码
if (!validateCheckCode(idCardStr.toUpperCase())) {
return false
}
}
return true
}
/**
* 验证出生日期是否有效
* @param {string} birthDateStr 出生日期字符串 (yyyyMMdd 或 yyMMdd)
* @returns {boolean} 是否有效
*/
function validateBirthDate(birthDateStr) {
// 统一为8位格式
if (birthDateStr.length === 6) {
birthDateStr = '19' + birthDateStr
}
if (birthDateStr.length !== 8) {
return false
}
const year = parseInt(birthDateStr.substr(0, 4))
const month = parseInt(birthDateStr.substr(4, 2))
const day = parseInt(birthDateStr.substr(6, 2))
// 验证年月日是否有效
if (year < 1900 || year > new Date().getFullYear()) {
return false
}
if (month < 1 || month > 12) {
return false
}
// 验证每月天数
const daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
// 闰年二月处理
if (month === 2 && isLeapYear(year)) {
if (day < 1 || day > 29) {
return false
}
} else {
if (day < 1 || day > daysInMonth[month - 1]) {
return false
}
}
// 验证日期不能晚于当前日期
const birthDate = new Date(year, month - 1, day)
const currentDate = new Date()
if (birthDate > currentDate) {
return false
}
// 验证年龄(最大150岁)
const age = calculateAge(birthDate)
if (age > 150) {
return false
}
return true
}
/**
* 验证省份代码
* @param {string} code 省份代码
* @returns {boolean} 是否有效
*/
function validateProvinceCode(code) {
const provinceCodes = [
'11',
'12',
'13',
'14',
'15', // 华北
'21',
'22',
'23', // 东北
'31',
'32',
'33',
'34',
'35',
'36',
'37', // 华东
'41',
'42',
'43',
'44',
'45',
'46', // 华中/华南
'50',
'51',
'52',
'53',
'54', // 西南
'61',
'62',
'63',
'64',
'65', // 西北
'71',
'81',
'82',
'91' // 港澳台及国外
]
return provinceCodes.includes(code)
}
/**
* 验证18位身份证的校验码
* @param {string} idCard 18位身份证号码(需大写)
* @returns {boolean} 是否校验通过
*/
function validateCheckCode(idCard) {
// 校验码对应关系
const checkCodeMap = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']
// 系数表
const coefficient = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
// 计算校验位
let sum = 0
for (let i = 0; i < 17; i++) {
sum += parseInt(idCard.charAt(i)) * coefficient[i]
}
// 取模
const mod = sum % 11
// 获取计算出的校验码
const expectedCheckCode = checkCodeMap[mod]
// 与实际校验码比较
const actualCheckCode = idCard.charAt(17)
return expectedCheckCode === actualCheckCode
}
/**
* 判断是否为闰年
* @param {number} year 年份
* @returns {boolean} 是否为闰年
*/
function isLeapYear(year) {
return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0
}
/**
* 计算年龄
* @param {Date} birthDate 出生日期
* @returns {number} 年龄
*/
function calculateAge(birthDate) {
const today = new Date()
let age = today.getFullYear() - birthDate.getFullYear()
const monthDiff = today.getMonth() - birthDate.getMonth()
// 如果当前月份小于出生月份,或者月份相同但日期小于出生日期,则年龄减1
if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {
age--
}
return age
}
/**
* 从身份证提取信息
* @param {string} idCard 身份证号码
* @returns {Object|null} 身份证信息对象,无效返回null
*/
export function extractIDCardInfo(idCard) {
if (!validIDCard(idCard)) {
return null
}
const idCardStr = idCard.toString().trim().toUpperCase()
// 提取出生日期
let birthDateStr = ''
if (idCardStr.length === 15) {
birthDateStr = '19' + idCardStr.substr(6, 6)
} else {
birthDateStr = idCardStr.substr(6, 8)
}
const year = parseInt(birthDateStr.substr(0, 4))
const month = parseInt(birthDateStr.substr(4, 2))
const day = parseInt(birthDateStr.substr(6, 2))
// 提取性别
let genderCode = 0
if (idCardStr.length === 15) {
genderCode = parseInt(idCardStr.substr(14, 1))
} else {
genderCode = parseInt(idCardStr.substr(16, 1))
}
const gender = genderCode % 2 === 1 ? 1 : 0 // 1:男, 0:女
// 提取省份代码
const provinceCode = idCardStr.substr(0, 2)
const province = getProvinceName(provinceCode)
// 计算年龄
const birthDate = new Date(year, month - 1, day)
const age = calculateAge(birthDate)
return {
provinceCode,
province,
birthDate: `${year}-${month.toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}`,
year,
month,
day,
gender,
genderText: gender === 1 ? '男' : '女',
age
}
}
/**
* 根据省份代码获取省份名称
* @param {string} code 省份代码
* @returns {string} 省份名称
*/
function getProvinceName(code) {
const provinceMap = {
11: '北京',
12: '天津',
13: '河北',
14: '山西',
15: '内蒙古',
21: '辽宁',
22: '吉林',
23: '黑龙江',
31: '上海',
32: '江苏',
33: '浙江',
34: '安徽',
35: '福建',
36: '江西',
37: '山东',
41: '河南',
42: '湖北',
43: '湖南',
44: '广东',
45: '广西',
46: '海南',
50: '重庆',
51: '四川',
52: '贵州',
53: '云南',
54: '西藏',
61: '陕西',
62: '甘肃',
63: '青海',
64: '宁夏',
65: '新疆',
71: '台湾',
81: '香港',
82: '澳门',
91: '国外'
}
return provinceMap[code] || '未知'
}
/**
* 身份证校验规则(用于Element Plus表单验证)
*/
export const validateIdCard = (rule, value, callback) => {
if (!value) {
// 如果值为空且字段不是必填的,直接通过校验
// 如果必填,应该在rules中另外添加required规则
return callback()
}
// 基本格式检查
const idCardStr = value.toString().trim()
if (idCardStr.length !== 15 && idCardStr.length !== 18) {
return callback(new Error('身份证号码长度应为15位或18位'))
}
if (idCardStr.length === 15) {
// 15位身份证:全部为数字
if (!/^\d{15}$/.test(idCardStr)) {
return callback(new Error('15位身份证号码应全部为数字'))
}
} else {
// 18位身份证:前17位为数字,最后一位为数字或X
if (!/^\d{17}[\dXx]$/.test(idCardStr)) {
return callback(new Error('18位身份证号码格式不正确'))
}
}
// 使用完整验证函数
if (!validIDCard(value)) {
return callback(new Error('请输入有效的身份证号码'))
}
callback()
}
/**
* 简单验证身份证格式(不验证校验码和详细逻辑)
*/
export const validateIdCardSimple = (rule, value, callback) => {
if (!value) {
return callback()
}
const idCardStr = value.toString().trim()
// 15位身份证验证
if (idCardStr.length === 15) {
if (!/^\d{15}$/.test(idCardStr)) {
return callback(new Error('15位身份证号码应全部为数字'))
}
} else if (idCardStr.length === 18) {
// 18位身份证验证
if (!/^\d{17}[\dXx]$/.test(idCardStr)) {
return callback(new Error('18位身份证号码格式不正确'))
}
} else {
return callback(new Error('身份证号码长度应为15位或18位'))
}
callback()
}
// 将身份证验证方法添加到默认导出对象中
export default { export default {
validateEnglish, validateEnglish,
validatePhone validateChinese,
validatePhone,
validateBMI,
validateIdCard,
validateIdCardSimple
} }
<template>
<div class="formContainer">
<div class="formLeft" v-if="showAnchor">
<el-affix :offset="affixOffset">
<el-anchor
:direction="direction"
:type="type"
:offset="anchorOffset"
@click="handleAnchorClick"
>
<!-- -->
<el-anchor-link
v-for="item in anchorList"
:href="'#' + item.title"
:title="item.name"
@click="e => handleLinkClick(e, item.title)"
/>
</el-anchor>
</el-affix>
</div>
<div class="formRight" :class="showAnchor ? 'formRightSelf' : ''">
<slot name="form-right"></slot>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, getCurrentInstance } from 'vue'
const props = defineProps({
containerRef: {
type: Object,
default: () => {
return {}
}
},
direction: {
type: String,
default: 'vertical'
},
type: {
type: String,
default: 'default'
},
anchorOffset: {
type: Number,
default: 30
},
affixOffset: {
type: Number,
default: 60
},
anchorList: {
type: Array,
default: () => {
return []
}
},
// 新增:滚动容器的选择器
scrollContainerSelector: {
type: String,
default: ''
},
// 新增:滚动到元素时额外的偏移量
scrollOffset: {
type: Number,
default: 0
},
domIndex: {
type: Number,
default: 0
},
showAnchor: {
type: Boolean,
default: true
}
})
const emit = defineEmits(['anchor-click'])
// 处理锚点点击
const handleAnchorClick = e => {
// 阻止默认的锚点跳转
e.preventDefault()
}
// 处理链接点击
const handleLinkClick = (e, anchorId) => {
e.preventDefault()
e.stopPropagation()
emit('anchor-click', anchorId)
// 延迟执行滚动,确保 DOM 已经更新
setTimeout(() => {
scrollToAnchor(anchorId)
}, 50)
}
// 滚动到锚点
const scrollToAnchor = anchorId => {
const targetElement = document.getElementById(anchorId)
if (!targetElement) return
let scrollContainer
if (props.scrollContainerSelector) {
scrollContainer = document.querySelectorAll(props.scrollContainerSelector)
}
if (scrollContainer.length > 0) {
// 计算在容器内的相对位置
const containerRect = scrollContainer[props.domIndex].getBoundingClientRect()
const targetRect = targetElement.getBoundingClientRect()
// 计算滚动位置
const scrollTop =
targetRect.top -
containerRect.top +
scrollContainer[props.domIndex].scrollTop -
props.scrollOffset
// 平滑滚动
scrollContainer[props.domIndex].scrollTo({
top: scrollTop,
behavior: 'smooth'
})
} else {
// 如果没有指定容器,使用默认滚动
targetElement.scrollIntoView({
behavior: 'smooth',
block: 'start'
})
}
}
// 暴露方法给父组件
defineExpose({
scrollToAnchor
})
</script>
<style lang="scss" scoped>
.formContainer {
width: 100%;
box-sizing: border-box;
display: flex;
}
.formLeft {
width: 15%;
box-sizing: border-box;
height: 100vh;
}
.formRight {
flex: 1;
padding-left: 10px;
box-sizing: border-box;
}
.formRightSelf {
border-left: 3px solid rgb(247 247 247);
}
</style>
<template> <template>
<div> <div class="customerContainer">
<div v-if="processedCustomerData.length > 0" class="customerContainer"> <div ref="customerRightRef">
<div class="editBtn"> <div class="editBtn">
<el-button <el-button
v-if="props.customerBizId" v-if="props.customerBizId && tabSource == 'customer'"
type="primary" type="primary"
icon="EditPen" icon="EditPen"
@click="handleEditStatus" @click="handleEditStatus"
>编辑</el-button >编辑</el-button
> >
</div> </div>
<div class="customerLeft" v-if="customerRightRef"> <CommonForm
<CommonAnchor
:anchorList="anchorList" :anchorList="anchorList"
:affixOffset="250" :affixOffset="affixOffset"
:anchorOffset="10" :anchorOffset="10"
:scrollContainerSelector="'.tabPaneBox'" :scrollContainerSelector="anchorContainer"
:scrollOffset="10" :scrollOffset="10"
:domIndex="1" :domIndex="tabIndex"
/> :activeName="activeName"
</div> v-if="customerRightRef"
<div class="customerRight" ref="customerRightRef"> >
<el-form ref="customerRef" :model="form" :rules="rules" label-width="120px"> <template #form-right>
<el-form :model="form" :rules="rules" label-width="120px" ref="customerFormRef">
<el-row v-for="(father, fIndex) in processedCustomerData" :id="father.anchorKey"> <el-row v-for="(father, fIndex) in processedCustomerData" :id="father.anchorKey">
<div class="formBox"> <div class="formBox">
<CardOne :title="father.fatherTitle"> <CardOne :title="father.fatherTitle" v-if="father.showMoudle">
<template #content> <template #content>
<el-row :gutter="20" v-if="!father.showTable"> <el-row :gutter="20" v-if="!father.showTable">
<template v-for="child in father.data" :key="child.key"> <template v-for="child in father.data" :key="child.key">
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
<div> <div>
<el-form-item <el-form-item
:label=" :label="
child.key === 'residentialAddress' && child.type === 'arrowRight' child.key === 'residentialAddress' && child.domType === 'arrowRight'
? '' ? ''
: child.label : child.label
" "
...@@ -44,7 +44,8 @@ ...@@ -44,7 +44,8 @@
<!-- 自定义 label 插槽 --> <!-- 自定义 label 插槽 -->
<template <template
v-if=" v-if="
child.key === 'residentialAddress' && child.type === 'arrowRight' child.key === 'residentialAddress' &&
child.domType === 'arrowRight'
" "
#label #label
> >
...@@ -69,11 +70,17 @@ ...@@ -69,11 +70,17 @@
v-model="form[child.key]" v-model="form[child.key]"
:placeholder="child.placeholder" :placeholder="child.placeholder"
maxlength="30" maxlength="30"
:disabled="child.disabled" :disabled="
@change="handleInputChange(child)" child.key == 'age' || child.key == 'bmi' ? true : editStatus
"
@blur="handleInputBlur(child)"
>
<template #append v-if="child.unit">
<span
@click="handleAppendInput(child)"
:style="{ color: child.unitColor }"
>{{ child.unit }}</span
> >
<template #append v-if="child.unit" @click="handleAppendInput(child)">
<span :style="{ color: child.unitColor }">{{ child.unit }}</span>
</template> </template>
</el-input> </el-input>
<el-select <el-select
...@@ -81,7 +88,7 @@ ...@@ -81,7 +88,7 @@
v-model="form[child.key]" v-model="form[child.key]"
:placeholder="child.placeholder" :placeholder="child.placeholder"
@change="handleSelectChange(child)" @change="handleSelectChange(child)"
:disabled="child.disabled" :disabled="editStatus"
> >
<el-option <el-option
v-for="item in child.options" v-for="item in child.options"
...@@ -98,7 +105,7 @@ ...@@ -98,7 +105,7 @@
format="YYYY-MM-DD" format="YYYY-MM-DD"
value-format="YYYY-MM-DD" value-format="YYYY-MM-DD"
:placeholder="child.placeholder" :placeholder="child.placeholder"
:disabled="child.disabled" :disabled="editStatus"
:disabled-date="time => disabledDate(time, child)" :disabled-date="time => disabledDate(time, child)"
:default-value="defaultDisplayDate" :default-value="defaultDisplayDate"
@change="handleDateChange(child)" @change="handleDateChange(child)"
...@@ -111,7 +118,7 @@ ...@@ -111,7 +118,7 @@
@click="handleFoucs(child)" @click="handleFoucs(child)"
:suffix-icon="ArrowRight" :suffix-icon="ArrowRight"
readonly readonly
:disabled="child.disabled" :disabled="editStatus"
> >
</el-input> </el-input>
</el-form-item> </el-form-item>
...@@ -169,8 +176,7 @@ ...@@ -169,8 +176,7 @@
</CardOne> </CardOne>
</div> </div>
</el-row> </el-row>
<el-row v-if="tabSource == 'customer'">
<el-row>
<el-col> <el-col>
<div class="tabButton"> <div class="tabButton">
<el-button <el-button
...@@ -181,10 +187,11 @@ ...@@ -181,10 +187,11 @@
:disabled="editStatus" :disabled="editStatus"
>取消</el-button >取消</el-button
> >
<!-- @click="submitForm" -->
<el-button <el-button
type="primary" type="primary"
icon="Check" icon="Check"
@click="submitForm" @click="handleFormValues"
size="large" size="large"
:disabled="editStatus" :disabled="editStatus"
>提交</el-button >提交</el-button
...@@ -193,57 +200,8 @@ ...@@ -193,57 +200,8 @@
</el-col> </el-col>
</el-row> </el-row>
</el-form> </el-form>
</div> </template>
</CommonForm>
<el-dialog title="客户信息" v-model="openList" width="600px" append-to-body>
<div>
<el-form :model="queryParams" ref="queryRef" :inline="true" label-width="68px">
<el-form-item label="客户姓名" prop="name">
<el-input v-model="queryParams.name" placeholder="请输入姓名" @input="customerList" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" circle @click="customerList" />
<el-button type="info" icon="Refresh" circle @click="resetCustomerList" />
</el-form-item>
</el-form>
<div class="customerBox">
<div class="customerItem" v-for="item in tableData" :key="item.id">
<div class="top">
<div class="left">
<div>{{ item.name }}</div>
<div v-if="item.gender" style="margin: 0 5px">-</div>
<div v-if="item.gender" class="gender">
<dict-tag :options="sys_gender" :value="item.gender" />
</div>
</div>
<div class="right">
<el-button type="primary" size="small" @click="handleExport(item)"
>导入客户信息</el-button
>
</div>
</div>
<div class="bottom">
<div class="infoItem">
<span>证件类型:</span>
<span> <dict-tag :options="csf_id_type" :value="item.idType" /></span>
</div>
<div class="infoItem">
<span>证件号码:</span>
<span> {{ item.idCard || '暂无' }}</span>
</div>
<div class="infoItem">
<span>电话号码:</span>
<span> {{ item.phone || '暂无' }}</span>
</div>
<div class="infoItem">
<span>出生日期:</span>
<span> {{ formatToDate(item.birthday) || '暂无' }}</span>
</div>
</div>
</div>
</div>
</div>
</el-dialog>
</div> </div>
<Phone <Phone
@close="handleCloseDrawer" @close="handleCloseDrawer"
...@@ -267,10 +225,93 @@ ...@@ -267,10 +225,93 @@
@confirmCountry="confirmDrawer" @confirmCountry="confirmDrawer"
/> />
<!-- 历史客户的弹窗 --> <!-- 历史客户的弹窗 -->
<CommonDialog
dialogTitle="历史客户"
:showConfirm="false"
cancleText="关闭"
dialogWidth="70%"
:openDialog="openList"
@close="openList = false"
>
<div class="dialogBox">
<CommonPage
:operationBtnList="operationBtnList"
:visibleDefaultButtons="visibleDefaultButtons"
:showSearchForm="true"
:show-pagination="true"
:currentPage="queryParams.pageNo"
:total="total"
:pageSize="queryParams.pageSize"
@current-change="changePageNo"
@size-change="changePageSize"
>
<!-- 查询条件插槽 -->
<template #searchForm>
<el-form :model="queryParams" ref="queryRef" label-width="100px" label-position="top">
<el-row :gutter="30">
<el-col :sm="12" :lg="8" :xs="24">
<el-form-item label="姓名" prop="name">
<el-input v-model="queryParams.name" placeholder="请输入姓名" clearable />
</el-form-item>
</el-col>
<el-col :sm="12" :lg="8" :xs="24">
<el-form-item label="手机号" prop="mobile">
<el-input v-model="queryParams.mobile" placeholder="请输入手机号" clearable />
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<!-- 表格插槽 -->
<template #table>
<el-table v-loading="tableLoading" :data="tableData" @row-click="handleExport">
<!-- <el-table-column type="selection" width="55" align="center" /> -->
<el-table-column label="姓名" align="center" prop="nameCn" width="200" />
<el-table-column label="性别" align="center" prop="gender">
<template #default="scope">
<dict-tag :options="fetchDictData('sys_gender')" :value="scope.row.gender" />
</template>
</el-table-column>
<el-table-column label="证件类型" align="center" prop="documentType">
<template #default="scope">
<dict-tag
:options="fetchDictData('csf_id_type')"
:value="scope.row.documentType"
/>
</template>
</el-table-column>
<el-table-column label="证件号码" align="center" prop="idNumber" />
<el-table-column label="电话号码" align="center" prop="mobile" />
<el-table-column label="出生日期" align="center" width="180" prop="birthday">
<template #default="scope">
<span>{{ scope.row.birthday ? formatToDate(scope.row.birthday) : '--' }}</span>
</template>
</el-table-column>
<el-table-column
label="操作"
align="center"
width="150"
class-name="small-padding fixed-width"
fixed="right"
>
<template #default="scope">
<el-button link type="primary" @click="handleExport(scope.row)"
>使用客户资料</el-button
>
</template>
</el-table-column>
</el-table>
</template>
</CommonPage>
</div>
</CommonDialog>
</div> </div>
</template> </template>
<script setup name="customer"> <script setup name="customer">
import { validateEnglish } from '@/utils/validate' import { validateEnglish, validateBMI, validateIdCard, validateChinese } from '@/utils/validate'
import { calculateExactAge } from '@/utils/date' import { calculateExactAge } from '@/utils/date'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { ArrowRight } from '@element-plus/icons-vue' import { ArrowRight } from '@element-plus/icons-vue'
...@@ -278,7 +319,9 @@ import customerDomData from '@/formJson/customer' ...@@ -278,7 +319,9 @@ import customerDomData from '@/formJson/customer'
import Country from '@/views/components/country' import Country from '@/views/components/country'
import Phone from '@/views/components/phone' import Phone from '@/views/components/phone'
import Address from '@/views/components/address' import Address from '@/views/components/address'
import CommonAnchor from '@/components/commonAnchor' import CommonForm from '@/views/components/commonForm'
import CommonDialog from '@/components/commonDialog'
import CommonPage from '@/components/commonPage'
import CardOne from '@/components/formCard/cardOne' import CardOne from '@/components/formCard/cardOne'
import { watch } from 'vue' import { watch } from 'vue'
import { import {
...@@ -287,23 +330,21 @@ import { ...@@ -287,23 +330,21 @@ import {
editCustomer, editCustomer,
getCustomerList, getCustomerList,
addFna, addFna,
calculateFieldValue, calculateFieldValue
} from '@/api/sign/fna' } from '@/api/sign/fna'
import useDictStore from '@/store/modules/dict' import useDictStore from '@/store/modules/dict'
const dictStore = useDictStore() //获取字典数据 const dictStore = useDictStore() //获取字典数据
const props = defineProps({ const props = defineProps({
activeName: { type: String, default: '' }, //tab名称 activeName: { type: String, default: '' }, //tab名称
tabPaneRef: { fatherEditStatus: { type: Boolean, default: true }, //因为嵌套了双层tab,所以需要父组件传值控制子组件的编辑状态
type: Object, anchorContainer: { type: String, default: '' }, //锚点滚动容器
default: null tabIndex: { type: [String, Number], default: '' }, //tab索引
}, affixOffset: { type: Number, default: 250 }, //锚点吸顶距离
fearthStatus: { type: String, default: '' }, //父组件状态,新增、修改 customerBizId: { type: String, default: '' }, //提交状态,新增、修改
customerBizId: { type: String, default: '' } //提交状态,新增、修改 tabSource: { type: String, default: '' } //引用这个组件的页面来源,用于逻辑判断
}) })
const emit = defineEmits(['handleSuccess']) const emit = defineEmits(['handleSuccess'])
const { proxy } = getCurrentInstance() const { proxy } = getCurrentInstance()
const { csf_id_type, sys_gender } = proxy.useDict('csf_id_type', 'sys_gender')
const anchorList = ref([]) //锚点列表
const customerRightRef = ref(null) const customerRightRef = ref(null)
const showPhoneDrawer = ref(false) //电话抽屉开关 const showPhoneDrawer = ref(false) //电话抽屉开关
const showAddressDrawer = ref(false) //地址抽屉开关 const showAddressDrawer = ref(false) //地址抽屉开关
...@@ -318,10 +359,8 @@ const oldObjInfo = ref({}) // 修改时存储原始数据,便于撤销操作 ...@@ -318,10 +359,8 @@ const oldObjInfo = ref({}) // 修改时存储原始数据,便于撤销操作
const tableLoading = ref(false) const tableLoading = ref(false)
const tableData = ref([]) const tableData = ref([])
const total = ref(0) const total = ref(0)
const customerRef = ref(null)
//计算默认显示的日期(18年前的今天) //计算默认显示的日期(18年前的今天)
const defaultDisplayDate = ref(dayjs().subtract(18, 'year').toDate()) const defaultDisplayDate = ref(dayjs().subtract(18, 'year').toDate())
// const copyAddress = ref(false) //是否可以复制地址
// 地址组件菜单数据 // 地址组件菜单数据
const addressMenuList = ref([ const addressMenuList = ref([
{ {
...@@ -377,7 +416,7 @@ const deleteKeyList = ref([ ...@@ -377,7 +416,7 @@ const deleteKeyList = ref([
'objType', 'objType',
'mailingAddress', 'mailingAddress',
'residentialAddress', 'residentialAddress',
'residenceAddress', 'mailingAddress',
'companyAddress' 'companyAddress'
]) // 存储需要删除的key ]) // 存储需要删除的key
const data = reactive({ const data = reactive({
...@@ -387,12 +426,117 @@ const data = reactive({ ...@@ -387,12 +426,117 @@ const data = reactive({
rules: {}, //表单验证规则, rules: {}, //表单验证规则,
queryParams: { queryParams: {
pageNo: 1, pageNo: 1,
pageSize: 4, pageSize: 10,
name: undefined name: undefined
} }
}) })
const { form, rules, processedCustomerData, queryParams, oldCustomerData } = toRefs(data) const { form, rules, processedCustomerData, queryParams, oldCustomerData } = toRefs(data)
const handleAppendInput = child => {} // 控制要显示的默认按钮
const visibleDefaultButtons = ref(['query', 'reset']) // 只显示新增和查询两个默认按钮
// 按钮配置
const operationBtnList = ref([
{
key: 'reset',
size: 'small',
direction: 'right',
click: resetQuery
},
{
key: 'query',
size: 'small',
direction: 'right',
click: handleQuery
}
])
const customerFormRef = ref(null)
const changePageNo = val => {
queryParams.value.pageNo = val
customerList()
}
const changePageSize = val => {
queryParams.value.pageSize = val
customerList()
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNo = 1
customerList()
}
/** 重置按钮操作 */
function resetQuery() {
proxy.resetForm('queryRef')
queryParams.value = {
pageNo: 1,
pageSize: 10
}
handleQuery()
}
const handleAppendInput = child => {
if (child.key == 'nameCn') {
if (editStatus.value) {
proxy.$modal.confirm(`请先点击编辑在导入客户信息`, { showCancel: '0', title: '填写提示' })
return
}
openList.value = true
queryParams.value = {
pageNo: 1,
pageSize: 10
}
customerList()
}
}
const handleInputBlur = child => {
if (form.value['documentType'] == 'idCard' && child.key == 'idNumber') {
getFieldValue(child.key)
} else if (
(child.key == 'weight' || child.key == 'height') &&
form.value['weight'] &&
form.value['height']
) {
getFieldValue(child.key)
} else if (child.key == 'nameCn' && form.value['nameCn']) {
getFieldValue(child.key)
}
}
const getFieldValue = key => {
let obj = {}
if (form.value['documentType'] == 'idCard' && key == 'idNumber') {
obj = {
calculateType: 6,
requestValue: form.value['idNumber']
}
} else if (key == 'weight' || key == 'height') {
obj = {
calculateType: 5,
requestValueList: [form.value['height'], form.value['weight']]
}
} else if (key == 'nameCn') {
obj = {
calculateType: 1,
requestValue: form.value['nameCn']
}
}
calculateFieldValue(obj).then(res => {
if (res.code == 200) {
res.data.forEach(item => {
if (obj.calculateType == 6) {
if (item.calculateType == 2) {
form.value['gender'] = item.responseKey
} else if (item.calculateType == 3) {
form.value['birthday'] = item.requestValue
} else if (item.calculateType == 4) {
form.value['age'] = item.requestValue
}
} else if (obj.calculateType == 5) {
form.value['bmi'] = item.responseValue
} else if (obj.calculateType == 1) {
form.value['namePyEn'] = item.responseValue
}
})
}
})
}
// 添加表单子级dom // 添加表单子级dom
const addChildren = father => { const addChildren = father => {
const processedData = JSON.parse(JSON.stringify(processedCustomerData.value)) const processedData = JSON.parse(JSON.stringify(processedCustomerData.value))
...@@ -401,7 +545,7 @@ const addChildren = father => { ...@@ -401,7 +545,7 @@ const addChildren = father => {
id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识 id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识
span: 24, //栅格布局份数 span: 24, //栅格布局份数
taxCountry: '', taxCountry: '',
taxNumber: '' taxId: ''
} }
for (const section of processedData) { for (const section of processedData) {
...@@ -409,9 +553,8 @@ const addChildren = father => { ...@@ -409,9 +553,8 @@ const addChildren = father => {
section.data.push(obj4) section.data.push(obj4)
} }
} }
//更新form表单对应的数据,以便收集填写的值
// form.value[father.key].push(obj)
processedCustomerData.value = processedData processedCustomerData.value = processedData
console.log('processedCustomerData.value', processedCustomerData.value)
} }
const deleteChildren = (father, childIndex) => { const deleteChildren = (father, childIndex) => {
if (editStatus.value) { if (editStatus.value) {
...@@ -427,10 +570,10 @@ const deleteChildren = (father, childIndex) => { ...@@ -427,10 +570,10 @@ const deleteChildren = (father, childIndex) => {
processedCustomerData.value = processedData processedCustomerData.value = processedData
} }
const copyAddress = computed(() => { const copyAddress = computed(() => {
const residenceAddressIndex = addressQuickList.value.findIndex( const mailingAddressIndex = addressQuickList.value.findIndex(
item => item.type === 'residenceAddress' item => item.type === 'mailingAddress'
) )
if (residenceAddressIndex !== -1) { if (mailingAddressIndex !== -1) {
return false return false
} else { } else {
return true return true
...@@ -440,10 +583,10 @@ const changeAddressStatus = child => { ...@@ -440,10 +583,10 @@ const changeAddressStatus = child => {
// 复用地址 // 复用地址
if (form.value.isCopyAddress.length > 0 && form.value.isCopyAddress[0]) { if (form.value.isCopyAddress.length > 0 && form.value.isCopyAddress[0]) {
if (child.key == 'residentialAddress') { if (child.key == 'residentialAddress') {
form.value[child.key] = form.value['residenceAddress'] form.value[child.key] = form.value['mailingAddress']
// 这里是直接复用地址了,但是地址组件的值是双向绑定的,所以这里需要手动更新地址组件的值 // 这里是直接复用地址了,但是地址组件的值是双向绑定的,所以这里需要手动更新地址组件的值
addressQuickList.value.forEach(item => { addressQuickList.value.forEach(item => {
if (item.type == 'residenceAddress') { if (item.type == 'mailingAddress') {
saveKey.value[child.key] = { ...item, type: child.key } saveKey.value[child.key] = { ...item, type: child.key }
} }
}) })
...@@ -451,15 +594,7 @@ const changeAddressStatus = child => { ...@@ -451,15 +594,7 @@ const changeAddressStatus = child => {
} }
console.log('saveKey.value', saveKey.value) console.log('saveKey.value', saveKey.value)
} }
const handleInputChange = child => {
if (
(child.key == 'lastName' || child.key == 'firstName') &&
form.value['lastName'] &&
form.value['firstName']
) {
form.value['name'] = form.value['lastName'] + form.value['firstName']
}
}
const handleDateChange = child => { const handleDateChange = child => {
let age = null let age = null
if (child.key == 'birthday') { if (child.key == 'birthday') {
...@@ -479,20 +614,16 @@ const disabledDate = (time, child) => { ...@@ -479,20 +614,16 @@ const disabledDate = (time, child) => {
return time.getTime() > Date.now() return time.getTime() > Date.now()
} }
} }
const resetCustomerList = () => {
queryParams.value = {
pageNo: 1,
pageSize: 4,
name: undefined
}
customerList()
}
const exportInfo = () => { const exportInfo = () => {
if (props.customerBizId && editStatus.value) { if (props.customerBizId && editStatus.value) {
proxy.$modal.confirm(`请先点击编辑在导入客户信息`, { showCancel: '0', title: '填写提示' }) proxy.$modal.confirm(`请先点击编辑在导入客户信息`, { showCancel: '0', title: '填写提示' })
return return
} }
queryParams.value = {
pageNo: 1,
pageSize: 10,
name: undefined
}
openList.value = true openList.value = true
customerList() customerList()
} }
...@@ -510,7 +641,11 @@ const customerList = () => { ...@@ -510,7 +641,11 @@ const customerList = () => {
} }
// 从客户列表中导入客户信息到当前表单 // 从客户列表中导入客户信息到当前表单
const handleExport = row => { const handleExport = row => {
oldCustomerData.value = JSON.parse(JSON.stringify(processedCustomerData.value)) // 修改时存储原始数据,便于撤销操作
oldObjInfo.value = JSON.parse(JSON.stringify(form.value)) // 修改时存储原始数据,便于撤销操作 oldObjInfo.value = JSON.parse(JSON.stringify(form.value)) // 修改时存储原始数据,便于撤销操作
console.log('导入前form', oldObjInfo.value)
console.log('导入前dom', oldCustomerData.value)
setFormValue(row, processedCustomerData.value, true) setFormValue(row, processedCustomerData.value, true)
openList.value = false openList.value = false
} }
...@@ -537,12 +672,30 @@ const fetchDictData = dictType => { ...@@ -537,12 +672,30 @@ const fetchDictData = dictType => {
} }
// 处理表单配置,添加字典数据 // 处理表单配置,添加字典数据
const processFormData = async () => { const processFormData = async () => {
anchorList.value = []
// 深拷贝原始数据 // 深拷贝原始数据
const processedData = JSON.parse(JSON.stringify(customerDomData)) const processedData = JSON.parse(JSON.stringify(customerDomData))
rules.value = {}
for (const section of processedData) { for (const section of processedData) {
anchorList.value.push({ title: section.anchorKey, name: section.fatherTitle }) // 如果在受保人中,与投保人关系已填写,根据填写内容展示对应的模块
if (
props.activeName == 'insurantInfo' &&
form.value['policyholderRel'] &&
form.value['policyholderRel'] == 'MYSELF'
) {
if (section.key == 'policyholderRel') {
section.showMoudle = true
} else {
section.showMoudle = false
}
} else {
section.showMoudle = true
}
if (props.activeName == 'insurantInfo' && section.key == 'policyholderRel') {
section.showMoudle = true
} else if (props.activeName !== 'insurantInfo' && section.key == 'policyholderRel') {
section.showMoudle = false
}
if (section.data) { if (section.data) {
for (const field of section.data) { for (const field of section.data) {
if (field.dictType) { if (field.dictType) {
...@@ -555,32 +708,38 @@ const processFormData = async () => { ...@@ -555,32 +708,38 @@ const processFormData = async () => {
{ required: true, message: `${field.label}不能为空`, trigger: 'blur' }, { required: true, message: `${field.label}不能为空`, trigger: 'blur' },
{ validator: validateEnglish, trigger: 'change' } { validator: validateEnglish, trigger: 'change' }
] ]
} else if (field.key === 'nameCn') {
rules.value[field.key] = [
{ required: true, message: `${field.label}不能为空`, trigger: 'blur' },
{ validator: validateChinese, trigger: 'blur' }
]
} else { } else {
rules.value[field.key] = [ rules.value[field.key] = [
{ required: true, message: `${field.label}不能为空`, trigger: 'blur' } { required: true, message: `${field.label}不能为空`, trigger: 'blur' }
] ]
} }
} }
if (props.customerBizId) { // if (field.key === 'bmi') {
field.disabled = true // rules.value[field.key] = [
} else if (field.key !== 'age') { // { required: false, trigger: 'change' },
field.disabled = false // { validator: validateBMI,trigger: 'change' }
// ]
// }
} }
} }
} }
// 为私有的加form验证
if (props.activeName == 'insurantInfo') {
rules.value['policyholderRel'] = [
{ required: true, message: `与投保人关系不能为空`, trigger: 'blur' }
]
} }
if (props.customerBizId) { if (props.customerBizId) {
getCustomerInfo(props.customerBizId, processedData) getCustomerInfo(props.customerBizId, processedData)
editStatus.value = true
} else { } else {
editStatus.value = false
form.value.customerType = 'INDIVIDUAL'
processedCustomerData.value = oldCustomerData.value = processedData processedCustomerData.value = oldCustomerData.value = processedData
} }
console.log('====================================') console.log('form', form.value)
console.log('anchorList.value', anchorList.value)
console.log('====================================')
} }
//弹出右侧抽屉 //弹出右侧抽屉
...@@ -641,8 +800,8 @@ const confirmDrawer = info => { ...@@ -641,8 +800,8 @@ const confirmDrawer = info => {
// console.log('抽屉info', info) // console.log('抽屉info', info)
// info 为抽屉返回的值 // info 为抽屉返回的值
if (drawerInfo.value.type == 'arrowRight' && drawerInfo.value.drawerType) { if (drawerInfo.value.domType == 'arrowRight' && drawerInfo.value.drawerType) {
// console.log('drawerInfo.value', drawerInfo.value) console.log('drawerInfo.value', drawerInfo.value)
let newObj = info[drawerInfo.value.key] let newObj = info[drawerInfo.value.key]
//要判断drawerType //要判断drawerType
...@@ -714,11 +873,14 @@ const confirmDrawer = info => { ...@@ -714,11 +873,14 @@ const confirmDrawer = info => {
default: default:
break break
} }
console.log('form.value', form.value)
console.log(' saveKey.value', saveKey.value)
// 手动触发表单验证 // 手动触发表单验证
nextTick(() => { nextTick(() => {
// 根据不同的drawerType确定要验证的字段key // 根据不同的drawerType确定要验证的字段key
const validateField = drawerInfo.value.key const validateField = drawerInfo.value.key
customerRef.value.clearValidate(validateField) customerFormRef.value.clearValidate(validateField)
}) })
} }
...@@ -727,26 +889,33 @@ const confirmDrawer = info => { ...@@ -727,26 +889,33 @@ const confirmDrawer = info => {
const handleSelectChange = child => { const handleSelectChange = child => {
switch (child.key) { switch (child.key) {
// case 'smokingStatus': case 'documentType':
// // 选择吸烟,展示吸烟数量 break
// if (form.value[child.key] == '1') { case 'isRetirement':
// resetShow('smokeQuantity', true) if (form.value[child.key] == '1') {
// } else { resetShow('retirementAge', true)
// resetShow('smokeQuantity', false) } else {
// } resetShow('retirementAge', false)
// break }
// case 'idType': break
// // 选择吸烟,展示吸烟数量 case 'policyholderRel':
// if (form.value[child.key] == 'idCard') { processedCustomerData.value.forEach(section => {
// resetShow('idCardAddress', true) if (form.value[child.key] == 'MYSELF') {
// } else { if (section.key == 'policyholderRel') {
// resetShow('idCardAddress', false) section.showMoudle = true
// } } else {
// break section.showMoudle = false
}
} else {
section.showMoudle = true
}
})
break
default: default:
break break
} }
} }
// 改变编辑状态 // 改变编辑状态
const handleEditStatus = () => { const handleEditStatus = () => {
editStatus.value = !editStatus.value editStatus.value = !editStatus.value
...@@ -757,12 +926,16 @@ const handleEditStatus = () => { ...@@ -757,12 +926,16 @@ const handleEditStatus = () => {
for (const field of section.data) { for (const field of section.data) {
if (editStatus.value) { if (editStatus.value) {
field.disabled = true field.disabled = true
} else if (field.key !== 'age') { } else {
if (field.key == 'age' || field.key == 'bmi') {
field.disabled = true
} else {
field.disabled = false field.disabled = false
} }
} }
} }
} }
}
processedCustomerData.value = processedData processedCustomerData.value = processedData
} }
//给表单赋值 方便表单回显 obj 为表单数据 //给表单赋值 方便表单回显 obj 为表单数据
...@@ -780,13 +953,16 @@ const setFormValue = (obj, formData, exportValue) => { ...@@ -780,13 +953,16 @@ const setFormValue = (obj, formData, exportValue) => {
// if (section.key == 'personInfo') { // if (section.key == 'personInfo') {
// section.data.push() // section.data.push()
// } // }
if (
section.key == 'apiTaxationDtoList' &&
obj.apiTaxationDtoList &&
obj.apiTaxationDtoList.length > 0
) {
section.data = JSON.parse(JSON.stringify(obj.apiTaxationDtoList))
}
if (section.data) { if (section.data) {
for (const field of section.data) { for (const field of section.data) {
// if (obj.smokeQuantity && field.key == 'smokeQuantity') { if (obj.isRetirement && obj.isRetirement == '1' && field.key == 'retirementAge') {
// field.show = true
// }
//证件类型是身份证,身份证地址就显示否则不显示
if (field.key == 'idCardAddress' && obj.idType == 'idCard') {
field.show = true field.show = true
} }
//要判断drawerType,因为抽屉要回显数据 //要判断drawerType,因为抽屉要回显数据
...@@ -848,12 +1024,12 @@ const setFormValue = (obj, formData, exportValue) => { ...@@ -848,12 +1024,12 @@ const setFormValue = (obj, formData, exportValue) => {
break break
case 'country': case 'country':
form.value[field.key] = obj.countryName form.value[field.key] = obj.nationality
saveKey.value[field.key] = { saveKey.value[field.key] = {
country: obj.country || '', // country: obj.country || '',
countryCode: obj.country || '', // countryCode: obj.country || '',
countryName: obj.countryName || '', // countryName: obj.countryName || '',
name: obj.countryName || '', name: obj.nationality || '',
objType: field.drawerType objType: field.drawerType
} }
break break
...@@ -890,11 +1066,11 @@ const setFormValue = (obj, formData, exportValue) => { ...@@ -890,11 +1066,11 @@ const setFormValue = (obj, formData, exportValue) => {
phoneQuickList.value = removeDuplicates(tempPhoneList, 'phoneString') phoneQuickList.value = removeDuplicates(tempPhoneList, 'phoneString')
addressQuickList.value = removeDuplicates(tempAddressList, 'addressString') addressQuickList.value = removeDuplicates(tempAddressList, 'addressString')
if (!exportValue) { // if (!exportValue) {
// 保存一份就得表单数据便于做撤销操作 // // 保存一份就得表单数据便于做撤销操作
oldObjInfo.value = JSON.parse(JSON.stringify(form.value)) // oldObjInfo.value = JSON.parse(JSON.stringify(form.value))
} // }
processedCustomerData.value = oldCustomerData.value = processedData processedCustomerData.value = processedData
} }
// 数组去重 // 数组去重
function removeDuplicates(arr, key) { function removeDuplicates(arr, key) {
...@@ -923,15 +1099,98 @@ const getInvalidFields = fields => { ...@@ -923,15 +1099,98 @@ const getInvalidFields = fields => {
} }
return errors return errors
} }
// 表单提交
const submitForm = () => { const resetForm = () => {
//提交得时候要处理税务国家得数据。表格得值收集在processedCustomerData中,所以需要从processedCustomerData中取值 proxy.$modal
.confirm('是否确认撤销所作操作?')
.then(function () {
customerFormRef.value.resetFields()
console.log('切换之前的form', oldObjInfo.value)
console.log('切换之前的dom', oldCustomerData.value)
// processedCustomerData.value = JSON.parse(JSON.stringify(oldCustomerData.value))
setFormValue(oldObjInfo.value, oldCustomerData.value)
})
.catch(() => {})
}
// 获取客户详情
function getCustomerInfo(customerBizId, formData) {
getCustomerDetail(customerBizId).then(async res => {
if (res.code == 200) {
// 回显值
setFormValue(res.data, formData)
}
})
}
// 根据联动重置表单项的显示与否
const resetShow = (key, status) => {
for (const section of processedCustomerData.value) {
if (section.data) {
for (const field of section.data) {
if (field.key == key) {
// 获取字典数据
field.show = status
}
}
}
}
}
// 方法1:使用 Promise 包装 validateField
const debugValidation = async () => {
const fieldNames = Object.keys(rules.value)
console.log('开始验证以下字段:', fieldNames)
// 1. 为每个字段创建验证Promise,并直接返回该字段的验证结果
const validationPromises = fieldNames.map(field => {
return new Promise(resolve => {
if (!customerFormRef.value) {
console.error(`[${field}] 表单实例不存在`)
resolve({ field, error: null, valid: false }) // 标记为无效
return
}
customerFormRef.value.validateField(field, errorMessage => {
console.log(`[${field}] 验证结果:`, errorMessage ? `失败 - ${errorMessage}` : '通过')
// 关键修改:只有当 errorMessage 存在(有错误)时,才携带错误信息
if (errorMessage) {
resolve({ field, error: errorMessage, valid: false })
} else {
resolve({ field, error: null, valid: true })
}
})
})
})
// 2. 等待所有验证完成
const results = await Promise.all(validationPromises)
// 3. 筛选出所有验证失败的字段
const errors = results
.filter(result => !result.valid && result.error)
.map(result => ({ field: result.field, message: result.error }))
console.log('最终收集到的错误列表:', errors)
return errors
}
// 滚动到第一个错误字段
const scrollToFirstError = () => {
const firstError = document.querySelector('.el-form-item__error')
if (firstError) {
firstError.scrollIntoView({ behavior: 'smooth', block: 'center' })
}
}
const handleFormValues = () => {
return new Promise(async resolve => {
let submitObj = { ...form.value } let submitObj = { ...form.value }
let addressList = [] let addressList = []
submitObj['birthday'] = proxy.formatToDate(submitObj['birthday']) submitObj['birthday'] = proxy.formatToDate(submitObj['birthday'])
customerFormRef.value.validate((valid, fields) => {
proxy.$refs['customerRef'].validate((valid, fields) => {
if (valid) { if (valid) {
errorFields.value = [] // 清空错误信息
//处理表单数据 //处理表单数据
for (const key1 in form.value) { for (const key1 in form.value) {
for (const key2 in saveKey.value) { for (const key2 in saveKey.value) {
...@@ -963,12 +1222,25 @@ const submitForm = () => { ...@@ -963,12 +1222,25 @@ const submitForm = () => {
} }
submitObj['birthday'] = proxy.formatToDate(submitObj['birthday']) submitObj['birthday'] = proxy.formatToDate(submitObj['birthday'])
submitObj['addressList'] = addressList submitObj['addressList'] = addressList
processedCustomerData.value.forEach(item => {
if (item.key == 'apiTaxationDtoList' && item.data.length > 0) {
submitObj['apiTaxationDtoList'] = item.data.filter(item => {
return item.taxCountry && item.taxCountry.trim() && item.taxId && item.taxId.trim()
})
}
})
// 删除多余字段 // 删除多余字段
deleteKeyList.value.forEach(item => { deleteKeyList.value.forEach(item => {
delete submitObj[item] delete submitObj[item]
}) })
if (props.customerBizId) { if (errorFields.value.length > 0) {
proxy.$message.error(errorFields.value[0].message)
return undefined
}
if (props.customerBizId && props.activeName == 'customer') {
editCustomer(submitObj).then(res => { editCustomer(submitObj).then(res => {
if (res.code == 200) { if (res.code == 200) {
handleEditStatus() handleEditStatus()
...@@ -980,10 +1252,9 @@ const submitForm = () => { ...@@ -980,10 +1252,9 @@ const submitForm = () => {
}) })
} }
}) })
} else { } else if (!props.customerBizId && props.activeName == 'customer') {
addFna({ remark: '' }).then(response => { addFna({ remark: '' }).then(response => {
if (response.code == 200) { if (response.code == 200) {
// res.data.fnaBizId 写到这了,先增加fna,再增加客户 看一下流程是否报错
addCustomer(submitObj).then(res => { addCustomer(submitObj).then(res => {
if (res.code == 200) { if (res.code == 200) {
proxy.$message.success('客户新增成功') proxy.$message.success('客户新增成功')
...@@ -998,56 +1269,64 @@ const submitForm = () => { ...@@ -998,56 +1269,64 @@ const submitForm = () => {
} }
}) })
} }
resolve(errorFields.value.length == 0 ? submitObj : null)
// emit('submitForm', submitObj)
errorFields.value = [] // 清空错误信息
} else { } else {
// 获取校验失败的字段信息
errorFields.value = getInvalidFields(fields) errorFields.value = getInvalidFields(fields)
if (errorFields.value.length > 0) { if (errorFields.value.length > 0) {
proxy.$message.error(errorFields.value[0].message) proxy.$message.error(errorFields.value[0].message)
} }
resolve(undefined)
} }
}) })
}
const resetForm = () => {
proxy.$modal
.confirm('是否确认撤销所作操作?')
.then(function () {
if (props.customerBizId) {
form.value = { ...oldObjInfo.value }
editStatus.value = true
} else {
// resetShow('smokeQuantity', false)
proxy.$refs['customerRef'].resetFields()
}
processedCustomerData.value = JSON.parse(JSON.stringify(oldCustomerData.value))
}) })
.catch(() => {})
} }
// 获取客户详情 const anchorList = computed(() => {
function getCustomerInfo(customerBizId, formData) { let data = []
getCustomerDetail(customerBizId).then(async res => { for (const section of processedCustomerData.value) {
if (res.code == 200) { if (section.showMoudle) {
// 回显值 data.push({ title: section.anchorKey, name: section.fatherTitle })
setFormValue(res.data, formData)
} }
}) }
} return data
})
watch( watch(
() => props.activeName, () => props.activeName,
newVal => { newVal => {
if (newVal === 'customer') { editStatus.value = false
customerRightRef.value = null customerRightRef.value = null
if (newVal === 'customer' || newVal === 'policyholder' || newVal === 'insurantInfo') {
processFormData() processFormData()
// 因为客户资料里的编辑状态是单独控制的
if (props.tabSource == 'customer' && props.customerBizId) {
editStatus.value = true
} else if (props.tabSource == 'customer' && !props.customerBizId) {
editStatus.value = false
}
}
} }
)
watch(
() => props.fatherEditStatus,
newVal => {
editStatus.value = newVal
} }
) )
// 暴露给父组件
defineExpose({
handleFormValues,
handleEditStatus
})
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.dialogBox {
margin: 10px;
width: 100%;
height: 600px;
overflow-y: scroll;
}
.customerContainer { .customerContainer {
display: flex; /* display: flex; */
height: 100%; height: 100%;
box-sizing: border-box; box-sizing: border-box;
position: relative; position: relative;
...@@ -1169,4 +1448,11 @@ watch( ...@@ -1169,4 +1448,11 @@ watch(
margin-bottom: 0px; margin-bottom: 0px;
} }
} }
/* 响应式调整 */
/* @media (max-width: 768px) {
.editBtn {
right: 5.5%;
top: 16%;
}
} */
</style> </style>
<template> <template>
<div>
<div v-if="processedFanFormData.length > 0"> <div v-if="processedFanFormData.length > 0">
<el-row> <div ref="fanContainerRef">
<!-- <el-row>
<el-col :span="24"> <el-col :span="24">
<div class="topBtn"> <div class="topBtn">
<el-button <el-button
...@@ -13,58 +13,79 @@ ...@@ -13,58 +13,79 @@
> >
</div> </div>
</el-col> </el-col>
</el-row> </el-row> -->
<el-form ref="fanFormRef" :model="form" :rules="rules"> <CommonForm
<div v-for="father in processedFanFormData"> :anchorList="anchorList"
<div> :affixOffset="250"
<div class="fatherLable"> :anchorOffset="10"
{{ father.fatherTitle }} :scrollContainerSelector="anchorContainer"
<div class="openCon" v-if="father.openIcon" @click="changeOpenStatus(father)"> :scrollOffset="10"
<el-icon v-if="!father.isOpen"><Hide /></el-icon> :domIndex="tabIndex"
<el-icon v-else><View /></el-icon> :activeName="activeName"
</div> v-if="fanContainerRef"
</div> >
<div class="subTitle" v-if="father.subTitle && father.isOpen"> <template #form-right>
{{ father.subTitle }} <el-form :model="form" :rules="rules" ref="fanFormRef">
</div> <el-row v-for="(father, fIndex) in processedFanFormData" :id="father.anchorKey">
<div class="formBox">
<CardOne :title="father.fatherTitle" v-if="father.showMoudle">
<template #mainTitCustom>
<div
class="dependNum"
v-if="father.key == 'dependantList' && father.data.length > 0"
>
受供养人数目:{{ father.data.length }}
</div> </div>
<el-row v-if="father.child == 'no'" :gutter="20"> </template>
<template #content>
<el-row :gutter="20" v-if="!father.showTable" class="selfStyle">
<template v-for="child in father.data" :key="child.key"> <template v-for="child in father.data" :key="child.key">
<el-col :sm="child.sm" :lg="child.lg" class="formItem" v-if="child.show"> <el-col :sm="child.sm" :lg="child.lg" class="formItem" v-if="child.show">
<div> <div>
<el-form-item <el-form-item
:label="child.label" :label="
:prop="father.key + '.' + child.key" child.key === 'monthlyIncome' && child.domType === 'Input'
? ''
: child.label
"
:prop="child.key"
:key="child.key" :key="child.key"
:label-width="child.labelWidth" :label-width="child.labelWidth"
:label-position="child.labelPosition" :label-position="child.labelPosition"
> >
<!-- 自定义 label 插槽 -->
<template
v-if="
(child.key === 'monthlyIncome' || child.key === 'liquidAssets') &&
child.domType === 'Input'
"
#label
>
<div class="custom-label">
<span>{{ child.label }}</span>
<el-tooltip :content="child.tooltip" placement="top">
<el-icon><QuestionFilled /></el-icon>
</el-tooltip>
</div>
</template>
<el-input <el-input
v-if="child.domType === 'Input'" v-if="child.domType === 'Input'"
:type="child.inputType" :type="child.inputType"
v-model="form[father.key][child.key]" v-model="child.value"
:placeholder="child.placeholder"
maxlength="30"
:disabled="child.disabled"
:style="{ width: child.inputWidth ? child.inputWidth : '100%' }"
/>
<el-input
v-if="child.inputType === 'Input'"
:type="child.inputType"
v-model="form[father.key][child.key]"
:placeholder="child.placeholder" :placeholder="child.placeholder"
maxlength="30" maxlength="30"
:disabled="child.disabled" :disabled="editStatus"
:style="{ width: child.inputWidth ? child.inputWidth : '100%' }" >
class="formInput" <template #append v-if="child.unit">
/> <span>{{ child.unit }}</span>
</template>
</el-input>
<el-select <el-select
v-if="child.domType === 'Select'" v-if="child.domType === 'Select'"
v-model="form[father.key][child.key]" v-model="child.value"
:placeholder="child.placeholder" :placeholder="child.placeholder"
@change="handleSelectChange(father, child)" @change="handleSelectChange(child)"
:disabled="child.disabled" :disabled="editStatus"
clearable
> >
<el-option <el-option
v-for="item in child.options" v-for="item in child.options"
...@@ -76,17 +97,33 @@ ...@@ -76,17 +97,33 @@
<el-date-picker <el-date-picker
style="width: 100%" style="width: 100%"
v-if="child.domType === 'DatePicker'" v-if="child.domType === 'DatePicker'"
v-model="form[father.key][child.key]" v-model="child.value"
type="date" type="date"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
:placeholder="child.placeholder" :placeholder="child.placeholder"
:disabled="child.disabled" :disabled="editStatus"
:disabled-date="time => disabledDate(time, child)"
:default-value="defaultDisplayDate"
@change="handleDateChange(child)"
/> />
<el-input
v-if="child.domType === 'arrowRight'"
v-model="child.value"
:placeholder="child.placeholder"
@click="handleFoucs(child)"
:suffix-icon="ArrowRight"
readonly
:disabled="editStatus"
>
</el-input>
<el-checkbox-group <el-checkbox-group
v-if="child.domType === 'Checkbox'" v-if="child.domType === 'Checkbox'"
v-model="form[father.key][child.key]" v-model="child.value"
:disabled="child.disabled" :disabled="editStatus"
@change="changeCheck(father, child)"
> >
<template class="customCheckBox">
<el-checkbox <el-checkbox
v-for="item in child.options" v-for="item in child.options"
:key="item.value" :key="item.value"
...@@ -94,299 +131,133 @@ ...@@ -94,299 +131,133 @@
> >
{{ item.label }} {{ item.label }}
</el-checkbox> </el-checkbox>
</el-checkbox-group>
<el-select <el-input
v-model="form[father.key][child.key]" style="width: 250px"
v-if="child.domType === 'SearchSelect'" v-if="
filterable child.key === 'liquidAssetType' &&
remote child.value.filter(item => item == 'G').length > 0
reserve-keyword "
placeholder="请输入关键词搜索" v-model="child.otherLiquidAsset"
:remote-method="query => searchSelectList(query, child.key)" placeholder="请输入说明"
:loading="searchLoadingStates[child.key]" :disabled="editStatus"
:disabled="child.disabled"
clearable
>
<el-option
v-for="item in searchOptions[child.key] || []"
:key="item.value"
:label="item.label"
:value="item.value"
/> />
</el-select> </template>
</el-checkbox-group>
</el-form-item> </el-form-item>
</div> </div>
</el-col> </el-col>
</template> </template>
</el-row> </el-row>
<el-row v-if="father.showTable && father.isOpen"> <el-row v-if="father.showTable">
<el-table :data="father.data" border> <el-col :span="24" v-if="father.addChildren">
<template v-if="father.key == 'familyMembers'"> <el-button
<el-table-column label="亲属" prop="childTitle" width="100px" align="center">
<template #default="scope">
{{
scope.row.type == '4'
? `${scope.row.childTitle}-${scope.$index - 2}`
: scope.row.childTitle
}}
</template>
</el-table-column>
<el-table-column label="年龄" prop="age" align="center">
<template #default="scope">
<el-input
v-model="scope.row.age"
size="default"
placeholder="请输入"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column label="是否需要供养" prop="needProvide" align="center">
<template #default="scope">
<el-select
v-model="scope.row.needProvide"
placeholder="请选择"
:disabled="editStatus" :disabled="editStatus"
clearable type="primary"
icon="Plus"
size="small"
style="margin-bottom: 10px"
@click="addChildren(father)"
>{{ father.addChildrenTxt }}</el-button
> >
<el-option </el-col>
v-for="item in scope.row.options" <el-table :data="father.data" border v-if="father.data.length > 0">
:key="item.value" <!-- 动态渲染列 -->
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column <el-table-column
width="60px" v-for="column in father.columns"
v-if="father.data && father.data.some(item => item.type === '4')" :key="column.prop"
:label="column.label"
:prop="column.prop"
align="center" align="center"
label="操作"
> >
<template #default="scope"> <template #default="scope">
<el-icon <!-- 远程搜索选择框 -->
v-if="scope.row.type == '4'"
@click="deleteChildren(father, scope.$index)"
class="deleteIcon"
><Delete
/></el-icon>
</template>
</el-table-column>
</template>
<template
v-if="
father.key == 'existingSecurityOwner' || father.key == 'existingSecurityInsured'
"
>
<el-table-column label="保险公司" prop="insurer" align="center">
<template #default="scope">
<el-input
size="default"
placeholder="请输入"
v-model="scope.row.insurer"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column label="保障类型" prop="insuranceType" align="center">
<template #default="scope">
<el-input
v-model="scope.row.insuranceType"
size="default"
placeholder="请输入"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column label="保额" prop="sumInsured" align="center">
<template #default="scope">
<el-input
v-model="scope.row.sumInsured"
size="default"
placeholder="请输入"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column label="币种" prop="currency" align="center">
<template #default="scope">
<el-select <el-select
v-model="scope.row.currency" v-if="column.type === 'remoteSelect'"
placeholder="请选择" v-model="scope.row[column.prop]"
filterable
remote
reserve-keyword
:placeholder="column.placeholder"
:remote-method="query => searchSelectList(query, column.searchType)"
:loading="searchLoadingStates[column.searchType]"
:disabled="editStatus" :disabled="editStatus"
clearable @change="handleRemoteSelectChange(scope.row, column)"
> >
<el-option <el-option
v-for="item in scope.row.options" v-for="item in searchOptions[column.searchType] || []"
:key="item.value" :key="item.id"
:label="item.label" :label="item.label"
:value="item.value" :value="item.value"
/> />
</el-select> </el-select>
</template>
</el-table-column> <!-- 普通选择框 -->
<el-table-column label="保单签发日期" prop="policyIssueDate" align="center">
<template #default="scope">
<el-date-picker
style="width: 100%"
v-model="scope.row.policyIssueDate"
type="date"
placeholder="请输入"
:disabled="editStatus"
:disabled-date="disabledDate"
/>
</template>
</el-table-column>
<el-table-column width="60px" align="center" label="操作">
<template #default="scope">
<el-icon @click="deleteChildren(father, scope.$index)" class="deleteIcon"
><Delete
/></el-icon>
</template>
</el-table-column>
</template>
<template v-if="father.key == 'investment'">
<el-table-column label="地址" prop="address" align="center">
<template #default="scope">
<el-input
size="default"
placeholder="请输入"
v-model="scope.row.address"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column label="市值" prop="marketValue" align="center">
<template #default="scope">
<el-input
v-model="scope.row.marketValue"
size="default"
placeholder="请输入"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column label="币种" prop="currency" align="center">
<template #default="scope">
<el-select <el-select
v-model="scope.row.currency" v-else-if="column.type === 'select'"
placeholder="请选择" v-model="scope.row[column.prop]"
:placeholder="column.placeholder"
:disabled="editStatus" :disabled="editStatus"
clearable
> >
<el-option <el-option
v-for="item in scope.row.options" v-for="item in fetchDictData(column.dictType)"
:key="item.value" :key="item.value"
:label="item.label" :label="item.label"
:value="item.value" :value="item.value"
/> />
</el-select> </el-select>
</template>
</el-table-column>
<el-table-column width="60px" align="center" label="操作">
<template #default="scope">
<el-icon @click="deleteChildren(father, scope.$index)" class="deleteIcon"
><Delete
/></el-icon>
</template>
</el-table-column>
</template>
<template v-if="father.key == 'primaryResidence'"> <!-- 日期选择器 -->
<el-table-column label="自住用途之房地产地址" prop="address" align="center"> <el-date-picker
<template #default="scope"> v-else-if="column.type === 'datePicker'"
<el-input v-model="scope.row[column.prop]"
size="default" type="date"
placeholder="请输入" format="YYYY-MM-DD"
v-model="scope.row.address" value-format="YYYY-MM-DD"
:placeholder="column.placeholder"
:disabled="editStatus" :disabled="editStatus"
style="width: 100%"
/> />
</template>
</el-table-column> <!-- 数字输入框 -->
<el-table-column label="自住用途之房地产市值" prop="marketValue" align="center">
<template #default="scope">
<el-input <el-input
v-model="scope.row.marketValue" v-else-if="column.type === 'inputNumber'"
size="default" v-model.number="scope.row[column.prop]"
placeholder="请输入" :placeholder="column.placeholder"
:disabled="editStatus" :disabled="editStatus"
/> type="number"
</template>
</el-table-column>
<el-table-column label="币种" prop="currency" align="center">
<template #default="scope">
<el-select
v-model="scope.row.currency"
placeholder="请选择"
:disabled="editStatus"
clearable
> >
<el-option <template v-if="column.unit" #append>
v-for="item in scope.row.options" <span>{{ column.unit }}</span>
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column width="60px" align="center" label="操作">
<template #default="scope">
<el-icon @click="deleteChildren(father, scope.$index)" class="deleteIcon"
><Delete
/></el-icon>
</template> </template>
</el-table-column> </el-input>
</template>
<template v-if="father.key == 'taxList'"> <!-- 普通输入框(默认) -->
<el-table-column label="税务国家" prop="taxCountry" align="center">
<template #default="scope">
<el-input
size="default"
placeholder="请输入"
v-model="scope.row.taxCountry"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column label="税务编号" prop="taxNumber" align="center">
<template #default="scope">
<el-input <el-input
v-model="scope.row.taxNumber" v-else
size="default" v-model="scope.row[column.prop]"
placeholder="请输入" :placeholder="column.placeholder"
:disabled="editStatus" :disabled="editStatus"
/> />
</template> </template>
</el-table-column> </el-table-column>
<!-- 操作列(固定) -->
<el-table-column width="60px" align="center" label="操作"> <el-table-column width="60px" align="center" label="操作">
<template #default="scope"> <template #default="scope">
<el-icon @click="deleteChildren(father, scope.$index)" class="deleteIcon" <el-icon
class="deleteIcon"
@click="deleteChildren(father, scope.$index)"
><Delete ><Delete
/></el-icon> /></el-icon>
</template> </template>
</el-table-column> </el-table-column>
</template>
</el-table> </el-table>
<el-col
:span="24"
v-if="father.addChildren"
style="display: flex; justify-content: center"
>
<el-button
:disabled="editStatus"
style="margin-top: 10px"
type="primary"
icon="Plus"
@click="addChildren(father)"
>{{ father.addChildrenTxt }}</el-button
>
</el-col>
</el-row> </el-row>
</template>
</CardOne>
</div> </div>
</el-row>
<el-row> <el-row>
<el-col> <el-col>
<div class="tabButton"> <div class="tabButton">
...@@ -410,31 +281,37 @@ ...@@ -410,31 +281,37 @@
</el-col> </el-col>
</el-row> </el-row>
</el-form> </el-form>
</template>
</CommonForm>
</div> </div>
<div v-else class="domEmpty" v-loading="loading"></div> <!-- <div v-else class="domEmpty" v-loading="loading"></div> -->
</div> </div>
</template> </template>
<script setup name="fanForm"> <script setup name="fanForm">
import CommonForm from '@/views/components/commonForm'
import CardOne from '@/components/formCard/cardOne'
import { processUserName } from '@/utils/common' import { processUserName } from '@/utils/common'
import useDictStore from '@/store/modules/dict' import useDictStore from '@/store/modules/dict'
import fanFormDomData from '@/formJson/fnaForm' import fanFormDomData from '@/formJson/fnaForm'
import { watch, nextTick } from 'vue' import { watch, nextTick } from 'vue'
import { addfanForm, getfanFormDetail, editFanForm, getCustomerList } from '@/api/sign/fna' import { addfanForm, getfanFormDetail, editFanForm, getCustomerList } from '@/api/sign/fna'
import { listTenantUser } from '@/api/common' import { getUserSaleExpandList, getAllTeam, getInsuranceCompany } from '@/api/common'
import useUserStore from '@/store/modules/user' import useUserStore from '@/store/modules/user'
const userStore = useUserStore() const userStore = useUserStore()
const dictStore = useDictStore() //获取字典数据 const dictStore = useDictStore() //获取字典数据
const props = defineProps({ const props = defineProps({
customerInfo: { type: Object, default: () => {} }, //客户详情 customerInfo: { type: Object, default: () => {} }, //客户详情
activeName: { type: String, default: '' }, //tab名称 activeName: { type: String, default: '' }, //tab名称
fearthStatus: { type: String, default: '' }, //父组件状态,新增、修改
fnaFormBizId: { type: String, default: '' }, //提交状态,新增、修改 fnaFormBizId: { type: String, default: '' }, //提交状态,新增、修改
customerBizId: { type: String, default: '' }, //提交状态,新增、修改 customerBizId: { type: String, default: '' }, //提交状态,新增、修改
dictTypeLists: { type: Array, default: () => [] } //多个字典值数据 dictTypeLists: { type: Array, default: () => [] }, //多个字典值数据
anchorContainer: { type: String, default: '' }, //锚点滚动容器
tabIndex: { type: [String, Number], default: '' } //tab索引
}) })
const emit = defineEmits(['handleSuccess']) const emit = defineEmits(['handleSuccess'])
const { proxy } = getCurrentInstance() const { proxy } = getCurrentInstance()
// const { sys_no_yes } = proxy.useDict('sys_no_yes') const fanContainerRef = ref(null)
const loading = ref(false) const loading = ref(false)
const fanFormRef = ref(null) const fanFormRef = ref(null)
const errorFields = ref([]) // 存储校验失败的字段信息 const errorFields = ref([]) // 存储校验失败的字段信息
...@@ -465,61 +342,70 @@ const { ...@@ -465,61 +342,70 @@ const {
tempFanFormValue, tempFanFormValue,
tempFanFormData tempFanFormData
} = toRefs(data) } = toRefs(data)
const changeCheck = (father, child) => { const handleRemoteSelectChange = (row, column) => {
if (child.key == 'liquidAssetType') { console.log(row, column)
resetShow('otherLiquidAsset', form.value[father.key][child.key].includes('G')) // 通过保险公司查保险种类 row中收集了insurer的值
} if (column.prop == 'insurer') {
}
const changeOpenStatus = father => {
const processedData = JSON.parse(JSON.stringify(processedFanFormData.value))
for (const section of processedData) {
if (
father.key == 'familyMembers' &&
section.key == father.key &&
section.moudleType == 'family'
) {
section.isOpen = !father.isOpen
}
if (section.moudleType == 'finance' && father.key !== 'familyMembers') {
section.isOpen = !father.isOpen
}
} }
processedFanFormData.value = processedData
console.log('processedFanFormData.value', processedFanFormData.value)
}
const disabledDate = time => {
return time.getTime() > Date.now()
} }
// 搜索方法 // 搜索方法
const searchSelectList = async (query, fieldKey) => { const searchSelectList = async (query, fieldKey) => {
// 设置该字段的加载状态 // 设置该字段的加载状态
searchLoadingStates.value[fieldKey] = true searchLoadingStates.value[fieldKey] = true
let queryString = query.trim()
try { try {
// 根据不同的字段key调用不同的API // 根据不同的字段key调用不同的API
if (fieldKey === 'accountName') { if (fieldKey === 'brokerName') {
const params = { const params5 = {
tenantBizId: userStore.projectInfo.tenantBizId,
realName: query.trim(),
pageNo: 1, pageNo: 1,
pageSize: 10 pageSize: 10,
queryContent: queryString
} }
const response5 = await getUserSaleExpandList(params5)
const response = await listTenantUser(params) if (response5.code == 200) {
if (response.code == 200) { response5.data.records = response5.data.records.map(item => {
let result = processUserName(response.data.records) return {
result = result.map(item => { ...item,
label: item.realName,
value: item.userSaleBizId
}
})
searchOptions.value[fieldKey] = response5.data.records
}
} else if (fieldKey === 'brokerTeam') {
const params8 = {
pageNo: 1,
pageSize: 10,
teamName: queryString
}
const response8 = await getAllTeam(params8)
if (response8.code == 200) {
response8.data.records = response8.data.records.map(item => {
return { return {
value: item.userBizId, ...item,
label: item.showName label: item.teamName,
value: item.teamBizId
} }
}) })
searchOptions.value[fieldKey] = result searchOptions.value[fieldKey] = response8.data.records
}
} else if (fieldKey === 'insurer') {
const params9 = {
pageNo: 1,
pageSize: 10,
queryContent: queryString
} }
const response9 = await getInsuranceCompany(params9)
if (response9.code == 200) {
response9.data.records = response9.data.records.map(item => {
return {
...item,
label: item.fullName,
value: item.insuranceCompanyBizId
}
})
searchOptions.value[fieldKey] = response9.data.records
} }
// 可以添加其他字段的处理,可以放其他的字段得请求,目前只有accountName,以后有了其他的在填充
else if (fieldKey === 'otherField') {
console.log('otherField')
} }
} catch (error) { } catch (error) {
console.error(`${fieldKey} 搜索失败`, error) console.error(`${fieldKey} 搜索失败`, error)
...@@ -529,6 +415,10 @@ const searchSelectList = async (query, fieldKey) => { ...@@ -529,6 +415,10 @@ const searchSelectList = async (query, fieldKey) => {
} }
} }
const disabledDate = time => {
return time.getTime() > Date.now()
}
// 获取字典数据 // 获取字典数据
const fetchDictData = dictType => { const fetchDictData = dictType => {
let options = [] let options = []
...@@ -569,36 +459,13 @@ const processFormData = async () => { ...@@ -569,36 +459,13 @@ const processFormData = async () => {
form.value[section.key] = {} form.value[section.key] = {}
} }
if (section.data) { if (section.data) {
for (const formKey in form.value) {
if (section.key == formKey) {
if (section.dataLength) {
for (let i = 1; i < section.dataLength; i++) {
section.data.push(JSON.parse(JSON.stringify(section.data[0])))
form.value[formKey].push(JSON.parse(JSON.stringify(section.data[0])))
}
}
for (const field of section.data) { for (const field of section.data) {
// 为下拉搜索框加options // 为下拉搜索框加options
if (field.domType == 'SearchSelect') { // if (field.domType == 'SearchSelect') {
if (field.key == 'accountName') { // if (field.key == 'accountName') {
searchOptions.value[field.key] = dictStore.tenantUserList // searchOptions.value[field.key] = dictStore.tenantUserList
} // }
} // }
if (section.key == formKey && field.children) {
for (const child of field.children) {
if (child.dictType) {
child.options = fetchDictData(child.dictType)
if (child.dictType == 'sys_no_yes') {
noYesList.value = child.options
}
}
if (props.fnaFormBizId) {
child.disabled = true
} else {
child.disabled = false
}
}
}
if (field.dictType) { if (field.dictType) {
// 获取字典数据 // 获取字典数据
field.options = fetchDictData(field.dictType) field.options = fetchDictData(field.dictType)
...@@ -606,35 +473,23 @@ const processFormData = async () => { ...@@ -606,35 +473,23 @@ const processFormData = async () => {
noYesList.value = field.options noYesList.value = field.options
} }
} }
//
/* if (field.required) {
1.没有嵌套子级的也就是没有children的数据加rules,根据data中的required字段判断是否必填 rules.value[field.key] = [
2.有嵌套子级的也就是有children的数据,根据children中的required字段判断是否必填,现在没这个需求,所以先注释
*/
if (field.required && section.child == 'no') {
rules.value[section.key][field.key] = [
{ required: true, message: `${field.label}不能为空`, trigger: 'blur' } { required: true, message: `${field.label}不能为空`, trigger: 'blur' }
] ]
} }
if (props.fnaFormBizId) { if (props.fnaFormBizId) {
field.disabled = true field.disabled = true
} else { } else {
if (field.key == 'customerName' && section.key == 'personalData') {
form.value['personalData'][field.key] = props.customerInfo.firstNamePinyin
}
field.disabled = false field.disabled = false
} }
} }
if (section.child == 'yes') {
form.value[formKey] = section.data //便于表单收集值
}
}
}
} }
} }
if (props.fnaFormBizId) { if (props.fnaFormBizId) {
getFanformInfo(props.fnaFormBizId, processedData) // getFanformInfo(props.fnaFormBizId, processedData)
editStatus.value = true // editStatus.value = true
} else { } else {
// tab切走在切回来时,表单会重置,所以这里需要把表单的值赋回去 // tab切走在切回来时,表单会重置,所以这里需要把表单的值赋回去
if (Object.keys(tempFanFormValue.value).length > 0) { if (Object.keys(tempFanFormValue.value).length > 0) {
...@@ -649,67 +504,55 @@ const processFormData = async () => { ...@@ -649,67 +504,55 @@ const processFormData = async () => {
} }
editStatus.value = false editStatus.value = false
loading.value = false loading.value = false
console.log('processedFanFormData.value', processedFanFormData.value)
} }
processedFanFormData.value = oldFanFormData.value = processedData
} }
// 添加表单子级dom // 添加表单子级dom
const addChildren = father => { const addChildren = father => {
const processedData = JSON.parse(JSON.stringify(processedFanFormData.value)) const processedData = JSON.parse(JSON.stringify(processedFanFormData.value))
let obj = { let obj1 = {
type: '4', brokerName: '',
childTitle: '儿女', brokerGender: '',
id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识 brokerNumber: '',
delete: true, //是否显示删除按钮 brokerTeam: '',
age: '', brokerRatio: '',
needProvide: '', remark: ''
options: noYesList.value
} }
let obj2 = { let obj2 = {
id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识 id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识
span: 24, //栅格布局份数 policyholderRel: '',
dependantAge: ''
}
let obj3 = {
id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识
insurer: '', insurer: '',
insuranceType: '', insuranceType: '',
sumInsured: '', sumInsured: '',
policyIssueDate: '',
currency: '', currency: '',
options: fetchDictData('bx_currency_type') policyIssueDate: ''
} }
let obj3 = { let obj4 = {
id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识 propertyType: '',
span: 24, //栅格布局份数
address: '', address: '',
currency: '',
marketValue: '', marketValue: '',
options: fetchDictData('bx_currency_type') currency: ''
}
let obj4 = {
id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识
span: 24, //栅格布局份数
taxCountry: '',
taxNumber: ''
} }
for (const section of processedData) { for (const section of processedData) {
if (father.key == 'familyMembers' && section.key == father.key) { if (father.key == 'brokerList' && section.key == father.key) {
section.data.push(obj) section.data.push(obj1)
} }
if (father.key == 'existingSecurityOwner' && section.key == father.key) { if (father.key == 'dependantList' && section.key == father.key) {
section.data.push(obj2) section.data.push(obj2)
} }
if (father.key == 'existingSecurityInsured' && section.key == father.key) { if (father.key == 'existingSecurityOwner' && section.key == father.key) {
section.data.push(obj2)
}
if (father.key == 'investment' && section.key == father.key) {
section.data.push(obj3) section.data.push(obj3)
} }
if (father.key == 'primaryResidence' && section.key == father.key) { if (father.key == 'primaryResidence' && section.key == father.key) {
section.data.push(obj3)
}
if (father.key == 'taxList' && section.key == father.key) {
section.data.push(obj4) section.data.push(obj4)
} }
} }
//更新form表单对应的数据,以便收集填写的值
form.value[father.key].push(obj)
processedFanFormData.value = processedData processedFanFormData.value = processedData
} }
const deleteChildren = (father, childIndex) => { const deleteChildren = (father, childIndex) => {
...@@ -1116,6 +959,15 @@ function getFanformInfo(fnaFormBizId, formData) { ...@@ -1116,6 +959,15 @@ function getFanformInfo(fnaFormBizId, formData) {
} }
}) })
} }
const anchorList = computed(() => {
let data = []
for (const section of processedFanFormData.value) {
if (section.showMoudle) {
data.push({ title: section.anchorKey, name: section.fatherTitle })
}
}
return data
})
watch(fanFormRef, newVal => { watch(fanFormRef, newVal => {
if (newVal) { if (newVal) {
for (const key in rules.value) { for (const key in rules.value) {
...@@ -1128,20 +980,30 @@ watch(fanFormRef, newVal => { ...@@ -1128,20 +980,30 @@ watch(fanFormRef, newVal => {
watch( watch(
() => props.activeName, () => props.activeName,
newVal => { newVal => {
fanContainerRef.value = null
tempFanFormValue.value = JSON.parse(JSON.stringify(form.value)) tempFanFormValue.value = JSON.parse(JSON.stringify(form.value))
tempFanFormData.value = JSON.parse(JSON.stringify(processedFanFormData.value)) tempFanFormData.value = JSON.parse(JSON.stringify(processedFanFormData.value))
if (newVal === 'fnaform') { if (newVal === 'fnaform') {
openList.value = false openList.value = false
setTimeout(() => {
processFormData() processFormData()
}, 500)
} }
} }
) )
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.dependNum {
font-size: 14px;
font-weight: none;
margin-left: 10px;
}
.customCheckBox {
display: flex;
flex-direction: column;
width: 100%;
}
.domEmpty { .domEmpty {
width: 100%; width: 100%;
height: 100%; height: 100%;
display: flex; display: flex;
align-items: center; align-items: center;
...@@ -1267,6 +1129,12 @@ watch( ...@@ -1267,6 +1129,12 @@ watch(
.formFna :deep(.el-checkbox) { .formFna :deep(.el-checkbox) {
margin-right: 10px; margin-right: 10px;
} }
.selfStyle :deep(.el-form-item--label-top .el-form-item__label) {
text-align: none !important;
display: flex;
align-items: center;
justify-content: flex-start;
}
/* @media only screen and (min-width: 768px) { /* @media only screen and (min-width: 768px) {
.formInput { .formInput {
......
...@@ -20,9 +20,20 @@ ...@@ -20,9 +20,20 @@
</div> </div>
</div> </div>
</div> </div>
<div class="tabsBox" ref="tabPaneRef"> <div class="tabsBox">
<el-tabs v-model="activeName" class="demo-tabs" :before-leave="beforeTabLeave"> <el-tabs
<el-tab-pane v-for="tab in tabsList" :key="tab.name" :label="tab.label" :name="tab.name"> v-model="activeName"
class="demo-tabs"
:before-leave="beforeTabLeave"
ref="tabPaneRef"
>
<el-tab-pane
v-for="(tab, tIndex) in tabsList"
:key="tab.name"
:label="tab.label"
:name="tab.name"
>
<!-- 注意tabPaneBox这个类名与子组件的锚点定位相关,不能轻易改动 -->
<div :class="{ tabPaneBox: activeName !== 'appointment' }"> <div :class="{ tabPaneBox: activeName !== 'appointment' }">
<div v-if="tab.name === 'overview'" class="overviewBox"> <div v-if="tab.name === 'overview'" class="overviewBox">
<div <div
...@@ -75,20 +86,22 @@ ...@@ -75,20 +86,22 @@
<Customer <Customer
v-if="tab.name === 'customer'" v-if="tab.name === 'customer'"
:activeName="activeName" :activeName="activeName"
:fearthStatus="route.query.type"
:customerBizId="processInfo.customerBizId" :customerBizId="processInfo.customerBizId"
@handleSuccess="handleSuccess" @handleSuccess="handleSuccess"
:tabPaneRef="tabPaneRef" :tabIndex="tabsList.findIndex(t => t.name === 'customer')"
anchorContainer=".tabPaneBox"
tabSource="customer"
/> />
<div v-if="tab.name === 'fnaform'"> <div v-if="tab.name === 'fnaform'">
<FanForm <FanForm
:activeName="activeName" :activeName="activeName"
:fearthStatus="route.query.type"
:fnaFormBizId="processInfo.fnaFormBizId" :fnaFormBizId="processInfo.fnaFormBizId"
:customerBizId="processInfo.customerBizId" :customerBizId="processInfo.customerBizId"
:dictTypeLists="dictTypeLists" :dictTypeLists="dictTypeLists"
:customerInfo="customerInfo" :customerInfo="customerInfo"
@handleSuccess="handleSuccess" @handleSuccess="handleSuccess"
:tabIndex="tabsList.findIndex(t => t.name === 'fnaform')"
anchorContainer=".tabPaneBox"
/> />
</div> </div>
<div v-if="tab.name === 'appointment'"> <div v-if="tab.name === 'appointment'">
...@@ -115,7 +128,17 @@ import AppointmentEdit from '@/views/sign/appointment/appointmentEdit' ...@@ -115,7 +128,17 @@ import AppointmentEdit from '@/views/sign/appointment/appointmentEdit'
import useUserStore from '@/store/modules/user' import useUserStore from '@/store/modules/user'
import useDictStore from '@/store/modules/dict' import useDictStore from '@/store/modules/dict'
import { addFna, getProcessDetail, updateProcess, getCustomerDetail } from '@/api/sign/fna' import { addFna, getProcessDetail, updateProcess, getCustomerDetail } from '@/api/sign/fna'
import { listTenantUser, getInsuranceProductList, getAdditionalProductList } from '@/api/common' import {
listTenantUser,
getInsuranceProductList,
getAdditionalProductList,
getBankList,
getUserSaleExpandList,
secondAdditonalList,
getAllSignList,
getAllTeam,
getInsuranceCompany
} from '@/api/common'
import Customer from './components/customer' import Customer from './components/customer'
import FanForm from './components/fanForm' import FanForm from './components/fanForm'
...@@ -206,17 +229,17 @@ const getDictsData = async () => { ...@@ -206,17 +229,17 @@ const getDictsData = async () => {
pageSize: 10 pageSize: 10
} }
const response2 = await getInsuranceProductList(params2) // const response2 = await getInsuranceProductList(params2)
if (response2.code == 200) { // if (response2.code == 200) {
response2.data.records = response2.data.records.map(item => { // response2.data.records = response2.data.records.map(item => {
return { // return {
...item, // ...item,
label: item.productName, // label: item.productName,
value: item.productBizId // value: item.productBizId
} // }
}) // })
dictStore.setInsureProductList(response2.data.records) // dictStore.setInsureProductList(response2.data.records)
} // }
const params3 = { const params3 = {
pageNo: 1, pageNo: 1,
pageSize: 10 pageSize: 10
...@@ -233,6 +256,100 @@ const getDictsData = async () => { ...@@ -233,6 +256,100 @@ const getDictsData = async () => {
}) })
dictStore.setAdditionalProductList(response3.data.records) dictStore.setAdditionalProductList(response3.data.records)
} }
const params4 = {
pageNo: 1,
pageSize: 99999
}
const response4 = await getBankList(params4)
if (response4.code == 200) {
response4.data.records = response4.data.records.map(item => {
return {
...item,
label: item.bankName,
value: item.bankBizId
}
})
dictStore.setBankList(response4.data.records)
}
const params5 = {
pageNo: 1,
pageSize: 99999
}
const response5 = await getUserSaleExpandList(params5)
if (response5.code == 200) {
response5.data.records = response5.data.records.map(item => {
return {
...item,
label: item.realName,
value: item.userSaleBizId
}
})
dictStore.setUserSaleExpandList(response5.data.records)
}
const params6 = {
pageNo: 1,
pageSize: 99999,
projectBizId: userStore.projectInfo.projectBizId,
tenantBizId: userStore.projectInfo.tenantBizId,
fieldBizId: 'field_olk1qZe81qHHKXbw',
fieldValueBizId: 'field_value_yXzTigvgUdRMFpoR'
}
const response6 = await secondAdditonalList(params6)
if (response6.code == 200) {
response6.data.records = response6.data.records.map(item => {
return {
...item,
label: item.title,
value: item.productLaunchBizId
}
})
dictStore.setProductAdditionalList(response6.data.records)
}
const params7 = {
pageNo: 1,
pageSize: 99999
}
const response7 = await getAllSignList(params7)
if (response7.code == 200) {
response7.data.records = response7.data.records.map(item => {
return {
...item,
label: item.realName,
value: item.userSignBizId
}
})
dictStore.setSignPeopleList(response7.data.records)
}
const params8 = {
pageNo: 1,
pageSize: 99999
}
const response8 = await getAllTeam(params8)
if (response8.code == 200) {
response8.data.records = response8.data.records.map(item => {
return {
...item,
label: item.teamName,
value: item.teamBizId
}
})
dictStore.setAllTeaList(response8.data.records)
}
const params9 = {
pageNo: 1,
pageSize: 99999
}
const response9 = await getInsuranceCompany(params9)
if (response9.code == 200) {
response9.data.records = response9.data.records.map(item => {
return {
...item,
label: item.fullName,
value: item.insuranceCompanyBizId
}
})
dictStore.setAllInsuranceCompanyList(response9.data.records)
}
// 请求每个流程中所涉及到的字典值数据 // 请求每个流程中所涉及到的字典值数据
proxy.useDictLists([ proxy.useDictLists([
'csf_employment', 'csf_employment',
...@@ -260,7 +377,8 @@ const getDictsData = async () => { ...@@ -260,7 +377,8 @@ const getDictsData = async () => {
'wj_question_first_category', 'wj_question_first_category',
'wj_question_second_category', 'wj_question_second_category',
'csf_ap_policy_transfer', 'csf_ap_policy_transfer',
'md_bank' 'md_bank',
'csf_property_type'
]) ])
} }
...@@ -276,15 +394,7 @@ const processUpdate = (data, status) => { ...@@ -276,15 +394,7 @@ const processUpdate = (data, status) => {
} }
}) })
} }
// 新建流程
// const getAddInfo = () => {
// addFna({ remark: '' }).then(res => {
// if (res.code == 200) {
// // 获取流程详情
// getProcessInfo(res.data.fnaBizId)
// }
// })
// }
// 获取流程详情 // 获取流程详情
function getProcessInfo(fnaBizId, changeTab) { function getProcessInfo(fnaBizId, changeTab) {
getProcessDetail(fnaBizId).then(res => { getProcessDetail(fnaBizId).then(res => {
...@@ -311,7 +421,7 @@ function getProcessInfo(fnaBizId, changeTab) { ...@@ -311,7 +421,7 @@ function getProcessInfo(fnaBizId, changeTab) {
// Tab切换前的验证 // Tab切换前的验证
const beforeTabLeave = (activeTabName, oldTabName) => { const beforeTabLeave = (activeTabName, oldTabName) => {
if (processInfo.value.customerBizId) { if (processInfo.value.customerBizId) {
getCustomerInfo(processInfo.value.customerBizId) // getCustomerInfo(processInfo.value.customerBizId)
} }
// 如果切换到总览,始终允许 // 如果切换到总览,始终允许
if (activeTabName === 'overview' || activeTabName === 'customer') { if (activeTabName === 'overview' || activeTabName === 'customer') {
...@@ -515,13 +625,9 @@ getDictsData() ...@@ -515,13 +625,9 @@ getDictsData()
} }
} }
} }
/* .tabPaneBox {
height: calc(100vh - 275px);
overflow-y: auto;
padding-right: 10px;
} */
.tabPaneBox { .tabPaneBox {
height: calc(100vh - 275px); height: calc(100vh - 280px);
overflow-y: auto; overflow-y: auto;
padding-right: 10px; padding-right: 10px;
position: relative; position: relative;
......
...@@ -72,6 +72,7 @@ ...@@ -72,6 +72,7 @@
:data="tenantList" :data="tenantList"
@selection-change="tableSelect" @selection-change="tableSelect"
@sort-change="sortChange" @sort-change="sortChange"
border
> >
<el-table-column type="index" width="50" label="序号" /> <el-table-column type="index" width="50" label="序号" />
<el-table-column label="客户姓名" align="center" prop="customerName" width="100" /> <el-table-column label="客户姓名" align="center" prop="customerName" width="100" />
...@@ -130,16 +131,6 @@ ...@@ -130,16 +131,6 @@
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<!-- <div style="width: 100%; display: flex; justify-content: flex-end; margin-bottom: 30px">
<pagination
v-show="total >= 0"
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
style="text-align: right"
/>
</div> -->
</template> </template>
</CommonPage> </CommonPage>
<!-- 下一步到预约 --> <!-- 下一步到预约 -->
......
...@@ -44,12 +44,19 @@ ...@@ -44,12 +44,19 @@
<el-row v-if="isEmbed"> <el-row v-if="isEmbed">
<el-col> <el-col>
<div class="topButtonBox"> <div class="topButtonBox">
<el-button <!-- <el-button
v-if="idsObj.appointmentBizId && pageSource !== 'policyList'" v-if="idsObj.appointmentBizId && pageSource !== 'policyList'"
type="primary" type="primary"
icon="Plus" icon="Plus"
@click="handleAddExecl" @click="handleAddExecl"
>上传EXECL</el-button >上传EXECL</el-button
> -->
<el-button
v-if="pageSource !== 'policyList'"
type="primary"
:icon="Edit"
@click="handleEdit"
>编辑</el-button
> >
<el-button <el-button
v-if="pageSource !== 'policyList'" v-if="pageSource !== 'policyList'"
...@@ -86,6 +93,10 @@ ...@@ -86,6 +93,10 @@
:appointmentStatus="appointmentSummeryInfo.status" :appointmentStatus="appointmentSummeryInfo.status"
@handleSuccessEdit="getAppointmentInfo(idsObj.appointmentBizId)" @handleSuccessEdit="getAppointmentInfo(idsObj.appointmentBizId)"
ref="appointmentInfoRef" ref="appointmentInfoRef"
:tabIndex="tabsList.findIndex(t => t.name === 'appointmentInfo')"
anchorContainer=".appointmentTabPaneBox"
:fatherTabName="tabName"
:editStatus="editStatus"
/> />
</div> </div>
<div v-if="tab.name === 'productPlan'"> <div v-if="tab.name === 'productPlan'">
...@@ -100,10 +111,27 @@ ...@@ -100,10 +111,27 @@
@policyEditSuccess="getPolicyDetail" @policyEditSuccess="getPolicyDetail"
:pageSource="pageSource" :pageSource="pageSource"
:showSubmitBtn="showSubmitBtn" :showSubmitBtn="showSubmitBtn"
:tabIndex="tabsList.findIndex(t => t.name === 'productPlan')"
anchorContainer=".appointmentTabPaneBox"
:fatherTabName="tabName"
:editStatus="editStatus"
/> />
</div> </div>
<!-- 投保人 -->
<div v-if="tab.name === 'policyholder'"> <div v-if="tab.name === 'policyholder'">
<PolicyHolderInfo <!-- :customerBizId="processInfo.customerBizId" @handleSuccess="handleSuccess"-->
<Customer
:activeName="activeName"
:fatherTabName="tabName"
:fatherStatus="editStatus"
:affixOffset="360"
:tabIndex="tabsList.findIndex(t => t.name === 'policyholder')"
anchorContainer=".appointmentTabPaneBox"
tabSource="policyholder"
ref="policyHolderInfoRef"
:fatherEditStatus="editStatus"
/>
<!-- <PolicyHolderInfo
:activeName="activeName" :activeName="activeName"
:formStatus="formStatus" :formStatus="formStatus"
:customerInfo="customerInfo" :customerInfo="customerInfo"
...@@ -115,10 +143,22 @@ ...@@ -115,10 +143,22 @@
:pageSource="pageSource" :pageSource="pageSource"
:showSubmitBtn="showSubmitBtn" :showSubmitBtn="showSubmitBtn"
@policyEditSuccess="getPolicyDetail" @policyEditSuccess="getPolicyDetail"
/> /> -->
</div> </div>
<div v-if="tab.name === 'insurantInfo'"> <div v-if="tab.name === 'insurantInfo'">
<InsuredInfo <!-- :customerBizId="processInfo.customerBizId" @handleSuccess="handleSuccess"-->
<Customer
:activeName="activeName"
:fatherTabName="tabName"
:fatherStatus="editStatus"
:affixOffset="360"
:tabIndex="tabsList.findIndex(t => t.name === 'insurantInfo')"
anchorContainer=".appointmentTabPaneBox"
tabSource="insurantInfo"
ref="insuredInfoRef"
:fatherEditStatus="editStatus"
/>
<!-- <InsuredInfo
:activeName="activeName" :activeName="activeName"
:formStatus="formStatus" :formStatus="formStatus"
:customerInfo="customerInfo" :customerInfo="customerInfo"
...@@ -131,7 +171,7 @@ ...@@ -131,7 +171,7 @@
:pageSource="pageSource" :pageSource="pageSource"
:showSubmitBtn="showSubmitBtn" :showSubmitBtn="showSubmitBtn"
@policyEditSuccess="getPolicyDetail" @policyEditSuccess="getPolicyDetail"
/> /> -->
</div> </div>
<div v-if="tab.name === 'secondHolder'"> <div v-if="tab.name === 'secondHolder'">
<SecondHolderInfo <SecondHolderInfo
...@@ -302,6 +342,7 @@ import PolicyTransferInfo from './components/policyTransferInfo.vue' ...@@ -302,6 +342,7 @@ import PolicyTransferInfo from './components/policyTransferInfo.vue'
import FileUpload from './components/fileUpload.vue' import FileUpload from './components/fileUpload.vue'
import HealthInfo from './components/healthInfo.vue' import HealthInfo from './components/healthInfo.vue'
import PolicyInfo from '@/views/sign/underwritingMain/components/policyInfo' //新单跟进里的保单信息 import PolicyInfo from '@/views/sign/underwritingMain/components/policyInfo' //新单跟进里的保单信息
import Customer from '@/views/sign/FnaList/components/customer'
import PolicyFileUpload from '@/views/sign/underwritingMain/components/fileUpload.vue' //新单跟进里的保单附件 import PolicyFileUpload from '@/views/sign/underwritingMain/components/fileUpload.vue' //新单跟进里的保单附件
import PolicyBrokerInfo from '@/views/sign/underwritingMain/components/brokerInfo.vue' //新单跟进里的保单附件 import PolicyBrokerInfo from '@/views/sign/underwritingMain/components/brokerInfo.vue' //新单跟进里的保单附件
import PolicyMailing from '@/views/sign/underwritingMain/components/policyMailing.vue' //新单跟进里的保单附件 import PolicyMailing from '@/views/sign/underwritingMain/components/policyMailing.vue' //新单跟进里的保单附件
...@@ -319,8 +360,16 @@ import { ...@@ -319,8 +360,16 @@ import {
uploadExcel uploadExcel
} from '@/api/sign/appointment' } from '@/api/sign/appointment'
import { getPolicyfollow, getPolicyInfo, signName } from '@/api/sign/underwritingMain' import { getPolicyfollow, getPolicyInfo, signName } from '@/api/sign/underwritingMain'
import { listTenantUser, getInsuranceProductList, getAdditionalProductList } from '@/api/common' import {
import { Check } from '@element-plus/icons-vue' listTenantUser,
getInsuranceProductList,
getAdditionalProductList,
getBankList,
getUserSaleExpandList,
secondAdditonalList,
getAllSignList
} from '@/api/common'
import { Check, Edit } from '@element-plus/icons-vue'
import { ref, nextTick, onUnmounted } from 'vue' import { ref, nextTick, onUnmounted } from 'vue'
const emit = defineEmits(['handleSuccess']) const emit = defineEmits(['handleSuccess'])
...@@ -363,13 +412,14 @@ const processInfo = ref({ ...@@ -363,13 +412,14 @@ const processInfo = ref({
createTime: proxy.parseTime(new Date()), createTime: proxy.parseTime(new Date()),
customerName: userStore.name customerName: userStore.name
}) })
const editStatus = ref(false) //编辑状态
const execlDialog = ref(false) const execlDialog = ref(false)
const isEmbed = ref(false) //是否作为组件插入 const isEmbed = ref(false) //是否作为组件插入
const policyNo = ref('') //新单跟进保单号 const policyNo = ref('') //新单跟进保单号
const currentPolicyholderInfo = ref({}) //存储下投保人信息,受保人模块要用到 const currentPolicyholderInfo = ref({}) //存储下投保人信息,受保人模块要用到
const tabsList = ref([ const tabsList = ref([
{ {
label: '约信息', label: '约信息',
name: 'appointmentInfo', name: 'appointmentInfo',
id: 1, id: 1,
key: 'appointmentBizId' key: 'appointmentBizId'
...@@ -559,7 +609,7 @@ function getAppointmentInfo(appointmentBizId, changeTab) { ...@@ -559,7 +609,7 @@ function getAppointmentInfo(appointmentBizId, changeTab) {
processInfo.value.status = item.label processInfo.value.status = item.label
} }
}) })
getCustomerInfo(res.data.apiAppointmentInfoDto.customerBizId) // getCustomerInfo(res.data.apiAppointmentInfoDto.customerBizId)
if (!appointmentSummeryInfo.value.apiAppointmentInfoDto.appointmentBizId) { if (!appointmentSummeryInfo.value.apiAppointmentInfoDto.appointmentBizId) {
showStorage.value = true showStorage.value = true
} }
...@@ -653,7 +703,73 @@ const getDictsData = async () => { ...@@ -653,7 +703,73 @@ const getDictsData = async () => {
}) })
dictStore.setAdditionalProductList(response3.data.records) dictStore.setAdditionalProductList(response3.data.records)
} }
const params4 = {
pageNo: 1,
pageSize: 99999
}
const response4 = await getBankList(params4)
if (response4.code == 200) {
response4.data.records = response4.data.records.map(item => {
return {
...item,
label: item.bankName,
value: item.bankBizId
}
})
dictStore.setBankList(response4.data.records)
}
const params5 = {
pageNo: 1,
pageSize: 99999
}
const response5 = await getUserSaleExpandList(params5)
if (response5.code == 200) {
console.log('response5', response5)
response5.data.records = response5.data.records.map(item => {
return {
...item,
label: item.realName,
value: item.userSaleBizId
}
})
dictStore.setUserSaleExpandList(response5.data.records)
}
const params6 = {
pageNo: 1,
pageSize: 99999,
projectBizId: userStore.projectInfo.projectBizId,
tenantBizId: userStore.projectInfo.tenantBizId,
fieldBizId: 'field_olk1qZe81qHHKXbw',
fieldValueBizId: 'field_value_yXzTigvgUdRMFpoR'
}
const response6 = await secondAdditonalList(params6)
if (response6.code == 200) {
response6.data.records = response6.data.records.map(item => {
return {
...item,
label: item.title,
value: item.productLaunchBizId
}
})
dictStore.setProductAdditionalList(response6.data.records)
}
const params7 = {
pageNo: 1,
pageSize: 99999
}
const response7 = await getAllSignList(params7)
if (response7.code == 200) {
response7.data.records = response7.data.records.map(item => {
return {
...item,
label: item.realName,
value: item.userSignBizId
}
})
dictStore.setSignPeopleList(response7.data.records)
}
proxy.useDictLists([ proxy.useDictLists([
'csf_employment', 'csf_employment',
'sys_no_yes', 'sys_no_yes',
...@@ -686,54 +802,6 @@ const getDictsData = async () => { ...@@ -686,54 +802,6 @@ const getDictsData = async () => {
} }
// Tab切换前的验证 // Tab切换前的验证
const beforeTabLeave = (activeTabName, oldTabName) => { const beforeTabLeave = (activeTabName, oldTabName) => {
// 受保人如果选择了本人,使用投保人得信息填充
// oldTabName == 'policyholder' &&
if (activeTabName == 'insurantInfo') {
currentPolicyholderInfo.value = policyHolderInfoRef.value[0].providePolicyholderInfoData()
} else if (
oldTabName !== 'policyholder' &&
activeTabName == 'insurantInfo' &&
showSubmitBtn.value &&
Object.keys(currentPolicyholderInfo.value).length == 0
) {
currentPolicyholderInfo.value = appointmentSummeryInfo.value.apiPolicyholderInfoDto
}
console.log('预约切换tab', currentPolicyholderInfo.value)
// 健康信息模块,如果投保人选择了本人以及受保人选择了本人,健康信息展示投保人/受保人
let policyHolderResult = policyHolderInfoRef.value[0].handleFormValues()
let insuredResult = insuredInfoRef.value[0].handleFormValues()
console.log('policyHolderResult', policyHolderResult)
console.log('insuredResult', insuredResult)
foldInsurantInfo.value = false
if (activeTabName == 'questionnaires') {
// 投保人和受保人都点击过可以拿到最新填写得表单值
if (
policyHolderResult.customerType &&
policyHolderResult.customerType == 'INDIVIDUAL' &&
insuredResult.policyholderRel &&
insuredResult.policyholderRel == 'MYSELF'
) {
foldInsurantInfo.value = true
} else if (
!policyHolderResult.customerType &&
!insuredResult.policyholderRel &&
showSubmitBtn.value
) {
// 如果投保人和受保人都没有点击过,则使用预约单里得信息
let policyHolderInfo = appointmentSummeryInfo.value.apiPolicyholderInfoDto
let insuredInfo = appointmentSummeryInfo.value.apiInsurantInfoDto
if (
policyHolderInfo.customerType &&
policyHolderInfo.customerType == 'INDIVIDUAL' &&
insuredInfo.policyholderRel &&
insuredInfo.policyholderRel == 'MYSELF'
) {
foldInsurantInfo.value = true
}
}
}
return true return true
} }
...@@ -752,16 +820,17 @@ const isArray = value => { ...@@ -752,16 +820,17 @@ const isArray = value => {
const isObject = value => { const isObject = value => {
return typeof value === 'object' && value !== null && !Array.isArray(value) return typeof value === 'object' && value !== null && !Array.isArray(value)
} }
const handleSubmit = type => { const handleSubmit = async type => {
// 提交得时候要拿到各个步骤得表单数据 // 提交得时候要拿到各个步骤得表单数据
if (appointmentInfoRef.value) { // if (appointmentInfoRef.value) {
submitAppointmentObj.value.apiAppointmentInfoDto = // const result = await appointmentInfoRef.value[0].handleFormValues()
appointmentInfoRef.value[0].handleFormValues() // submitAppointmentObj.value.apiAppointmentInfoDto = result
if (!submitAppointmentObj.value.apiAppointmentInfoDto) return // if (!submitAppointmentObj.value.apiAppointmentInfoDto) return
} // }
if (productPlanRef.value) {
submitAppointmentObj.value.apiProductPlanInfoDto = productPlanRef.value[0].handleSubmitForm() // if (productPlanRef.value) {
} // submitAppointmentObj.value.apiProductPlanInfoDto = productPlanRef.value[0].handleSubmitForm()
// }
if (policyHolderInfoRef.value) { if (policyHolderInfoRef.value) {
submitAppointmentObj.value.apiPolicyholderInfoDto = submitAppointmentObj.value.apiPolicyholderInfoDto =
policyHolderInfoRef.value[0].handleFormValues() policyHolderInfoRef.value[0].handleFormValues()
...@@ -769,6 +838,7 @@ const handleSubmit = type => { ...@@ -769,6 +838,7 @@ const handleSubmit = type => {
if (insuredInfoRef.value) { if (insuredInfoRef.value) {
submitAppointmentObj.value.apiInsurantInfoDto = insuredInfoRef.value[0].handleFormValues() submitAppointmentObj.value.apiInsurantInfoDto = insuredInfoRef.value[0].handleFormValues()
} }
return
if (secondHolderInfoRef.value) { if (secondHolderInfoRef.value) {
submitAppointmentObj.value.apiSecondHolderInfoDto = submitAppointmentObj.value.apiSecondHolderInfoDto =
secondHolderInfoRef.value[0].handleFormValues() secondHolderInfoRef.value[0].handleFormValues()
...@@ -777,7 +847,7 @@ const handleSubmit = type => { ...@@ -777,7 +847,7 @@ const handleSubmit = type => {
submitAppointmentObj.value.apiBeneficiaryInfoDtoList = submitAppointmentObj.value.apiBeneficiaryInfoDtoList =
beneficiaryInfoRef.value[0].handleFormValues() beneficiaryInfoRef.value[0].handleFormValues()
} }
// return return
// 代表新增预约 // 代表新增预约
if (formStatus.value == 'appointmentAdd' && !idsObj.value.appointmentBizId) { if (formStatus.value == 'appointmentAdd' && !idsObj.value.appointmentBizId) {
submitAppointmentObj.value.apiAppointmentInfoDto.customerBizId = submitAppointmentObj.value.apiAppointmentInfoDto.customerBizId =
...@@ -858,7 +928,6 @@ const handleSubmit = type => { ...@@ -858,7 +928,6 @@ const handleSubmit = type => {
// 编辑预约单 // 编辑预约单
editAppointmentDetail(submitAppointmentObj.value).then(res => { editAppointmentDetail(submitAppointmentObj.value).then(res => {
if (res.code == 200) { if (res.code == 200) {
// getAppointmentInfo(idsObj.value.appointmentBizId)
appointmentInfoRef.value[0].handleEditStatus(true) appointmentInfoRef.value[0].handleEditStatus(true)
productPlanRef.value[0].handleEditStatus(true) productPlanRef.value[0].handleEditStatus(true)
policyHolderInfoRef.value[0].handleEditStatus(true) policyHolderInfoRef.value[0].handleEditStatus(true)
...@@ -887,7 +956,9 @@ const handleSubmit = type => { ...@@ -887,7 +956,9 @@ const handleSubmit = type => {
}) })
} }
} }
const handleEdit = () => {
editStatus.value = !editStatus.value
}
//修改预约数据 //修改预约数据
if (route.query.appointmentNo && route.query.source == 'appointmentList') { if (route.query.appointmentNo && route.query.source == 'appointmentList') {
processInfo.value = route.query processInfo.value = route.query
...@@ -901,7 +972,7 @@ const pageSource = computed(() => { ...@@ -901,7 +972,7 @@ const pageSource = computed(() => {
}) })
const tabHight = computed(() => { const tabHight = computed(() => {
if (pageSource.value == 'fnaList') { if (pageSource.value == 'fnaList') {
return 'calc(100vh - 407px)' return 'calc(100vh - 412px)'
} else if (pageSource.value == 'policyList') { } else if (pageSource.value == 'policyList') {
return 'calc(100vh - 225px)' return 'calc(100vh - 225px)'
} else { } else {
...@@ -910,7 +981,7 @@ const tabHight = computed(() => { ...@@ -910,7 +981,7 @@ const tabHight = computed(() => {
}) })
const minHight = computed(() => { const minHight = computed(() => {
if (pageSource.value == 'fnaList') { if (pageSource.value == 'fnaList') {
return 'calc(100vh - 84.5px)' return 'calc(100vh - 80px)'
} else if (pageSource.value == 'policyList') { } else if (pageSource.value == 'policyList') {
return 'calc(100vh - 84.5px)' return 'calc(100vh - 84.5px)'
} else { } else {
...@@ -934,11 +1005,11 @@ watch( ...@@ -934,11 +1005,11 @@ watch(
//代表是新增预约状态 //代表是新增预约状态
if (!idsObj.value.appointmentBizId) { if (!idsObj.value.appointmentBizId) {
formStatus.value = 'appointmentAdd' formStatus.value = 'appointmentAdd'
getCustomerInfo(props.processDetail.customerBizId) // getCustomerInfo(props.processDetail.customerBizId)
tabsList.value = [ tabsList.value = [
{ {
label: '约信息', label: '约信息',
name: 'appointmentInfo', name: 'appointmentInfo',
id: 1, id: 1,
key: 'appointmentBizId' key: 'appointmentBizId'
...@@ -983,10 +1054,10 @@ watch( ...@@ -983,10 +1054,10 @@ watch(
activeName.value = 'appointmentInfo' activeName.value = 'appointmentInfo'
}) })
} else { } else {
getAppointmentInfo(idsObj.value.appointmentBizId) // getAppointmentInfo(idsObj.value.appointmentBizId)
tabsList.value = [ tabsList.value = [
{ {
label: '约信息', label: '约信息',
name: 'appointmentInfo', name: 'appointmentInfo',
id: 1, id: 1,
key: 'appointmentBizId' key: 'appointmentBizId'
...@@ -1094,7 +1165,7 @@ const getPolicyDetail = tabName => { ...@@ -1094,7 +1165,7 @@ const getPolicyDetail = tabName => {
} }
if (route.query.source == 'policyList') { if (route.query.source == 'policyList') {
idsObj.value.policyBizId = route.query.policyBizId idsObj.value.policyBizId = route.query.policyBizId
getCustomerInfo(props.policyDetailInfo.customerBizId) // getCustomerInfo(props.policyDetailInfo.customerBizId)
appointmentSummeryInfo.value = JSON.parse(JSON.stringify(props.policyDetailInfo)) appointmentSummeryInfo.value = JSON.parse(JSON.stringify(props.policyDetailInfo))
if (appointmentSummeryInfo.value.apiProductPlanInfoDto) { if (appointmentSummeryInfo.value.apiProductPlanInfoDto) {
appointmentSummeryInfo.value.apiAppointmentInfoDto = JSON.parse( appointmentSummeryInfo.value.apiAppointmentInfoDto = JSON.parse(
...@@ -1235,6 +1306,17 @@ const showSubmitBtn = computed(() => { ...@@ -1235,6 +1306,17 @@ const showSubmitBtn = computed(() => {
return false return false
} }
}) })
if (route.query.appointmentNo && route.query.source == 'appointmentList') {
editStatus.value = true
} else if (route.query.source == 'policyList') {
editStatus.value = true
} else if (route.query.source == 'fnaList' && idsObj.value.appointmentBizId) {
editStatus.value = true
} else if (route.query.source == 'fnaList' && !idsObj.value.appointmentBizId) {
editStatus.value = false
}
console.log('editStatus.value ', editStatus.value, idsObj.value)
onUnmounted(() => { onUnmounted(() => {
// 彻底重置所有响应式数据 // 彻底重置所有响应式数据
submitAppointmentObj.value = {} submitAppointmentObj.value = {}
......
<template> <template>
<div>
<div v-if="processedAppointmentData.length > 0"> <div v-if="processedAppointmentData.length > 0">
<el-row> <div ref="appointmentRef">
<el-col :span="24"> <CommonForm
<div class="topBtn"> :anchorList="anchorList"
<el-button :affixOffset="360"
v-if="props.idsObj.appointmentBizId" :anchorOffset="10"
type="primary" :scrollContainerSelector="anchorContainer"
icon="EditPen" :scrollOffset="10"
@click="handleEditStatus(!editStatus)" :domIndex="tabIndex"
>编辑</el-button :activeName="activeName"
v-if="appointmentRef"
> >
</div> <template #form-right>
</el-col>
</el-row>
<el-form ref="appointmentInfoFormRef" :model="form" :rules="rules" label-width="120px"> <el-form ref="appointmentInfoFormRef" :model="form" :rules="rules" label-width="120px">
<div v-for="father in processedAppointmentData"> <div v-for="father in processedAppointmentData">
<el-row style="margin-bottom: 10px" v-if="father.showMoudle"> <el-row style="margin-bottom: 10px" v-if="father.showMoudle" :id="father.anchorKey">
<div class="formBox"> <div class="formBox">
<div class="fatherLable">{{ father.fatherTitle }}</div> <CardOne :title="father.fatherTitle">
<div class="fatherDes">{{ father.description }}</div> <template #content>
<!-- 不是表格 -->
<el-row :gutter="20"> <el-row :gutter="20" v-if="!father.showTable">
<template v-for="child in father.data" :key="child.key"> <template v-for="child in father.data" :key="child.key">
<el-col :sm="child.sm" :lg="child.lg" class="formItemBox" v-if="child.show"> <el-col
:sm="child.sm"
:lg="child.lg"
class="formItemBox"
v-if="child.show"
>
<div> <div>
<el-form-item <el-form-item
:label-width="child.labelWidth" :label-width="child.labelWidth"
...@@ -39,14 +42,15 @@ ...@@ -39,14 +42,15 @@
v-model="form[child.key]" v-model="form[child.key]"
:placeholder="child.placeholder" :placeholder="child.placeholder"
maxlength="30" maxlength="30"
:disabled="child.disabled" :rows="child.rows"
:disabled="editStatus"
/> />
<el-select <el-select
v-if="child.domType === 'Select'" v-if="child.domType === 'Select'"
v-model="form[child.key]" v-model="form[child.key]"
:placeholder="child.placeholder" :placeholder="child.placeholder"
@change="handleSelectChange(father, child)" @change="handleSelectChange(father, child)"
:disabled="child.disabled" :disabled="editStatus"
> >
<el-option <el-option
v-for="item in child.options" v-for="item in child.options"
...@@ -56,27 +60,42 @@ ...@@ -56,27 +60,42 @@
/> />
</el-select> </el-select>
<!-- 带时分的时间框 --> <!-- 带时分的时间框 -->
<div
v-if="child.domType === 'datetimePicker'"
class="compositionDateTime"
>
<el-date-picker <el-date-picker
v-model="form[child.key]" type="date"
placeholder="选择日期"
style="width: 100%" style="width: 100%"
v-if="child.domType === 'datetimePicker'" v-model="form[child.key]"
:type="child.timeType || 'datetime'" :disabled="editStatus"
:placeholder="child.placeholder"
:disabled="child.disabled"
@change="handleDateChange(child)" @change="handleDateChange(child)"
:disabled-date="time => disabledDate(time, child)" :disabled-date="time => disabledDate(time, child)"
format="YYYY-MM-DD HH:mm" format="YYYY-MM-DD"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD"
@clear="handleDateClear(child)" @clear="handleDateClear(child)"
/> />
<span class="text-gray-500">-</span>
<el-time-picker
placeholder="选择时分"
style="width: 100%"
v-model="child.timeValue"
:disabled="editStatus"
format="HH:mm"
value-format="HH:mm"
/>
</div>
<!-- 不带时分 --> <!-- 不带时分 -->
<el-date-picker <el-date-picker
style="width: 100%" style="width: 100%"
v-if="child.domType === 'DatePicker'" v-if="child.domType === 'DatePicker'"
v-model="form[child.key]" v-model="form[child.key]"
type="date" type="date"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
:placeholder="child.placeholder" :placeholder="child.placeholder"
:disabled="child.disabled" :disabled="editStatus"
:disabled-date="time => disabledDate(time, child)" :disabled-date="time => disabledDate(time, child)"
@change="handleDateChange(child)" @change="handleDateChange(child)"
@clear="handleDateClear(child)" @clear="handleDateClear(child)"
...@@ -87,7 +106,7 @@ ...@@ -87,7 +106,7 @@
:placeholder="child.placeholder" :placeholder="child.placeholder"
:suffix-icon="ArrowRight" :suffix-icon="ArrowRight"
readonly readonly
:disabled="child.disabled" :disabled="editStatus"
@focus="handleFoucs(child)" @focus="handleFoucs(child)"
> >
</el-input> </el-input>
...@@ -99,16 +118,17 @@ ...@@ -99,16 +118,17 @@
>{{ child.buttonTxt }}</el-button >{{ child.buttonTxt }}</el-button
> >
<!-- 搜索下拉框 :remote-method="query => searchSelectList(query, child)" remote-->
<el-select <el-select
v-model="form[child.key]" v-model="form[child.key]"
v-if="child.domType === 'SearchSelect'" v-if="child.domType === 'SearchSelect'"
filterable filterable
:allow-create="child.allowCreate" :allow-create="child.allowCreate"
:reserve-keyword="false" reserve-keyword
@change="handleSelectChange(father, child)"
:remote-method="query => searchSelectList(query, child.key)"
placeholder="请输入关键词搜索" placeholder="请输入关键词搜索"
:loading="searchLoadingStates[child.key]" :loading="searchLoadingStates[child.key]"
:disabled="child.disabled" :disabled="editStatus"
> >
<el-option <el-option
v-for="item in searchOptions[child.key] || []" v-for="item in searchOptions[child.key] || []"
...@@ -122,7 +142,10 @@ ...@@ -122,7 +142,10 @@
<div v-if="child.key == 'information'" class="desBox"> <div v-if="child.key == 'information'" class="desBox">
<div class="title">{{ child.title }}</div> <div class="title">{{ child.title }}</div>
<div class="informationBox"> <div class="informationBox">
<div v-for="(item, index) in child.informationList" :key="index"> <div
v-for="(item, index) in child.informationList"
:key="index"
>
{{ item.name }} {{ item.name }}
</div> </div>
</div> </div>
...@@ -132,34 +155,191 @@ ...@@ -132,34 +155,191 @@
</el-col> </el-col>
</template> </template>
</el-row> </el-row>
</div> <!-- 是表格数据 -->
</el-row> <el-row v-if="father.showTable">
</div> <el-col :span="24" v-if="father.addChildren">
<el-row v-if="props.idsObj.appointmentBizId">
<el-col>
<div class="tabButton">
<!-- <el-button
type="primary"
icon="RefreshRight"
@click="resetForm"
size="large"
:disabled="editStatus"
>重置</el-button
> -->
<el-button <el-button
:disabled="editStatus"
type="primary" type="primary"
icon="Check" icon="Plus"
@click="submitForm" size="small"
size="large" style="margin-bottom: 10px"
@click="addChildren(father)"
>{{ father.addChildrenTxt }}</el-button
>
</el-col>
<el-table :data="father.data" border v-if="father.data.length > 0">
<template v-if="father.key == 'referrerDtoList'">
<el-table-column label="姓名" prop="realName" align="center">
<template #header>
<span class="required-label">姓名</span>
</template>
<template #default="scope">
<el-select
v-model="scope.row.realName"
filterable
remote
reserve-keyword
placeholder="请输入关键词搜索"
:remote-method="query => searchSelectList(query, 'realName')"
:loading="searchLoadingStates['realName']"
:disabled="editStatus"
>
<el-option
v-for="item in searchOptions['realName'] || []"
:key="item.id"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column label="手机号" prop="phone" align="center">
<template #header>
<span class="required-label">手机号</span>
</template>
<template #default="scope">
<el-input
v-model="scope.row.phone"
size="default"
placeholder="请输入"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column label="邮箱" prop="email" align="center">
<template #header>
<span class="required-label">邮箱</span>
</template>
<template #default="scope">
<el-input
v-model="scope.row.email"
size="default"
placeholder="请输入"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column width="60px" align="center" label="操作">
<template #default="scope">
<el-icon
class="deleteIcon"
@click="deleteChildren(father, scope.$index)"
><Delete
/></el-icon>
</template>
</el-table-column>
</template>
<template v-if="father.key == 'userSignDtoList'">
<el-table-column label="姓名" prop="name" align="center">
<template #header>
<span class="required-label">姓名</span>
</template>
<template #default="scope">
<el-select
v-model="scope.row.name"
filterable
remote
reserve-keyword
placeholder="请选择"
:remote-method="query => searchSelectList(query, 'name')"
:loading="searchLoadingStates['name']"
:disabled="editStatus"
>
<el-option
v-for="item in searchOptions['name'] || []"
:key="item.id"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column label="手机号" prop="phone" align="center">
<template #header>
<span class="required-label">手机号</span>
</template>
<template #default="scope">
<el-input
v-model="scope.row.phone"
size="default"
placeholder="请输入"
:disabled="editStatus" :disabled="editStatus"
>提交</el-button />
</template>
</el-table-column>
<el-table-column label="执业编码" prop="practiceCode" align="center">
<template #header>
<span class="required-label">执业编码</span>
</template>
<template #default="scope">
<el-input
v-model="scope.row.practiceCode"
size="default"
placeholder="请输入"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column label="邮箱" prop="email" align="center">
<template #default="scope">
<el-input
v-model="scope.row.email"
size="default"
placeholder="请输入"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column label="证件类型" prop="cardType" align="center">
<template #default="scope">
<el-select
v-model="scope.row.cardType"
placeholder="请选择"
:disabled="editStatus"
clearable
> >
<el-option
v-for="item in fetchDictData('csf_id_type')"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column label="证件号" prop="cardNo" align="center">
<template #default="scope">
<el-input
v-model="scope.row.cardNo"
size="default"
placeholder="请输入"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column width="60px" align="center" label="操作">
<template #default="scope">
<el-icon
@click="deleteChildren(father, scope.$index)"
class="deleteIcon"
><Delete
/></el-icon>
</template>
</el-table-column>
</template>
</el-table>
</el-row>
</template>
</CardOne>
</div> </div>
</el-col>
</el-row> </el-row>
</div>
</el-form> </el-form>
</template>
</CommonForm>
</div> </div>
<!-- <div v-else class="domEmpty" v-loading="loading"></div> -->
<Phone <Phone
@close="handleCloseDrawer" @close="handleCloseDrawer"
:showDrawer="showPhoneDrawer" :showDrawer="showPhoneDrawer"
...@@ -192,29 +372,35 @@ import Phone from '@/views/components/phone' ...@@ -192,29 +372,35 @@ import Phone from '@/views/components/phone'
import Address from '@/views/components/address' import Address from '@/views/components/address'
import { watch, nextTick } from 'vue' import { watch, nextTick } from 'vue'
import { getCustomerDetail } from '@/api/sign/fna'
import { editAppointmentInfo, newPolicy } from '@/api/sign/appointment' import { editAppointmentInfo, newPolicy } from '@/api/sign/appointment'
import { getBankList, getAllSignList, getUserSaleExpandList } from '@/api/common'
import CommonForm from '@/views/components/commonForm'
import CardOne from '@/components/formCard/cardOne'
import useDictStore from '@/store/modules/dict' import useDictStore from '@/store/modules/dict'
const dictStore = useDictStore() //获取字典数据 const dictStore = useDictStore() //获取字典数据
const props = defineProps({ const props = defineProps({
activeName: { type: String, default: '' }, //tab名称 activeName: { type: String, default: '' }, //tab名称
formStatus: { type: String, default: '' }, //父组件状态,新增、修改 formStatus: { type: String, default: '' }, //父组件状态,新增、修改
idsObj: { type: Object, default: () => ({}) }, //父组件传递过来的id对象 idsObj: { type: Object, default: () => ({}) }, //父组件传递过来的id对象
apiAppointmentInfoDto: { type: Object, default: () => ({}) }, //父组件传递过来的约信息的详情 apiAppointmentInfoDto: { type: Object, default: () => ({}) }, //父组件传递过来的约信息的详情
appointmentStatus: { type: Number }, //父组件传递过来的预约的状态 appointmentStatus: { type: Number }, //父组件传递过来的预约的状态
customerBizId: { type: String, default: '' } //提交状态,新增、修改 customerBizId: { type: String, default: '' }, //提交状态,新增、修改
fatherTabName: { type: String, default: '' }, //一级tab名称
anchorContainer: { type: String, default: '' }, //锚点滚动容器
editStatus: { type: Boolean, default: true }, //编辑状态
tabIndex: { type: [String, Number], default: '' } //tab索引
}) })
const emit = defineEmits(['handleSuccessEdit']) const emit = defineEmits(['handleSuccessEdit'])
const { proxy } = getCurrentInstance() const { proxy } = getCurrentInstance()
// const { csf_id_type, sys_gender } = proxy.useDict('csf_id_type', 'sys_gender') const appointmentRef = ref(null)
const showPhoneDrawer = ref(false) //电话抽屉开关 const showPhoneDrawer = ref(false) //电话抽屉开关
const showAddressDrawer = ref(false) //地址抽屉开关 const showAddressDrawer = ref(false) //地址抽屉开关
const showCountryDrawer = ref(false) //国家/地区抽屉开关 const showCountryDrawer = ref(false) //国家/地区抽屉开关
const drawerInfo = ref({}) // 用于存储所有arrowRight类型的输入框输入值 const drawerInfo = ref({}) // 用于存储所有arrowRight类型的输入框输入值
const saveKey = ref({}) // 用于存储当前点击的drawer框返回的对象,修改的时候回显值也要存key const saveKey = ref({}) // 用于存储当前点击的drawer框返回的对象,修改的时候回显值也要存key
const errorFields = ref([]) // 存储校验失败的字段信息 const errorFields = ref([]) // 存储校验失败的字段信息
const editStatus = ref(true) // 表单是否可编辑,若是修改初始不可编辑
const openList = ref(false) // 客户列表弹窗 const openList = ref(false) // 客户列表弹窗
const oldObjInfo = ref({}) // 修改时存储原始数据,便于撤销操作 const oldObjInfo = ref({}) // 修改时存储原始数据,便于撤销操作
const consultKey = ref({}) const consultKey = ref({})
...@@ -292,21 +478,120 @@ const data = reactive({ ...@@ -292,21 +478,120 @@ const data = reactive({
} }
}) })
const { form, rules, processedAppointmentData, queryParams, oldAppointmentData } = toRefs(data) const { form, rules, processedAppointmentData, queryParams, oldAppointmentData } = toRefs(data)
// 添加表单子级dom
const addChildren = father => {
const processedData = JSON.parse(JSON.stringify(processedAppointmentData.value))
let obj4 = {
id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识
span: 24, //栅格布局份数
email: '',
phone: '',
realName: ''
}
let obj5 = {
id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识
span: 24, //栅格布局份数
name: '', //姓名
practiceCode: '', //执业编码
phone: '', //手机号
cardType: '', //证件类型
cardNo: '', //证件号码
email: '' //邮箱
}
for (const section of processedData) {
if (father.key == 'referrerDtoList' && section.key == father.key) {
section.data.push(obj4)
}
if (father.key == 'userSignDtoList' && section.key == father.key) {
section.data.push(obj5)
}
}
//更新form表单对应的数据,以便收集填写的值
// form.value[father.key].push(obj)
processedAppointmentData.value = processedData
}
const deleteChildren = (father, childIndex) => {
if (props.editStatus.value) {
proxy.$modal.confirm(`请先点击编辑再进行删除操作`, { showCancel: '0', title: '填写提示' })
return
}
const processedData = JSON.parse(JSON.stringify(processedAppointmentData.value))
for (const section of processedData) {
if (father.key == 'referrerDtoList' && section.key == father.key) {
section.data.splice(childIndex, 1)
}
if (father.key == 'userSignDtoList' && section.key == father.key) {
section.data.splice(childIndex, 1)
}
}
processedAppointmentData.value = processedData
}
// 搜索方法 // 搜索方法
const searchSelectList = async (query, field) => { const searchSelectList = async (query, key) => {
// 设置该字段的加载状态 // 设置该字段的加载状态
searchLoadingStates.value[field.key] = true searchLoadingStates.value[key] = true
let queryString = query.trim()
try { try {
// 根据不同的字段key调用不同的API // 根据不同的字段key调用不同的API
if (field.key === 'bankName') { if (key === 'bankName') {
console.log('searchOptions.value[field.key]', searchOptions.value[field.key]) const params4 = {
pageNo: 1,
pageSize: 10,
queryContent: queryString
}
const response4 = await getBankList(params4)
if (response4.code == 200) {
response4.data.records = response4.data.records.map(item => {
return {
...item,
label: item.bankName,
value: item.bankBizId
}
})
searchOptions.value[key] = response4.data.records
}
} else if (key == 'realName') {
const params5 = {
pageNo: 1,
pageSize: 10,
queryContent: queryString
}
const response5 = await getUserSaleExpandList(params5)
if (response5.code == 200) {
response5.data.records = response5.data.records.map(item => {
return {
...item,
label: item.realName,
value: item.userSaleBizId
}
})
searchOptions.value[key] = response5.data.records
}
} else if (key == 'name') {
const params5 = {
pageNo: 1,
pageSize: 10,
realName: queryString
}
const response5 = await getAllSignList(params5)
if (response5.code == 200) {
response5.data.records = response5.data.records.map(item => {
return {
...item,
label: item.realName,
value: item.userSignBizId
}
})
searchOptions.value[key] = response5.data.records
}
} }
} catch (error) { } catch (error) {
console.error(`${field.label} 搜索失败`, error) console.error(` 搜索失败`, error)
searchOptions.value[field.key] = [] searchOptions.value[key] = []
} finally { } finally {
searchLoadingStates.value[field.key] = false searchLoadingStates.value[key] = false
} }
} }
const disabledDate = (time, child) => { const disabledDate = (time, child) => {
...@@ -321,22 +606,7 @@ const disabledDate = (time, child) => { ...@@ -321,22 +606,7 @@ const disabledDate = (time, child) => {
// 默认禁用今天及今天之前 // 默认禁用今天及今天之前
return inputDate.isBefore(today, 'day') || inputDate.isSame(today, 'day') return inputDate.isBefore(today, 'day') || inputDate.isSame(today, 'day')
break break
// case 'arrivalTime':
// // 如果允许选择今天,只禁用今天之前的日期
// return inputDate.isBefore(today, 'day')
// break
// case 'departureTime':
// // 获取开始日期(需要从表单数据中获取)
// const startTime1 = form.value.arrivalTime
// if (startTime1) {
// const arrivalDate = dayjs(startTime1).startOf('day')
// // 只禁用到达日期之前的日期,允许选择同一天
// return inputDate.isBefore(arrivalDate, 'day')
// } else {
// // 如果没有选择到达时间,禁用今天之前的日期
// return inputDate.isBefore(today, 'day')
// }
// break
case 'confirmAppointmentTime': case 'confirmAppointmentTime':
return inputDate.isBefore(today, 'day') return inputDate.isBefore(today, 'day')
break break
...@@ -393,8 +663,7 @@ const handleDateChange = child => { ...@@ -393,8 +663,7 @@ const handleDateChange = child => {
resetShow({ type: 'child', key: 'openAccountEndTime', status: false, flag: 'disabled' }) resetShow({ type: 'child', key: 'openAccountEndTime', status: false, flag: 'disabled' })
disabledDate(form.value['openAccountStartTime'], { key: 'openAccountEndTime' }) disabledDate(form.value['openAccountStartTime'], { key: 'openAccountEndTime' })
} }
// resetShow({ type: 'child', key: 'departureTime', status: false, flag: 'disabled' })
// disabledDate(form.value['arrivalTime'], { key: 'departureTime' })
// 离港时间在到港时间之前 // 离港时间在到港时间之前
if ( if (
child.key == 'arrivalTime' && child.key == 'arrivalTime' &&
...@@ -415,51 +684,6 @@ const handleDateChange = child => { ...@@ -415,51 +684,6 @@ const handleDateChange = child => {
} else if (child.key === 'confirmAppointmentTime' && form.value[child.key]) { } else if (child.key === 'confirmAppointmentTime' && form.value[child.key]) {
resetShow({ type: 'child', key: 'newPolicyButton', status: true, flag: 'show' }) resetShow({ type: 'child', key: 'newPolicyButton', status: true, flag: 'show' })
} }
// if (child.key === 'confirmAppointmentTime' && form.value[child.key]) {
// if (form.value['arrivalTime']) {
// const appointmentTimestamp = dayjs(form.value['confirmAppointmentTime']).valueOf()
// const arrivalTimestamp = dayjs(form.value['arrivalTime']).valueOf()
// if (appointmentTimestamp < arrivalTimestamp) {
// proxy.$modal.msgError('预约时间早于到港时间,请重新选择预约时间')
// form.value['confirmAppointmentTime'] = ''
// return
// } else if (appointmentTimestamp > arrivalTimestamp) {
// } else {
// proxy.$modal.msgError('预约时间应晚于到港时间,请重新选择预约时间')
// form.value['confirmAppointmentTime'] = ''
// return
// }
// }
// resetShow({ type: 'child', key: 'newPolicyButton', status: true, flag: 'show' })
// } else if (child.key === 'confirmAppointmentTime' && !form.value[child.key]) {
// resetShow({ type: 'child', key: 'newPolicyButton', status: false, flag: 'show' })
// } else if (child.key === 'arrivalTime') {
// if (form.value['confirmAppointmentTime']) {
// const appointmentTimestamp = dayjs(form.value['confirmAppointmentTime']).valueOf()
// const arrivalTimestamp = dayjs(form.value['arrivalTime']).valueOf()
// if (appointmentTimestamp < arrivalTimestamp) {
// proxy.$modal.msgError('预约时间早于到港时间,请重新选择到港时间')
// form.value['arrivalTime'] = ''
// form.value['departureTime'] = ''
// resetShow({ type: 'child', key: 'departureTime', status: true, flag: 'disabled' })
// } else if (appointmentTimestamp > arrivalTimestamp) {
// console.log('预约时间晚于到港时间')
// } else {
// proxy.$modal.msgError('到港时间应早于预约时间,请重新选择到港时间')
// form.value['arrivalTime'] = ''
// form.value['departureTime'] = ''
// resetShow({ type: 'child', key: 'departureTime', status: true, flag: 'disabled' })
// }
// }
// } else if (child.key === 'confirmAppointmentTime') {
// if (form.value['arrivalTime']) {
// const appointmentTimestamp = dayjs(form.value['confirmAppointmentTime']).valueOf()
// const arrivalTimestamp = dayjs(form.value['arrivalTime']).valueOf()
// console.log('appointmentTimestamp', appointmentTimestamp)
// console.log('arrivalTimestamp', arrivalTimestamp)
// }
// }
} }
// 获取字典数据 // 获取字典数据
const fetchDictData = dictType => { const fetchDictData = dictType => {
...@@ -512,7 +736,10 @@ const processFormData = async () => { ...@@ -512,7 +736,10 @@ const processFormData = async () => {
field.options = fetchDictData(field.dictType) field.options = fetchDictData(field.dictType)
} }
if (field.key == 'bankName') { if (field.key == 'bankName') {
searchOptions.value[field.key] = fetchDictData(field.dictType) searchOptions.value[field.key] = dictStore.bankList
}
if (field.key == 'realName') {
searchOptions.value[field.key] = dictStore.userSaleExpandList
} }
if (field.required) { if (field.required) {
if (field.key === 'firstNamePinyin') { if (field.key === 'firstNamePinyin') {
...@@ -531,10 +758,11 @@ const processFormData = async () => { ...@@ -531,10 +758,11 @@ const processFormData = async () => {
} }
if (props.idsObj.appointmentBizId) { if (props.idsObj.appointmentBizId) {
editStatus.value = true // editStatus.value = true
setFormValue(props.apiAppointmentInfoDto, processedData) setFormValue(props.apiAppointmentInfoDto, processedData)
} else { } else {
editStatus.value = false // 新增给默认值
form.value['isReferrerAccompany'] = form.value['isOpenAccount'] = form.value['isUseCar'] = 0
processedAppointmentData.value = processedData processedAppointmentData.value = processedData
} }
} }
...@@ -674,12 +902,12 @@ const resetShow = obj => { ...@@ -674,12 +902,12 @@ const resetShow = obj => {
} }
const handleSelectChange = (father, child) => { const handleSelectChange = (father, child) => {
switch (child.key) { switch (child.key) {
case 'isAccompany': case 'isReferrerAccompany':
// 选择吸烟,展示吸烟数量 // 选择吸烟,展示吸烟数量
if (form.value[child.key] == '1') { if (form.value[child.key] == '1') {
resetShow({ type: 'father', key: 'consult', status: true }) resetShow({ type: 'father', key: 'referrerDtoList', status: true })
} else { } else {
resetShow({ type: 'father', key: 'consult', status: false }) resetShow({ type: 'father', key: 'referrerDtoList', status: false })
} }
break break
...@@ -690,6 +918,23 @@ const handleSelectChange = (father, child) => { ...@@ -690,6 +918,23 @@ const handleSelectChange = (father, child) => {
} else { } else {
resetShow({ type: 'father', key: 'openAccount', status: false }) resetShow({ type: 'father', key: 'openAccount', status: false })
} }
break
case 'bankName':
// 选择吸烟,展示吸烟数量
if (form.value[child.key]) {
if (
searchOptions.value[child.key].findIndex(item => item.value == form.value[child.key]) !==
-1
) {
searchOptions.value[child.key].forEach(item => {
if (item.value == form.value[child.key]) {
form.value['materials'] = item.materials
}
})
} else {
form.value['materials'] = ''
}
}
break break
...@@ -754,9 +999,9 @@ const setFormValue = (obj, formData) => { ...@@ -754,9 +999,9 @@ const setFormValue = (obj, formData) => {
} else { } else {
field.disabled = false field.disabled = false
} }
if (field.key == 'bankName') { // if (field.key == 'bankName') {
searchOptions.value[field.key] = fetchDictData(field.dictType) // searchOptions.value[field.key] = fetchDictData(field.dictType)
} // }
// 处理时间 // 处理时间
if (field.key == 'openAccountEndTime' && obj[field.key]) { if (field.key == 'openAccountEndTime' && obj[field.key]) {
// 开始时间是否在结束时间之前 // 开始时间是否在结束时间之前
...@@ -898,28 +1143,27 @@ const getInvalidFields = fields => { ...@@ -898,28 +1143,27 @@ const getInvalidFields = fields => {
return errors return errors
} }
// 处理表单填写得数据
const handleFormValues = () => { const handleFormValues = () => {
return new Promise(resolve => {
let submitObj = { ...form.value } let submitObj = { ...form.value }
const pattern = /Time$/ // 以Time结尾 const pattern = /Time$/
proxy.$refs['appointmentInfoFormRef'].validate((valid, fields) => {
if (valid) {
errorFields.value = [] // 清空错误信息
//处理表单数据 //处理表单数据
for (const key1 in form.value) { for (const key1 in form.value) {
// 不开户去除开户相关信息 // 不开户去除开户相关信息
if (key1 == 'isOpenAccount' && form.value[key1] === 0) { if (key1 == 'isOpenAccount' && form.value[key1] == 0) {
for (const key4 in openAccountKey.value) { for (const key4 in openAccountKey.value) {
delete submitObj[key4] delete submitObj[key4]
} }
} }
// 没顾问去除顾问相关信息
if (key1 == 'isAccompany' && form.value[key1] === 0) {
for (const key5 in consultKey.value) {
delete submitObj[key5]
}
}
if (pattern.test(key1) && form.value[key1]) { if (pattern.test(key1) && form.value[key1]) {
submitObj[key1] = proxy.formatToDateTime(form.value[key1]) submitObj[key1] = proxy.formatToDateTime(form.value[key1])
} }
// 处理电话和地址相关的
for (const key2 in saveKey.value) { for (const key2 in saveKey.value) {
//要判断drawerType //要判断drawerType
switch (saveKey.value[key2].objType) { switch (saveKey.value[key2].objType) {
...@@ -947,70 +1191,146 @@ const handleFormValues = () => { ...@@ -947,70 +1191,146 @@ const handleFormValues = () => {
} }
} }
} }
if (submitObj['bankName']) {
searchOptions.value['bankName'].forEach(item => {
if (submitObj['bankName'] == item.bankBizId) {
submitObj['bankName'] = item.bankName
}
})
}
let obj = {
realName: '转介人姓名',
phone: '转介人手机',
email: '转介人邮箱'
}
let obj1 = {
name: '签单员姓名',
phone: '签单员电话',
practiceCode: '签单员执业编码'
}
processedAppointmentData.value.forEach(item => {
if (item.key == 'referrerDtoList') {
if (form.value['isReferrerAccompany'] == 1 && item.data.length > 0) {
submitObj['referrerDtoList'] = item.data.map((item1, index) => {
if (item1.realName) {
searchOptions.value['realName'].forEach(item2 => {
if (item1.realName == item2.userSaleBizId) {
item1.realName = item2.realName
}
})
}
for (const key in item1) {
if (!item1[key]) {
errorFields.value.push({
message: `陪同转介人-第${index + 1}${obj[key]}不能为空`
})
}
}
return {
realName: item1.realName,
phone: item1.phone,
email: item1.email
}
})
} else if (form.value['isReferrerAccompany'] == 1 && item.data.length == 0) {
errorFields.value.push({
message: '签约信息模块--转介人陪同时,陪同转介人信息不能为空!!'
})
}
}
if (item.key == 'position') {
item.data.forEach((item1, index) => {
if (item1.compositionTime) {
if (item1.timeValue) {
submitObj[item1.key] = form.value[item1.key] + ' ' + item1.timeValue + ':00'
} else {
submitObj[item1.key] = form.value[item1.key] + ' 00:00:00'
}
}
})
}
if (item.key == 'userSignDtoList' && item.data.length > 0) {
submitObj['userSignDtoList'] = item.data.map((item1, index) => {
if (item1.name) {
searchOptions.value['name'].forEach(item2 => {
if (item1.name == item2.userSignBizId) {
item1.name = item2.realName
}
})
}
for (const key in item1) {
if (!item1[key]) {
errorFields.value.push({
message: `签单员-第${index + 1}${obj1[key]}不能为空`
})
}
}
return {
name: item1.name,
phone: item1.phone,
email: item1.email,
practiceCode: item1.practiceCode,
cardType: item1.cardType,
cardNo: item1.cardNo
}
})
}
})
console.log('submitObj', submitObj)
if (submitObj['departureTime']) { if (submitObj['departureTime']) {
// 开始时间是否在结束时间之前 // 开始时间是否在结束时间之前
if ( if (
submitObj['arrivalTime'] && submitObj['arrivalTime'] &&
!dayjs(submitObj['arrivalTime']).isBefore(dayjs(submitObj['departureTime'])) !dayjs(submitObj['arrivalTime']).isBefore(dayjs(submitObj['departureTime']))
) { ) {
proxy.$message.error('预约信息模块--离港时间必须晚于到港时间!!') errorFields.value.push({
return undefined message: '签约信息模块--离港时间必须晚于到港时间!!'
})
// return undefined
} }
} }
return submitObj if (errorFields.value.length > 0) {
} proxy.$message.error(errorFields.value[0].message)
// 表单提交
const submitForm = () => {
// return
proxy.$refs['appointmentInfoFormRef'].validate((valid, fields) => {
if (valid) {
let submitObj = handleFormValues()
console.log('====================================')
console.log('submitObj', submitObj)
console.log('====================================')
// return
if (!submitObj) return
if (props.idsObj.appointmentBizId) {
editAppointmentInfo(submitObj).then(res => {
if (res.code == 200) {
handleEditStatus(true)
proxy.$message.success('预约信息修改成功')
emit('handleSuccessEdit')
}
})
} }
errorFields.value = [] // 清空错误信息 resolve(errorFields.value.length == 0 ? submitObj : null)
} else { } else {
// 获取校验失败的字段信息
errorFields.value = getInvalidFields(fields) errorFields.value = getInvalidFields(fields)
if (errorFields.value.length > 0) { if (errorFields.value.length > 0) {
proxy.$message.error(errorFields.value[0].message) proxy.$message.error(errorFields.value[0].message)
} }
resolve(undefined)
} }
}) })
}
const resetForm = () => {
proxy.$modal
.confirm('是否确认撤销所作操作?')
.then(function () {
form.value = { ...oldObjInfo.value }
editStatus.value = true
processedAppointmentData.value = JSON.parse(JSON.stringify(oldAppointmentData.value))
proxy.$refs['appointmentInfoFormRef'].resetFields()
}) })
.catch(() => {})
} }
const anchorList = computed(() => {
let data = []
for (const section of processedAppointmentData.value) {
if (section.showMoudle) {
data.push({ title: section.anchorKey, name: section.fatherTitle })
}
}
return data
})
watch( watch(
() => props.activeName, () => props.activeName,
newVal => { newVal => {
appointmentRef.value = null
if (newVal === 'appointmentInfo') { if (newVal === 'appointmentInfo') {
openList.value = false openList.value = false
setTimeout(() => {
processFormData() processFormData()
}, 500) }
}
)
// 因为tab嵌套了两层,所以需要监听父组件的tab否则锚点的显示就会有bug
watch(
() => props.fatherTabName,
newVal => {
if (newVal) {
appointmentRef.value = null
} }
} }
) )
...@@ -1030,6 +1350,11 @@ defineExpose({ ...@@ -1030,6 +1350,11 @@ defineExpose({
}) })
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.required-label::before {
content: '*';
color: #f56c6c;
margin-right: 4px;
}
.domEmpty { .domEmpty {
width: 100%; width: 100%;
height: 100%; height: 100%;
...@@ -1150,6 +1475,16 @@ defineExpose({ ...@@ -1150,6 +1475,16 @@ defineExpose({
margin-bottom: 0px; margin-bottom: 0px;
} }
} }
.deleteIcon {
color: red;
font-size: 18px;
padding-top: 10px;
}
.compositionDateTime {
display: flex;
width: 100%;
box-sizing: border-box;
}
@media only screen and (min-width: 768px) { @media only screen and (min-width: 768px) {
.formBtn { .formBtn {
margin-top: 0 !important; margin-top: 0 !important;
......
<template> <template>
<div> <!-- 只画好了样式具体的逻辑还没处理 -->
<div v-if="processedProductData.length > 0"> <div v-if="processedProductData.length > 0">
<el-row> <div ref="productRef">
<el-col :span="24"> <CommonForm
<div class="topBtn"> :anchorList="anchorList"
<!-- v-if="props.idsObj.appointmentBizId" --> :affixOffset="360"
<el-button :anchorOffset="10"
v-if="props.showSubmitBtn" :scrollContainerSelector="anchorContainer"
type="primary" :scrollOffset="10"
icon="EditPen" :domIndex="tabIndex"
@click="handleEditStatus(!editStatus)" :activeName="activeName"
>编辑</el-button v-if="productRef"
> >
</div> <template #form-right>
</el-col>
</el-row>
<el-form ref="productFormRef" :model="form" :rules="rules"> <el-form ref="productFormRef" :model="form" :rules="rules">
<el-row v-for="father in processedProductData" style="margin-bottom: 10px"> <el-row
<div class="formBox formFna"> v-for="father in processedProductData"
<div class="fatherLable"> style="margin-bottom: 10px"
<span>{{ father.fatherTitle }}</span> :id="father.anchorKey"
<el-button
style="margin-left: 10px"
v-if="father.addBtn"
type="primary"
icon="Plus"
@click="addChildren(father)"
size="small"
:disabled="editStatus"
>新增</el-button
> >
</div> <div class="formBox formFna">
<div class="subTitle" v-if="father.subTitle">{{ father.subTitle }}</div> <CardOne :title="father.fatherTitle">
<template #content>
<el-row v-if="father.child == 'no'" :gutter="20"> <el-row v-if="!father.showTable" :gutter="20">
<template v-for="child in father.data" :key="child.key"> <template v-for="child in father.data" :key="child.key">
<el-col :sm="child.sm" :lg="child.lg" class="formItem" v-if="child.show"> <el-col :sm="child.sm" :lg="child.lg" class="formItem" v-if="child.show">
<div> <div>
...@@ -50,7 +39,7 @@ ...@@ -50,7 +39,7 @@
v-model="form[father.key][child.key]" v-model="form[father.key][child.key]"
:placeholder="child.placeholder" :placeholder="child.placeholder"
maxlength="30" maxlength="30"
:disabled="child.disabled" :disabled="editStatus"
:style="{ width: child.inputWidth ? child.inputWidth : '100%' }" :style="{ width: child.inputWidth ? child.inputWidth : '100%' }"
/> />
<el-select <el-select
...@@ -58,7 +47,7 @@ ...@@ -58,7 +47,7 @@
v-model="form[father.key][child.key]" v-model="form[father.key][child.key]"
:placeholder="child.placeholder" :placeholder="child.placeholder"
@change="handleSelectChange(father, child)" @change="handleSelectChange(father, child)"
:disabled="child.disabled" :disabled="editStatus"
> >
<el-option <el-option
v-for="item in child.options" v-for="item in child.options"
...@@ -73,12 +62,12 @@ ...@@ -73,12 +62,12 @@
v-model="form[father.key][child.key]" v-model="form[father.key][child.key]"
type="date" type="date"
:placeholder="child.placeholder" :placeholder="child.placeholder"
:disabled="child.disabled" :disabled="editStatus"
/> />
<el-checkbox-group <el-checkbox-group
v-if="child.domType === 'Checkbox'" v-if="child.domType === 'Checkbox'"
v-model="form[father.key][child.key]" v-model="form[father.key][child.key]"
:disabled="child.disabled" :disabled="editStatus"
> >
<el-checkbox <el-checkbox
v-for="item in child.options" v-for="item in child.options"
...@@ -97,7 +86,7 @@ ...@@ -97,7 +86,7 @@
placeholder="请输入关键词搜索" placeholder="请输入关键词搜索"
:remote-method="query => searchSelectList(query, child.key)" :remote-method="query => searchSelectList(query, child.key)"
:loading="searchLoadingStates[child.key]" :loading="searchLoadingStates[child.key]"
:disabled="child.disabled" :disabled="editStatus"
@change="handleSearchSelectChange(father, child)" @change="handleSearchSelectChange(father, child)"
> >
<el-option <el-option
...@@ -112,54 +101,78 @@ ...@@ -112,54 +101,78 @@
</el-col> </el-col>
</template> </template>
</el-row> </el-row>
<!-- 有子孙的dom --> <!-- 是表格数据 -->
<el-row v-if="father.child == 'yes' && father.data.length > 0" :gutter="20"> <el-row v-if="father.showTable">
<template v-for="(child, childIndex) in father.data" :key="child.id"> <el-col :span="24" v-if="father.addChildren">
<el-col :span="child.span"> <el-button
<div :disabled="editStatus"
class="childLabel" type="primary"
v-if="father.key == 'apiProductPlanAdditionalInfoDtoList'" icon="Plus"
@click="deleteChildren(father, childIndex)" size="small"
style="margin-bottom: 10px"
@click="addChildren(father)"
>{{ father.addChildrenTxt }}</el-button
> >
<span>{{ `${child.childTitle}-${childIndex + 1}` }}</span> </el-col>
<el-table :data="father.data" border v-if="father.data.length > 0">
<template v-if="father.key == 'apiProductPlanAdditionalInfoDtoList'">
<el-table-column label="姓名" prop="realName" align="center" />
<el-table-column width="60px" align="center" label="操作">
<template #default="scope">
<el-icon <el-icon
v-if="child.deleteBtn" class="deleteIcon"
style="color: red; font-size: 18px; margin-left: 10px" @click="deleteChildren(father, scope.$index)"
><Delete ><Delete
/></el-icon> /></el-icon>
</template>
</el-table-column>
</template>
</el-table>
</el-row>
</template>
</CardOne>
</div> </div>
</el-col> </el-row>
<template v-for="grandchildren in child.children" :key="grandchildren.key"> </el-form>
<el-col </template>
:sm="grandchildren.sm" </CommonForm>
:lg="grandchildren.lg" </div>
class="formItem" <CommonDialog
v-if="grandchildren.show && form[father.key] && form[father.key][childIndex]" :dialogTitle="dialogTitle"
confirmText="确定"
cancleText="关闭"
dialogWidth="70%"
:showClose="true"
:openDialog="dialogVisible"
@close="dialogVisible = false"
> >
<div class="dialogBox">
<el-form>
<el-row :gutter="20">
<template v-for="(child, dIndex) in additionalProductForm">
<el-col :sm="child.sm" :lg="child.lg" class="formItem">
<el-form-item <el-form-item
:label="grandchildren.label" :label="child.label"
:prop="grandchildren.key" :prop="child.key"
:key="grandchildren.key" :key="child.key"
:label-width="grandchildren.labelWidth" :label-width="child.labelWidth"
:label-position="grandchildren.labelPosition" :label-position="child.labelPosition"
> >
<el-input <el-input
v-if="grandchildren.domType === 'Input'" v-if="child.domType === 'Input'"
:type="grandchildren.inputType" :type="child.inputType"
v-model="form[father.key][childIndex][grandchildren.key]" v-model="child.value"
:placeholder="grandchildren.placeholder" :placeholder="child.placeholder"
maxlength="30" maxlength="30"
:disabled="grandchildren.disabled"
/> />
<!-- 下拉框 -->
<el-select <el-select
v-if="grandchildren.domType === 'Select'" v-if="child.domType === 'Select'"
v-model="form[father.key][childIndex][grandchildren.key]" v-model="child.value"
:placeholder="grandchildren.placeholder" :placeholder="child.placeholder"
:disabled="grandchildren.disabled"
> >
<el-option <el-option
v-for="item in grandchildren.options" v-for="item in child.options"
:key="item.value" :key="item.value"
:label="item.label" :label="item.label"
:value="item.value" :value="item.value"
...@@ -167,26 +180,24 @@ ...@@ -167,26 +180,24 @@
</el-select> </el-select>
<el-date-picker <el-date-picker
style="width: 100%" style="width: 100%"
v-if="grandchildren.domType === 'DatePicker'" v-if="child.domType === 'DatePicker'"
v-model="form[father.key][childIndex][grandchildren.key]" v-model="child.value"
type="date" type="date"
:placeholder="grandchildren.placeholder" :placeholder="child.placeholder"
:disabled="grandchildren.disabled"
/> />
<!-- 搜索下拉框 -->
<el-select <el-select
v-model="form[father.key][childIndex][grandchildren.key]" v-model="child.value"
v-if="grandchildren.domType === 'SearchSelect'" v-if="child.domType === 'SearchSelect'"
filterable filterable
remote remote
reserve-keyword reserve-keyword
placeholder="请输入关键词搜索" placeholder="请输入关键词搜索"
:remote-method="query => searchSelectList(query, grandchildren.key)" @change="handleSearchSelectChange(child.key, dIndex)"
:loading="searchLoadingStates[grandchildren.key]" :remote-method="query => searchSelectList(query, child.key)"
:disabled="grandchildren.disabled" :loading="searchLoadingStates[child.key]"
> >
<el-option <el-option
v-for="item in searchOptions[grandchildren.key] || []" v-for="item in searchOptions[child.key] || []"
:key="item.id" :key="item.id"
:label="item.label" :label="item.label"
:value="item.value" :value="item.value"
...@@ -195,35 +206,26 @@ ...@@ -195,35 +206,26 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</template> </template>
</template>
</el-row>
</div>
</el-row>
<el-row v-if="props.showSubmitBtn">
<el-col>
<div class="tabButton">
<el-button
type="success"
icon="Check"
@click="submitForm()"
size="large"
:disabled="editStatus"
>保存</el-button
>
</div>
</el-col>
</el-row> </el-row>
</el-form> </el-form>
</div> </div>
</CommonDialog>
</div> </div>
</template> </template>
<script setup name="customer"> <script setup name="customer">
import CommonForm from '@/views/components/commonForm'
import CommonDialog from '@/components/commonDialog'
import CardOne from '@/components/formCard/cardOne'
import useDictStore from '@/store/modules/dict' import useDictStore from '@/store/modules/dict'
import productDomData from '@/formJson/productPlan' import productDomData from '@/formJson/productPlan'
import { watch } from 'vue' import { watch } from 'vue'
import { getInsuranceProductList, getAdditionalProductList } from '@/api/common' import {
getInsuranceProductList,
getAdditionalProductList,
secondAdditonalList
} from '@/api/common'
import { editProductPlanInfo, delAdditional } from '@/api/sign/appointment' import { editProductPlanInfo, delAdditional } from '@/api/sign/appointment'
import { updatePolicyProduct, delPolicyAdditional } from '@/api/sign/underwritingMain' import { updatePolicyProduct, delPolicyAdditional } from '@/api/sign/underwritingMain'
import useUserStore from '@/store/modules/user' import useUserStore from '@/store/modules/user'
...@@ -240,19 +242,27 @@ const props = defineProps({ ...@@ -240,19 +242,27 @@ const props = defineProps({
pageSource: { type: String, default: '' }, //页面来源 pageSource: { type: String, default: '' }, //页面来源
idsObj: { type: Object, default: () => ({}) }, //父组件传递过来的id对象 idsObj: { type: Object, default: () => ({}) }, //父组件传递过来的id对象
apiProductPlanInfoDto: { type: Object, default: () => ({}) }, //父组件传递过来的预约信息的详情 apiProductPlanInfoDto: { type: Object, default: () => ({}) }, //父组件传递过来的预约信息的详情
appointmentStatus: { type: Number } //父组件传递过来的预约的状态 appointmentStatus: { type: Number }, //父组件传递过来的预约的状态
fatherTabName: { type: String, default: '' }, //一级tab名称
anchorContainer: { type: String, default: '' }, //锚点滚动容器
editStatus: { type: Boolean, default: true }, //编辑状态
tabIndex: { type: [String, Number], default: '' } //tab索引
}) })
const emit = defineEmits(['handleSuccessEdit', 'policyEditSuccess']) const emit = defineEmits(['handleSuccessEdit', 'policyEditSuccess'])
const { proxy } = getCurrentInstance() const { proxy } = getCurrentInstance()
// const { sys_no_yes } = proxy.useDict('sys_no_yes') // const { sys_no_yes } = proxy.useDict('sys_no_yes')
const saveKey = ref({}) // 用于存储当前点击的drawer框返回的对象,修改的时候回显值也要存key const dialogTitle = ref('新增')
const dialogVisible = ref(false)
const productRef = ref(null) // 用于存储当前点击的drawer框返回的对象,修改的时候回显值也要存key
const errorFields = ref([]) // 存储校验失败的字段信息 const errorFields = ref([]) // 存储校验失败的字段信息
const editStatus = ref(true) // 表单是否可编辑,若是修改初始不可编辑 // const anchorList = ref([]) // 存储校验失败的字段信息
// const editStatus = ref(true) // 表单是否可编辑,若是修改初始不可编辑
const openList = ref(false) // 客户列表弹窗 const openList = ref(false) // 客户列表弹窗
const oldObjInfo = ref({}) // 修改时存储原始数据,便于撤销操作 const oldObjInfo = ref({}) // 修改时存储原始数据,便于撤销操作
const currencyType = ref([]) // 是否列表 const currencyType = ref([]) // 是否列表
const searchOptions = ref({}) // 存储不同key对应的选项 const searchOptions = ref({}) // 存储不同key对应的选项
const searchLoadingStates = ref({}) // 存储不同key对应的加载状态 const searchLoadingStates = ref({}) // 存储不同key对应的加载状态
const additionalProductForm = ref([]) // 附加险的表单
const data = reactive({ const data = reactive({
form: {}, form: {},
tempForm: {}, //由于切换tab的时候,表单数据会重置,所以需要保存一份临时表单数据 tempForm: {}, //由于切换tab的时候,表单数据会重置,所以需要保存一份临时表单数据
...@@ -266,46 +276,102 @@ const data = reactive({ ...@@ -266,46 +276,102 @@ const data = reactive({
} }
}) })
const { form, rules, processedProductData, queryParams, oldProductDomData, tempForm } = toRefs(data) const { form, rules, processedProductData, queryParams, oldProductDomData, tempForm } = toRefs(data)
const resetForm = () => { // 添加表单子级dom
proxy.$modal const addChildren = father => {
.confirm('是否确认撤销所作操作?') if (props.editStatus) {
.then(function () { proxy.$message.warning('请先点击编辑')
form.value = { ...oldObjInfo.value } return
editStatus.value = true }
processedProductData.value = JSON.parse(JSON.stringify(oldProductDomData.value)) if (father.key == 'apiProductPlanAdditionalInfoDtoList') {
proxy.$refs['productFormRef'].resetFields() dialogTitle.value = '新增附加计划'
}) additionalProductForm.value = JSON.parse(JSON.stringify(father.formItem))
dialogVisible.value = true
.catch(() => {}) }
} }
const handleSearchSelectChange = (father, child) => { const deleteChildren = (father, childIndex) => {
let productItem = dictStore.insureProductList.filter(item => { if (editStatus.value) {
return item.value == form.value[father.key][child.key] proxy.$message.warning('编辑状态下才能删除')
}) return
let options = productItem[0].paymentTerm.split(',').map(item => {
return {
label: item,
value: item
} }
}) return
const processedData = JSON.parse(JSON.stringify(processedProductData.value)) const processedData = JSON.parse(JSON.stringify(processedProductData.value))
if (
props.idsObj.appointmentBizId &&
form.value[father.key][childIndex].additionalBizId &&
(props.pageSource == 'appointmentList' || props.pageSource == 'fnaList')
) {
delAdditional(form.value[father.key][childIndex].additionalBizId).then(res => {
if (res.code == 200) {
proxy.$message.success('附加险删除成功')
for (const section of processedData) { for (const section of processedData) {
if (section.key == father.key) { if (father.key == 'apiProductPlanAdditionalInfoDtoList' && section.key == father.key) {
if (section.data) { section.data.splice(childIndex, 1)
for (const field of section.data) {
if (field.dictType && field.dictType == 'paymentTerm') {
field.options = options
} }
} }
//更新form表单对应的数据,以便收集填写的值
form.value[father.key].splice(childIndex, 1)
emit('handleSuccessEdit')
} }
})
} else if (
props.idsObj.policyBizId &&
form.value[father.key][childIndex].id &&
props.pageSource == 'policyList'
) {
delPolicyAdditional(form.value[father.key][childIndex].id).then(res => {
if (res.code == 200) {
proxy.$message.success('附加险删除成功')
for (const section of processedData) {
if (father.key == 'apiProductPlanAdditionalInfoDtoList' && section.key == father.key) {
section.data.splice(childIndex, 1)
} }
} }
if (options.length > 0) { //更新form表单对应的数据,以便收集填写的值
form.value[father.key]['paymentTerm'] = options[0].value form.value[father.key].splice(childIndex, 1)
emit('policyEditSuccess')
} }
})
} else {
for (const section of processedData) {
if (father.key == 'apiProductPlanAdditionalInfoDtoList' && section.key == father.key) {
section.data.splice(childIndex, 1)
}
}
//更新form表单对应的数据,以便收集填写的值
form.value[father.key].splice(childIndex, 1)
}
processedProductData.value = processedData processedProductData.value = processedData
} }
const handleSearchSelectChange = (key, index) => {
// 附加计划选择产品后,给供款期数下拉框赋值
if (key == 'productLaunchName') {
additionalProductForm.value.forEach(item => {
searchOptions.value['productLaunchName'].forEach(item1 => {
if (item1.value == additionalProductForm.value[index]['value']) {
item1.apiAttributeSettingDtoList.forEach(item2 => {
if (
item2.attributeSettingBizId == 'attribute_setting_okpcuc8tlXRfVIAy' &&
item.key == 'issueNumber'
) {
if (item2.value) {
item.options = item2.value
.split(/[,,;;\s]+/)
.map(item => item.trim())
.filter(item => item !== '')
.map(item => {
return { label: item, value: item }
})
if (item.options.length > 0) item.value = item.options[0].value
}
}
})
}
})
})
}
}
// 下拉框搜索方法 // 下拉框搜索方法
// 搜索方法 // 搜索方法
const searchSelectList = async (query, fieldKey) => { const searchSelectList = async (query, fieldKey) => {
...@@ -335,20 +401,24 @@ const searchSelectList = async (query, fieldKey) => { ...@@ -335,20 +401,24 @@ const searchSelectList = async (query, fieldKey) => {
} }
} }
// 可以添加其他字段的处理,可以放其他的字段得请求,目前只有accountName,以后有了其他的在填充 // 可以添加其他字段的处理,可以放其他的字段得请求,目前只有accountName,以后有了其他的在填充
else if (fieldKey === 'addProductName') { else if (fieldKey === 'productLaunchName') {
const params = { const params = {
productName: query.trim(), productName: query.trim(),
pageNo: 1, pageNo: 1,
pageSize: 10 pageSize: 10,
projectBizId: userStore.projectInfo.projectBizId,
tenantBizId: userStore.projectInfo.tenantBizId,
fieldBizId: 'field_olk1qZe81qHHKXbw',
fieldValueBizId: 'field_value_yXzTigvgUdRMFpoR'
} }
const response = await getAdditionalProductList(params) const response = await secondAdditonalList(params)
if (response.code == 200) { if (response.code == 200) {
response.data.records = response.data.records.map(item => { response.data.records = response.data.records.map(item => {
return { return {
...item, ...item,
label: item.productName, label: item.title,
value: item.additionalProductBizId value: item.productLaunchBizId
} }
}) })
searchOptions.value[fieldKey] = response.data.records searchOptions.value[fieldKey] = response.data.records
...@@ -383,6 +453,7 @@ const processFormData = async () => { ...@@ -383,6 +453,7 @@ const processFormData = async () => {
const processedData = JSON.parse(JSON.stringify(productDomData)) const processedData = JSON.parse(JSON.stringify(productDomData))
for (const section of processedData) { for (const section of processedData) {
// anchorList.value.push({ title: section.anchorKey, name: section.fatherTitle })
if (section.fatherRequired) { if (section.fatherRequired) {
rules.value[section.key] = {} rules.value[section.key] = {}
} }
...@@ -392,6 +463,13 @@ const processFormData = async () => { ...@@ -392,6 +463,13 @@ const processFormData = async () => {
} else if (section.keyType == 'Object') { } else if (section.keyType == 'Object') {
form.value[section.key] = {} form.value[section.key] = {}
} }
if (section.formItem) {
section.formItem.forEach(item => {
if (item.dictType) {
item.options = fetchDictData(item.dictType)
}
})
}
if (section.data) { if (section.data) {
for (const formKey in form.value) { for (const formKey in form.value) {
if (section.key == formKey) { if (section.key == formKey) {
...@@ -430,7 +508,7 @@ const processFormData = async () => { ...@@ -430,7 +508,7 @@ const processFormData = async () => {
/* /*
1.没有嵌套子级的也就是没有children的数据加rules,根据data中的required字段判断是否必填 1.没有嵌套子级的也就是没有children的数据加rules,根据data中的required字段判断是否必填
*/ */
if (field.required && section.child == 'no') { if (field.required) {
rules.value[section.key][field.key] = [ rules.value[section.key][field.key] = [
{ required: true, message: `${field.label}不能为空`, trigger: 'blur' } { required: true, message: `${field.label}不能为空`, trigger: 'blur' }
] ]
...@@ -470,218 +548,16 @@ const processFormData = async () => { ...@@ -470,218 +548,16 @@ const processFormData = async () => {
// idsObj.appointmentBizId // idsObj.appointmentBizId
// 证明是修改 // 证明是修改
if (props.showSubmitBtn) { if (props.showSubmitBtn) {
editStatus.value = true // editStatus.value = true
// processedProductData.value = processedData // processedProductData.value = processedData
//在流程和预约的时候要调用这个方法回显修改数据 //在流程和预约的时候要调用这个方法回显修改数据
console.log('====================================')
console.log('props.apiProductPlanInfoDto', props.apiProductPlanInfoDto)
console.log('====================================')
setFormValue(props.apiProductPlanInfoDto, processedData) setFormValue(props.apiProductPlanInfoDto, processedData)
} else { } else {
editStatus.value = false // editStatus.value = false
processedProductData.value = processedData processedProductData.value = processedData
} }
} }
// 添加表单子级dom
const addChildren = father => {
if (editStatus.value) {
proxy.$message.warning('请先点击编辑')
return
}
const processedData = JSON.parse(JSON.stringify(processedProductData.value))
let obj = {
// id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识
span: 24, //栅格布局份数
childTitle: '附加险',
deleteBtn: true,
children: [
{
label: '产品名称',
key: 'addProductName',
domType: 'SearchSelect',
required: true,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数
labelPosition: 'top', //标签的位置
lg: 8 //栅格布局份数
},
{
label: '保额',
key: 'sumInsured',
domType: 'Input',
inputType: 'number',
required: true,
maxLength: 300,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '保费',
key: 'premium',
domType: 'Input',
inputType: 'number',
required: true,
maxLength: 300,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '保障地区',
key: 'guaranteeRegion',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 300,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '货币',
key: 'currency',
domType: 'Select',
inputType: 'text',
required: false,
maxLength: 300,
disabled: false,
placeholder: '请输入',
show: true,
dictType: 'bx_currency_type',
options: fetchDictData('bx_currency_type'),
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '等级',
key: 'insuranceType',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 300,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '自付额',
key: 'deductibles',
domType: 'Input',
inputType: 'number',
required: false,
maxLength: 300,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '附加保障',
key: 'additionalSafeguards',
domType: 'Input',
inputType: 'textarea',
required: false,
maxLength: 300,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 24, //栅格布局份数
lg: 24 //栅格布局份数
}
]
}
for (const section of processedData) {
if (father.key == 'apiProductPlanAdditionalInfoDtoList' && section.key == father.key) {
section.data.push(obj)
}
}
//更新form表单对应的数据,以便收集填写的值
form.value[father.key].push(obj)
processedProductData.value = processedData
}
const deleteChildren = (father, childIndex) => {
if (editStatus.value) {
proxy.$message.warning('编辑状态下才能删除')
return
}
const processedData = JSON.parse(JSON.stringify(processedProductData.value))
if (
props.idsObj.appointmentBizId &&
form.value[father.key][childIndex].additionalBizId &&
(props.pageSource == 'appointmentList' || props.pageSource == 'fnaList')
) {
delAdditional(form.value[father.key][childIndex].additionalBizId).then(res => {
if (res.code == 200) {
proxy.$message.success('附加险删除成功')
for (const section of processedData) {
if (father.key == 'apiProductPlanAdditionalInfoDtoList' && section.key == father.key) {
section.data.splice(childIndex, 1)
}
}
//更新form表单对应的数据,以便收集填写的值
form.value[father.key].splice(childIndex, 1)
emit('handleSuccessEdit')
}
})
} else if (
props.idsObj.policyBizId &&
form.value[father.key][childIndex].id &&
props.pageSource == 'policyList'
) {
delPolicyAdditional(form.value[father.key][childIndex].id).then(res => {
if (res.code == 200) {
proxy.$message.success('附加险删除成功')
for (const section of processedData) {
if (father.key == 'apiProductPlanAdditionalInfoDtoList' && section.key == father.key) {
section.data.splice(childIndex, 1)
}
}
//更新form表单对应的数据,以便收集填写的值
form.value[father.key].splice(childIndex, 1)
emit('policyEditSuccess')
}
})
} else {
for (const section of processedData) {
if (father.key == 'apiProductPlanAdditionalInfoDtoList' && section.key == father.key) {
section.data.splice(childIndex, 1)
}
}
//更新form表单对应的数据,以便收集填写的值
form.value[father.key].splice(childIndex, 1)
}
processedProductData.value = processedData
}
// 根据联动重置表单项的显示与否 // 根据联动重置表单项的显示与否
const resetShow = (childKey, status) => { const resetShow = (childKey, status) => {
console.log(childKey, status) console.log(childKey, status)
...@@ -1073,16 +949,32 @@ const submitForm = saveType => { ...@@ -1073,16 +949,32 @@ const submitForm = saveType => {
} }
}) })
} }
const anchorList = computed(() => {
let data = []
for (const section of processedProductData.value) {
if (section.showMoudle) {
data.push({ title: section.anchorKey, name: section.fatherTitle })
}
}
return data
})
// 因为tab嵌套了两层,所以需要监听父组件的tab否则锚点的显示就会有bug
watch(
() => props.fatherTabName,
newVal => {
if (newVal) {
productRef.value = null
}
}
)
watch( watch(
() => props.activeName, () => props.activeName,
newVal => { newVal => {
productRef.value = null
tempForm.value = { ...form.value } tempForm.value = { ...form.value }
if (newVal === 'productPlan') { if (newVal === 'productPlan') {
openList.value = false openList.value = false
setTimeout(() => {
processFormData() processFormData()
}, 500)
} }
} }
) )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment