Commit ec72c02e by yuzhenWang

提交新单跟进详情到测试

parent 4b7adae7
...@@ -79,3 +79,19 @@ export function getAdditionalProductList(data) { ...@@ -79,3 +79,19 @@ export function getAdditionalProductList(data) {
data: data data: data
}) })
} }
//获取保险公司列表
export function getAllCompanys(data) {
return request({
url: '/user/api/sysDept/company/page',
method: 'post',
data: data
})
}
//获取转介人列表
export function getClientUser(data) {
return request({
url: '/user/api/clientUser/page',
method: 'post',
data: data
})
}
...@@ -27,3 +27,49 @@ export function updateToPolicyLib(data) { ...@@ -27,3 +27,49 @@ export function updateToPolicyLib(data) {
data: data data: data
}) })
} }
// 更新新单跟进
export function updatePolicyfollow(data) {
return request({
url: '/csf/api/policy_follow/update',
method: 'post',
data: data
})
}
// 获取新单跟进详情
export function getPolicyfollow(policyBizId) {
return request({
url: `/csf/api/policy_follow/get/vo?policyBizId=${policyBizId}`,
method: 'get'
})
}
// 获取新单跟进状态
export function getPolicyStatus(policyBizId) {
return request({
url: `/csf/api/policy_follow/status/list?policyBizId=${policyBizId}`,
method: 'get'
})
}
// 新单跟进附件列表
export function getAttachmentList(data) {
return request({
url: '/csf/api/policy_follow/attachment/list/page',
method: 'post',
data: data
})
}
// 删除单个新单跟进附件
export function delAttachmentFile(fileId) {
return request({
url: '/csf/api/policy_follow/attachment/delete?fileId=' + fileId,
method: 'delete'
})
}
// 上传新单跟进附件
export function uploadPolicyfollow(data) {
return request({
url: '/csf/api/policy_follow/attachment/upload',
method: 'post',
data: data
})
}
...@@ -161,7 +161,7 @@ const appointmentInfo = [ ...@@ -161,7 +161,7 @@ const appointmentInfo = [
}, },
{ {
label: '顾问是否陪同', label: '转介人是否陪同',
key: 'isAccompany', key: 'isAccompany',
domType: 'Select', domType: 'Select',
required: false, required: false,
...@@ -192,7 +192,7 @@ const appointmentInfo = [ ...@@ -192,7 +192,7 @@ const appointmentInfo = [
}, },
// 陪同顾问信息 // 陪同顾问信息
{ {
fatherTitle: '陪同顾问信息', fatherTitle: '转介人信息',
type: 'object', type: 'object',
key: 'consult', key: 'consult',
showMoudle: false, //模块是否展示 showMoudle: false, //模块是否展示
...@@ -394,9 +394,9 @@ const appointmentInfo = [ ...@@ -394,9 +394,9 @@ const appointmentInfo = [
label: '开户时间段(开始)', label: '开户时间段(开始)',
key: 'openAccountStartTime', key: 'openAccountStartTime',
domType: 'datetimePicker', domType: 'datetimePicker',
timeType:'date', timeType: 'date',
required: false, required: false,
disabled: true, disabled: false,
placeholder: '请选择', placeholder: '请选择',
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
...@@ -409,7 +409,7 @@ const appointmentInfo = [ ...@@ -409,7 +409,7 @@ const appointmentInfo = [
key: 'openAccountEndTime', key: 'openAccountEndTime',
domType: 'datetimePicker', domType: 'datetimePicker',
required: false, required: false,
disabled: true, disabled: false,
placeholder: '请选择', placeholder: '请选择',
show: true, show: true,
labelPosition: 'top', //标签的位置 labelPosition: 'top', //标签的位置
......
const brokerInfo = [
// 转介人信息
{
fatherTitle: '转介人信息',
keyType: 'Array', //用于表单收集值时,判断是数组还是对象
showTable: true, //以table的形式展示
key: 'brokerList',
addFamilyChildren: true, //是否可以新增子级dom
fatherRequired: false, //父级必填,代表个人资料这个模块有必填项
data: [
// {
// id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识
// brokerName: '',
// team: '',
// brokerRatio: '',
// remark: ''
// }
]
}
]
export default brokerInfo
const policyFallow = [
// 保单信息
{
fatherTitle: '保单信息',
keyType: 'Object', //用于表单收集值时,判断是数组还是对象
key: 'policyFollowUpdateDto',
child: 'no', //没有子级dom,直接展示
fatherrequired: false, //父级必填,代表个人资料这个模块有必填项
data: [
{
label: '客户姓名',
key: 'customerName',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '客户编号',
key: 'customerBizId',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '140px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '保单号',
key: 'policyNo',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '130px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '签单日期',
key: 'signDate',
domType: 'DatePicker',
required: false,
disabled: false,
placeholder: '请选择',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '签单人',
key: 'signer',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '130px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '生效日期',
key: 'effectiveDate',
domType: 'DatePicker',
required: false,
disabled: false,
placeholder: '请选择',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '续保日期',
key: 'renewalDate',
domType: 'DatePicker',
required: false,
disabled: false,
placeholder: '请选择',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '产品名称',
key: 'productName',
domType: 'SearchSelect',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
labelPosition: 'top', //标签的位置
lg: 8 //栅格布局份数
},
{
label: '产品类别',
key: 'productCate',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '130px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '供款年期',
key: 'paymentTerm',
domType: 'Select',
required: false,
disabled: false,
placeholder: '请选择',
dictType: 'paymentTerm',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '期交保费',
key: 'paymentPremium',
domType: 'Input',
inputType: 'number',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '是否预缴',
key: 'isPrepaid',
domType: 'Select',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
dictType: 'sys_no_yes',
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '预缴年期',
key: 'prepaidTerm',
domType: 'Input',
inputType: 'number',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '保险公司',
key: 'insurer',
domType: 'SearchSelect',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
labelPosition: 'top', //标签的位置
lg: 8 //栅格布局份数
},
{
label: '对账公司',
key: 'reconciliationCompany',
domType: 'SearchSelect',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
labelPosition: 'top', //标签的位置
lg: 8 //栅格布局份数
},
{
label: '保单持有人',
key: 'policyHolder',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '受保人',
key: 'insured',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '币种',
key: 'currency',
domType: 'Select',
required: false,
disabled: false,
placeholder: '请选择',
dictType: 'bx_currency_type',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '首期保费',
key: 'initialPremium',
domType: 'Input',
inputType: 'number',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '备注',
key: 'remark',
domType: 'Input',
inputType: 'textarea',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 24, //栅格布局份数
lg: 24 //栅格布局份数
}
]
},
// 转介人信息
{
fatherTitle: '转介人信息',
keyType: 'Array', //用于表单收集值时,判断是数组还是对象
showTable: true, //以table的形式展示
key: 'brokerList',
addFamilyChildren: true, //是否可以新增子级dom
fatherRequired: false, //父级必填,代表个人资料这个模块有必填项
data: [
// {
// id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识
// brokerName: '',
// team: '',
// brokerRatio: '',
// remark: ''
// }
]
},
// 核保信息
{
fatherTitle: '核保信息',
keyType: 'Object', //用于表单收集值时,判断是数组还是对象
key: 'verifyPolicyInfo',
child: 'no', //没有子级dom,直接展示
fatherrequired: false, //父级必填,代表个人资料这个模块有必填项
data: [
{
label: '保险种类',
key: 'productCate',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '签单日期',
key: 'signDate',
domType: 'DatePicker',
required: false,
disabled: false,
placeholder: '请选择',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '递交日期',
key: 'submitDate',
domType: 'DatePicker',
required: false,
disabled: false,
placeholder: '请选择',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '缮发日期',
key: 'issueDate',
domType: 'DatePicker',
required: false,
disabled: false,
placeholder: '请选择',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '保单生效日',
key: 'effectiveDate',
domType: 'DatePicker',
required: false,
disabled: false,
placeholder: '请选择',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '保单截止日期',
key: 'policyExpirationDate',
domType: 'DatePicker',
required: false,
disabled: false,
placeholder: '请选择',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '是否预缴',
key: 'isPrepaid',
domType: 'Select',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
dictType: 'sys_no_yes',
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '预付额',
key: 'prepaidAmount',
domType: 'Input',
inputType: 'number',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '140px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '折扣后预付额',
key: 'prepaidAmountAfterDiscount',
domType: 'Input',
inputType: 'number',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '130px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '缴费编号',
key: 'paymentNumber',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '130px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
}
]
},
// 保单邮寄
{
fatherTitle: '保单邮寄',
keyType: 'Object', //用于表单收集值时,判断是数组还是对象
key: 'policyMailing',
child: 'no', //没有子级dom,直接展示
fatherrequired: false, //父级必填,代表个人资料这个模块有必填项
data: [
{
label: '寄送方式',
key: 'productCate',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '经纪公司签收日期',
key: 'brokerSignDate',
domType: 'DatePicker',
required: false,
disabled: false,
placeholder: '请选择',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '保险公司寄出日期',
key: 'insurerMailingDate',
domType: 'DatePicker',
required: false,
disabled: false,
placeholder: '请选择',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '客户签收日期',
key: 'customerSignDate',
domType: 'DatePicker',
required: false,
disabled: false,
placeholder: '请选择',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
}
]
}
]
export default policyFallow
const policyInfo = [
// 保单信息
{
fatherTitle: '保单信息',
keyType: 'Object', //用于表单收集值时,判断是数组还是对象
key: 'policyFollowUpdateDto',
child: 'no', //没有子级dom,直接展示
fatherrequired: false, //父级必填,代表个人资料这个模块有必填项
data: [
{
label: '客户姓名',
key: 'customerName',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
value: '',
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '客户编号',
key: 'customerBizId',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
value: '',
labelPosition: 'top', //标签的位置
labelWidth: '140px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '保单号',
key: 'policyNo',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
value: '',
labelPosition: 'top', //标签的位置
labelWidth: '130px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '签单日期',
key: 'signDate',
domType: 'DatePicker',
required: false,
disabled: false,
placeholder: '请选择',
show: true,
value: '',
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '签单人',
key: 'signer',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
value: '',
labelPosition: 'top', //标签的位置
labelWidth: '130px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '生效日期',
key: 'effectiveDate',
domType: 'DatePicker',
required: false,
disabled: false,
placeholder: '请选择',
show: true,
value: '',
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '续保日期',
key: 'renewalDate',
domType: 'DatePicker',
required: false,
disabled: false,
placeholder: '请选择',
show: true,
value: '',
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '产品名称',
key: 'productName',
domType: 'SearchSelect',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
value: '',
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
labelPosition: 'top', //标签的位置
lg: 8 //栅格布局份数
},
{
label: '产品类别',
key: 'productCate',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
value: '',
labelPosition: 'top', //标签的位置
labelWidth: '130px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '供款年期',
key: 'paymentTerm',
domType: 'Select',
required: false,
disabled: false,
placeholder: '请选择',
dictType: 'paymentTerm',
show: true,
value: '',
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '期交保费',
key: 'paymentPremium',
domType: 'Input',
inputType: 'number',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
value: '',
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '是否预缴',
key: 'isPrepaid',
domType: 'Select',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
value: '',
dictType: 'sys_no_yes',
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '预缴年期',
key: 'prepaidTerm',
domType: 'Input',
inputType: 'number',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
value: '',
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '保险公司',
key: 'insurer',
domType: 'SearchSelect',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
value: '',
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
labelPosition: 'top', //标签的位置
lg: 8 //栅格布局份数
},
{
label: '对账公司',
key: 'reconciliationCompany',
domType: 'SearchSelect',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
value: '',
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
labelPosition: 'top', //标签的位置
lg: 8 //栅格布局份数
},
{
label: '保单持有人',
key: 'policyHolder',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
value: '',
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '受保人',
key: 'insured',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
value: '',
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '币种',
key: 'currency',
domType: 'Select',
required: false,
disabled: false,
placeholder: '请选择',
dictType: 'bx_currency_type',
show: true,
value: '',
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '首期保费',
key: 'initialPremium',
domType: 'Input',
inputType: 'number',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
value: '',
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '备注',
key: 'remark',
domType: 'Input',
inputType: 'textarea',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
value: '',
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 24, //栅格布局份数
lg: 24 //栅格布局份数
}
]
}
]
export default policyInfo
const policyMailing = [
// 保单邮寄
{
fatherTitle: '保单邮寄',
keyType: 'Object', //用于表单收集值时,判断是数组还是对象
key: 'policyMailing',
child: 'no', //没有子级dom,直接展示
fatherrequired: false, //父级必填,代表个人资料这个模块有必填项
data: [
{
label: '寄送方式',
key: 'productCate',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '经纪公司签收日期',
key: 'brokerSignDate',
domType: 'DatePicker',
required: false,
disabled: false,
placeholder: '请选择',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '保险公司寄出日期',
key: 'insurerMailingDate',
domType: 'DatePicker',
required: false,
disabled: false,
placeholder: '请选择',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '客户签收日期',
key: 'customerSignDate',
domType: 'DatePicker',
required: false,
disabled: false,
placeholder: '请选择',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
}
]
}
]
export default policyMailing
const verifyPolicyInfo = [
// 核保信息
{
fatherTitle: '核保信息',
keyType: 'Object', //用于表单收集值时,判断是数组还是对象
key: 'verifyPolicyInfo',
child: 'no', //没有子级dom,直接展示
fatherrequired: false, //父级必填,代表个人资料这个模块有必填项
data: [
{
label: '保险种类',
key: 'productCate',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '签单日期',
key: 'signDate',
domType: 'DatePicker',
required: false,
disabled: false,
placeholder: '请选择',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '递交日期',
key: 'submitDate',
domType: 'DatePicker',
required: false,
disabled: false,
placeholder: '请选择',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '缮发日期',
key: 'issueDate',
domType: 'DatePicker',
required: false,
disabled: false,
placeholder: '请选择',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '保单生效日',
key: 'effectiveDate',
domType: 'DatePicker',
required: false,
disabled: false,
placeholder: '请选择',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '保单截止日期',
key: 'policyExpirationDate',
domType: 'DatePicker',
required: false,
disabled: false,
placeholder: '请选择',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '是否预缴',
key: 'isPrepaid',
domType: 'Select',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
dictType: 'sys_no_yes',
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '预付额',
key: 'prepaidAmount',
domType: 'Input',
inputType: 'number',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '140px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '折扣后预付额',
key: 'prepaidAmountAfterDiscount',
domType: 'Input',
inputType: 'number',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '130px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '缴费编号',
key: 'paymentNumber',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '130px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
}
]
}
]
export default verifyPolicyInfo
...@@ -4,6 +4,8 @@ const useDictStore = defineStore('dict', { ...@@ -4,6 +4,8 @@ const useDictStore = defineStore('dict', {
tenantUserList: [], //租户用户数据 tenantUserList: [], //租户用户数据
insureProductList: [], //保险产品数据 insureProductList: [], //保险产品数据
additionalProductList: [], //附加险产品数据 additionalProductList: [], //附加险产品数据
insureCompanyList: [], //保险公司数据
clientUserList: [], //用户数据,转介人
dictTypeLists: [] //字典列表,根据请求得不同会变化,所以使用之前需要使用useDictLists请求数据 dictTypeLists: [] //字典列表,根据请求得不同会变化,所以使用之前需要使用useDictLists请求数据
}), }),
actions: { actions: {
...@@ -64,6 +66,14 @@ const useDictStore = defineStore('dict', { ...@@ -64,6 +66,14 @@ const useDictStore = defineStore('dict', {
setAdditionalProductList(product) { setAdditionalProductList(product) {
this.additionalProductList = product this.additionalProductList = product
}, },
// 设置保险公司列表
setInsureCompanyList(company) {
this.insureCompanyList = company
},
// 设置用户列表
setClientUserList(user) {
this.clientUserList = user
},
// 设置字典列表 // 设置字典列表
setDictTypeLists(typeList) { setDictTypeLists(typeList) {
this.dictTypeLists = typeList this.dictTypeLists = typeList
......
...@@ -117,6 +117,7 @@ ...@@ -117,6 +117,7 @@
:tabName="activeName" :tabName="activeName"
:processDetail="processInfo" :processDetail="processInfo"
@handleSuccess="handleSuccess" @handleSuccess="handleSuccess"
source="fnaList"
/> />
</div> </div>
<div v-if="tab.name === 'newpolicy'">关联新单内容</div> <div v-if="tab.name === 'newpolicy'">关联新单内容</div>
......
...@@ -291,7 +291,7 @@ function handleAdd() { ...@@ -291,7 +291,7 @@ function handleAdd() {
function handleUpdate(row) { function handleUpdate(row) {
router.push({ router.push({
path: '/sign/FnaList/edit', path: '/sign/FnaList/edit',
query: { fnaBizId: row.fnaBizId, type: 'edit', status: row.status } query: { fnaBizId: row.fnaBizId, type: 'edit', status: row.status, source:'fnaList'}
}) })
} }
......
...@@ -2,18 +2,14 @@ ...@@ -2,18 +2,14 @@
<div <div
class="appointment-container" class="appointment-container"
:class="{ :class="{
'noembed-container': !embed, 'noembed-container': !isEmbed
'embed-container': embed }"
:style="{
minHight
}" }"
> >
<!-- <div v-if="!embed">
<el-button type="primary" icon="Back" @click="handleBack" style="margin-bottom: 10px"
>返回</el-button
>
</div> -->
<el-card shadow="never"> <el-card shadow="never">
<div class="cardHeader" v-if="!embed"> <div class="cardHeader" v-if="!isEmbed">
<div class="left"> <div class="left">
<img class="iconBox" src="@/assets/images/icon1.png" alt="" /> <img class="iconBox" src="@/assets/images/icon1.png" alt="" />
<div class="rightBox"> <div class="rightBox">
...@@ -45,23 +41,28 @@ ...@@ -45,23 +41,28 @@
</div> </div>
</div> </div>
<div class="tabsBox"> <div class="tabsBox">
<el-row v-if="embed"> <el-row v-if="isEmbed">
<el-col> <el-col>
<div class="topButtonBox"> <div class="topButtonBox">
<!-- -->
<el-button <el-button
v-if="idsObj.appointmentBizId" 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 type="success" :icon="Check" @click="handleSubmit('submit')" <el-button
v-if="pageSource !== 'policyList'"
type="success"
:icon="Check"
@click="handleSubmit('submit')"
>提交</el-button >提交</el-button
> >
<el-button <el-button
type="primary" type="primary"
plain plain
v-if="!idsObj.appointmentBizId" v-if="!idsObj.appointmentBizId && source == 'fnaList'"
@click="handleSubmit('storage')" @click="handleSubmit('storage')"
>暂存</el-button >暂存</el-button
> >
...@@ -72,7 +73,9 @@ ...@@ -72,7 +73,9 @@
<el-tab-pane v-for="tab in tabsList" :key="tab.name" :label="tab.label" :name="tab.name"> <el-tab-pane v-for="tab in tabsList" :key="tab.name" :label="tab.label" :name="tab.name">
<div <div
class="appointmentTabPaneBox" class="appointmentTabPaneBox"
:class="{ yesEmbedTabPaneBox: embed, noEmbedTabPaneBox: !embed }" :style="{
height: tabHight
}"
> >
<div v-if="tab.name === 'appointmentInfo'"> <div v-if="tab.name === 'appointmentInfo'">
<AppointmentInfo <AppointmentInfo
...@@ -95,6 +98,8 @@ ...@@ -95,6 +98,8 @@
:appointmentStatus="appointmentSummeryInfo.status" :appointmentStatus="appointmentSummeryInfo.status"
@handleSuccessEdit="getAppointmentInfo(idsObj.appointmentBizId)" @handleSuccessEdit="getAppointmentInfo(idsObj.appointmentBizId)"
ref="productPlanRef" ref="productPlanRef"
:pageSource="pageSource"
:showSubmitBtn="showSubmitBtn"
/> />
</div> </div>
<div v-if="tab.name === 'policyholder'"> <div v-if="tab.name === 'policyholder'">
...@@ -107,6 +112,7 @@ ...@@ -107,6 +112,7 @@
:appointmentStatus="appointmentSummeryInfo.status" :appointmentStatus="appointmentSummeryInfo.status"
@handleSuccessEdit="getAppointmentInfo(idsObj.appointmentBizId)" @handleSuccessEdit="getAppointmentInfo(idsObj.appointmentBizId)"
ref="policyHolderInfoRef" ref="policyHolderInfoRef"
:pageSource="pageSource"
/> />
</div> </div>
<div v-if="tab.name === 'insurantInfo'"> <div v-if="tab.name === 'insurantInfo'">
...@@ -119,6 +125,7 @@ ...@@ -119,6 +125,7 @@
:appointmentStatus="appointmentSummeryInfo.status" :appointmentStatus="appointmentSummeryInfo.status"
@handleSuccessEdit="getAppointmentInfo(idsObj.appointmentBizId)" @handleSuccessEdit="getAppointmentInfo(idsObj.appointmentBizId)"
ref="insuredInfoRef" ref="insuredInfoRef"
:pageSource="pageSource"
/> />
</div> </div>
<div v-if="tab.name === 'secondHolder'"> <div v-if="tab.name === 'secondHolder'">
...@@ -131,6 +138,7 @@ ...@@ -131,6 +138,7 @@
:customerInfo="customerInfo" :customerInfo="customerInfo"
@handleSuccessEdit="getAppointmentInfo(idsObj.appointmentBizId)" @handleSuccessEdit="getAppointmentInfo(idsObj.appointmentBizId)"
ref="secondHolderInfoRef" ref="secondHolderInfoRef"
:pageSource="pageSource"
/> />
</div> </div>
<div v-if="tab.name === 'beneficiary'"> <div v-if="tab.name === 'beneficiary'">
...@@ -142,6 +150,7 @@ ...@@ -142,6 +150,7 @@
:appointmentStatus="appointmentSummeryInfo.status" :appointmentStatus="appointmentSummeryInfo.status"
@handleSuccessEdit="getAppointmentInfo(idsObj.appointmentBizId)" @handleSuccessEdit="getAppointmentInfo(idsObj.appointmentBizId)"
ref="beneficiaryInfoRef" ref="beneficiaryInfoRef"
:pageSource="pageSource"
/> />
</div> </div>
<div v-if="tab.name === 'questionnaires'"> <div v-if="tab.name === 'questionnaires'">
...@@ -152,6 +161,7 @@ ...@@ -152,6 +161,7 @@
:appointmentStatus="appointmentSummeryInfo.status" :appointmentStatus="appointmentSummeryInfo.status"
@handleSuccessEdit="getAppointmentInfo(idsObj.appointmentBizId)" @handleSuccessEdit="getAppointmentInfo(idsObj.appointmentBizId)"
ref="questionnairesInfoRef" ref="questionnairesInfoRef"
:pageSource="pageSource"
/> />
</div> </div>
<div v-if="tab.name === 'fna'"> <div v-if="tab.name === 'fna'">
...@@ -160,6 +170,7 @@ ...@@ -160,6 +170,7 @@
:formStatus="formStatus" :formStatus="formStatus"
:idsObj="idsObj" :idsObj="idsObj"
@handleSuccessEdit="getAppointmentInfo(idsObj.appointmentBizId)" @handleSuccessEdit="getAppointmentInfo(idsObj.appointmentBizId)"
:pageSource="pageSource"
/> />
</div> </div>
<div v-if="tab.name === 'policyTransfer'"> <div v-if="tab.name === 'policyTransfer'">
...@@ -170,6 +181,7 @@ ...@@ -170,6 +181,7 @@
:apiAppointmentInfoDto="appointmentSummeryInfo.apiAppointmentInfoDto" :apiAppointmentInfoDto="appointmentSummeryInfo.apiAppointmentInfoDto"
@handleSuccessEdit="getAppointmentInfo(idsObj.appointmentBizId)" @handleSuccessEdit="getAppointmentInfo(idsObj.appointmentBizId)"
ref="policyTransferRef" ref="policyTransferRef"
:pageSource="pageSource"
/> />
</div> </div>
<div v-if="tab.name === 'accessories'"> <div v-if="tab.name === 'accessories'">
...@@ -179,8 +191,25 @@ ...@@ -179,8 +191,25 @@
:idsObj="idsObj" :idsObj="idsObj"
:apiAppointmentInfoDto="appointmentSummeryInfo.apiAppointmentInfoDto" :apiAppointmentInfoDto="appointmentSummeryInfo.apiAppointmentInfoDto"
@handleSuccessEdit="getAppointmentInfo(idsObj.appointmentBizId)" @handleSuccessEdit="getAppointmentInfo(idsObj.appointmentBizId)"
:pageSource="pageSource"
/> />
</div> </div>
<div v-if="tab.name === 'policyInfo'">
<PolicyInfo :activeName="activeName" :policyBizId="route.query.policyBizId" />
</div>
<div v-if="tab.name === 'policyAccessories'">
<PolicyFileUpload :activeName="activeName" :policyBizId="route.query.policyBizId" />
</div>
<div v-if="tab.name === 'policyBroker'">
<PolicyBrokerInfo :activeName="activeName" :policyBizId="route.query.policyBizId" />
</div>
<div v-if="tab.name === 'policyMailing'">
<PolicyMailing :activeName="activeName" :policyBizId="route.query.policyBizId" />
</div>
<div v-if="tab.name === 'newpolicyTodo'">新单事项</div>
<div v-if="tab.name === 'verifyPolicyInfo'">
<VerifyPolicyInfo :activeName="activeName" :policyBizId="route.query.policyBizId" />
</div>
</div> </div>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
...@@ -229,6 +258,11 @@ import FnaInfo from './components/fnaInfo.vue' ...@@ -229,6 +258,11 @@ import FnaInfo from './components/fnaInfo.vue'
import PolicyTransferInfo from './components/policyTransferInfo.vue' 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 PolicyFileUpload from '@/views/sign/underwritingMain/components/fileUpload.vue' //新单跟进里的保单附件
import PolicyBrokerInfo from '@/views/sign/underwritingMain/components/brokerInfo.vue' //新单跟进里的保单附件
import PolicyMailing from '@/views/sign/underwritingMain/components/policyMailing.vue' //新单跟进里的保单附件
import VerifyPolicyInfo from '@/views/sign/underwritingMain/components/verifyPolicyInfo.vue' //新单跟进里的保单附件
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 { getCustomerDetail } from '@/api/sign/fna' import { getCustomerDetail } from '@/api/sign/fna'
...@@ -249,9 +283,13 @@ const { proxy } = getCurrentInstance() ...@@ -249,9 +283,13 @@ const { proxy } = getCurrentInstance()
const props = defineProps({ const props = defineProps({
embed: { type: Boolean, default: false }, //作为组件嵌入别的地方 embed: { type: Boolean, default: false }, //作为组件嵌入别的地方
editStatus: { type: String, default: '' }, //作为组件嵌入别的地方 editStatus: { type: String, default: '' }, //作为组件嵌入别的地方
source: { type: String, default: '' }, //页面来源,不一样的页面会有不一样的操作
tabName: { type: String, default: '' }, //父组件的tab名称 tabName: { type: String, default: '' }, //父组件的tab名称
processDetail: { type: Object, default: () => ({}) } //新增预约单时,传入的流程详情信息 processDetail: { type: Object, default: () => ({}) }, //新增预约单时,传入的流程详情信息
policyDetailInfo: { type: Object, default: () => ({}) } //新单跟进传递的参数
}) })
console.log('props', props.policyDetailInfo)
const userStore = useUserStore() const userStore = useUserStore()
const dictStore = useDictStore() const dictStore = useDictStore()
const showStorage = ref(false) const showStorage = ref(false)
...@@ -280,6 +318,7 @@ const processInfo = ref({ ...@@ -280,6 +318,7 @@ const processInfo = ref({
customerName: userStore.name customerName: userStore.name
}) })
const execlDialog = ref(false) const execlDialog = ref(false)
const isEmbed = ref(false) //是否作为组件插入
const tabsList = ref([ const tabsList = ref([
{ {
...@@ -324,7 +363,7 @@ const tabsList = ref([ ...@@ -324,7 +363,7 @@ const tabsList = ref([
key: 'secondHolderBizId' key: 'secondHolderBizId'
}, },
{ {
label: '健康信息', //后端还没加这个字段 label: '健康信息',
name: 'questionnaires', name: 'questionnaires',
id: 7, id: 7,
status: '0', status: '0',
...@@ -726,14 +765,35 @@ const handleSubmit = type => { ...@@ -726,14 +765,35 @@ const handleSubmit = type => {
} }
//修改预约数据 //修改预约数据
if (route.query.appointmentNo) { if (route.query.appointmentNo && route.query.source == 'appointmentList') {
processInfo.value = route.query processInfo.value = route.query
idsObj.value.appointmentBizId = route.query.appointmentBizId idsObj.value.appointmentBizId = route.query.appointmentBizId
getDictsData() getDictsData()
// 请求预约单聚合详情 // 请求预约单聚合详情
getAppointmentInfo(idsObj.value.appointmentBizId, true) getAppointmentInfo(idsObj.value.appointmentBizId, true)
} }
const pageSource = computed(() => {
return props.source || route.query.source
})
const tabHight = computed(() => {
if (pageSource.value == 'fnaList') {
return 'calc(100vh - 407px)'
} else if (pageSource.value == 'policyList') {
return 'calc(100vh - 230px)'
} else {
return 'calc(100vh - 276px)'
}
})
const minHight = computed(() => {
if (pageSource.value == 'fnaList') {
return 'calc(100vh - 84.5px)'
} else if (pageSource.value == 'policyList') {
return 'calc(100vh - 84.5px)'
} else {
return 'calc(100vh - 325px)'
}
})
// 预约作为组件在别的地放提交成功后processDetail会改变,所以需要监听 // 预约作为组件在别的地放提交成功后processDetail会改变,所以需要监听
watch( watch(
() => props.processDetail, () => props.processDetail,
...@@ -741,12 +801,12 @@ watch( ...@@ -741,12 +801,12 @@ watch(
idsObj.value = { ...newVal } idsObj.value = { ...newVal }
} }
) )
// 嵌入到了流程详情页面,所以需要监听流程详情的tabName
watch( watch(
() => props.tabName, () => props.tabName,
newVal => { newVal => {
if (newVal === 'appointment') { if (newVal === 'appointment') {
// 这个页面作为组件在别的地方使用,所以需要判断是新增还是编辑 isEmbed.value = props.embed
//props.editStatus == 'add'
//代表是新增预约状态 //代表是新增预约状态
if (!idsObj.value.appointmentBizId) { if (!idsObj.value.appointmentBizId) {
formStatus.value = 'appointmentAdd' formStatus.value = 'appointmentAdd'
...@@ -879,7 +939,128 @@ watch( ...@@ -879,7 +939,128 @@ watch(
} }
} }
) )
if (route.query.source == 'policyList') {
idsObj.value.policyBizId = route.query.policyBizId
// idsObj.value.appointmentNo = route.query.appointmentNo
// idsObj.value.appointmentBizId = route.query.appointmentBizId
isEmbed.value = route.query.embed
tabsList.value = [
{
label: '保单信息',
name: 'policyInfo',
id: 1,
key: 'policyInfo'
},
{
label: '保单附件',
name: 'policyAccessories',
id: 2,
key: 'policyAccessories'
},
{
label: '转介人',
name: 'policyBroker',
id: 3,
key: 'policyBroker'
},
{
label: '邮寄信息',
name: 'policyMailing',
id: 4,
key: 'policyMailing'
},
{
label: '核保信息',
name: 'verifyPolicyInfo',
id: 5,
key: 'verifyPolicyInfo'
},
{
label: '新单事项',
name: 'newpolicyTodo',
id: 6,
key: 'newpolicyTodo'
},
{
label: '产品计划',
name: 'productPlan',
id: 7,
status: '0',
key: 'planBizId'
},
{
label: '投保人',
name: 'policyholder',
id: 8,
status: '0',
key: 'policyholderBizId'
},
{
label: '受保人',
name: 'insurantInfo',
id: 9,
status: '0',
key: 'insurantBizId'
},
{
label: '受益人',
name: 'beneficiary',
id: 10,
status: '0',
key: 'beneficiaryBizId'
},
{
label: '第二持有人',
name: 'secondHolder',
id: 11,
status: '0',
key: 'secondHolderBizId'
},
{
label: '健康信息', //后端还没加这个字段
name: 'questionnaires',
id: 12,
status: '0',
key: 'questionnaireBizId'
},
{
label: '关联FNA',
name: 'fna',
id: 13,
status: '0',
key: 'fnaBizId'
},
{
label: '转保声明',
name: 'policyTransfer',
id: 14,
status: '0',
key: 'policyTransfer'
},
{
label: '预约附件', //大提交的时候不用提交了,因为上传文件的时候已经入库了
name: 'accessories',
id: 15,
status: '0',
key: 'fnaBizId'
}
]
nextTick(() => {
activeName.value = 'policyInfo'
})
}
// 根据页面来源的不同控制tab项内模块小提交按钮的显示与否,也能证明是修改状态
const showSubmitBtn = computed(() => {
if (route.query.appointmentNo && route.query.source == 'appointmentList') {
return true
} else if (route.query.source == 'policyList') {
return true
} else if (route.query.source == 'fnaList' && idsObj.value.appointmentBizId) {
return true
} else if (route.query.source == 'fnaList' && !idsObj.value.appointmentBizId) {
return false
}
})
onUnmounted(() => { onUnmounted(() => {
console.log('预约编辑页面完全销毁') console.log('预约编辑页面完全销毁')
...@@ -919,11 +1100,9 @@ onUnmounted(() => { ...@@ -919,11 +1100,9 @@ onUnmounted(() => {
.noembed-container { .noembed-container {
padding: 20px; padding: 20px;
background-color: #f2f3f5; background-color: #f2f3f5;
min-height: calc(100vh - 84.5px); /* min-height: calc(100vh - 84.5px); */
}
.embed-container {
min-height: calc(100vh - 325px);
} }
.appointment-container { .appointment-container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
...@@ -1008,12 +1187,7 @@ onUnmounted(() => { ...@@ -1008,12 +1187,7 @@ onUnmounted(() => {
} }
} }
} }
.noEmbedTabPaneBox {
height: calc(100vh - 276px);
}
.yesEmbedTabPaneBox {
height: calc(100vh - 407px);
}
.appointmentTabPaneBox { .appointmentTabPaneBox {
overflow-y: auto; overflow-y: auto;
padding-right: 10px; padding-right: 10px;
......
...@@ -1069,7 +1069,7 @@ watch( ...@@ -1069,7 +1069,7 @@ watch(
tempAddressQuickList.value = JSON.parse(JSON.stringify(addressQuickList.value)) tempAddressQuickList.value = JSON.parse(JSON.stringify(addressQuickList.value))
tempPhoneQuickList.value = JSON.parse(JSON.stringify(phoneQuickList.value)) tempPhoneQuickList.value = JSON.parse(JSON.stringify(phoneQuickList.value))
tempBeneficiaryDomData.value = JSON.parse(JSON.stringify(processedBeneficiaryData.value)) tempBeneficiaryDomData.value = JSON.parse(JSON.stringify(processedBeneficiaryData.value))
console.log('tempBeneficiaryDomData.value', tempBeneficiaryDomData.value)
if (newVal === 'beneficiary') { if (newVal === 'beneficiary') {
openList.value = false openList.value = false
setTimeout(() => { setTimeout(() => {
......
...@@ -199,17 +199,9 @@ ...@@ -199,17 +199,9 @@
</div> </div>
</el-row> </el-row>
<el-row v-if="props.idsObj.appointmentBizId"> <el-row v-if="props.showSubmitBtn">
<el-col> <el-col>
<div class="tabButton"> <div class="tabButton">
<!-- <el-button
type="primary"
icon="RefreshRight"
size="large"
@click="resetForm()"
:disabled="editStatus"
>重置</el-button
> -->
<el-button <el-button
type="success" type="success"
icon="Check" icon="Check"
...@@ -242,6 +234,8 @@ const props = defineProps({ ...@@ -242,6 +234,8 @@ const props = defineProps({
customerBizId: { type: String, default: '' }, //提交状态,新增、修改 customerBizId: { type: String, default: '' }, //提交状态,新增、修改
dictTypeLists: { type: Array, default: () => [] }, //多个字典值数据 dictTypeLists: { type: Array, default: () => [] }, //多个字典值数据
formStatus: { type: String, default: '' }, //父组件状态,新增、修改 formStatus: { type: String, default: '' }, //父组件状态,新增、修改
showSubmitBtn: { type: Boolean, default: false }, //父组件状态,新增、修改
pageSource: { type: String, default: false }, //页面来源
idsObj: { type: Object, default: () => ({}) }, //父组件传递过来的id对象 idsObj: { type: Object, default: () => ({}) }, //父组件传递过来的id对象
apiProductPlanInfoDto: { type: Object, default: () => ({}) }, //父组件传递过来的预约信息的详情 apiProductPlanInfoDto: { type: Object, default: () => ({}) }, //父组件传递过来的预约信息的详情
appointmentStatus: { type: Number } //父组件传递过来的预约的状态 appointmentStatus: { type: Number } //父组件传递过来的预约的状态
...@@ -439,7 +433,7 @@ const processFormData = async () => { ...@@ -439,7 +433,7 @@ const processFormData = async () => {
{ required: true, message: `${field.label}不能为空`, trigger: 'blur' } { required: true, message: `${field.label}不能为空`, trigger: 'blur' }
] ]
} }
if (props.idsObj.appointmentBizId) { if (props.showSubmitBtn) {
field.disabled = true field.disabled = true
} else { } else {
field.disabled = false field.disabled = false
...@@ -471,9 +465,12 @@ const processFormData = async () => { ...@@ -471,9 +465,12 @@ const processFormData = async () => {
} }
} }
} }
if (props.idsObj.appointmentBizId) { // idsObj.appointmentBizId
// 证明是修改
if (props.showSubmitBtn) {
editStatus.value = true editStatus.value = true
setFormValue(props.apiProductPlanInfoDto, processedData) processedProductData.value = processedData
// setFormValue(props.apiProductPlanInfoDto, processedData)
} else { } else {
editStatus.value = false editStatus.value = false
processedProductData.value = processedData processedProductData.value = processedData
...@@ -1018,7 +1015,10 @@ const submitForm = saveType => { ...@@ -1018,7 +1015,10 @@ const submitForm = saveType => {
console.log('提交的数据', result) console.log('提交的数据', result)
console.log('====================================') console.log('====================================')
// return // return
if (props.idsObj.appointmentBizId) { if (
props.idsObj.appointmentBizId &&
(props.pageSource == 'fnaList' || props.pageSource == 'appointmentList')
) {
editProductPlanInfo(result).then(res => { editProductPlanInfo(result).then(res => {
if (res.code == 200) { if (res.code == 200) {
handleEditStatus(true) handleEditStatus(true)
...@@ -1117,7 +1117,7 @@ defineExpose({ ...@@ -1117,7 +1117,7 @@ defineExpose({
} }
} }
.tabButton { .tabButton {
box-shadow: 0 -1px 14px #00000014; /* box-shadow: 0 -1px 14px #00000014; */
width: 100%; width: 100%;
display: flex; display: flex;
align-items: center; align-items: center;
......
<template>
<div>
<div v-if="processedFanFormData.length > 0">
<el-row>
<el-col :span="24">
<div class="topBtn">
<el-button
v-if="props.fnaFormBizId"
type="primary"
icon="EditPen"
@click="handleEditStatus"
>编辑</el-button
>
</div>
</el-col>
</el-row>
<el-form ref="fanFormRef" :model="form" :rules="rules">
<el-row v-for="father in processedFanFormData" style="margin-bottom: 10px">
<div class="formBox formFna">
<!-- <div class="fatherLable">{{ father.fatherTitle }}</div>
<div class="subTitle" v-if="father.subTitle">{{ father.subTitle }}</div> -->
<el-row v-if="father.showTable">
<el-table :data="father.data" border>
<!-- && form[father.key].length > 0 -->
<template v-if="father.key == 'brokerList'">
<el-table-column label="转介人比例" prop="brokerRatio" align="center">
<template #default="scope">
<el-input
v-model="scope.row.brokerRatio"
size="default"
type="number"
placeholder="请输入"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column label="转介人名称" prop="brokerName" align="center">
<template #default="scope">
<el-select
v-model="scope.row.brokerName"
filterable
remote
reserve-keyword
placeholder="请输入关键词搜索"
:remote-method="query => searchSelectList(query, 'brokerName', scope.row)"
:loading="searchLoadingStates['brokerName']"
:disabled="editStatus"
>
<el-option
v-for="item in searchOptions['brokerName'] || []"
:key="item.id"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column label="所属团队" prop="team" align="center">
<template #default="scope">
<el-input
v-model="scope.row.team"
size="default"
type="text"
placeholder="请输入"
:disabled="editStatus"
/>
<!-- 和csf的销售小程序团队挂钩,因为没有接口现在先放在这等有了在换 -->
<!-- <el-select
v-model="scope.row.team"
filterable
remote
reserve-keyword
placeholder="请输入关键词搜索"
:remote-method="query => searchSelectList(query, 'team')"
:loading="searchLoadingStates['team']"
:disabled="editStatus"
>
<el-option
v-for="item in searchOptions['team'] || []"
:key="item.userBizId"
:label="item.realName"
:value="item.userBizId"
/>
</el-select> -->
</template>
</el-table-column>
<el-table-column label="备注" prop="remark" align="center">
<template #default="scope">
<el-input
v-model="scope.row.remark"
size="default"
type="textarea"
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-col
:span="24"
v-if="father.addFamilyChildren"
style="display: flex; justify-content: center"
>
<el-button
:disabled="editStatus"
style="margin-top: 10px"
type="primary"
icon="Plus"
@click="addChildren(father)"
>添加转介人</el-button
>
</el-col>
</el-row>
</div>
</el-row>
<el-row>
<el-col>
<div class="tabButton">
<el-button
type="success"
icon="Check"
@click="submitForm('save')"
size="large"
:disabled="editStatus"
>提交</el-button
>
</div>
</el-col>
</el-row>
</el-form>
</div>
<div v-else class="domEmpty" v-loading="loading"></div>
</div>
</template>
<script setup name="policyInfo">
import useDictStore from '@/store/modules/dict'
import brokerInfo from '@/formJson/brokerInfo'
import { getDicts } from '@/api/system/dict/data'
import { watch, nextTick } from 'vue'
import { addfanForm, getfanFormDetail, editFanForm, getCustomerList } from '@/api/sign/fna'
import {
listTenantUser,
getInsuranceProductList,
getAllCompanys,
getClientUser
} from '@/api/common'
import { updatePolicyfollow } from '@/api/sign/underwritingMain'
import useUserStore from '@/store/modules/user'
const userStore = useUserStore()
const dictStore = useDictStore() //获取字典数据
const props = defineProps({
customerInfo: { type: Object, default: () => {} }, //客户详情
activeName: { type: String, default: '' }, //tab名称
fearthStatus: { type: String, default: '' }, //父组件状态,新增、修改
policyBizId: { type: String, default: '' }, //提交状态,新增、修改
customerBizId: { type: String, default: '' }, //提交状态,新增、修改
dictTypeLists: { type: Array, default: () => [] } //多个字典值数据
})
const emit = defineEmits(['handleSuccess'])
const { proxy } = getCurrentInstance()
const loading = ref(false)
const fanFormRef = ref(null)
const errorFields = ref([]) // 存储校验失败的字段信息
const editStatus = ref(false) // 表单是否可编辑,若是修改初始不可编辑
const openList = ref(false) // 客户列表弹窗
const noYesList = ref([]) // 是否列表
const searchOptions = ref({}) // 存储不同key对应的选项
const searchLoadingStates = ref({}) // 存储不同key对应的加载状态
const data = reactive({
form: {},
processedFanFormData: [], // 处理后的表单数据
tempFanFormValue: {}, // 切换tab得时候保存临时填写得值
tempFanFormData: [], // 处理后的表单数据
oldFanFormData: [], // 保存旧的表单Dom,便于撤销操作
rules: {}, //表单验证规则,
queryParams: {
pageNo: 1,
pageSize: 4,
name: undefined
}
})
const {
form,
rules,
processedFanFormData,
queryParams,
oldFanFormData,
tempFanFormValue,
tempFanFormData
} = toRefs(data)
const disabledDate = time => {
return time.getTime() > Date.now()
}
// 搜索方法
const searchSelectList = async (query, fieldKey) => {
// 设置该字段的加载状态
searchLoadingStates.value[fieldKey] = true
try {
// 根据不同的字段key调用不同的API
if (fieldKey === 'productName') {
const params = {
loginTenantBizId: userStore.projectInfo.tenantBizId,
productName: query.trim(),
pageNo: 1,
pageSize: 10
}
const response = await getInsuranceProductList(params)
if (response.code == 200) {
response.data.records = response.data.records.map(item => {
return {
...item,
label: item.productName,
value: item.productBizId
}
})
searchOptions.value[fieldKey] = response.data.records
}
}
// 可以添加其他字段的处理,可以放其他的字段得请求,目前只有accountName,以后有了其他的在填充
else if (fieldKey === 'reconciliationCompany' || fieldKey === 'insurer') {
const params = {
deptName: query.trim(),
pageNo: 1,
pageSize: 10
}
getAllCompanys(params).then(response => {
response.data.records = response.data.records.map(item => {
return {
...item,
label: item.deptName,
value: item.deptBizId
}
})
searchOptions.value[fieldKey] = response.data.records
})
} else if (fieldKey === 'brokerName') {
const params = {
projectBizId: 'project_IbjfmMTYvNEBuh2S',
tenantBizId: userStore.projectInfo.tenantBizId,
queryContent: query.trim(),
pageNo: 1,
pageSize: 10
}
getClientUser(params).then(response => {
response.data.records = response.data.records.map(item => {
return {
...item,
label: item.name,
value: item.clientUserBizId
}
})
searchOptions.value[fieldKey] = response.data.records
})
}
} catch (error) {
console.error(`${fieldKey} 搜索失败`, error)
searchOptions.value[fieldKey] = []
} finally {
searchLoadingStates.value[fieldKey] = false
}
}
const handleSearchSelectChange = (father, child) => {
if (child.key == 'productName') {
let productItem = dictStore.insureProductList.filter(item => {
return item.value == form.value[father.key][child.key]
})
let options = productItem[0].paymentTerm.split(',').map(item => {
return {
label: item,
value: item
}
})
const processedData = JSON.parse(JSON.stringify(processedFanFormData.value))
for (const section of processedData) {
if (section.key == father.key) {
if (section.data) {
for (const field of section.data) {
if (field.dictType && field.dictType == 'paymentTerm') {
field.options = options
}
}
}
}
}
if (options.length > 0) {
form.value[father.key]['paymentTerm'] = options[0].value
}
processedFanFormData.value = processedData
}
}
// 获取字典数据
const fetchDictData = dictType => {
let options = []
try {
dictStore.dictTypeLists.forEach(item => {
if (item.dictType == dictType) {
options = item.dictItemList
}
})
return options
} catch (error) {
console.error('获取字典数据失败:', error)
return []
}
}
// 处理表单配置,添加字典数据
const processFormData = () => {
loading.value = true
// 深拷贝原始数据
const processedData = JSON.parse(JSON.stringify(brokerInfo))
for (const section of processedData) {
if (section.fatherRequired) {
rules.value[section.key] = {}
}
//给表单赋值各模块key,对应表单的father.key便于收集值
if (section.keyType == 'Array') {
form.value[section.key] = []
if (section.key == 'brokerList') {
form.value[section.key] = section.data
}
} else if (section.keyType == 'Object') {
form.value[section.key] = {}
}
if (section.data) {
for (const formKey in form.value) {
if (section.key == formKey) {
for (const field of section.data) {
// 为下拉搜索框加options
if (field.domType == 'SearchSelect') {
if (field.key == 'accountName') {
searchOptions.value[field.key] = dictStore.tenantUserList
}
}
if (field.dictType) {
// 获取字典数据
field.options = fetchDictData(field.dictType)
}
//
/*
1.没有嵌套子级的也就是没有children的数据加rules,根据data中的required字段判断是否必填
2.有嵌套子级的也就是有children的数据,根据children中的required字段判断是否必填,现在没这个需求,所以先注释
*/
if (field.required && section.child == 'no') {
rules.value[section.key][field.key] = [
{ required: true, message: `${field.label}不能为空`, trigger: 'blur' }
]
}
if (props.fnaFormBizId) {
field.disabled = true
} else {
field.disabled = false
}
}
}
}
}
}
if (Object.keys(tempFanFormValue.value).length > 0) {
form.value = JSON.parse(JSON.stringify(tempFanFormValue.value))
}
if (tempFanFormData.value.length > 0) {
processedFanFormData.value = oldFanFormData.value = JSON.parse(
JSON.stringify(tempFanFormData.value)
)
} else {
processedFanFormData.value = oldFanFormData.value = processedData
}
if (props.policyBizId) {
// editStatus.value = true
} else {
editStatus.value = false
loading.value = false
}
console.log('form', form.value)
}
// 添加表单子级dom
const addChildren = father => {
// if (editStatus.value) {
// proxy.$modal.confirm(`请先点击编辑再添加儿女`, { showCancel: '0', title: '填写提示' })
// return
// }
const processedData = JSON.parse(JSON.stringify(processedFanFormData.value))
let obj = {
id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识
brokerName: '',
team: '',
brokerRatio: '',
remark: ''
}
for (const section of processedData) {
if (father.key == 'brokerList' && section.key == father.key) {
section.data.push(obj)
}
}
//更新form表单对应的数据,以便收集填写的值
form.value[father.key].push(obj)
processedFanFormData.value = processedData
}
const deleteChildren = (father, childIndex) => {
// if (editStatus.value) {
// proxy.$modal.confirm(`请先点击编辑再删除儿女`, { showCancel: '0', title: '填写提示' })
// }
const processedData = JSON.parse(JSON.stringify(processedFanFormData.value))
for (const section of processedData) {
if (father.key == 'brokerList' && section.key == father.key) {
section.data.splice(childIndex, 1)
}
}
//更新form表单对应的数据,以便收集填写的值
form.value[father.key].splice(childIndex, 1)
processedFanFormData.value = processedData
}
// 根据联动重置表单项的显示与否
const resetShow = (childKey, status) => {
console.log(childKey, status)
for (const section of processedFanFormData.value) {
// 暂时没考虑data里嵌套children的情况
if (section.data) {
for (const field of section.data) {
if (field.key == childKey) {
// 获取字典数据
field.show = status
}
}
}
}
}
const handleSelectChange = (father, child) => {
switch (child.key) {
case 'employment':
// 选择吸烟,展示吸烟数量
if (form.value[father.key][child.key] == 'OTHER') {
resetShow('otherEmployment', true)
form.value[father.key]['otherEmployment'] = ''
} else {
resetShow('otherEmployment', false)
}
break
default:
break
}
}
// 改变编辑状态
const handleEditStatus = () => {
editStatus.value = !editStatus.value
// 深拷贝原始数据
const processedData = JSON.parse(JSON.stringify(processedFanFormData.value))
for (const section of processedData) {
if (section.data) {
for (const field of section.data) {
// 改变data中字段得编辑状态
if (editStatus.value) {
field.disabled = true
} else {
field.disabled = false
}
// 改变data中的children字段得编辑状态
if (field.children) {
for (const child of field.children) {
if (editStatus.value) {
child.disabled = true
} else {
child.disabled = false
}
}
}
}
}
}
processedFanFormData.value = processedData
}
//给表单赋值 方便表单回显 obj 为表单数据
const setFormValue = (obj, formData) => {
loading.value = true
}
// 获取校验失败的字段信息
const getInvalidFields = fields => {
const errors = []
for (const field in fields) {
if (fields[field] && fields[field].length > 0) {
errors.push({
field: field,
message: fields[field][0].message
})
}
}
return errors
}
// 判断是否为数组
const isArray = value => {
return Array.isArray(value)
}
// 判断是否为对象
const isObject = value => {
return typeof value === 'object' && value !== null && !Array.isArray(value)
}
// 处理表单填写得数据
const handleFormValues = () => {
// 提交要从dom中拿数据,因为收集到dom中了
console.log('processedFanFormData.value', processedFanFormData.value)
let submitObj = JSON.parse(JSON.stringify(form.value))
const pattern = /Date$/ // 以Time结尾
// debugger
//处理表单数据
for (const key1 in form.value) {
// 对象数据格式
if (isObject(form.value[key1]) && Object.keys(form.value[key1]).length > 0) {
for (const key2 in form.value[key1]) {
if (pattern.test(key2) && form.value[key1][key2]) {
submitObj[key1][key2] = proxy.formatToDate(form.value[key1][key2])
}
// 处理搜索下拉框数据需要返回的各种业务ID
if ((key2 == 'insurer' || key2 === 'reconciliationCompany') && form.value[key1][key2]) {
dictStore.insureCompanyList.forEach(item => {
if (item.deptBizId == form.value[key1][key2]) {
submitObj[key1][key2] = item.deptName
submitObj[key1][`${key2}BizId`] = item.deptBizId
}
})
} else if (key2 == 'productName' && form.value[key1][key2]) {
dictStore.insureProductList.forEach(item => {
if (item.productBizId == form.value[key1][key2]) {
submitObj[key1][key2] = item.productName
submitObj[key1]['productBizId'] = item.productBizId
}
})
}
}
}
// 数组数据格式
if (isArray(form.value[key1]) && form.value[key1].length > 0) {
submitObj[key1] = form.value[key1].map(item1 => {
if (item1.brokerName) {
dictStore.clientUserList.forEach(item => {
if (item.clientUserBizId == item1.brokerName) {
item1.brokerName = item.name
item1['brokerBizId'] = item.clientUserBizId
}
})
}
delete item1.id
return item1
})
}
}
return submitObj
}
// 表单提交
const submitForm = saveType => {
let submitObj = handleFormValues()
// return
proxy.$refs['fanFormRef'].validate((valid, fields) => {
if (valid) {
console.log('====================================')
console.log(' props.policyBizId', submitObj)
console.log('====================================')
// return
if (props.policyBizId) {
// submitObj.PolicyFollowUpdateDto.policyBizId = props.policyBizId
updatePolicyfollow(submitObj).then(res => {
if (res.code == 200) {
handleEditStatus()
proxy.$message.success('提交成功')
// emit('handleSuccess', {
// tab: 'fnaform',
// fnaFormBizId: props.fnaFormBizId,
// type: 'edit'
// })
}
})
} else {
// addfanForm(result).then(res => {
// if (res.code == 200) {
// proxy.$message.success('fnaForm新增成功')
// emit('handleSuccess', {
// tab: 'fnaform',
// fnaFormBizId: res.data.fnaFormBizId,
// type: 'add'
// })
// }
// })
}
errorFields.value = [] // 清空错误信息
} else {
// 获取校验失败的字段信息
errorFields.value = getInvalidFields(fields)
if (errorFields.value.length > 0) {
proxy.$message.error(errorFields.value[0].message)
}
}
})
}
// 获取流程详情
function getFanformInfo(fnaFormBizId, formData) {
getfanFormDetail(fnaFormBizId).then(async res => {
if (res.code == 200) {
// 回显值
setFormValue(res.data, formData)
}
})
}
watch(fanFormRef, newVal => {
if (newVal) {
for (const key in rules.value) {
for (const key2 in rules.value[key]) {
fanFormRef.value.clearValidate(key2)
}
}
}
})
watch(
() => props.activeName,
newVal => {
tempFanFormValue.value = JSON.parse(JSON.stringify(form.value))
tempFanFormData.value = JSON.parse(JSON.stringify(processedFanFormData.value))
if (newVal === 'policyBroker') {
setTimeout(() => {
processFormData()
}, 500)
}
}
)
</script>
<style lang="scss" scoped>
.domEmpty {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
height: 100%;
font-size: 16px;
color: #a8abb2;
margin-top: 100px;
}
.topBtn {
width: 100%;
display: flex;
justify-content: space-between;
margin-bottom: 10px;
}
.formBox {
width: 100%;
.fatherLable {
font-size: 18px;
border-left: 4px solid #165dff;
padding-left: 5px;
margin-bottom: 5px;
}
.subTitle {
font-size: 15px;
/* padding-left: 8px; */
margin-bottom: 10px;
}
.childLabel {
font-size: 14px;
/* padding-left: 15px; */
margin-bottom: 15px;
}
.fatherDes {
font-size: 14px;
color: #a8abb2;
margin-top: 5px;
margin-bottom: 20px;
}
.inputBox {
width: 100%;
border: 1px solid #dcdfe6;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: space-between;
min-height: 32px;
padding: 0px 11px;
.rightArrow {
font-size: 14px;
color: #a8abb2;
}
}
.deleteIcon {
color: red;
font-size: 18px;
padding-top: 10px;
}
}
.tabButton {
/* box-shadow: 0 -1px 14px #00000014; */
width: 100%;
display: flex;
align-items: center;
justify-content: center;
padding-top: 20px;
.sumbitBtn {
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
height: 60px;
background-color: #165dff;
color: #fff;
padding: 0 30px;
.buttonIcon {
font-size: 16px;
color: #fff;
}
}
}
.customerBox {
.customerItem {
padding: 10px;
border-radius: 5px;
margin-bottom: 20px;
box-shadow: 0 -1px 14px #00000014;
.top {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
.left {
width: 40%;
display: flex;
align-items: center;
justify-content: flex-start;
.gender {
display: flex;
align-items: center;
}
}
}
.bottom {
.infoItem {
display: flex;
align-items: center;
margin: 5px 0;
}
}
}
.customerItem:last-child {
margin-bottom: 0px;
}
}
/* 新增的样式:防止label换行并显示省略号 */
.formFna :deep(.el-checkbox) {
margin-right: 10px;
}
@media only screen and (min-width: 768px) {
.formInput {
margin-top: 30px !important;
}
}
@media only screen and (min-width: 1200px) {
.formInput {
margin-top: 30px !important;
}
}
</style>
<template>
<!-- :limit="limit" :on-exceed="handleExceed"-->
<div>
<div class="fileUploadBox">
<el-upload
:action="uploadImgUrl"
:headers="headers"
:show-file-list="false"
:on-success="uploadSuccess"
:before-upload="handleBeforeUpload"
>
<div class="uploadBox">
<el-icon size="20"><DocumentAdd /></el-icon>
<div class="file">选择文件</div>
</div>
</el-upload>
</div>
<div class="tip">(支持Word,Excel,PDF,图片格式)</div>
<el-table v-loading="loading" :data="fileTableList">
<el-table-column label="序号" type="index" width="50" />
<el-table-column label="文件名" align="center" prop="fileName" width="200" />
<!-- sortable -->
<el-table-column label="上传时间" align="center" prop="createTime" width="200">
<template #default="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="上传人" align="center" prop="creatorName" />
<el-table-column label="文件类型" align="center" prop="fileType" />
<el-table-column
label="操作"
align="center"
width="250"
class-name="small-padding fixed-width"
fixed="right"
>
<template #default="scope">
<el-button type="primary" link @click="downloadFile(scope.row)">下载</el-button>
<el-button
v-if="isImageFile(scope.row.fileName)"
type="primary"
link
@click="handleView(scope.row)"
>
查看
</el-button>
<!-- <el-button type="primary" link @click="handleUpdate(scope.row)">修改</el-button> -->
<el-button type="danger" link @click="handleDetele(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total >= 0"
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getFileList"
/>
<el-dialog title="重命名文件" v-model="editVisible" width="800px" append-to-body>
<el-form>
<el-row>
<el-col :span="12">
<el-form-item label="文件名">
<el-input v-model="form.fileName" placeholder="请输入文件名" maxlength="300" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="canelEdit">取 消</el-button>
</div>
</template>
</el-dialog>
<!-- 图片查看器 -->
<el-dialog v-model="imageViewerVisible" title="图片预览" width="60%">
<div style="text-align: center">
<el-image :src="imageUrl" fit="contain" />
</div>
</el-dialog>
</div>
</template>
<script setup name="FileUpload">
import { getToken } from '@/utils/auth'
import { addFile, getAppointmentFile, delFile, editAppointmentFile } from '@/api/sign/appointment'
import {
getAttachmentList,
uploadPolicyfollow,
delAttachmentFile
} from '@/api/sign/underwritingMain'
const props = defineProps({
activeName: { type: String, default: '' }, //tab名称
policyBizId: { type: String, default: '' } //父组件状态,新增、修改
})
const { proxy } = getCurrentInstance()
const editVisible = ref(false)
const loading = ref(true)
const total = ref(0)
const fileTableList = ref([])
const limit = ref(2)
const fileSize = ref(10)
const headers = ref({ Authorization: 'Bearer ' + getToken() })
const uploadImgUrl = ref(import.meta.env.VITE_APP_BASE_API + '/oss/api/oss/upload') // 上传的服务器地址
// 图片查看相关状态
const imageViewerVisible = ref(false)
const imageUrl = ref('')
const data = reactive({
form: {},
queryParams: {
pageNo: 1,
pageSize: 4,
policyBizId: props.policyBizId
}
})
const { queryParams, form } = toRefs(data)
const canelEdit = () => {
editVisible.value = false
form.value = {}
console.log('fileTableList', fileTableList.value)
}
const submitForm = () => {
let obj = {
appointmentFileBizId: form.value.appointmentFileBizId,
fileName: form.value.fileName
}
editAppointmentFile(obj).then(response => {
if (response.code == 200) {
proxy.$modal.msgSuccess('文件名修改成功')
editVisible.value = false
getFileList()
}
})
}
const handleDetele = row => {
proxy.$modal
.confirm('是否确认删除名称为"' + row.fileName + '"的文件?')
.then(function () {
return delAttachmentFile(row.id)
})
.then(res => {
if (res.code == 200) {
proxy.$modal.msgSuccess('删除成功')
getFileList()
}
})
.catch(() => {})
}
const isImageFile = fileName => {
return /\.(jpg|jpeg|png|gif|bmp|webp|svg|ico)$/i.test(fileName || '')
}
const handleUpdate = row => {
editVisible.value = true
form.value = JSON.parse(JSON.stringify(row))
}
const handleView = row => {
imageUrl.value = row.fileUrl
imageViewerVisible.value = true
}
const downloadFile = row => {
// 创建隐藏的下载链接
const link = document.createElement('a')
link.href = row.fileUrl
link.target = '_blank' // 新窗口打开
// 设置下载文件名(重要)
// 从URL中提取文件名,或者使用返回的文件名
const fileName = row.fileName
link.download = fileName
// 触发下载
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}
// 上传前loading加载
function handleBeforeUpload(file) {
// if (file.name.includes(',')) {
// proxy.$modal.msgError('文件名不正确,不能包含英文逗号!')
// return false
// }
const isLt = file.size / 1024 / 1024 < fileSize.value
if (!isLt) {
proxy.$modal.msgError(`上传文件大小不能超过 ${fileSize.value} MB!`)
return false
}
}
// 文件个数超出
function handleExceed() {
proxy.$modal.msgError(`一次只能上传${limit.value}个文件!`)
}
const uploadSuccess = res => {
console.log('上传成功', res)
if (res.code == 200) {
if (props.policyBizId) {
let submitObj = {
policyBizId: props.policyBizId,
fileUrl: res.data.url,
fileName: res.data.originalName,
ossFileBizId: res.data.fileBizId
}
uploadPolicyfollow(submitObj).then(res => {
if (res.code == 200) {
proxy.$message.success('文件上传成功')
queryParams.value.pageNo = 1
getFileList()
}
})
}
}
}
const getFileList = () => {
loading.value = true
try {
getAttachmentList(queryParams.value).then(response => {
total.value = response.data.total
fileTableList.value = response.data.records
if (fileTableList.value.length > 0) {
for (const item of fileTableList.value) {
item.fileType = '保单文件'
}
}
loading.value = false
})
} catch (error) {
fileTableList.value = []
} finally {
loading.value = false
}
}
watch(
() => props.activeName,
newVal => {
if (newVal === 'policyAccessories') {
queryParams.value.pageNo = 1
getFileList()
}
}
)
</script>
<style lang="scss" scoped>
.fileUploadBox {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100%;
padding: 20px 0;
border: 1px dashed #dcdfe6;
}
.uploadBox {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.file {
font-size: 14px;
margin-top: 10px;
color: #409eff;
}
}
.tip {
font-size: 14px;
color: #909399;
margin: 10px 0 20px 0;
}
</style>
<template>
<div>
<div v-if="processedFanFormData.length > 0">
<el-row>
<el-col :span="24">
<div class="topBtn">
<el-button
v-if="props.fnaFormBizId"
type="primary"
icon="EditPen"
@click="handleEditStatus"
>编辑</el-button
>
</div>
</el-col>
</el-row>
<el-form ref="fanFormRef" :model="form" :rules="rules">
<el-row v-for="father in processedFanFormData" style="margin-bottom: 10px">
<div class="formBox formFna">
<!-- <div class="fatherLable">{{ father.fatherTitle }}</div>
<div class="subTitle" v-if="father.subTitle">{{ father.subTitle }}</div> -->
<el-row v-if="father.child == 'no'" :gutter="20">
<template v-for="child in father.data" :key="child.key">
<el-col :sm="child.sm" :lg="child.lg" class="formItem" v-if="child.show">
<div>
<el-form-item
:label="child.label"
:prop="father.key + '.' + child.key"
:key="child.key"
:label-width="child.labelWidth"
:label-position="child.labelPosition"
>
<el-input
v-if="child.domType === 'Input'"
:type="child.inputType"
v-model="form[father.key][child.key]"
: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"
maxlength="30"
:disabled="child.disabled"
:style="{ width: child.inputWidth ? child.inputWidth : '100%' }"
class="formInput"
/>
<el-select
v-if="child.domType === 'Select'"
v-model="form[father.key][child.key]"
:placeholder="child.placeholder"
@change="handleSelectChange(father, child)"
:disabled="child.disabled"
>
<el-option
v-for="item in child.options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-date-picker
style="width: 100%"
v-if="child.domType === 'DatePicker'"
v-model="form[father.key][child.key]"
type="date"
:placeholder="child.placeholder"
:disabled="child.disabled"
/>
<el-checkbox-group
v-if="child.domType === 'Checkbox'"
v-model="form[father.key][child.key]"
:disabled="child.disabled"
>
<el-checkbox
v-for="item in child.options"
:key="item.value"
:label="item.value"
>
{{ item.label }}
</el-checkbox>
</el-checkbox-group>
<el-select
v-model="form[father.key][child.key]"
v-if="child.domType === 'SearchSelect'"
filterable
remote
reserve-keyword
placeholder="请输入关键词搜索"
:remote-method="query => searchSelectList(query, child.key)"
:loading="searchLoadingStates[child.key]"
:disabled="child.disabled"
@change="handleSearchSelectChange(father, child)"
>
<el-option
v-for="item in searchOptions[child.key] || []"
:key="item.id"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</div>
</el-col>
</template>
</el-row>
<el-row v-if="father.showTable">
<el-table :data="father.data" border>
<!-- && form[father.key].length > 0 -->
<template v-if="father.key == 'brokerList'">
<el-table-column label="转介人比例" prop="brokerRatio" align="center">
<template #default="scope">
<el-input
v-model="scope.row.brokerRatio"
size="default"
type="number"
placeholder="请输入"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column label="转介人名称" prop="brokerName" align="center">
<template #default="scope">
<el-select
v-model="scope.row.brokerName"
filterable
remote
reserve-keyword
placeholder="请输入关键词搜索"
:remote-method="query => searchSelectList(query, 'brokerName', scope.row)"
:loading="searchLoadingStates['brokerName']"
:disabled="editStatus"
>
<el-option
v-for="item in searchOptions['brokerName'] || []"
:key="item.id"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column label="所属团队" prop="team" align="center">
<template #default="scope">
<el-input
v-model="scope.row.team"
size="default"
type="text"
placeholder="请输入"
:disabled="editStatus"
/>
<!-- 和csf的销售小程序团队挂钩,因为没有接口现在先放在这等有了在换 -->
<!-- <el-select
v-model="scope.row.team"
filterable
remote
reserve-keyword
placeholder="请输入关键词搜索"
:remote-method="query => searchSelectList(query, 'team')"
:loading="searchLoadingStates['team']"
:disabled="editStatus"
>
<el-option
v-for="item in searchOptions['team'] || []"
:key="item.userBizId"
:label="item.realName"
:value="item.userBizId"
/>
</el-select> -->
</template>
</el-table-column>
<el-table-column label="备注" prop="remark" align="center">
<template #default="scope">
<el-input
v-model="scope.row.remark"
size="default"
type="textarea"
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-col
:span="24"
v-if="father.addFamilyChildren"
style="display: flex; justify-content: center"
>
<el-button
:disabled="editStatus"
style="margin-top: 10px"
type="primary"
icon="Plus"
@click="addChildren(father)"
>添加转介人</el-button
>
</el-col>
</el-row>
</div>
</el-row>
<el-row>
<el-col>
<div class="tabButton">
<el-button
type="success"
icon="Check"
@click="submitForm('save')"
size="large"
:disabled="editStatus"
>提交</el-button
>
</div>
</el-col>
</el-row>
</el-form>
</div>
<div v-else class="domEmpty" v-loading="loading"></div>
</div>
</template>
<script setup name="policyInfo">
import useDictStore from '@/store/modules/dict'
import policyInfo from '@/formJson/policyInfo'
import { getDicts } from '@/api/system/dict/data'
import { watch, nextTick } from 'vue'
import { addfanForm, getfanFormDetail, editFanForm, getCustomerList } from '@/api/sign/fna'
import {
listTenantUser,
getInsuranceProductList,
getAllCompanys,
getClientUser
} from '@/api/common'
import { updatePolicyfollow } from '@/api/sign/underwritingMain'
import useUserStore from '@/store/modules/user'
const userStore = useUserStore()
const dictStore = useDictStore() //获取字典数据
const props = defineProps({
customerInfo: { type: Object, default: () => {} }, //客户详情
// policyInfo: { type: Object, default: () => {} }, //客户详情
activeName: { type: String, default: '' }, //tab名称
fearthStatus: { type: String, default: '' }, //父组件状态,新增、修改
policyBizId: { type: String, default: '' }, //提交状态,新增、修改
customerBizId: { type: String, default: '' }, //提交状态,新增、修改
dictTypeLists: { type: Array, default: () => [] } //多个字典值数据
})
const emit = defineEmits(['handleSuccess'])
const { proxy } = getCurrentInstance()
const loading = ref(false)
const fanFormRef = ref(null)
const errorFields = ref([]) // 存储校验失败的字段信息
const editStatus = ref(true) // 表单是否可编辑,若是修改初始不可编辑
const openList = ref(false) // 客户列表弹窗
const noYesList = ref([]) // 是否列表
const searchOptions = ref({}) // 存储不同key对应的选项
const searchLoadingStates = ref({}) // 存储不同key对应的加载状态
const data = reactive({
form: {},
processedFanFormData: [], // 处理后的表单数据
tempFanFormValue: {}, // 切换tab得时候保存临时填写得值
tempFanFormData: [], // 处理后的表单数据
oldFanFormData: [], // 保存旧的表单Dom,便于撤销操作
rules: {}, //表单验证规则,
queryParams: {
pageNo: 1,
pageSize: 4,
name: undefined
}
})
const {
form,
rules,
processedFanFormData,
queryParams,
oldFanFormData,
tempFanFormValue,
tempFanFormData
} = toRefs(data)
const disabledDate = time => {
return time.getTime() > Date.now()
}
// 搜索方法
const searchSelectList = async (query, fieldKey) => {
// 设置该字段的加载状态
searchLoadingStates.value[fieldKey] = true
try {
// 根据不同的字段key调用不同的API
if (fieldKey === 'productName') {
const params = {
loginTenantBizId: userStore.projectInfo.tenantBizId,
productName: query.trim(),
pageNo: 1,
pageSize: 10
}
const response = await getInsuranceProductList(params)
if (response.code == 200) {
response.data.records = response.data.records.map(item => {
return {
...item,
label: item.productName,
value: item.productBizId
}
})
searchOptions.value[fieldKey] = response.data.records
}
}
// 可以添加其他字段的处理,可以放其他的字段得请求,目前只有accountName,以后有了其他的在填充
else if (fieldKey === 'reconciliationCompany' || fieldKey === 'insurer') {
const params = {
deptName: query.trim(),
pageNo: 1,
pageSize: 10
}
getAllCompanys(params).then(response => {
response.data.records = response.data.records.map(item => {
return {
...item,
label: item.deptName,
value: item.deptBizId
}
})
searchOptions.value[fieldKey] = response.data.records
})
} else if (fieldKey === 'brokerName') {
const params = {
projectBizId: 'project_IbjfmMTYvNEBuh2S',
tenantBizId: userStore.projectInfo.tenantBizId,
queryContent: query.trim(),
pageNo: 1,
pageSize: 10
}
getClientUser(params).then(response => {
response.data.records = response.data.records.map(item => {
return {
...item,
label: item.name,
value: item.clientUserBizId
}
})
searchOptions.value[fieldKey] = response.data.records
})
}
} catch (error) {
console.error(`${fieldKey} 搜索失败`, error)
searchOptions.value[fieldKey] = []
} finally {
searchLoadingStates.value[fieldKey] = false
}
}
const handleSearchSelectChange = (father, child) => {
if (child.key == 'productName') {
let productItem = dictStore.insureProductList.filter(item => {
return item.value == form.value[father.key][child.key]
})
let options = productItem[0].paymentTerm.split(',').map(item => {
return {
label: item,
value: item
}
})
const processedData = JSON.parse(JSON.stringify(processedFanFormData.value))
for (const section of processedData) {
if (section.key == father.key) {
if (section.data) {
for (const field of section.data) {
if (field.dictType && field.dictType == 'paymentTerm') {
field.options = options
}
}
}
}
}
if (options.length > 0) {
form.value[father.key]['paymentTerm'] = options[0].value
}
processedFanFormData.value = processedData
}
}
// 获取字典数据
const fetchDictData = dictType => {
let options = []
try {
dictStore.dictTypeLists.forEach(item => {
if (item.dictType == dictType) {
options = item.dictItemList
}
})
return options
} catch (error) {
console.error('获取字典数据失败:', error)
return []
}
}
// 处理表单配置,添加字典数据
const processFormData = () => {
loading.value = true
// 深拷贝原始数据
const processedData = JSON.parse(JSON.stringify(policyInfo))
for (const section of processedData) {
if (section.fatherRequired) {
rules.value[section.key] = {}
}
//给表单赋值各模块key,对应表单的father.key便于收集值
if (section.keyType == 'Array') {
form.value[section.key] = []
if (section.key == 'brokerList') {
form.value[section.key] = section.data
}
} else if (section.keyType == 'Object') {
form.value[section.key] = {}
}
if (section.data) {
for (const formKey in form.value) {
if (section.key == formKey) {
for (const field of section.data) {
// 为下拉搜索框加options
if (field.domType == 'SearchSelect') {
if (field.key == 'accountName') {
searchOptions.value[field.key] = dictStore.tenantUserList
}
}
if (field.dictType) {
// 获取字典数据
field.options = fetchDictData(field.dictType)
}
//
/*
1.没有嵌套子级的也就是没有children的数据加rules,根据data中的required字段判断是否必填
2.有嵌套子级的也就是有children的数据,根据children中的required字段判断是否必填,现在没这个需求,所以先注释
*/
if (field.required && section.child == 'no') {
rules.value[section.key][field.key] = [
{ required: true, message: `${field.label}不能为空`, trigger: 'blur' }
]
}
if (props.fnaFormBizId) {
field.disabled = true
} else {
field.disabled = false
}
}
}
}
}
}
if (Object.keys(tempFanFormValue.value).length > 0) {
form.value = JSON.parse(JSON.stringify(tempFanFormValue.value))
}
if (tempFanFormData.value.length > 0) {
processedFanFormData.value = oldFanFormData.value = JSON.parse(
JSON.stringify(tempFanFormData.value)
)
} else {
processedFanFormData.value = oldFanFormData.value = processedData
}
if (props.policyBizId) {
editStatus.value = true
} else {
// tab切走在切回来时,表单会重置,所以这里需要把表单的值赋回去
editStatus.value = false
loading.value = false
}
console.log('form', form.value)
}
// 添加表单子级dom
const addChildren = father => {
// if (editStatus.value) {
// proxy.$modal.confirm(`请先点击编辑再添加儿女`, { showCancel: '0', title: '填写提示' })
// return
// }
const processedData = JSON.parse(JSON.stringify(processedFanFormData.value))
let obj = {
id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识
brokerName: '',
team: '',
brokerRatio: '',
remark: ''
}
for (const section of processedData) {
if (father.key == 'brokerList' && section.key == father.key) {
section.data.push(obj)
}
}
//更新form表单对应的数据,以便收集填写的值
form.value[father.key].push(obj)
processedFanFormData.value = processedData
}
const deleteChildren = (father, childIndex) => {
// if (editStatus.value) {
// proxy.$modal.confirm(`请先点击编辑再删除儿女`, { showCancel: '0', title: '填写提示' })
// }
const processedData = JSON.parse(JSON.stringify(processedFanFormData.value))
for (const section of processedData) {
if (father.key == 'brokerList' && section.key == father.key) {
section.data.splice(childIndex, 1)
}
}
//更新form表单对应的数据,以便收集填写的值
form.value[father.key].splice(childIndex, 1)
processedFanFormData.value = processedData
}
// 根据联动重置表单项的显示与否
const resetShow = (childKey, status) => {
console.log(childKey, status)
for (const section of processedFanFormData.value) {
// 暂时没考虑data里嵌套children的情况
if (section.data) {
for (const field of section.data) {
if (field.key == childKey) {
// 获取字典数据
field.show = status
}
}
}
}
}
const handleSelectChange = (father, child) => {
switch (child.key) {
case 'employment':
// 选择吸烟,展示吸烟数量
if (form.value[father.key][child.key] == 'OTHER') {
resetShow('otherEmployment', true)
form.value[father.key]['otherEmployment'] = ''
} else {
resetShow('otherEmployment', false)
}
break
default:
break
}
}
// 改变编辑状态
const handleEditStatus = () => {
editStatus.value = !editStatus.value
// 深拷贝原始数据
const processedData = JSON.parse(JSON.stringify(processedFanFormData.value))
for (const section of processedData) {
if (section.data) {
for (const field of section.data) {
// 改变data中字段得编辑状态
if (editStatus.value) {
field.disabled = true
} else {
field.disabled = false
}
// 改变data中的children字段得编辑状态
if (field.children) {
for (const child of field.children) {
if (editStatus.value) {
child.disabled = true
} else {
child.disabled = false
}
}
}
}
}
}
processedFanFormData.value = processedData
}
//给表单赋值 方便表单回显 obj 为表单数据
const setFormValue = (obj, formData) => {
loading.value = true
}
// 获取校验失败的字段信息
const getInvalidFields = fields => {
const errors = []
for (const field in fields) {
if (fields[field] && fields[field].length > 0) {
errors.push({
field: field,
message: fields[field][0].message
})
}
}
return errors
}
// 判断是否为数组
const isArray = value => {
return Array.isArray(value)
}
// 判断是否为对象
const isObject = value => {
return typeof value === 'object' && value !== null && !Array.isArray(value)
}
// 处理表单填写得数据
const handleFormValues = () => {
let submitObj = JSON.parse(JSON.stringify(form.value))
const pattern = /Date$/ // 以Time结尾
// debugger
//处理表单数据
for (const key1 in form.value) {
// 对象数据格式
if (isObject(form.value[key1]) && Object.keys(form.value[key1]).length > 0) {
for (const key2 in form.value[key1]) {
if (pattern.test(key2) && form.value[key1][key2]) {
submitObj[key1][key2] = proxy.formatToDate(form.value[key1][key2])
}
// 处理搜索下拉框数据需要返回的各种业务ID
if ((key2 == 'insurer' || key2 === 'reconciliationCompany') && form.value[key1][key2]) {
dictStore.insureCompanyList.forEach(item => {
if (item.deptBizId == form.value[key1][key2]) {
submitObj[key1][key2] = item.deptName
submitObj[key1][`${key2}BizId`] = item.deptBizId
}
})
} else if (key2 == 'productName' && form.value[key1][key2]) {
dictStore.insureProductList.forEach(item => {
if (item.productBizId == form.value[key1][key2]) {
submitObj[key1][key2] = item.productName
submitObj[key1]['productBizId'] = item.productBizId
}
})
}
}
}
// 数组数据格式
if (isArray(form.value[key1]) && form.value[key1].length > 0) {
submitObj[key1] = form.value[key1].map(item1 => {
if (item1.brokerName) {
dictStore.clientUserList.forEach(item => {
if (item.clientUserBizId == item1.brokerName) {
item1.brokerName = item.name
item1['brokerBizId'] = item.clientUserBizId
}
})
}
delete item1.id
return item1
})
}
}
return submitObj
}
// 表单提交
const submitForm = saveType => {
let submitObj = handleFormValues()
// return
proxy.$refs['fanFormRef'].validate((valid, fields) => {
if (valid) {
console.log('====================================')
console.log(' props.policyBizId', submitObj)
console.log('====================================')
// return
if (props.policyBizId) {
// submitObj.PolicyFollowUpdateDto.policyBizId = props.policyBizId
updatePolicyfollow(submitObj).then(res => {
if (res.code == 200) {
handleEditStatus()
proxy.$message.success('提交成功')
// emit('handleSuccess', {
// tab: 'fnaform',
// fnaFormBizId: props.fnaFormBizId,
// type: 'edit'
// })
}
})
} else {
// addfanForm(result).then(res => {
// if (res.code == 200) {
// proxy.$message.success('fnaForm新增成功')
// emit('handleSuccess', {
// tab: 'fnaform',
// fnaFormBizId: res.data.fnaFormBizId,
// type: 'add'
// })
// }
// })
}
errorFields.value = [] // 清空错误信息
} else {
// 获取校验失败的字段信息
errorFields.value = getInvalidFields(fields)
if (errorFields.value.length > 0) {
proxy.$message.error(errorFields.value[0].message)
}
}
})
}
// 获取流程详情
function getFanformInfo(fnaFormBizId, formData) {
getfanFormDetail(fnaFormBizId).then(async res => {
if (res.code == 200) {
// 回显值
setFormValue(res.data, formData)
}
})
}
watch(fanFormRef, newVal => {
if (newVal) {
for (const key in rules.value) {
for (const key2 in rules.value[key]) {
fanFormRef.value.clearValidate(key2)
}
}
}
})
watch(
() => props.activeName,
newVal => {
tempFanFormValue.value = JSON.parse(JSON.stringify(form.value))
tempFanFormData.value = JSON.parse(JSON.stringify(processedFanFormData.value))
if (newVal === 'policyInfo') {
setTimeout(() => {
processFormData()
}, 500)
}
}
)
processFormData()
</script>
<style lang="scss" scoped>
.domEmpty {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
height: 100%;
font-size: 16px;
color: #a8abb2;
margin-top: 100px;
}
.topBtn {
width: 100%;
display: flex;
justify-content: space-between;
margin-bottom: 10px;
}
.formBox {
width: 100%;
.fatherLable {
font-size: 18px;
border-left: 4px solid #165dff;
padding-left: 5px;
margin-bottom: 5px;
}
.subTitle {
font-size: 15px;
/* padding-left: 8px; */
margin-bottom: 10px;
}
.childLabel {
font-size: 14px;
/* padding-left: 15px; */
margin-bottom: 15px;
}
.fatherDes {
font-size: 14px;
color: #a8abb2;
margin-top: 5px;
margin-bottom: 20px;
}
.inputBox {
width: 100%;
border: 1px solid #dcdfe6;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: space-between;
min-height: 32px;
padding: 0px 11px;
.rightArrow {
font-size: 14px;
color: #a8abb2;
}
}
.deleteIcon {
color: red;
font-size: 18px;
padding-top: 10px;
}
}
.tabButton {
/* box-shadow: 0 -1px 14px #00000014; */
width: 100%;
display: flex;
align-items: center;
justify-content: center;
padding-top: 20px;
.sumbitBtn {
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
height: 60px;
background-color: #165dff;
color: #fff;
padding: 0 30px;
.buttonIcon {
font-size: 16px;
color: #fff;
}
}
}
.customerBox {
.customerItem {
padding: 10px;
border-radius: 5px;
margin-bottom: 20px;
box-shadow: 0 -1px 14px #00000014;
.top {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
.left {
width: 40%;
display: flex;
align-items: center;
justify-content: flex-start;
.gender {
display: flex;
align-items: center;
}
}
}
.bottom {
.infoItem {
display: flex;
align-items: center;
margin: 5px 0;
}
}
}
.customerItem:last-child {
margin-bottom: 0px;
}
}
/* 新增的样式:防止label换行并显示省略号 */
.formFna :deep(.el-checkbox) {
margin-right: 10px;
}
@media only screen and (min-width: 768px) {
.formInput {
margin-top: 30px !important;
}
}
@media only screen and (min-width: 1200px) {
.formInput {
margin-top: 30px !important;
}
}
</style>
<template>
<div>
<div v-if="processedFanFormData.length > 0">
<el-row>
<el-col :span="24">
<div class="topBtn">
<el-button
v-if="props.fnaFormBizId"
type="primary"
icon="EditPen"
@click="handleEditStatus"
>编辑</el-button
>
</div>
</el-col>
</el-row>
<el-form ref="fanFormRef" :model="form" :rules="rules">
<el-row v-for="father in processedFanFormData" style="margin-bottom: 10px">
<div class="formBox formFna">
<!-- <div class="fatherLable">{{ father.fatherTitle }}</div>
<div class="subTitle" v-if="father.subTitle">{{ father.subTitle }}</div> -->
<el-row v-if="father.child == 'no'" :gutter="20">
<template v-for="child in father.data" :key="child.key">
<el-col :sm="child.sm" :lg="child.lg" class="formItem" v-if="child.show">
<div>
<el-form-item
:label="child.label"
:prop="father.key + '.' + child.key"
:key="child.key"
:label-width="child.labelWidth"
:label-position="child.labelPosition"
>
<el-input
v-if="child.domType === 'Input'"
:type="child.inputType"
v-model="form[father.key][child.key]"
: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"
maxlength="30"
:disabled="child.disabled"
:style="{ width: child.inputWidth ? child.inputWidth : '100%' }"
class="formInput"
/>
<el-select
v-if="child.domType === 'Select'"
v-model="form[father.key][child.key]"
:placeholder="child.placeholder"
@change="handleSelectChange(father, child)"
:disabled="child.disabled"
>
<el-option
v-for="item in child.options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-date-picker
style="width: 100%"
v-if="child.domType === 'DatePicker'"
v-model="form[father.key][child.key]"
type="date"
:placeholder="child.placeholder"
:disabled="child.disabled"
/>
<el-checkbox-group
v-if="child.domType === 'Checkbox'"
v-model="form[father.key][child.key]"
:disabled="child.disabled"
>
<el-checkbox
v-for="item in child.options"
:key="item.value"
:label="item.value"
>
{{ item.label }}
</el-checkbox>
</el-checkbox-group>
<el-select
v-model="form[father.key][child.key]"
v-if="child.domType === 'SearchSelect'"
filterable
remote
reserve-keyword
placeholder="请输入关键词搜索"
:remote-method="query => searchSelectList(query, child.key)"
:loading="searchLoadingStates[child.key]"
:disabled="child.disabled"
@change="handleSearchSelectChange(father, child)"
>
<el-option
v-for="item in searchOptions[child.key] || []"
:key="item.id"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</div>
</el-col>
</template>
</el-row>
<el-row v-if="father.showTable">
<el-table :data="father.data" border>
<!-- && form[father.key].length > 0 -->
<template v-if="father.key == 'brokerList'">
<el-table-column label="转介人比例" prop="brokerRatio" align="center">
<template #default="scope">
<el-input
v-model="scope.row.brokerRatio"
size="default"
type="number"
placeholder="请输入"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column label="转介人名称" prop="brokerName" align="center">
<template #default="scope">
<el-select
v-model="scope.row.brokerName"
filterable
remote
reserve-keyword
placeholder="请输入关键词搜索"
:remote-method="query => searchSelectList(query, 'brokerName', scope.row)"
:loading="searchLoadingStates['brokerName']"
:disabled="editStatus"
>
<el-option
v-for="item in searchOptions['brokerName'] || []"
:key="item.id"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column label="所属团队" prop="team" align="center">
<template #default="scope">
<el-input
v-model="scope.row.team"
size="default"
type="text"
placeholder="请输入"
:disabled="editStatus"
/>
<!-- 和csf的销售小程序团队挂钩,因为没有接口现在先放在这等有了在换 -->
<!-- <el-select
v-model="scope.row.team"
filterable
remote
reserve-keyword
placeholder="请输入关键词搜索"
:remote-method="query => searchSelectList(query, 'team')"
:loading="searchLoadingStates['team']"
:disabled="editStatus"
>
<el-option
v-for="item in searchOptions['team'] || []"
:key="item.userBizId"
:label="item.realName"
:value="item.userBizId"
/>
</el-select> -->
</template>
</el-table-column>
<el-table-column label="备注" prop="remark" align="center">
<template #default="scope">
<el-input
v-model="scope.row.remark"
size="default"
type="textarea"
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-col
:span="24"
v-if="father.addFamilyChildren"
style="display: flex; justify-content: center"
>
<el-button
:disabled="editStatus"
style="margin-top: 10px"
type="primary"
icon="Plus"
@click="addChildren(father)"
>添加转介人</el-button
>
</el-col>
</el-row>
</div>
</el-row>
<el-row>
<el-col>
<div class="tabButton">
<el-button
type="success"
icon="Check"
@click="submitForm('save')"
size="large"
:disabled="editStatus"
>提交</el-button
>
</div>
</el-col>
</el-row>
</el-form>
</div>
<div v-else class="domEmpty" v-loading="loading"></div>
</div>
</template>
<script setup name="PolicyMailing">
import useDictStore from '@/store/modules/dict'
import policyMailing from '@/formJson/policyMailing'
import { getDicts } from '@/api/system/dict/data'
import { watch, nextTick } from 'vue'
import { addfanForm, getfanFormDetail, editFanForm, getCustomerList } from '@/api/sign/fna'
import {
listTenantUser,
getInsuranceProductList,
getAllCompanys,
getClientUser
} from '@/api/common'
import { updatePolicyfollow } from '@/api/sign/underwritingMain'
import useUserStore from '@/store/modules/user'
const userStore = useUserStore()
const dictStore = useDictStore() //获取字典数据
const props = defineProps({
customerInfo: { type: Object, default: () => {} }, //客户详情
activeName: { type: String, default: '' }, //tab名称
fearthStatus: { type: String, default: '' }, //父组件状态,新增、修改
policyBizId: { type: String, default: '' }, //提交状态,新增、修改
customerBizId: { type: String, default: '' }, //提交状态,新增、修改
dictTypeLists: { type: Array, default: () => [] } //多个字典值数据
})
const emit = defineEmits(['handleSuccess'])
const { proxy } = getCurrentInstance()
const loading = ref(false)
const fanFormRef = ref(null)
const errorFields = ref([]) // 存储校验失败的字段信息
const editStatus = ref(true) // 表单是否可编辑,若是修改初始不可编辑
const openList = ref(false) // 客户列表弹窗
const noYesList = ref([]) // 是否列表
const searchOptions = ref({}) // 存储不同key对应的选项
const searchLoadingStates = ref({}) // 存储不同key对应的加载状态
const data = reactive({
form: {},
processedFanFormData: [], // 处理后的表单数据
tempFanFormValue: {}, // 切换tab得时候保存临时填写得值
tempFanFormData: [], // 处理后的表单数据
oldFanFormData: [], // 保存旧的表单Dom,便于撤销操作
rules: {}, //表单验证规则,
queryParams: {
pageNo: 1,
pageSize: 4,
name: undefined
}
})
const {
form,
rules,
processedFanFormData,
queryParams,
oldFanFormData,
tempFanFormValue,
tempFanFormData
} = toRefs(data)
const disabledDate = time => {
return time.getTime() > Date.now()
}
// 搜索方法
const searchSelectList = async (query, fieldKey) => {
// 设置该字段的加载状态
searchLoadingStates.value[fieldKey] = true
try {
// 根据不同的字段key调用不同的API
if (fieldKey === 'productName') {
const params = {
loginTenantBizId: userStore.projectInfo.tenantBizId,
productName: query.trim(),
pageNo: 1,
pageSize: 10
}
const response = await getInsuranceProductList(params)
if (response.code == 200) {
response.data.records = response.data.records.map(item => {
return {
...item,
label: item.productName,
value: item.productBizId
}
})
searchOptions.value[fieldKey] = response.data.records
}
}
// 可以添加其他字段的处理,可以放其他的字段得请求,目前只有accountName,以后有了其他的在填充
else if (fieldKey === 'reconciliationCompany' || fieldKey === 'insurer') {
const params = {
deptName: query.trim(),
pageNo: 1,
pageSize: 10
}
getAllCompanys(params).then(response => {
response.data.records = response.data.records.map(item => {
return {
...item,
label: item.deptName,
value: item.deptBizId
}
})
searchOptions.value[fieldKey] = response.data.records
})
} else if (fieldKey === 'brokerName') {
const params = {
projectBizId: 'project_IbjfmMTYvNEBuh2S',
tenantBizId: userStore.projectInfo.tenantBizId,
queryContent: query.trim(),
pageNo: 1,
pageSize: 10
}
getClientUser(params).then(response => {
response.data.records = response.data.records.map(item => {
return {
...item,
label: item.name,
value: item.clientUserBizId
}
})
searchOptions.value[fieldKey] = response.data.records
})
}
} catch (error) {
console.error(`${fieldKey} 搜索失败`, error)
searchOptions.value[fieldKey] = []
} finally {
searchLoadingStates.value[fieldKey] = false
}
}
const handleSearchSelectChange = (father, child) => {
if (child.key == 'productName') {
let productItem = dictStore.insureProductList.filter(item => {
return item.value == form.value[father.key][child.key]
})
let options = productItem[0].paymentTerm.split(',').map(item => {
return {
label: item,
value: item
}
})
const processedData = JSON.parse(JSON.stringify(processedFanFormData.value))
for (const section of processedData) {
if (section.key == father.key) {
if (section.data) {
for (const field of section.data) {
if (field.dictType && field.dictType == 'paymentTerm') {
field.options = options
}
}
}
}
}
if (options.length > 0) {
form.value[father.key]['paymentTerm'] = options[0].value
}
processedFanFormData.value = processedData
}
}
// 获取字典数据
const fetchDictData = dictType => {
let options = []
try {
dictStore.dictTypeLists.forEach(item => {
if (item.dictType == dictType) {
options = item.dictItemList
}
})
return options
} catch (error) {
console.error('获取字典数据失败:', error)
return []
}
}
// 处理表单配置,添加字典数据
const processFormData = () => {
loading.value = true
// 深拷贝原始数据
const processedData = JSON.parse(JSON.stringify(policyMailing))
for (const section of processedData) {
if (section.fatherRequired) {
rules.value[section.key] = {}
}
//给表单赋值各模块key,对应表单的father.key便于收集值
if (section.keyType == 'Array') {
form.value[section.key] = []
if (section.key == 'brokerList') {
form.value[section.key] = section.data
}
} else if (section.keyType == 'Object') {
form.value[section.key] = {}
}
if (section.data) {
for (const formKey in form.value) {
if (section.key == formKey) {
for (const field of section.data) {
// 为下拉搜索框加options
if (field.domType == 'SearchSelect') {
if (field.key == 'accountName') {
searchOptions.value[field.key] = dictStore.tenantUserList
}
}
if (field.dictType) {
// 获取字典数据
field.options = fetchDictData(field.dictType)
}
//
/*
1.没有嵌套子级的也就是没有children的数据加rules,根据data中的required字段判断是否必填
2.有嵌套子级的也就是有children的数据,根据children中的required字段判断是否必填,现在没这个需求,所以先注释
*/
if (field.required && section.child == 'no') {
rules.value[section.key][field.key] = [
{ required: true, message: `${field.label}不能为空`, trigger: 'blur' }
]
}
if (props.fnaFormBizId) {
field.disabled = true
} else {
field.disabled = false
}
}
}
}
}
}
if (Object.keys(tempFanFormValue.value).length > 0) {
form.value = JSON.parse(JSON.stringify(tempFanFormValue.value))
}
if (tempFanFormData.value.length > 0) {
processedFanFormData.value = oldFanFormData.value = JSON.parse(
JSON.stringify(tempFanFormData.value)
)
} else {
processedFanFormData.value = oldFanFormData.value = processedData
}
if (props.policyBizId) {
editStatus.value = true
} else {
// tab切走在切回来时,表单会重置,所以这里需要把表单的值赋回去
editStatus.value = false
loading.value = false
}
console.log('form', form.value)
}
// 添加表单子级dom
const addChildren = father => {
// if (editStatus.value) {
// proxy.$modal.confirm(`请先点击编辑再添加儿女`, { showCancel: '0', title: '填写提示' })
// return
// }
const processedData = JSON.parse(JSON.stringify(processedFanFormData.value))
let obj = {
id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识
brokerName: '',
team: '',
brokerRatio: '',
remark: ''
}
for (const section of processedData) {
if (father.key == 'brokerList' && section.key == father.key) {
section.data.push(obj)
}
}
//更新form表单对应的数据,以便收集填写的值
form.value[father.key].push(obj)
processedFanFormData.value = processedData
}
const deleteChildren = (father, childIndex) => {
// if (editStatus.value) {
// proxy.$modal.confirm(`请先点击编辑再删除儿女`, { showCancel: '0', title: '填写提示' })
// }
const processedData = JSON.parse(JSON.stringify(processedFanFormData.value))
for (const section of processedData) {
if (father.key == 'brokerList' && section.key == father.key) {
section.data.splice(childIndex, 1)
}
}
//更新form表单对应的数据,以便收集填写的值
form.value[father.key].splice(childIndex, 1)
processedFanFormData.value = processedData
}
// 根据联动重置表单项的显示与否
const resetShow = (childKey, status) => {
console.log(childKey, status)
for (const section of processedFanFormData.value) {
// 暂时没考虑data里嵌套children的情况
if (section.data) {
for (const field of section.data) {
if (field.key == childKey) {
// 获取字典数据
field.show = status
}
}
}
}
}
const handleSelectChange = (father, child) => {
switch (child.key) {
case 'employment':
// 选择吸烟,展示吸烟数量
if (form.value[father.key][child.key] == 'OTHER') {
resetShow('otherEmployment', true)
form.value[father.key]['otherEmployment'] = ''
} else {
resetShow('otherEmployment', false)
}
break
default:
break
}
}
// 改变编辑状态
const handleEditStatus = () => {
editStatus.value = !editStatus.value
// 深拷贝原始数据
const processedData = JSON.parse(JSON.stringify(processedFanFormData.value))
for (const section of processedData) {
if (section.data) {
for (const field of section.data) {
// 改变data中字段得编辑状态
if (editStatus.value) {
field.disabled = true
} else {
field.disabled = false
}
// 改变data中的children字段得编辑状态
if (field.children) {
for (const child of field.children) {
if (editStatus.value) {
child.disabled = true
} else {
child.disabled = false
}
}
}
}
}
}
processedFanFormData.value = processedData
}
//给表单赋值 方便表单回显 obj 为表单数据
const setFormValue = (obj, formData) => {
loading.value = true
}
// 获取校验失败的字段信息
const getInvalidFields = fields => {
const errors = []
for (const field in fields) {
if (fields[field] && fields[field].length > 0) {
errors.push({
field: field,
message: fields[field][0].message
})
}
}
return errors
}
// 判断是否为数组
const isArray = value => {
return Array.isArray(value)
}
// 判断是否为对象
const isObject = value => {
return typeof value === 'object' && value !== null && !Array.isArray(value)
}
// 处理表单填写得数据
const handleFormValues = () => {
let submitObj = JSON.parse(JSON.stringify(form.value))
const pattern = /Date$/ // 以Time结尾
// debugger
//处理表单数据
for (const key1 in form.value) {
// 对象数据格式
if (isObject(form.value[key1]) && Object.keys(form.value[key1]).length > 0) {
for (const key2 in form.value[key1]) {
if (pattern.test(key2) && form.value[key1][key2]) {
submitObj[key1][key2] = proxy.formatToDate(form.value[key1][key2])
}
// 处理搜索下拉框数据需要返回的各种业务ID
if ((key2 == 'insurer' || key2 === 'reconciliationCompany') && form.value[key1][key2]) {
dictStore.insureCompanyList.forEach(item => {
if (item.deptBizId == form.value[key1][key2]) {
submitObj[key1][key2] = item.deptName
submitObj[key1][`${key2}BizId`] = item.deptBizId
}
})
} else if (key2 == 'productName' && form.value[key1][key2]) {
dictStore.insureProductList.forEach(item => {
if (item.productBizId == form.value[key1][key2]) {
submitObj[key1][key2] = item.productName
submitObj[key1]['productBizId'] = item.productBizId
}
})
}
}
}
// 数组数据格式
if (isArray(form.value[key1]) && form.value[key1].length > 0) {
submitObj[key1] = form.value[key1].map(item1 => {
if (item1.brokerName) {
dictStore.clientUserList.forEach(item => {
if (item.clientUserBizId == item1.brokerName) {
item1.brokerName = item.name
item1['brokerBizId'] = item.clientUserBizId
}
})
}
delete item1.id
return item1
})
}
}
return submitObj
}
// 表单提交
const submitForm = saveType => {
let submitObj = handleFormValues()
// return
proxy.$refs['fanFormRef'].validate((valid, fields) => {
if (valid) {
console.log('====================================')
console.log(' props.policyBizId', submitObj)
console.log('====================================')
// return
if (props.policyBizId) {
// submitObj.PolicyFollowUpdateDto.policyBizId = props.policyBizId
updatePolicyfollow(submitObj).then(res => {
if (res.code == 200) {
handleEditStatus()
proxy.$message.success('提交成功')
// emit('handleSuccess', {
// tab: 'fnaform',
// fnaFormBizId: props.fnaFormBizId,
// type: 'edit'
// })
}
})
} else {
// addfanForm(result).then(res => {
// if (res.code == 200) {
// proxy.$message.success('fnaForm新增成功')
// emit('handleSuccess', {
// tab: 'fnaform',
// fnaFormBizId: res.data.fnaFormBizId,
// type: 'add'
// })
// }
// })
}
errorFields.value = [] // 清空错误信息
} else {
// 获取校验失败的字段信息
errorFields.value = getInvalidFields(fields)
if (errorFields.value.length > 0) {
proxy.$message.error(errorFields.value[0].message)
}
}
})
}
// 获取流程详情
function getFanformInfo(fnaFormBizId, formData) {
getfanFormDetail(fnaFormBizId).then(async res => {
if (res.code == 200) {
// 回显值
setFormValue(res.data, formData)
}
})
}
watch(fanFormRef, newVal => {
if (newVal) {
for (const key in rules.value) {
for (const key2 in rules.value[key]) {
fanFormRef.value.clearValidate(key2)
}
}
}
})
watch(
() => props.activeName,
newVal => {
tempFanFormValue.value = JSON.parse(JSON.stringify(form.value))
tempFanFormData.value = JSON.parse(JSON.stringify(processedFanFormData.value))
if (newVal === 'policyMailing') {
setTimeout(() => {
processFormData()
}, 500)
}
}
)
processFormData()
</script>
<style lang="scss" scoped>
.domEmpty {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
height: 100%;
font-size: 16px;
color: #a8abb2;
margin-top: 100px;
}
.topBtn {
width: 100%;
display: flex;
justify-content: space-between;
margin-bottom: 10px;
}
.formBox {
width: 100%;
.fatherLable {
font-size: 18px;
border-left: 4px solid #165dff;
padding-left: 5px;
margin-bottom: 5px;
}
.subTitle {
font-size: 15px;
/* padding-left: 8px; */
margin-bottom: 10px;
}
.childLabel {
font-size: 14px;
/* padding-left: 15px; */
margin-bottom: 15px;
}
.fatherDes {
font-size: 14px;
color: #a8abb2;
margin-top: 5px;
margin-bottom: 20px;
}
.inputBox {
width: 100%;
border: 1px solid #dcdfe6;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: space-between;
min-height: 32px;
padding: 0px 11px;
.rightArrow {
font-size: 14px;
color: #a8abb2;
}
}
.deleteIcon {
color: red;
font-size: 18px;
padding-top: 10px;
}
}
.tabButton {
/* box-shadow: 0 -1px 14px #00000014; */
width: 100%;
display: flex;
align-items: center;
justify-content: center;
padding-top: 20px;
.sumbitBtn {
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
height: 60px;
background-color: #165dff;
color: #fff;
padding: 0 30px;
.buttonIcon {
font-size: 16px;
color: #fff;
}
}
}
.customerBox {
.customerItem {
padding: 10px;
border-radius: 5px;
margin-bottom: 20px;
box-shadow: 0 -1px 14px #00000014;
.top {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
.left {
width: 40%;
display: flex;
align-items: center;
justify-content: flex-start;
.gender {
display: flex;
align-items: center;
}
}
}
.bottom {
.infoItem {
display: flex;
align-items: center;
margin: 5px 0;
}
}
}
.customerItem:last-child {
margin-bottom: 0px;
}
}
/* 新增的样式:防止label换行并显示省略号 */
.formFna :deep(.el-checkbox) {
margin-right: 10px;
}
@media only screen and (min-width: 768px) {
.formInput {
margin-top: 30px !important;
}
}
@media only screen and (min-width: 1200px) {
.formInput {
margin-top: 30px !important;
}
}
</style>
<template>
<div>
<div v-if="processedFanFormData.length > 0">
<el-row>
<el-col :span="24">
<div class="topBtn">
<el-button
v-if="props.fnaFormBizId"
type="primary"
icon="EditPen"
@click="handleEditStatus"
>编辑</el-button
>
</div>
</el-col>
</el-row>
<el-form ref="fanFormRef" :model="form" :rules="rules">
<el-row v-for="father in processedFanFormData" style="margin-bottom: 10px">
<div class="formBox formFna">
<!-- <div class="fatherLable">{{ father.fatherTitle }}</div>
<div class="subTitle" v-if="father.subTitle">{{ father.subTitle }}</div> -->
<el-row v-if="father.child == 'no'" :gutter="20">
<template v-for="child in father.data" :key="child.key">
<el-col :sm="child.sm" :lg="child.lg" class="formItem" v-if="child.show">
<div>
<el-form-item
:label="child.label"
:prop="father.key + '.' + child.key"
:key="child.key"
:label-width="child.labelWidth"
:label-position="child.labelPosition"
>
<el-input
v-if="child.domType === 'Input'"
:type="child.inputType"
v-model="form[father.key][child.key]"
: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"
maxlength="30"
:disabled="child.disabled"
:style="{ width: child.inputWidth ? child.inputWidth : '100%' }"
class="formInput"
/>
<el-select
v-if="child.domType === 'Select'"
v-model="form[father.key][child.key]"
:placeholder="child.placeholder"
@change="handleSelectChange(father, child)"
:disabled="child.disabled"
>
<el-option
v-for="item in child.options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-date-picker
style="width: 100%"
v-if="child.domType === 'DatePicker'"
v-model="form[father.key][child.key]"
type="date"
:placeholder="child.placeholder"
:disabled="child.disabled"
/>
<el-checkbox-group
v-if="child.domType === 'Checkbox'"
v-model="form[father.key][child.key]"
:disabled="child.disabled"
>
<el-checkbox
v-for="item in child.options"
:key="item.value"
:label="item.value"
>
{{ item.label }}
</el-checkbox>
</el-checkbox-group>
<el-select
v-model="form[father.key][child.key]"
v-if="child.domType === 'SearchSelect'"
filterable
remote
reserve-keyword
placeholder="请输入关键词搜索"
:remote-method="query => searchSelectList(query, child.key)"
:loading="searchLoadingStates[child.key]"
:disabled="child.disabled"
@change="handleSearchSelectChange(father, child)"
>
<el-option
v-for="item in searchOptions[child.key] || []"
:key="item.id"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</div>
</el-col>
</template>
</el-row>
<el-row v-if="father.showTable">
<el-table :data="father.data" border>
<!-- && form[father.key].length > 0 -->
<template v-if="father.key == 'brokerList'">
<el-table-column label="转介人比例" prop="brokerRatio" align="center">
<template #default="scope">
<el-input
v-model="scope.row.brokerRatio"
size="default"
type="number"
placeholder="请输入"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column label="转介人名称" prop="brokerName" align="center">
<template #default="scope">
<el-select
v-model="scope.row.brokerName"
filterable
remote
reserve-keyword
placeholder="请输入关键词搜索"
:remote-method="query => searchSelectList(query, 'brokerName', scope.row)"
:loading="searchLoadingStates['brokerName']"
:disabled="editStatus"
>
<el-option
v-for="item in searchOptions['brokerName'] || []"
:key="item.id"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column label="所属团队" prop="team" align="center">
<template #default="scope">
<el-input
v-model="scope.row.team"
size="default"
type="text"
placeholder="请输入"
:disabled="editStatus"
/>
<!-- 和csf的销售小程序团队挂钩,因为没有接口现在先放在这等有了在换 -->
<!-- <el-select
v-model="scope.row.team"
filterable
remote
reserve-keyword
placeholder="请输入关键词搜索"
:remote-method="query => searchSelectList(query, 'team')"
:loading="searchLoadingStates['team']"
:disabled="editStatus"
>
<el-option
v-for="item in searchOptions['team'] || []"
:key="item.userBizId"
:label="item.realName"
:value="item.userBizId"
/>
</el-select> -->
</template>
</el-table-column>
<el-table-column label="备注" prop="remark" align="center">
<template #default="scope">
<el-input
v-model="scope.row.remark"
size="default"
type="textarea"
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-col
:span="24"
v-if="father.addFamilyChildren"
style="display: flex; justify-content: center"
>
<el-button
:disabled="editStatus"
style="margin-top: 10px"
type="primary"
icon="Plus"
@click="addChildren(father)"
>添加转介人</el-button
>
</el-col>
</el-row>
</div>
</el-row>
<el-row>
<el-col>
<div class="tabButton">
<el-button
type="success"
icon="Check"
@click="submitForm('save')"
size="large"
:disabled="editStatus"
>提交</el-button
>
</div>
</el-col>
</el-row>
</el-form>
</div>
<div v-else class="domEmpty" v-loading="loading"></div>
</div>
</template>
<script setup name="VerifyPolicyInfo">
import useDictStore from '@/store/modules/dict'
import verifyPolicyInfo from '@/formJson/verifyPolicyInfo'
import { getDicts } from '@/api/system/dict/data'
import { watch, nextTick } from 'vue'
import { addfanForm, getfanFormDetail, editFanForm, getCustomerList } from '@/api/sign/fna'
import {
listTenantUser,
getInsuranceProductList,
getAllCompanys,
getClientUser
} from '@/api/common'
import { updatePolicyfollow } from '@/api/sign/underwritingMain'
import useUserStore from '@/store/modules/user'
const userStore = useUserStore()
const dictStore = useDictStore() //获取字典数据
const props = defineProps({
customerInfo: { type: Object, default: () => {} }, //客户详情
activeName: { type: String, default: '' }, //tab名称
fearthStatus: { type: String, default: '' }, //父组件状态,新增、修改
policyBizId: { type: String, default: '' }, //提交状态,新增、修改
customerBizId: { type: String, default: '' }, //提交状态,新增、修改
dictTypeLists: { type: Array, default: () => [] } //多个字典值数据
})
const emit = defineEmits(['handleSuccess'])
const { proxy } = getCurrentInstance()
const loading = ref(false)
const fanFormRef = ref(null)
const errorFields = ref([]) // 存储校验失败的字段信息
const editStatus = ref(true) // 表单是否可编辑,若是修改初始不可编辑
const openList = ref(false) // 客户列表弹窗
const noYesList = ref([]) // 是否列表
const searchOptions = ref({}) // 存储不同key对应的选项
const searchLoadingStates = ref({}) // 存储不同key对应的加载状态
const data = reactive({
form: {},
processedFanFormData: [], // 处理后的表单数据
tempFanFormValue: {}, // 切换tab得时候保存临时填写得值
tempFanFormData: [], // 处理后的表单数据
oldFanFormData: [], // 保存旧的表单Dom,便于撤销操作
rules: {}, //表单验证规则,
queryParams: {
pageNo: 1,
pageSize: 4,
name: undefined
}
})
const {
form,
rules,
processedFanFormData,
queryParams,
oldFanFormData,
tempFanFormValue,
tempFanFormData
} = toRefs(data)
const disabledDate = time => {
return time.getTime() > Date.now()
}
// 搜索方法
const searchSelectList = async (query, fieldKey) => {
// 设置该字段的加载状态
searchLoadingStates.value[fieldKey] = true
try {
// 根据不同的字段key调用不同的API
if (fieldKey === 'productName') {
const params = {
loginTenantBizId: userStore.projectInfo.tenantBizId,
productName: query.trim(),
pageNo: 1,
pageSize: 10
}
const response = await getInsuranceProductList(params)
if (response.code == 200) {
response.data.records = response.data.records.map(item => {
return {
...item,
label: item.productName,
value: item.productBizId
}
})
searchOptions.value[fieldKey] = response.data.records
}
}
// 可以添加其他字段的处理,可以放其他的字段得请求,目前只有accountName,以后有了其他的在填充
else if (fieldKey === 'reconciliationCompany' || fieldKey === 'insurer') {
const params = {
deptName: query.trim(),
pageNo: 1,
pageSize: 10
}
getAllCompanys(params).then(response => {
response.data.records = response.data.records.map(item => {
return {
...item,
label: item.deptName,
value: item.deptBizId
}
})
searchOptions.value[fieldKey] = response.data.records
})
} else if (fieldKey === 'brokerName') {
const params = {
projectBizId: 'project_IbjfmMTYvNEBuh2S',
tenantBizId: userStore.projectInfo.tenantBizId,
queryContent: query.trim(),
pageNo: 1,
pageSize: 10
}
getClientUser(params).then(response => {
response.data.records = response.data.records.map(item => {
return {
...item,
label: item.name,
value: item.clientUserBizId
}
})
searchOptions.value[fieldKey] = response.data.records
})
}
} catch (error) {
console.error(`${fieldKey} 搜索失败`, error)
searchOptions.value[fieldKey] = []
} finally {
searchLoadingStates.value[fieldKey] = false
}
}
const handleSearchSelectChange = (father, child) => {
if (child.key == 'productName') {
let productItem = dictStore.insureProductList.filter(item => {
return item.value == form.value[father.key][child.key]
})
let options = productItem[0].paymentTerm.split(',').map(item => {
return {
label: item,
value: item
}
})
const processedData = JSON.parse(JSON.stringify(processedFanFormData.value))
for (const section of processedData) {
if (section.key == father.key) {
if (section.data) {
for (const field of section.data) {
if (field.dictType && field.dictType == 'paymentTerm') {
field.options = options
}
}
}
}
}
if (options.length > 0) {
form.value[father.key]['paymentTerm'] = options[0].value
}
processedFanFormData.value = processedData
}
}
// 获取字典数据
const fetchDictData = dictType => {
let options = []
try {
dictStore.dictTypeLists.forEach(item => {
if (item.dictType == dictType) {
options = item.dictItemList
}
})
return options
} catch (error) {
console.error('获取字典数据失败:', error)
return []
}
}
// 处理表单配置,添加字典数据
const processFormData = () => {
loading.value = true
// 深拷贝原始数据
const processedData = JSON.parse(JSON.stringify(verifyPolicyInfo))
for (const section of processedData) {
if (section.fatherRequired) {
rules.value[section.key] = {}
}
//给表单赋值各模块key,对应表单的father.key便于收集值
if (section.keyType == 'Array') {
form.value[section.key] = []
if (section.key == 'brokerList') {
form.value[section.key] = section.data
}
} else if (section.keyType == 'Object') {
form.value[section.key] = {}
}
if (section.data) {
for (const formKey in form.value) {
if (section.key == formKey) {
for (const field of section.data) {
// 为下拉搜索框加options
if (field.domType == 'SearchSelect') {
if (field.key == 'accountName') {
searchOptions.value[field.key] = dictStore.tenantUserList
}
}
if (field.dictType) {
// 获取字典数据
field.options = fetchDictData(field.dictType)
}
//
/*
1.没有嵌套子级的也就是没有children的数据加rules,根据data中的required字段判断是否必填
2.有嵌套子级的也就是有children的数据,根据children中的required字段判断是否必填,现在没这个需求,所以先注释
*/
if (field.required && section.child == 'no') {
rules.value[section.key][field.key] = [
{ required: true, message: `${field.label}不能为空`, trigger: 'blur' }
]
}
if (props.fnaFormBizId) {
field.disabled = true
} else {
field.disabled = false
}
}
}
}
}
}
if (Object.keys(tempFanFormValue.value).length > 0) {
form.value = JSON.parse(JSON.stringify(tempFanFormValue.value))
}
if (tempFanFormData.value.length > 0) {
processedFanFormData.value = oldFanFormData.value = JSON.parse(
JSON.stringify(tempFanFormData.value)
)
} else {
processedFanFormData.value = oldFanFormData.value = processedData
}
if (props.policyBizId) {
editStatus.value = true
} else {
// tab切走在切回来时,表单会重置,所以这里需要把表单的值赋回去
editStatus.value = false
loading.value = false
}
console.log('form', form.value)
}
// 添加表单子级dom
const addChildren = father => {
// if (editStatus.value) {
// proxy.$modal.confirm(`请先点击编辑再添加儿女`, { showCancel: '0', title: '填写提示' })
// return
// }
const processedData = JSON.parse(JSON.stringify(processedFanFormData.value))
let obj = {
id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识
brokerName: '',
team: '',
brokerRatio: '',
remark: ''
}
for (const section of processedData) {
if (father.key == 'brokerList' && section.key == father.key) {
section.data.push(obj)
}
}
//更新form表单对应的数据,以便收集填写的值
form.value[father.key].push(obj)
processedFanFormData.value = processedData
}
const deleteChildren = (father, childIndex) => {
// if (editStatus.value) {
// proxy.$modal.confirm(`请先点击编辑再删除儿女`, { showCancel: '0', title: '填写提示' })
// }
const processedData = JSON.parse(JSON.stringify(processedFanFormData.value))
for (const section of processedData) {
if (father.key == 'brokerList' && section.key == father.key) {
section.data.splice(childIndex, 1)
}
}
//更新form表单对应的数据,以便收集填写的值
form.value[father.key].splice(childIndex, 1)
processedFanFormData.value = processedData
}
// 根据联动重置表单项的显示与否
const resetShow = (childKey, status) => {
console.log(childKey, status)
for (const section of processedFanFormData.value) {
// 暂时没考虑data里嵌套children的情况
if (section.data) {
for (const field of section.data) {
if (field.key == childKey) {
// 获取字典数据
field.show = status
}
}
}
}
}
const handleSelectChange = (father, child) => {
switch (child.key) {
case 'employment':
// 选择吸烟,展示吸烟数量
if (form.value[father.key][child.key] == 'OTHER') {
resetShow('otherEmployment', true)
form.value[father.key]['otherEmployment'] = ''
} else {
resetShow('otherEmployment', false)
}
break
default:
break
}
}
// 改变编辑状态
const handleEditStatus = () => {
editStatus.value = !editStatus.value
// 深拷贝原始数据
const processedData = JSON.parse(JSON.stringify(processedFanFormData.value))
for (const section of processedData) {
if (section.data) {
for (const field of section.data) {
// 改变data中字段得编辑状态
if (editStatus.value) {
field.disabled = true
} else {
field.disabled = false
}
// 改变data中的children字段得编辑状态
if (field.children) {
for (const child of field.children) {
if (editStatus.value) {
child.disabled = true
} else {
child.disabled = false
}
}
}
}
}
}
processedFanFormData.value = processedData
}
//给表单赋值 方便表单回显 obj 为表单数据
const setFormValue = (obj, formData) => {
loading.value = true
}
// 获取校验失败的字段信息
const getInvalidFields = fields => {
const errors = []
for (const field in fields) {
if (fields[field] && fields[field].length > 0) {
errors.push({
field: field,
message: fields[field][0].message
})
}
}
return errors
}
// 判断是否为数组
const isArray = value => {
return Array.isArray(value)
}
// 判断是否为对象
const isObject = value => {
return typeof value === 'object' && value !== null && !Array.isArray(value)
}
// 处理表单填写得数据
const handleFormValues = () => {
let submitObj = JSON.parse(JSON.stringify(form.value))
const pattern = /Date$/ // 以Time结尾
// debugger
//处理表单数据
for (const key1 in form.value) {
// 对象数据格式
if (isObject(form.value[key1]) && Object.keys(form.value[key1]).length > 0) {
for (const key2 in form.value[key1]) {
if (pattern.test(key2) && form.value[key1][key2]) {
submitObj[key1][key2] = proxy.formatToDate(form.value[key1][key2])
}
// 处理搜索下拉框数据需要返回的各种业务ID
if ((key2 == 'insurer' || key2 === 'reconciliationCompany') && form.value[key1][key2]) {
dictStore.insureCompanyList.forEach(item => {
if (item.deptBizId == form.value[key1][key2]) {
submitObj[key1][key2] = item.deptName
submitObj[key1][`${key2}BizId`] = item.deptBizId
}
})
} else if (key2 == 'productName' && form.value[key1][key2]) {
dictStore.insureProductList.forEach(item => {
if (item.productBizId == form.value[key1][key2]) {
submitObj[key1][key2] = item.productName
submitObj[key1]['productBizId'] = item.productBizId
}
})
}
}
}
// 数组数据格式
if (isArray(form.value[key1]) && form.value[key1].length > 0) {
submitObj[key1] = form.value[key1].map(item1 => {
if (item1.brokerName) {
dictStore.clientUserList.forEach(item => {
if (item.clientUserBizId == item1.brokerName) {
item1.brokerName = item.name
item1['brokerBizId'] = item.clientUserBizId
}
})
}
delete item1.id
return item1
})
}
}
return submitObj
}
// 表单提交
const submitForm = saveType => {
let submitObj = handleFormValues()
// return
proxy.$refs['fanFormRef'].validate((valid, fields) => {
if (valid) {
console.log('====================================')
console.log(' props.policyBizId', submitObj)
console.log('====================================')
// return
if (props.policyBizId) {
// submitObj.PolicyFollowUpdateDto.policyBizId = props.policyBizId
updatePolicyfollow(submitObj).then(res => {
if (res.code == 200) {
handleEditStatus()
proxy.$message.success('提交成功')
// emit('handleSuccess', {
// tab: 'fnaform',
// fnaFormBizId: props.fnaFormBizId,
// type: 'edit'
// })
}
})
} else {
// addfanForm(result).then(res => {
// if (res.code == 200) {
// proxy.$message.success('fnaForm新增成功')
// emit('handleSuccess', {
// tab: 'fnaform',
// fnaFormBizId: res.data.fnaFormBizId,
// type: 'add'
// })
// }
// })
}
errorFields.value = [] // 清空错误信息
} else {
// 获取校验失败的字段信息
errorFields.value = getInvalidFields(fields)
if (errorFields.value.length > 0) {
proxy.$message.error(errorFields.value[0].message)
}
}
})
}
// 获取流程详情
function getFanformInfo(fnaFormBizId, formData) {
getfanFormDetail(fnaFormBizId).then(async res => {
if (res.code == 200) {
// 回显值
setFormValue(res.data, formData)
}
})
}
watch(fanFormRef, newVal => {
if (newVal) {
for (const key in rules.value) {
for (const key2 in rules.value[key]) {
fanFormRef.value.clearValidate(key2)
}
}
}
})
watch(
() => props.activeName,
newVal => {
tempFanFormValue.value = JSON.parse(JSON.stringify(form.value))
tempFanFormData.value = JSON.parse(JSON.stringify(processedFanFormData.value))
if (newVal === 'verifyPolicyInfo') {
setTimeout(() => {
processFormData()
}, 500)
}
}
)
processFormData()
</script>
<style lang="scss" scoped>
.domEmpty {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
height: 100%;
font-size: 16px;
color: #a8abb2;
margin-top: 100px;
}
.topBtn {
width: 100%;
display: flex;
justify-content: space-between;
margin-bottom: 10px;
}
.formBox {
width: 100%;
.fatherLable {
font-size: 18px;
border-left: 4px solid #165dff;
padding-left: 5px;
margin-bottom: 5px;
}
.subTitle {
font-size: 15px;
/* padding-left: 8px; */
margin-bottom: 10px;
}
.childLabel {
font-size: 14px;
/* padding-left: 15px; */
margin-bottom: 15px;
}
.fatherDes {
font-size: 14px;
color: #a8abb2;
margin-top: 5px;
margin-bottom: 20px;
}
.inputBox {
width: 100%;
border: 1px solid #dcdfe6;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: space-between;
min-height: 32px;
padding: 0px 11px;
.rightArrow {
font-size: 14px;
color: #a8abb2;
}
}
.deleteIcon {
color: red;
font-size: 18px;
padding-top: 10px;
}
}
.tabButton {
/* box-shadow: 0 -1px 14px #00000014; */
width: 100%;
display: flex;
align-items: center;
justify-content: center;
padding-top: 20px;
.sumbitBtn {
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
height: 60px;
background-color: #165dff;
color: #fff;
padding: 0 30px;
.buttonIcon {
font-size: 16px;
color: #fff;
}
}
}
.customerBox {
.customerItem {
padding: 10px;
border-radius: 5px;
margin-bottom: 20px;
box-shadow: 0 -1px 14px #00000014;
.top {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
.left {
width: 40%;
display: flex;
align-items: center;
justify-content: flex-start;
.gender {
display: flex;
align-items: center;
}
}
}
.bottom {
.infoItem {
display: flex;
align-items: center;
margin: 5px 0;
}
}
}
.customerItem:last-child {
margin-bottom: 0px;
}
}
/* 新增的样式:防止label换行并显示省略号 */
.formFna :deep(.el-checkbox) {
margin-right: 10px;
}
@media only screen and (min-width: 768px) {
.formInput {
margin-top: 30px !important;
}
}
@media only screen and (min-width: 1200px) {
.formInput {
margin-top: 30px !important;
}
}
</style>
<template>
<div class="app-container">
<!-- <div>
<el-button type="primary" icon="Back" @click="handleBack" style="margin-bottom: 10px"
>返回</el-button
>
</div> -->
<!-- <el-card shadow="never">
<div class="tabsBox">
<el-tabs v-model="activeName" type="card" class="demo-tabs" :before-leave="beforeTabLeave">
<el-tab-pane v-for="tab in tabsList" :key="tab.name" :label="tab.label" :name="tab.name">
<div class="tabPaneBox">
<div v-if="tab.name === 'status'">新单状态</div>
<div v-if="tab.name === 'info'">
<PolicyInfo
:activeName="activeName"
:policyBizId="route.query.policyBizId"
:dictTypeLists="dictTypeLists"
:policyInfo="policyInfo"
/>
</div>
<div v-if="tab.name === 'accessories'">
<FileUpload
:activeName="activeName"
:policyBizId="route.query.policyBizId"
/>
</div>
</div>
</el-tab-pane>
</el-tabs>
</div>
</el-card> -->
<AppointmentEdit source='policyList' :policyDetailInfo="route.query"/>
</div>
</template>
<script setup name="FollowUpDetail">
import AppointmentEdit from '@/views/sign/appointment/appointmentEdit'
import { onUnmounted } from 'vue'
import { getPolicyfollow, getPolicyStatus } from '@/api/sign/underwritingMain'
import useUserStore from '@/store/modules/user'
import useDictStore from '@/store/modules/dict'
import { addFna, getProcessDetail, updateProcess, getCustomerDetail } from '@/api/sign/fna'
import {
listTenantUser,
getInsuranceProductList,
getAdditionalProductList,
getAllCompanys,
getClientUser
} from '@/api/common'
import PolicyInfo from './components/policyInfo'
import FileUpload from './components/fileUpload.vue'
import { Check } from '@element-plus/icons-vue'
import { ref } from 'vue'
const userStore = useUserStore()
const dictStore = useDictStore()
const { proxy } = getCurrentInstance()
const route = useRoute()
const router = useRouter()
const activeName = ref('status')
const processInfo = ref({
fnaNo: '--',
status: '未保存',
createTime: proxy.parseTime(new Date()),
customerName: userStore.name
}) // 流程详情信息
const updateStatus = ref(false)
const dictTypeLists = ref([])
const customerInfo = ref({})
const tabsList = ref([
{
label: '新单状态',
name: 'status',
id: 1,
status: '0',
key: 'customerBizId'
},
{
label: '新单信息',
name: 'info',
id: 2,
status: '0',
key: 'fnaFormBizId'
},
{
label: '新单附件',
name: 'accessories',
id: 3,
status: '0',
key: 'policyBizld'
}
])
const policyInfo = ref({}) //新单信息详情
const policyStatusList = ref({}) //新单信息状态
const { csf_fna_status } = proxy.useDict('csf_fna_status')
// 获取各个流程所需要得字典数据
const getDictsData = async () => {
// 获取租户用户列表
const params1 = {
tenantBizId: userStore.projectInfo.tenantBizId,
pageNo: 1,
pageSize: 10
}
const response1 = await listTenantUser(params1)
if (response1.code == 200) {
dictStore.setTenantUserList(response1.data.records)
}
const params2 = {
loginTenantBizId: userStore.projectInfo.tenantBizId,
pageNo: 1,
pageSize: 10
}
const response2 = await getInsuranceProductList(params2)
if (response2.code == 200) {
response2.data.records = response2.data.records.map(item => {
return {
...item,
label: item.productName,
value: item.productBizId
}
})
dictStore.setInsureProductList(response2.data.records)
}
const params3 = {
pageNo: 1,
pageSize: 10
}
const response3 = await getAdditionalProductList(params3)
if (response3.code == 200) {
response3.data.records = response3.data.records.map(item => {
return {
...item,
label: item.productName,
value: item.additionalProductBizId
}
})
dictStore.setAdditionalProductList(response3.data.records)
}
const params4 = {
pageNo: 1,
pageSize: 10
}
const response4 = await getAllCompanys(params4)
if (response4.code == 200) {
response4.data.records = response4.data.records.map(item => {
return {
...item,
label: item.deptName,
value: item.deptBizId
}
})
dictStore.setInsureCompanyList(response4.data.records)
}
const params5 = {
projectBizId: 'project_IbjfmMTYvNEBuh2S',
tenantBizId: userStore.projectInfo.tenantBizId,
pageNo: 1,
pageSize: 10
}
const response5 = await getClientUser(params5)
if (response5.code == 200) {
response5.data.records = response5.data.records.map(item => {
return {
...item,
label: item.name,
value: item.clientUserBizId
}
})
dictStore.setClientUserList(response5.data.records)
}
// 请求每个流程中所涉及到的字典值数据
proxy.useDictLists([
'csf_employment',
'sys_no_yes',
'bx_currency_type',
'csf_liquid_asset_type',
'csf_premium_funding_source',
'csf_customer_type',
'csf_customer_title',
'sys_gender',
'csf_marriage',
'csf_education',
'csf_id_type',
'csf_ap_apply_type',
'csf_ap_meeting_point',
'csf_ap_first_issue',
'csf_ap_dividend',
'csf_ap_frequency',
'csf_ap_rel',
'csf_ap_registration',
'csf_ap_exercise',
'csf_ap_risk',
'csf_ap_movie',
'csf_ap_game',
'wj_question_first_category',
'wj_question_second_category',
'csf_ap_policy_transfer',
'md_bank'
])
}
// 获取新单跟进详情数据
const getPolicyDetail = () => {
getPolicyfollow(route.query.policyBizId).then(res => {
if (res.code == 200) {
console.log('新单跟进详情', res)
policyInfo.value = res.data
}
})
getPolicyStatus(route.query.policyBizId).then(res => {
if (res.code == 200) {
console.log('新单跟进状态', res)
policyStatusList.value = res.data
}
})
}
// 更新流程
const processUpdate = (data, status) => {
updateProcess(data).then(res => {
if (res.code == 200) {
updateStatus.value = false
console.log('更新流程', res)
// 获取流程详情
getProcessInfo(data.fnaBizId, status)
}
})
}
// 获取流程详情
function getProcessInfo(fnaBizId, changeTab) {
getProcessDetail(fnaBizId).then(res => {
if (res.code == 200) {
processInfo.value = res.data
tabsList.value.forEach(item => {
if (res.data[item.key] && item.status) {
item.status = '1'
} else {
item.status = '0'
}
})
csf_fna_status._object.csf_fna_status.forEach(item => {
if (item.value == res.data.status) {
processInfo.value.status = item.label
}
})
if (changeTab) {
activeName.value = changeTab
}
}
})
}
// Tab切换前的验证
const beforeTabLeave = (activeTabName, oldTabName) => {
// if (processInfo.value.customerBizId) {
// getCustomerInfo(processInfo.value.customerBizId)
// }
// // 如果切换到总览,始终允许
// if (activeTabName === 'overview' || activeTabName === 'customer') {
// return true
// }
// // 获取当前要切换到的tab
// const targetTab = tabsList.value.find(tab => tab.name === activeTabName)
// // 如果目标tab不存在,阻止切换
// if (!targetTab) {
// return false
// }
// // 检查前一项状态
// const prevTabIndex = tabsList.value.findIndex(tab => tab.name === activeTabName) - 1
// if (prevTabIndex >= 0) {
// const prevTab = tabsList.value[prevTabIndex]
// // 如果前一项存在且未完成,阻止切换
// if (prevTab.status === '0') {
// proxy.$modal.confirm(`请先填写${prevTab.label}`, { showCancel: '0', title: '填写提示' })
// return false
// }
// }
return true
}
// 处理步骤点击
const handleStep = item => {
// 总览页可以直接切换
if (item.id === -1 || item.name === 'customer') {
activeName.value = item.name
return
}
// 检查前一项状态
const prevTabIndex = tabsList.value.findIndex(tab => tab.id === item.id) - 1
if (prevTabIndex >= 0) {
const prevTab = tabsList.value[prevTabIndex]
// 如果前一项存在且未完成,阻止切换
if (prevTab.status === '0') {
proxy.$modal.confirm(`请先填写${prevTab.label}`, { showCancel: false })
return
}
}
// 允许切换
activeName.value = item.name
}
const handleBack = () => {
router.go(-1)
}
// 获取客户详情
function getCustomerInfo(customerBizId) {
getCustomerDetail(customerBizId).then(async res => {
if (res.code == 200) {
customerInfo.value = res.data
}
})
}
const handleSuccess = info => {
switch (info.tab) {
case 'customer':
if (info.type == 'add') {
//客户提交成功,更新流程
processUpdate({ fnaBizId: info.fnaBizId, customerBizId: info.customerBizId }, 'fnaform')
} else {
processUpdate({ fnaBizId: processInfo.value.fnaBizId, customerBizId: info.customerBizId })
}
getCustomerInfo(info.customerBizId)
break
case 'fnaform':
if (info.type == 'add') {
//客户提交成功,更新流程
processUpdate(
{
fnaBizId: processInfo.value.fnaBizId,
customerBizId: info.customerBizId,
fnaFormBizId: info.fnaFormBizId
},
'appointment'
)
} else {
processUpdate({
fnaBizId: processInfo.value.fnaBizId,
customerBizId: info.customerBizId,
fnaFormBizId: info.fnaFormBizId
})
}
break
case 'appointment':
if (info.type == 'add') {
getProcessInfo(processInfo.value.fnaBizId, 'newpolicy')
} else {
}
break
case 'newpolicy':
break
case 'policy':
break
default:
break
}
}
if (route.query.type == 'edit') {
getPolicyDetail()
}
getDictsData()
</script>
<style lang="scss" scoped>
::v-deep .el-card {
border: none !important;
}
::v-deep .el-input-group__append,
.el-input-group__prepend {
background-color: #fff !important;
}
.app-container {
display: flex;
flex-direction: column;
min-height: calc(100vh - 84.5px);
padding: 20px;
background-color: #f2f3f5;
.cardHeader {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
.left {
display: flex;
justify-content: flex-start;
align-items: center;
.iconBox {
width: 40px;
height: 40px;
margin-right: 5px;
background-color: #e8f3ff;
border-radius: 3px;
text-align: center;
padding: 5px;
}
.rightBox {
margin-left: 10px;
display: flex;
flex-direction: column;
.num {
font-size: 14px;
}
.bottom {
display: flex;
align-items: center;
margin-top: 3px;
.status {
font-size: 11px;
color: #00b42a;
background-color: #e8ffea;
padding: 4px 6px;
border-radius: 2px;
margin-right: 10px;
}
.time {
font-size: 12px;
color: #86909c;
.icon-yanqiweiwancheng {
margin-right: 5px;
font-size: 12px;
}
}
}
}
}
}
.tabsBox {
.tabButton {
box-shadow: 0 -1px 14px #00000014;
width: 100%;
display: flex;
align-items: center;
justify-content: flex-end;
padding-right: 20px;
padding-top: 20px;
.sumbitBtn {
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
height: 60px;
background-color: #165dff;
color: #fff;
padding: 0 30px;
.buttonIcon {
font-size: 16px;
color: #fff;
}
}
}
}
.tabPaneBox {
/* height: calc(100vh - 317px); */
height: calc(100vh - 215px);
overflow-y: auto;
padding-right: 10px;
}
.overviewBox {
display: flex;
align-items: center;
justify-content: space-between;
.oneItem {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
.circle {
width: 35px;
height: 35px;
box-sizing: border-box;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 5px;
}
.el-icon {
font-size: 16px;
font-weight: 600;
}
}
.finfishCircle {
background-color: #e8f3ff;
color: #165dff;
}
.todoCircle {
background-color: #165dff;
color: #fff;
}
.unFinishCircle {
background-color: #f2f3f5;
color: #4e5969;
}
.title {
font-size: 14px;
margin-bottom: 5px;
}
.finfishTitle {
color: #1d2129;
font-size: 14px;
}
.unFinishTitle {
color: #4e5969;
font-size: 13px;
}
.status {
font-size: 12px;
margin-bottom: 8px;
color: #86909c;
}
.finfishStatus {
color: #165dff;
}
.unFinishStatus {
color: #4e5969;
}
.operation {
display: flex;
align-items: center;
font-size: 12px;
.editIcon {
margin-right: 3px;
color: #165dff;
font-size: 12px;
}
}
.finfishOperation {
color: #4e5969;
}
.unFinishOperation {
color: #165dff;
}
}
}
</style>
...@@ -31,15 +31,15 @@ ...@@ -31,15 +31,15 @@
<el-col :span="8"> <el-col :span="8">
<div class="form-item"> <div class="form-item">
<label class="form-label">新单状态</label> <label class="form-label">新单状态</label>
<el-select <el-select v-model="searchForm.status" placeholder="请选择" clearable size="default">
v-model="searchForm.status"
placeholder="请选择"
clearable
size="default"
>
<!-- 增加全部,默认传空字符串 --> <!-- 增加全部,默认传空字符串 -->
<el-option label="全部" value=" " /> <el-option label="全部" value=" " />
<el-option v-for="item in policyFollowStatusList" :key="item.itemValue" :label="item.itemLabel" :value="item.itemValue" /> <el-option
v-for="item in policyFollowStatusList"
:key="item.itemValue"
:label="item.itemLabel"
:value="item.itemValue"
/>
</el-select> </el-select>
</div> </div>
</el-col> </el-col>
...@@ -60,24 +60,13 @@ ...@@ -60,24 +60,13 @@
/> />
</div> </div>
</el-col> </el-col>
<!-- :icon="Search" -->
<el-col :span="8" class="search-buttons"> <el-col :span="8" class="search-buttons">
<el-button <el-button type="primary" @click="handleSearch" size="default" class="search-btn">
type="primary"
@click="handleSearch"
size="default"
:icon="Search"
class="search-btn"
>
查询 查询
</el-button> </el-button>
<el-button <!-- :icon="RefreshLeft" -->
@click="resetForm" <el-button @click="resetForm" size="default"> 重置 </el-button>
size="default"
:icon="RefreshLeft"
>
重置
</el-button>
</el-col> </el-col>
</el-row> </el-row>
</el-card> </el-card>
...@@ -94,20 +83,11 @@ ...@@ -94,20 +83,11 @@
:show-file-list="false" :show-file-list="false"
accept=".xlsx, .xls" accept=".xlsx, .xls"
> >
<el-button <el-button type="success" :icon="UploadFilled" size="default">
type="success"
:icon="UploadFilled"
size="default"
>
上传Excel文件 上传Excel文件
</el-button> </el-button>
</el-upload> </el-upload>
<el-button <el-button text @click="downloadTemplate" size="default" class="download-template-btn">
text
@click="downloadTemplate"
size="default"
class="download-template-btn"
>
下载模板 下载模板
</el-button> </el-button>
</div> </div>
...@@ -151,40 +131,49 @@ ...@@ -151,40 +131,49 @@
> >
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<!-- 新单状态需要通过policyFollowStatusList和value匹配,显示label --> <!-- 新单状态需要通过policyFollowStatusList和value匹配,显示label -->
<el-table-column prop="status" label="新单状态" min-width="100" align="center" sortable> <el-table-column prop="status" label="新单状态" width="100" align="center" sortable>
<template #default="scope"> <template #default="scope">
<span>{{ convertStatusToDict(1,scope.row.status) }}</span> <span>{{ convertStatusToDict(1, scope.row.status) }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="policyNo" label="保单号" min-width="100" align="center" sortable/> <el-table-column prop="policyNo" label="保单号" width="150" align="center" sortable />
<el-table-column prop="customerName" label="客户名称" min-width="100" align="center" sortable/> <el-table-column prop="customerName" label="客户名称" width="100" align="center" sortable />
<el-table-column prop="signDate" label="签单日期" min-width="100" align="center" sortable/> <el-table-column prop="signDate" label="签单日期" width="150" align="center" sortable />
<el-table-column prop="signer" label="签单人" min-width="100" align="center" sortable/> <el-table-column prop="signer" label="签单人" width="100" align="center" sortable />
<el-table-column prop="paymentTerm" label="供款年期" min-width="100" align="center" sortable/> <el-table-column prop="paymentTerm" label="供款年期" width="100" align="center" sortable />
<el-table-column prop="productName" label="产品名称" min-width="100" align="center" sortable/> <el-table-column prop="productName" label="产品名称" width="150" align="center" sortable />
<el-table-column prop="insurer" label="保险公司" min-width="100" align="center" sortable/> <el-table-column prop="insurer" label="保险公司" width="150" align="center" sortable />
<el-table-column prop="reconciliationCompany" label="对账公司" min-width="100" align="center" sortable/> <el-table-column
<el-table-column prop="policyHolder" label="保单持有人" min-width="100" align="center" sortable/> prop="reconciliationCompany"
<el-table-column prop="insured" label="受保人" min-width="100" align="center" sortable/> label="对账公司"
<el-table-column prop="currency" label="币种" min-width="100" align="center" sortable/> width="150"
<el-table-column prop="initialPremium" label="首期保费" min-width="100" align="center" sortable> align="center"
sortable
/>
<el-table-column
prop="policyHolder"
label="保单持有人"
width="150"
align="center"
sortable
/>
<el-table-column prop="insured" label="受保人" width="100" align="center" sortable />
<el-table-column prop="currency" label="币种" width="100" align="center" sortable />
<el-table-column prop="initialPremium" label="首期保费" width="150" align="center" sortable>
<template #default="scope"> <template #default="scope">
{{ numberWithCommas(scope.row.initialPremium) }} {{ numberWithCommas(scope.row.initialPremium) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
label="操作" label="操作"
min-width="180"
align="center" align="center"
width="250"
class-name="small-padding fixed-width"
fixed="right"
> >
<template #default="scope"> <template #default="scope">
<el-button <el-button text size="primary" @click="handleView(scope.row)"> 查看 </el-button>
text <el-button text size="primary" @click="handleStatus(scope.row)"> 跟进 </el-button>
size="primary"
@click="handleView(scope.row)"
>
查看
</el-button>
<!-- <el-button <!-- <el-button
text text
size="default" size="default"
...@@ -221,8 +210,6 @@ ...@@ -221,8 +210,6 @@
@close="handleDetailClose" @close="handleDetailClose"
/> />
</div> </div>
</template> </template>
<script setup> <script setup>
...@@ -230,39 +217,47 @@ import { ref, reactive, onMounted } from 'vue' ...@@ -230,39 +217,47 @@ import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import axios from 'axios' import axios from 'axios'
import { getPolicyFollowList, getExpectedCommissionList } from '@/api/sign/underwritingMain' import { getPolicyFollowList, getExpectedCommissionList } from '@/api/sign/underwritingMain'
import { getToken } from "@/utils/auth" import { getToken } from '@/utils/auth'
import { listType } from '@/api/system/dict/type' import { listType } from '@/api/system/dict/type'
import date from '@/utils/date' import date from '@/utils/date'
import PolicyDetailDialog from '@/components/PolicyDetailDialog/index.vue' import PolicyDetailDialog from '@/components/PolicyDetailDialog/index.vue'
import { numberWithCommas } from '@/utils/index.js' import { numberWithCommas } from '@/utils/index.js'
import { getPolicyFortuneList } from '@/api/financial/commission' import { getPolicyFortuneList } from '@/api/financial/commission'
const router = useRouter()
// 通过dictType=csf_policy_follow_status获取新单状态字典值,获取对象中的dictItemList // 通过dictType=csf_policy_follow_status获取新单状态字典值,获取对象中的dictItemList
const policyFollowStatusList = ref([]); const policyFollowStatusList = ref([])
const commissionStatusList = ref([]); const commissionStatusList = ref([])
const fortuneStatusList = ref([]); const fortuneStatusList = ref([])
const getLists = ()=>{ const getLists = () => {
listType({typeList: ['csf_policy_follow_status','csf_expected_commission_status','csf_fortune_status']}).then(res => { listType({
typeList: ['csf_policy_follow_status', 'csf_expected_commission_status', 'csf_fortune_status']
})
.then(res => {
if (res.code === 200 && res.data) { if (res.code === 200 && res.data) {
const statusData = res.data.find(item => item.dictType === 'csf_policy_follow_status'); const statusData = res.data.find(item => item.dictType === 'csf_policy_follow_status')
policyFollowStatusList.value = statusData?.dictItemList || []; policyFollowStatusList.value = statusData?.dictItemList || []
const commissionStatusData = res.data.find(item => item.dictType === 'csf_expected_commission_status'); const commissionStatusData = res.data.find(
commissionStatusList.value = commissionStatusData?.dictItemList || []; item => item.dictType === 'csf_expected_commission_status'
const fortuneStatusData = res.data.find(item => item.dictType === 'csf_fortune_status'); )
fortuneStatusList.value = fortuneStatusData?.dictItemList || []; commissionStatusList.value = commissionStatusData?.dictItemList || []
const fortuneStatusData = res.data.find(item => item.dictType === 'csf_fortune_status')
fortuneStatusList.value = fortuneStatusData?.dictItemList || []
} else { } else {
policyFollowStatusList.value = []; policyFollowStatusList.value = []
commissionStatusList.value = []; commissionStatusList.value = []
fortuneStatusList.value = []; fortuneStatusList.value = []
} }
}).catch(error => { })
console.error('获取状态列表失败:', error); .catch(error => {
policyFollowStatusList.value = []; console.error('获取状态列表失败:', error)
policyFollowStatusList.value = []
}) })
} }
// 返回数据中状态需要转换为字典值 // 返回数据中状态需要转换为字典值
const convertStatusToDict = (type=1,status) => { const convertStatusToDict = (type = 1, status) => {
const arr = type === 1 ? policyFollowStatusList : type === 2 ? commissionStatusList : fortuneStatusList const arr =
type === 1 ? policyFollowStatusList : type === 2 ? commissionStatusList : fortuneStatusList
const dictItem = arr.value.find(item => item.itemValue == status) const dictItem = arr.value.find(item => item.itemValue == status)
return dictItem?.itemLabel ?? status return dictItem?.itemLabel ?? status
} }
...@@ -278,22 +273,21 @@ const searchForm = reactive({ ...@@ -278,22 +273,21 @@ const searchForm = reactive({
signDateRange: [], // 签单时间范围 signDateRange: [], // 签单时间范围
status: '', // 新单状态(对应接口的status) status: '', // 新单状态(对应接口的status)
// 高级筛选字段 // 高级筛选字段
insurer : '', // 保险公司 insurer: '', // 保险公司
productCode: '' // 产品代码(对应接口的productCode) productCode: '' // 产品代码(对应接口的productCode)
}) })
// 预计来佣列表 // 预计来佣列表
const expectedCommissionList = ref([]) const expectedCommissionList = ref([])
const policyFortuneList = ref([]) const policyFortuneList = ref([])
const getPolicyFortuneLists = async (policyNo) => { const getPolicyFortuneLists = async policyNo => {
try { try {
const response = await getPolicyFortuneList({ policyNo }) const response = await getPolicyFortuneList({ policyNo })
if (response.code === 200 && response.data) { if (response.code === 200 && response.data) {
policyFortuneList.value = response.data.records || [] policyFortuneList.value = response.data.records || []
policyFortuneList.value.forEach(item => { policyFortuneList.value.forEach(item => {
item.fortuneStatusLabel = convertStatusToDict(3,item.status) item.fortuneStatusLabel = convertStatusToDict(3, item.status)
}) })
} else { } else {
policyFortuneList.value = [] policyFortuneList.value = []
...@@ -321,9 +315,9 @@ const pagination = reactive({ ...@@ -321,9 +315,9 @@ const pagination = reactive({
}) })
// 处理查看 // 处理查看
const handleView = async (row) => { const handleView = async row => {
console.log('查看详情:', row) console.log('查看详情:', row)
currentRow.value = { ...row} currentRow.value = { ...row }
viewDialogVisible.value = true viewDialogVisible.value = true
fetchExpectedCommissionList(row.policyNo) fetchExpectedCommissionList(row.policyNo)
getPolicyFortuneLists(row.policyNo) getPolicyFortuneLists(row.policyNo)
...@@ -341,8 +335,8 @@ const importLoading = ref(false) ...@@ -341,8 +335,8 @@ const importLoading = ref(false)
// 页面加载时获取数据 // 页面加载时获取数据
onMounted(() => { onMounted(() => {
fetchTableData(); fetchTableData()
getLists(); getLists()
}) })
// 获取列表数据 // 获取列表数据
...@@ -360,11 +354,12 @@ const fetchTableData = async () => { ...@@ -360,11 +354,12 @@ const fetchTableData = async () => {
policyNo: searchForm.policyNo, policyNo: searchForm.policyNo,
customerName: searchForm.customerName, customerName: searchForm.customerName,
customerBizId: searchForm.customerBizId, customerBizId: searchForm.customerBizId,
insurer : searchForm.insurer, insurer: searchForm.insurer,
productCode: searchForm.productCode, productCode: searchForm.productCode,
// 签单时间范围需要根据后端要求的参数名进行调整 // 签单时间范围需要根据后端要求的参数名进行调整
// 例如:如果后端需要startSignDate和endSignDate // 例如:如果后端需要startSignDate和endSignDate
...(searchForm.signDateRange && searchForm.signDateRange.length === 2 && { ...(searchForm.signDateRange &&
searchForm.signDateRange.length === 2 && {
startSignDate: date.formatToDate(searchForm.signDateRange[0]) + ' 00:00:00', startSignDate: date.formatToDate(searchForm.signDateRange[0]) + ' 00:00:00',
endSignDate: date.formatToDate(searchForm.signDateRange[1]) + ' 23:59:59' endSignDate: date.formatToDate(searchForm.signDateRange[1]) + ' 23:59:59'
}) })
...@@ -400,14 +395,14 @@ const fetchTableData = async () => { ...@@ -400,14 +395,14 @@ const fetchTableData = async () => {
} finally { } finally {
tableLoading.value = false tableLoading.value = false
} }
}// 获取预计来佣列表 } // 获取预计来佣列表
const fetchExpectedCommissionList = async (policyNo,pageNo=1,pageSize=100) => { const fetchExpectedCommissionList = async (policyNo, pageNo = 1, pageSize = 100) => {
try { try {
// 构造接口请求参数 // 构造接口请求参数
const params = { const params = {
pageNo: pageNo, // 注意:如果后端是从0开始的页码,需要减1 pageNo: pageNo, // 注意:如果后端是从0开始的页码,需要减1
pageSize: pageSize, pageSize: pageSize,
policyNo: policyNo, policyNo: policyNo
} }
// 调用后台接口 // 调用后台接口
const response = await getExpectedCommissionList(params) const response = await getExpectedCommissionList(params)
...@@ -417,7 +412,7 @@ const fetchExpectedCommissionList = async (policyNo,pageNo=1,pageSize=100) => { ...@@ -417,7 +412,7 @@ const fetchExpectedCommissionList = async (policyNo,pageNo=1,pageSize=100) => {
// 将接口返回的数据映射到表格 // 将接口返回的数据映射到表格
expectedCommissionList.value = result.records.map(record => ({ expectedCommissionList.value = result.records.map(record => ({
...record, ...record,
commissionStatusLabel: convertStatusToDict(2,record.status) commissionStatusLabel: convertStatusToDict(2, record.status)
})) }))
} else { } else {
// 接口返回错误信息 // 接口返回错误信息
...@@ -429,15 +424,12 @@ const fetchExpectedCommissionList = async (policyNo,pageNo=1,pageSize=100) => { ...@@ -429,15 +424,12 @@ const fetchExpectedCommissionList = async (policyNo,pageNo=1,pageSize=100) => {
console.error('请求失败:', error) console.error('请求失败:', error)
ElMessage.error('网络异常,请稍后重试') ElMessage.error('网络异常,请稍后重试')
expectedCommissionList.value = [] expectedCommissionList.value = []
} finally { } finally {
} }
} }
// 增加通过表格排序,排序字段sortField,升降序sortOrder // 增加通过表格排序,排序字段sortField,升降序sortOrder
const handleSortChange = (column) => { const handleSortChange = column => {
pagination.sortField = column.prop pagination.sortField = column.prop
pagination.sortOrder = column.order === 'ascending' ? 'ascend' : 'descend' pagination.sortOrder = column.order === 'ascending' ? 'ascend' : 'descend'
fetchTableData() fetchTableData()
...@@ -464,19 +456,19 @@ const resetForm = () => { ...@@ -464,19 +456,19 @@ const resetForm = () => {
} }
// 处理分页大小变化 // 处理分页大小变化
const handleSizeChange = (val) => { const handleSizeChange = val => {
pagination.pageSize = val pagination.pageSize = val
fetchTableData() fetchTableData()
} }
// 处理分页页码变化 // 处理分页页码变化
const handleCurrentChange = (val) => { const handleCurrentChange = val => {
pagination.currentPage = val pagination.currentPage = val
fetchTableData() fetchTableData()
} }
// 处理表格选择变化 // 处理表格选择变化
const handleSelectionChange = (rows) => { const handleSelectionChange = rows => {
selectedRows.value = rows selectedRows.value = rows
} }
...@@ -486,7 +478,7 @@ const tableRowClassName = ({ row }) => { ...@@ -486,7 +478,7 @@ const tableRowClassName = ({ row }) => {
} }
// 处理文件选择 // 处理文件选择
const handleFileChange = (file) => { const handleFileChange = file => {
selectedFile.value = file.raw selectedFile.value = file.raw
} }
...@@ -498,15 +490,12 @@ const handleImport = async () => { ...@@ -498,15 +490,12 @@ const handleImport = async () => {
} }
// 二次确认 // 二次确认
ElMessageBox.confirm( ElMessageBox.confirm(`确定要导入"${selectedFile.value.name}"吗?`, '导入确认', {
`确定要导入"${selectedFile.value.name}"吗?`,
'导入确认',
{
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'info' type: 'info'
} })
).then(async () => { .then(async () => {
importLoading.value = true importLoading.value = true
try { try {
...@@ -519,16 +508,12 @@ const handleImport = async () => { ...@@ -519,16 +508,12 @@ const handleImport = async () => {
// formData.append('otherParam', 'value') // formData.append('otherParam', 'value')
// 调用上传接口 // 调用上传接口
const response = await axios.post( const response = await axios.post(uploadUrl.value, formData, {
uploadUrl.value,
formData,
{
headers: { headers: {
'Content-Type': 'multipart/form-data', // 指定内容类型, 'Content-Type': 'multipart/form-data', // 指定内容类型,
'Authorization': 'Bearer ' + getToken() Authorization: 'Bearer ' + getToken()
} }
} })
)
// 处理接口响应 // 处理接口响应
if (response.data.code === 200) { if (response.data.code === 200) {
ElMessage.success('导入成功') ElMessage.success('导入成功')
...@@ -548,7 +533,8 @@ const handleImport = async () => { ...@@ -548,7 +533,8 @@ const handleImport = async () => {
} finally { } finally {
importLoading.value = false importLoading.value = false
} }
}).catch(() => { })
.catch(() => {
// 用户取消导入 // 用户取消导入
ElMessage.info('已取消导入') ElMessage.info('已取消导入')
}) })
...@@ -556,14 +542,14 @@ const handleImport = async () => { ...@@ -556,14 +542,14 @@ const handleImport = async () => {
// 下载模板 // 下载模板
const downloadTemplate = () => { const downloadTemplate = () => {
// 下载地址 // 下载地址
const templateUrl = 'https://yd-ali-oss.oss-cn-shanghai-finance-1-pub.aliyuncs.com/xlsx/2025/10/14/54ce715eabab4f1abd8652ba0fca0c51.xlsx' const templateUrl =
'https://yd-ali-oss.oss-cn-shanghai-finance-1-pub.aliyuncs.com/xlsx/2025/10/14/54ce715eabab4f1abd8652ba0fca0c51.xlsx'
// 修改下载文件名 // 修改下载文件名
const fileName = '保单导入模板.xlsx' const fileName = '保单导入模板.xlsx'
// 下载文件 // 下载文件
window.open(templateUrl, '_blank', `download=${fileName}-${new Date().getTime()}`) window.open(templateUrl, '_blank', `download=${fileName}-${new Date().getTime()}`)
} }
import { updateToPolicyLib } from '@/api/sign/underwritingMain' import { updateToPolicyLib } from '@/api/sign/underwritingMain'
// 处理更新至保单库 // 处理更新至保单库
const handleUpdateToPolicyLib = () => { const handleUpdateToPolicyLib = () => {
...@@ -575,7 +561,8 @@ const handleUpdateToPolicyLib = () => { ...@@ -575,7 +561,8 @@ const handleUpdateToPolicyLib = () => {
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'
} }
).then(() => { )
.then(() => {
// 调用更新至保单库接口 // 调用更新至保单库接口
updateToPolicyLib({ updateToPolicyLib({
policyNoList: selectedRows.value.map(row => row.policyNo) policyNoList: selectedRows.value.map(row => row.policyNo)
...@@ -590,20 +577,28 @@ const handleUpdateToPolicyLib = () => { ...@@ -590,20 +577,28 @@ const handleUpdateToPolicyLib = () => {
.catch(() => { .catch(() => {
ElMessage({ ElMessage({
type: 'info', type: 'info',
message: '取消更新至保单库', message: '取消更新至保单库'
}) })
}) })
} }
// 格式化文件大小 // 格式化文件大小
const formatFileSize = (bytes) => { const formatFileSize = bytes => {
if (bytes === 0) return '0 B' if (bytes === 0) return '0 B'
const k = 1024 const k = 1024
const sizes = ['B', 'KB', 'MB', 'GB'] const sizes = ['B', 'KB', 'MB', 'GB']
const i = Math.floor(Math.log(bytes) / Math.log(k)) const i = Math.floor(Math.log(bytes) / Math.log(k))
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i] return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
} }
// 新单跟进详情
const handleStatus = row => {
router.push({
path: '/sign/underwritingMain/followUpDetail',
query: { policyBizId: row.policyBizId, type: 'edit', source: 'policyList', embed:true,appointmentNo:row.appointmentNo ,appointmentBizId:row.appointmentBizId }
})
}
</script> </script>
<style scoped> <style scoped>
......
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