Commit 935894cd by yuzhenWang

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

优化修复bug,发布测试

See merge request !25
parents 98c6fe67 2fbd81ef
......@@ -107,7 +107,6 @@ export function completePolicyFortune(data) {
})
}
// 获取对账公司
// /csf/api/reconciliation_company/list/page
export function getReconciliationCompanyList(data) {
......@@ -148,7 +147,6 @@ export function addPolicyFortuneAccount(data) {
})
}
// 删除发佣
// /csf/api/fortune/delete/fortuneAccount
export function deletePolicyFortuneAccount(data) {
......@@ -168,11 +166,27 @@ export function addPolicyCommission(data) {
data: data
})
}
// 入账管理的统计数据
export function incomeStatistics(data) {
return request({
url: '/csf/api/commission/statistics',
method: 'post',
data: data
})
}
// 出账管理的统计数据
export function billStatistics(data) {
return request({
url: '/csf/api/fortune/statistics',
method: 'post',
data: data
})
}
// 出账管理的统计数据
export function salaryStatistics(data) {
return request({
url: '/csf/api/fortune/fortuneAccount/statistics',
method: 'post',
data: data
})
}
......@@ -56,6 +56,37 @@ export function getPolicyStatus(policyBizId) {
method: 'get'
})
}
// 获取预计来佣生成状态
export function expectedFortuneIsGenerate(policyNo) {
return request({
url: `/csf/api/expectedFortune/isGenerate?policyNo=${policyNo}`,
method: 'get'
})
}
// 生成签约单
export function policyFollowReport(policyBizId) {
return request({
url: `/csf/api/policy_follow/report/download?policyBizId=${policyBizId}`,
method: 'get',
responseType: 'blob' // 关键设置
})
}
// 生成预计发佣
export function expectedFortuneGenerate(data) {
return request({
url: '/csf/api/expectedFortune/generate',
method: 'post',
data: data
})
}
//发佣日志信息
export function getExpectedFortuneLog(data) {
return request({
url: '/csf/api/expectedFortuneLog/page',
method: 'post',
data: data
})
}
// 新单跟进附件列表
export function getAttachmentList(data) {
return request({
......@@ -142,6 +173,14 @@ export function getCommissionList(data) {
data: data
})
}
// 新单跟进的预计发佣列表
export function getExpectedFortuneList(data) {
return request({
url: '/csf/api/expectedFortune/page',
method: 'post',
data: data
})
}
// 新单跟进的预计来佣单个提交
export function editSigalCommission(data) {
return request({
......@@ -173,3 +212,4 @@ export function changePolicyStatus(data) {
data: data
})
}
......@@ -3,11 +3,15 @@
<template v-for="(item, index) in options">
<template v-if="values.includes(item.value)">
<span
v-if="(item.elTagType == 'default' || item.elTagType == '') && (item.elTagClass == '' || item.elTagClass == null)"
v-if="
(item.elTagType == 'default' || item.elTagType == '') &&
(item.elTagClass == '' || item.elTagClass == null)
"
:key="item.value"
:index="index"
:class="item.elTagClass"
>{{ item.label + " " }}</span>
>{{ item.label + ' ' }}</span
>
<el-tag
v-else
:disable-transitions="true"
......@@ -15,7 +19,8 @@
:index="index"
:type="item.elTagType"
:class="item.elTagClass"
>{{ item.label + " " }}</el-tag>
>{{ item.label + ' ' }}</el-tag
>
</template>
</template>
<template v-if="unmatch && showValue">
......@@ -32,30 +37,39 @@ const props = defineProps({
// 数据
options: {
type: Array,
default: null,
default: null
},
// 当前的值
value: [Number, String, Array],
// 当未找到匹配的数据时,显示value
showValue: {
type: Boolean,
default: true,
default: true
},
separator: {
type: String,
default: ",",
default: ','
}
})
const values = computed(() => {
if (props.value === null || typeof props.value === 'undefined' || props.value === '') return []
return Array.isArray(props.value) ? props.value.map(item => '' + item) : String(props.value).split(props.separator)
return Array.isArray(props.value)
? props.value.map(item => '' + item)
: String(props.value).split(props.separator)
})
const unmatch = computed(() => {
unmatchArray.value = []
// 没有value不显示
if (props.value === null || typeof props.value === 'undefined' || props.value === '' || !Array.isArray(props.options) || props.options.length === 0) return false
if (
props.value === null ||
typeof props.value === 'undefined' ||
props.value === '' ||
!Array.isArray(props.options) ||
props.options.length === 0
)
return false
// 传入值为数组
let unmatch = false // 添加一个标志来判断是否有未匹配项
values.value.forEach(item => {
......@@ -68,9 +82,9 @@ const unmatch = computed(() => {
})
function handleArray(array) {
if (array.length === 0) return ""
if (array.length === 0) return ''
return array.reduce((pre, cur) => {
return pre + " " + cur
return pre + ' ' + cur
})
}
</script>
......
......@@ -178,7 +178,7 @@ const applicant = [
label: '通讯地址',
commonKey: true, //是否是公共字段
key: 'txAddress',
// customerKey: 'mailingAddress',
customerKey: 'residenceAddress',
domType: 'arrowRight',
required: false,
disabled: false,
......
......@@ -75,7 +75,7 @@ const appointmentInfo = [
lg: 8 //栅格布局份数
},
{
label: '业务代表账号',
label: '签单员账号',
key: 'businessRepresentAccount1',
domType: 'Input',
inputType: 'text',
......@@ -90,7 +90,7 @@ const appointmentInfo = [
lg: 8 //栅格布局份数
},
{
label: '业务代表姓名',
label: '签单员姓名',
key: 'businessRepresentName1',
domType: 'Input',
inputType: 'text',
......@@ -105,7 +105,7 @@ const appointmentInfo = [
lg: 8 //栅格布局份数
},
{
label: '业务代表电话号码',
label: '签单员电话号码',
key: 'businessRepresentMobile1',
domType: 'arrowRight',
required: false,
......@@ -122,7 +122,7 @@ const appointmentInfo = [
lg: 8 //栅格布局份数
},
{
label: '业务代表邮箱',
label: '签单员邮箱',
key: 'businessRepresentEmail1',
domType: 'Input',
inputType: 'text',
......@@ -267,11 +267,11 @@ const appointmentInfo = [
lg: 8 //栅格布局份数
},
{
label: '离港时间(先选择离港时间)',
label: '离港时间(离港时间必须晚于到港时间)',
key: 'departureTime',
domType: 'datetimePicker',
required: false,
disabled: true,
disabled: false,
placeholder: '请选择',
show: true,
labelPosition: 'top', //标签的位置
......
......@@ -452,6 +452,21 @@ const customer = [
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '身份证地址',
key: 'idCardAddress',
type: 'Input',
inputType: 'text',
required: false,
maxLength: 20,
disabled: false,
placeholder: '请输入',
show: false,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
}
]
},
......@@ -493,12 +508,27 @@ const customer = [
lg: 8 //栅格布局份数
},
{
label: '职位',
key: 'position',
label: '公司地址',
key: 'companyAddress',
type: 'arrowRight',
required: false,
disabled: false,
placeholder: '请填写',
show: true,
drawerType: 'address',
companyAddress: {},
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '公司地址邮编',
key: 'companyAddressPostcode',
type: 'Input',
inputType: 'text',
required: false,
maxLength: 300,
maxLength: 20,
disabled: false,
placeholder: '请输入',
show: true,
......@@ -508,10 +538,10 @@ const customer = [
lg: 8 //栅格布局份数
},
{
label: '总工作年期',
key: 'workYear',
label: '职位',
key: 'position',
type: 'Input',
inputType: 'number',
inputType: 'text',
required: false,
maxLength: 300,
disabled: false,
......@@ -523,8 +553,8 @@ const customer = [
lg: 8 //栅格布局份数
},
{
label: '现时每月收入',
key: 'salary',
label: '工作年期',
key: 'workYear',
type: 'Input',
inputType: 'number',
required: false,
......@@ -538,15 +568,15 @@ const customer = [
lg: 8 //栅格布局份数
},
{
label: '公司地址',
key: 'companyAddress',
type: 'arrowRight',
label: '现时每月收入',
key: 'salary',
type: 'Input',
inputType: 'number',
required: false,
maxLength: 300,
disabled: false,
placeholder: '请填写',
placeholder: '请输入',
show: true,
drawerType: 'address',
companyAddress: {},
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
......
......@@ -41,36 +41,36 @@ const fnaForm = [
lg: 8 //栅格布局份数
},
{
label: '签单员注册编号',
key: 'registrationNumber',
domType: 'Input',
inputType: 'text',
required: true,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '140px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '签单员内部编码',
key: 'number',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '130px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
// {
// label: '签单员注册编号',
// key: 'registrationNumber',
// domType: 'Input',
// inputType: 'text',
// required: true,
// maxLength: 30,
// disabled: false,
// placeholder: '请输入',
// show: true,
// labelPosition: 'top', //标签的位置
// labelWidth: '140px', //标签宽度
// sm: 8, //栅格布局份数
// lg: 8 //栅格布局份数
// },
// {
// label: '签单员内部编码',
// key: 'number',
// domType: 'Input',
// inputType: 'text',
// required: false,
// maxLength: 30,
// disabled: false,
// placeholder: '请输入',
// show: true,
// labelPosition: 'top', //标签的位置
// labelWidth: '130px', //标签宽度
// sm: 8, //栅格布局份数
// lg: 8 //栅格布局份数
// },
{
label: '客户姓名',
key: 'customerName',
......@@ -86,21 +86,21 @@ const fnaForm = [
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '税务国家',
key: 'taxCountry',
domType: 'Input',
inputType: 'text',
required: true,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
// {
// label: '税务国家',
// key: 'taxCountry',
// domType: 'Input',
// inputType: 'text',
// required: true,
// maxLength: 30,
// disabled: false,
// placeholder: '请输入',
// show: true,
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 8, //栅格布局份数
// lg: 8 //栅格布局份数
// },
{
label: '就业情况',
key: 'employment',
......@@ -169,8 +169,13 @@ const fnaForm = [
keyType: 'Array', //用于表单收集值时,判断是数组还是对象
showTable: true, //以table的形式展示
key: 'familyMembers',
addFamilyChildren: true, //是否可以新增子级dom
moudleType: 'family',
addChildren: true, //是否可以新增子级dom
addChildrenTxt: '添加儿女', //新增按钮得文本
fatherRequired: false, //父级必填,代表个人资料这个模块有必填项
isOpen: false,
openIcon: true,
data: [
{
type: '1',
......@@ -212,9 +217,13 @@ const fnaForm = [
subTitle: '保单持有人个人已有保障',
keyType: 'Array', //用于表单收集值时,判断是数组还是对象
key: 'existingSecurityOwner',
moudleType: 'finance',
addChildren: true, //是否可以新增子级dom
addChildrenTxt: '保单持有人个人已有保障', //新增按钮得文本
showTable: true,
dataLength: 5, //设置dataLength,用于控制子级dom的个数,子级保存一个样例数据,便于加子级数据
isOpen: false,
openIcon: true,
fatherRequired: false, //父级必填,代表个人资料这个模块有必填项
data: [
{
......@@ -236,9 +245,12 @@ const fnaForm = [
keyType: 'Array', //用于表单收集值时,判断是数组还是对象
subTitle: '受保人个人已有保障',
key: 'existingSecurityInsured',
moudleType: 'finance',
addChildren: true, //是否可以新增子级dom
addChildrenTxt: '受保人个人已有保障', //新增按钮得文本
dataLength: 5, //设置dataLength,用于控制子级dom的个数,子级保存一个样例数据,便于加子级数据
showTable: true,
isOpen: false, //dom是否展开
fatherRequired: false, //父级必填,代表个人资料这个模块有必填项
data: [
{
......@@ -254,99 +266,19 @@ const fnaForm = [
options: []
}
]
// data: [
// {
// childTitle: '受保人个人已有保障',
// id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识
// span: 24, //栅格布局份数
// children: [
// {
// label: '保险公司',
// key: 'insurer',
// domType: 'Input',
// inputType: 'text',
// required: false,
// maxLength: 300,
// disabled: false,
// placeholder: '请输入',
// show: true,
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 8, //栅格布局份数
// lg: 8 //栅格布局份数
// },
// {
// label: '保障类型',
// key: 'insuranceType',
// domType: 'Input',
// inputType: 'text',
// required: false,
// maxLength: 300,
// disabled: false,
// placeholder: '请输入',
// show: true,
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 8, //栅格布局份数
// lg: 8 //栅格布局份数
// },
// {
// label: '保额',
// key: 'sumInsured',
// domType: 'Input',
// inputType: 'text',
// required: false,
// maxLength: 300,
// disabled: false,
// placeholder: '请输入',
// show: true,
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 8, //栅格布局份数
// lg: 8 //栅格布局份数
// },
// {
// label: '币种',
// key: 'currency',
// domType: 'Select',
// inputType: 'text',
// required: false,
// maxLength: 300,
// disabled: false,
// placeholder: '请输入',
// show: true,
// dictType: 'bx_currency_type',
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 8, //栅格布局份数
// lg: 8 //栅格布局份数
// },
// {
// label: '保单签发日期',
// key: 'policyIssueDate',
// domType: 'DatePicker',
// required: false,
// maxLength: 300,
// disabled: false,
// placeholder: '请输入',
// show: true,
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 8, //栅格布局份数
// lg: 8 //栅格布局份数
// }
// ]
// }
// ]
},
// 投资房地产
{
keyType: 'Array', //用于表单收集值时,判断是数组还是对象
key: 'investment',
moudleType: 'finance',
subTitle: '投资房地产',
showTable: true,
dataLength: 2, //设置dataLength,用于控制子级dom的个数,子级保存一个样例数据,便于加子级数据
addChildren: true, //是否可以新增子级dom
addChildrenTxt: '投资房地产', //新增按钮得文本
isOpen: false, //dom是否展开
fatherRequired: false, //父级必填,代表个人资料这个模块有必填项
data: [
{
......@@ -364,9 +296,13 @@ const fnaForm = [
{
keyType: 'Array', //用于表单收集值时,判断是数组还是对象
key: 'primaryResidence',
moudleType: 'finance',
dataLength: 1, //设置dataLength,用于控制子级dom的个数,子级保存一个样例数据,便于加子级数据
showTable: true,
subTitle: '保单持有人资产',
addChildren: true, //是否可以新增子级dom
addChildrenTxt: '保单持有人资产', //新增按钮得文本
isOpen: false, //dom是否展开
fatherRequired: false, //父级必填,代表个人资料这个模块有必填项
data: [
{
......@@ -380,11 +316,33 @@ const fnaForm = [
}
]
},
// 税务国家
{
keyType: 'Array', //用于表单收集值时,判断是数组还是对象
key: 'taxList',
moudleType: 'finance',
dataLength: 1, //设置dataLength,用于控制子级dom的个数,子级保存一个样例数据,便于加子级数据
showTable: true,
subTitle: '税务',
addChildren: true, //是否可以新增子级dom
addChildrenTxt: '税务', //新增按钮得文本
fatherRequired: false, //父级必填,代表个人资料这个模块有必填项
isOpen: false, //dom是否展开
data: [
{
id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识
span: 24, //栅格布局份数
taxCountry: '',
taxNumber: ''
}
]
},
//公司业务资料
{
keyType: 'Object', //用于表单收集值时,判断是数组还是对象
key: 'companyBusinessData',
child: 'no', //有子级dom,需要循环展示
isOpen: true, //是否展开
fatherRequired: false, //父级必填,代表个人资料这个模块有必填项
subTitle: '公司业务资料 (适用于公司老板跟股东)',
data: [
......@@ -460,7 +418,7 @@ const fnaForm = [
data: [
{
label:
'在过去24个月里,你从所有所得的收入来源所得的平均每月收入为(包括薪金、花红、佣金、其他薪酬红利、银行存款利息、债券利息及股息等。',
'在过去12个月里,你从所有所得的收入来源所得的平均每月收入为(包括薪金、花红、佣金、其他薪酬红利、银行存款利息、债券利息及股息等。',
key: 'monthlyIncome',
domType: 'Input',
inputType: 'text',
......@@ -476,7 +434,7 @@ const fnaForm = [
labelPosition: 'top' //标签的位置
},
{
label: '过去24个月每月里,你每月的平均开支为',
label: '过去12个月每月里,你每月的平均开支为',
key: 'monthlyExpense',
domType: 'Input',
inputType: 'text',
......@@ -525,8 +483,8 @@ const fnaForm = [
placeholder: '请输入',
show: true,
labelWidth: '100px', //标签宽度
sm: 18, //栅格布局份数
lg: 16, //栅格布局份数
sm: 24, //栅格布局份数
lg: 24, //栅格布局份数
labelPosition: 'top', //标签的位置
dictType: 'csf_liquid_asset_type'
},
......@@ -538,10 +496,10 @@ const fnaForm = [
maxLength: 300,
disabled: false,
placeholder: '请输入',
show: true,
show: false,
labelWidth: '0px', //标签宽度
sm: 6, //栅格布局份数
lg: 8, //栅格布局份数
sm: 24, //栅格布局份数
lg: 24, //栅格布局份数
labelPosition: 'top' //标签的位置
}
]
......
......@@ -8,6 +8,21 @@ const insured = [
showMoudle: true, //模块是否展示
data: [
{
label: '与投保人关系',
key: 'policyholderRel',
// customerKey: 'customerType',
domType: 'Select',
required: true,
disabled: false,
placeholder: '请选择',
dictType: 'csf_ap_rel',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '客户类型',
key: 'customerType',
customerKey: 'customerType',
......@@ -37,25 +52,10 @@ const insured = [
labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '与投保人关系',
key: 'policyholderRel',
// customerKey: 'customerType',
domType: 'Select',
required: true,
disabled: false,
placeholder: '请选择',
dictType: 'csf_ap_rel',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 12, //栅格布局份数
lg: 8 //栅格布局份数
}
]
},
// 基础信息
{
fatherTitle: '基础信息',
type: 'object',
......@@ -193,7 +193,7 @@ const insured = [
label: '通讯地址',
commonKey: true, //是否是公共字段
key: 'txAddress',
// customerKey: 'mailingAddress',
customerKey: 'residenceAddress',
domType: 'arrowRight',
required: false,
disabled: false,
......@@ -482,36 +482,7 @@ const insured = [
sm: 12, //栅格布局份数
lg: 8 //栅格布局份数
},
// {
// label: '平均每月收入',
// key: 'monthIncome',
// domType: 'Input',
// inputType: 'number',
// required: false,
// maxLength: 300,
// disabled: false,
// placeholder: '请输入平均每月收入',
// show: true,
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 12, //栅格布局份数
// lg: 8 //栅格布局份数
// },
// {
// label: '平均每月支出',
// key: 'monthExpenditure',
// domType: 'Input',
// inputType: 'number',
// required: false,
// maxLength: 300,
// disabled: false,
// placeholder: '请输入平均每月支出',
// show: true,
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 12, //栅格布局份数
// lg: 8 //栅格布局份数
// },
{
label: '受雇于现职年期',
key: 'currentTenure',
......@@ -527,21 +498,7 @@ const insured = [
sm: 12, //栅格布局份数
lg: 8 //栅格布局份数
},
// {
// label: '总流动资产',
// key: 'totalCurrentAssets',
// domType: 'Input',
// inputType: 'number',
// required: false,
// maxLength: 300,
// disabled: false,
// placeholder: '请输入平均每月支出',
// show: true,
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 12, //栅格布局份数
// lg: 8 //栅格布局份数
// },
{
label: '总负债额',
key: 'totalDebt',
......
......@@ -7,38 +7,6 @@ const policyInfo = [
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',
......@@ -69,22 +37,22 @@ const policyInfo = [
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: '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',
......@@ -113,53 +81,7 @@ const policyInfo = [
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',
......@@ -254,37 +176,32 @@ const policyInfo = [
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: 'remark',
domType: 'Input',
inputType: 'textarea',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
value: '',
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 24, //栅格布局份数
lg: 24 //栅格布局份数
}
]
},
{
fatherTitle: '缴费信息',
keyType: 'Object', //用于表单收集值时,判断是数组还是对象
key: 'policyFollowUpdateDto',
child: 'no', //没有子级dom,直接展示
fatherrequired: false, //父级必填,代表个人资料这个模块有必填项
data: [
{
label: '首期保费',
key: 'initialPremium',
......@@ -302,10 +219,10 @@ const policyInfo = [
lg: 8 //栅格布局份数
},
{
label: '备注',
key: 'remark',
label: '保单征费',
key: 'policyLevy',
domType: 'Input',
inputType: 'textarea',
inputType: 'number',
required: false,
maxLength: 30,
disabled: false,
......@@ -314,10 +231,79 @@ const policyInfo = [
value: '',
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 24, //栅格布局份数
lg: 24 //栅格布局份数
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '首期待交保费',
key: 'initialPremiumDue',
domType: 'Input',
inputType: 'number',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
value: '',
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '首期已交保费',
key: 'initialPremiumPaid',
domType: 'Input',
inputType: 'number',
required: false,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
value: '',
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '最晚缴费日期',
key: 'latestPaymentDate',
domType: 'DatePicker',
required: false,
disabled: false,
placeholder: '请选择',
show: true,
value: '',
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
}
]
},
//签单人信息
{
keyType: 'Array', //用于表单收集值时,判断是数组还是对象
key: 'signerList',
showTable: true,
subTitle: '签单人信息',
addChildren: true, //是否可以新增子级dom
addChildrenTxt: '签单人', //新增按钮得文本
isOpen: false, //dom是否展开
fatherRequired: false, //父级必填,代表个人资料这个模块有必填项
data: [
// {
// span: 24, //栅格布局份数
// signer: '',
// phone: '',
// email: '',
// idType: '',
// idNo: '',
// dictType: 'csf_id_type',
// registrationNumber: ''
// }
]
}
]
export default policyInfo
......@@ -55,7 +55,7 @@
<!-- <router-link to="/user/profile">
<el-dropdown-item>个人中心</el-dropdown-item>
</router-link> -->
<el-dropdown-item divided command="logout">
<el-dropdown-item command="logout">
<span>退出登录</span>
</el-dropdown-item>
</el-dropdown-menu>
......
......@@ -13,3 +13,36 @@ export default function deepClone(obj) {
return clonedObj
}
}
// 处理用户名相同的情况
export function processUserName(users) {
const nameCountMap = new Map()
// 统计 realName 重复情况
users.forEach(user => {
if (!nameCountMap.has(user.realName)) {
nameCountMap.set(user.realName, new Set())
}
nameCountMap.get(user.realName).add(user.userBizId)
})
// 处理 showName
return users.map(user => {
const userBizIds = nameCountMap.get(user.realName)
const needDistinguish = userBizIds && userBizIds.size > 1
if (needDistinguish) {
const mobile = user.mobile
const prefix = mobile.substring(0, 3)
const suffix = mobile.substring(mobile.length - 4)
return {
...user,
showName: `${user.realName} ${prefix}****${suffix}`
}
} else {
return {
...user,
showName: user.realName
}
}
})
}
......@@ -6,11 +6,7 @@
<el-row :gutter="20">
<el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-form-item label="保单号">
<el-input
v-model="queryParams.policyNo"
placeholder="请输入保单号"
clearable
/>
<el-input v-model="queryParams.policyNo" placeholder="请输入保单号" clearable />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6">
......@@ -25,6 +21,7 @@
/>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-form-item>
<el-button type="primary" @click="handleQuery">查询</el-button>
......@@ -38,39 +35,51 @@
<!-- 数据表格 -->
<el-card>
<el-row :gutter="20">
<el-text class="mx-1" type="danger" style="margin-right: 20px;">勾选出账记录,点击“下载选中项”按钮,下载导入模版</el-text>
<el-text class="mx-1" type="danger" style="margin-right: 20px"
>勾选出账记录,点击“下载选中项”按钮,下载导入模版</el-text
>
</el-row>
<div class="button-row" style="display: flex;gap: 1rem;justify-content: end;">
<el-button
type="primary"
:disabled="selectedRows.length === 0"
@click="downloadSelected"
>
下载选中项
</el-button>
<FileUpload :fileType="['xlsx', 'xls']"
:action="'/csf/api/fortune/upload/excel'"
:uploadBtnText="'批量导入'"
:isShowTip="false"
@uploadEnd = 'getUploadFileFunc'
:responseType="'onlyStatus'"
/>
<el-button
type="success"
:disabled="selectedRows.length === 0"
@click="generateBillingList"
>
生成出账清单
</el-button>
</div>
<div class="button-row" style="display: flex; gap: 1rem; justify-content: end">
<el-button type="primary" :disabled="selectedRows.length === 0" @click="downloadSelected">
下载选中项
</el-button>
<FileUpload
:fileType="['xlsx', 'xls']"
:action="'/csf/api/fortune/upload/excel'"
:uploadBtnText="'批量导入'"
:isShowTip="false"
@uploadEnd="getUploadFileFunc"
:responseType="'onlyStatus'"
/>
<el-button
type="success"
:disabled="selectedRows.length === 0"
@click="generateBillingList"
>
生成出账清单
</el-button>
</div>
<div class="totalData" v-if="getAllSelectedRows().length > 0 || isSearch">
<span v-for="(item, index) in statisticList">
<span :style="{ marginLeft: index == 0 ? ' 0' : '20px' }">{{ item.name }}</span>
<span>{{ item.format ? formatCurrency(item.value) : item.value }}</span>
</span>
</div>
<el-table
:data="tableData"
@selection-change="handleSelectionChange"
v-loading="loading"
row-key="fortuneBizId"
:reserve-selection="true"
ref="tableRef"
>
<el-table-column type="selection" width="55" />
<el-table-column type="selection" width="55" :reserve-selection="true" />
<el-table-column prop="policyNo" label="保单号" min-width="120" />
<el-table-column prop="commissionAmount" label="本次已来佣金额" width="150">
<template #default="{ row }">
{{ formatCurrency(row.commissionAmount) }}
</template>
</el-table-column>
<el-table-column prop="fortunePeriod" label="出账期数" width="100" />
<el-table-column prop="fortuneTotalPeriod" label="预计总期数" width="100" />
<el-table-column prop="fortuneName" label="出账项目" min-width="120" />
......@@ -112,11 +121,7 @@
</el-card>
<!-- 新建/编辑对话框 -->
<el-dialog
:title="dialogTitle"
v-model="dialogVisible"
width="600px"
>
<el-dialog :title="dialogTitle" v-model="dialogVisible" width="600px">
<el-form :model="formData" label-width="100px">
<el-form-item label="保单号" required>
<el-input v-model="formData.policyNo" />
......@@ -164,11 +169,7 @@
</el-select>
</el-form-item>
<el-form-item label="备注">
<el-input
v-model="formData.remark"
type="textarea"
:rows="3"
/>
<el-input v-model="formData.remark" type="textarea" :rows="3" />
</el-form-item>
</el-form>
<template #footer>
......@@ -180,11 +181,25 @@
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ref, reactive, onMounted, nextTick } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
// 引入API
import { getPolicyFortuneList, downloadPolicyFortune ,downloadPolicyFortuneAccount} from "@/api/financial/commission"
import {
getPolicyFortuneList,
downloadPolicyFortune,
downloadPolicyFortuneAccount,
billStatistics
} from '@/api/financial/commission'
// 添加表格引用
const tableRef = ref()
// 存储所有选中的行数据(用于跨页保持选择)
const allSelectedRows = ref(new Map())
const isSearch = ref(false)
const statisticList = ref([
{ name: '总出账金额', value: '0', key: 'totalOutAmount', format: true },
{ name: '总入账金额', value: '0', key: 'totalInAmount', format: true },
{ name: '总保单数', value: '0', key: 'totalPolicyCount', format: false }
])
// 查询参数
const queryParams = reactive({
policyNo: '',
......@@ -192,6 +207,7 @@ const queryParams = reactive({
billingDate: [],
pageNum: 1,
pageSize: 100
// pageSize: 10
})
// 表格数据
......@@ -216,8 +232,82 @@ const formData = reactive({
status: 'pending',
remark: ''
})
// 设置当前页的选中状态
const setCurrentPageSelection = () => {
if (!tableRef.value) return
// 清除当前页的选择
// tableRef.value.clearSelection()
// 设置当前页应该选中的行
tableData.value.forEach(row => {
if (allSelectedRows.value.has(row.fortuneBizId)) {
tableRef.value.toggleRowSelection(row, true)
}
})
}
// 获取所有选中的行(包含跨页选择的)
const getAllSelectedRows = () => {
return Array.from(allSelectedRows.value.values())
}
// 更新全局选中状态
const updateAllSelectedRows = () => {
// 获取当前页的所有行的 key(fortuneBizId)
const currentPageKeys = tableData.value.map(row => row.fortuneBizId)
// 从全局选中中移除当前页不再存在的行
// for (const key of allSelectedRows.value.keys()) {
// if (!currentPageKeys.includes(key)) {
// allSelectedRows.value.delete(key)
// }
// }
// 更新当前页的选中状态
tableData.value.forEach(row => {
const isSelected = selectedRows.value.some(
selectedRow => selectedRow.fortuneBizId === row.fortuneBizId
)
if (isSelected) {
allSelectedRows.value.set(row.fortuneBizId, row)
} else {
allSelectedRows.value.delete(row.fortuneBizId)
}
})
// 当勾选项发生变化的时候,拿到最新的统计数据
getStatistics()
}
const getStatistics = async () => {
try {
let fortuneIdList = getAllSelectedRows().map(item => item.id)
if (fortuneIdList.length > 0) {
// 调用接口获取来佣列表
const res = await billStatistics({
fortuneIdList: fortuneIdList
})
if (res.data) {
statisticList.value.forEach(item => {
item.value = res.data[item.key]
})
}
} else {
isSearch.value = false
}
} catch (error) {
console.error('获取数据失败:', error)
ElMessage.error('统计失败')
}
}
// 清空所有选择
const clearAllSelection = () => {
allSelectedRows.value.clear()
selectedRows.value = []
if (tableRef.value) {
tableRef.value.clearSelection()
}
console.log('allSelectedRows', allSelectedRows.value)
console.log('selectedRows', selectedRows.value)
}
// 下载选中项
const downloadSelected = async () => {
if (selectedRows.value.length === 0) {
......@@ -233,17 +323,20 @@ const downloadSelected = async () => {
ElMessage.success('下载成功')
// 触发文件下载
// 处理下载响应
const blob = response instanceof Blob ? response : new Blob([response], { type: 'application/vnd.ms-excel;charset=utf-8' })
// 创建Blob对象,指定正确的MIME类型
const url = window.URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = url
// 不需要指定文件名,浏览器会自动使用默认文件名
link.download = `出账管理_${new Date().getTime()}.xlsx`
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
window.URL.revokeObjectURL(url)
const blob =
response instanceof Blob
? response
: new Blob([response], { type: 'application/vnd.ms-excel;charset=utf-8' })
// 创建Blob对象,指定正确的MIME类型
const url = window.URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = url
// 不需要指定文件名,浏览器会自动使用默认文件名
link.download = `出账管理_${new Date().getTime()}.xlsx`
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
window.URL.revokeObjectURL(url)
} else {
ElMessage.error('下载失败')
}
......@@ -251,12 +344,12 @@ const downloadSelected = async () => {
ElMessage.error('下载失败')
}
}
const getUploadFileFunc = (data) => {
const getUploadFileFunc = data => {
console.log(data)
if(data===200){
ElMessage.success('上传成功');
if (data === 200) {
ElMessage.success('上传成功')
getList()
}else{
} else {
ElMessage.error('上传失败')
}
}
......@@ -266,18 +359,41 @@ const getList = async () => {
try {
// API调用
const response = await getPolicyFortuneList(queryParams)
tableData.value = response.data.records
total.value = response.data.total
if (response.data.page) {
tableData.value = response.data.page.records
total.value = response.data.page.total
loading.value = false
}
if (response.data.statisticsVO && isSearch.value) {
statisticList.value.forEach(item => {
item.value = response.data.statisticsVO[item.key]
})
}
// 数据加载完成后,设置当前页的选中状态
nextTick(() => {
setCurrentPageSelection()
})
} catch (error) {
loading.value = false
ElMessage.error('获取数据失败')
tableData.value = []
console.log('获取列表失败', error)
// ElMessage.error('获取数据失败')
}
}
// 查询
const handleQuery = () => {
queryParams.pageNum = 1
Object.values(queryParams).some(value => {
if (Array.isArray(value) && value.length > 0) {
isSearch.value = true
}
if (value !== '' && value != null) {
isSearch.value = true
}
})
clearAllSelection()
getList()
}
......@@ -288,14 +404,18 @@ const resetQuery = () => {
company: '',
billingDate: [],
pageNum: 1,
pageSize: 10
pageSize: 100
})
isSearch.value = false
// 清空选择
clearAllSelection()
getList()
}
// 选择行变化
const handleSelectionChange = (selection) => {
const handleSelectionChange = selection => {
selectedRows.value = selection
updateAllSelectedRows()
}
// 新建出账记录
......@@ -318,14 +438,14 @@ const handleCreate = () => {
}
// 编辑出账记录
const handleEdit = (row) => {
const handleEdit = row => {
dialogTitle.value = '编辑出账记录'
Object.assign(formData, { ...row })
dialogVisible.value = true
}
// 删除出账记录
const handleDelete = async (row) => {
const handleDelete = async row => {
try {
await ElMessageBox.confirm('确认删除这条出账记录吗?', '提示', {
type: 'warning'
......@@ -341,52 +461,52 @@ const handleDelete = async (row) => {
}
// 查看详情
const handleView = (row) => {
const handleView = row => {
// 这里可以跳转到详情页面或者打开详情对话框
ElMessage.info(`查看保单号:${row.policyNo}`)
}
const generateBillingList = async () => {
if (selectedRows.value.length === 0) {
ElMessage.warning('请先选择要生成清单的记录')
return
}
ElMessageBox.confirm(
`确认生成 ${selectedRows.value.length} 条记录的出账清单吗?`,
'提示',
{
type: 'warning'
}
).then(async () => {
console.log('开始生成出账清单')
const response = await downloadPolicyFortuneAccount({
fortuneBizIdList: selectedRows.value.map(item => item.fortuneBizId)
})
console.log(response)
// 调用下载API
if(response){
// 处理下载响应
const blob = response instanceof Blob ? response : new Blob([response], { type: 'application/vnd.ms-excel;charset=utf-8' })
// 创建Blob对象,指定正确的MIME类型
const url = window.URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = url
// 不需要指定文件名,浏览器会自动使用默认文件名
link.download = `出账清单_${new Date().getTime()}.xlsx`
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
window.URL.revokeObjectURL(url)
}else{
ElMessage.error('下载失败')
}
selectedRows.value = []
}).catch((error) => {
if (error !== 'cancel') {
console.log('生成出账清单出错:', error)
}
ElMessageBox.confirm(`确认生成 ${selectedRows.value.length} 条记录的出账清单吗?`, '提示', {
type: 'warning'
})
.then(async () => {
console.log('开始生成出账清单')
const response = await downloadPolicyFortuneAccount({
fortuneBizIdList: selectedRows.value.map(item => item.fortuneBizId)
})
console.log(response)
// 调用下载API
if (response) {
// 处理下载响应
const blob =
response instanceof Blob
? response
: new Blob([response], { type: 'application/vnd.ms-excel;charset=utf-8' })
// 创建Blob对象,指定正确的MIME类型
const url = window.URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = url
// 不需要指定文件名,浏览器会自动使用默认文件名
link.download = `出账清单_${new Date().getTime()}.xlsx`
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
window.URL.revokeObjectURL(url)
} else {
ElMessage.error('下载失败')
}
selectedRows.value = []
})
.catch(error => {
if (error !== 'cancel') {
console.log('生成出账清单出错:', error)
}
})
}
// 提交表单
......@@ -397,14 +517,14 @@ const submitForm = async () => {
ElMessage.warning('请填写必填字段')
return
}
// 调用保存API
// if (formData.id) {
// await api.updateBilling(formData)
// } else {
// await api.createBilling(formData)
// }
ElMessage.success('保存成功')
dialogVisible.value = false
getList()
......@@ -414,7 +534,7 @@ const submitForm = async () => {
}
// 格式化金额
const formatCurrency = (amount) => {
const formatCurrency = amount => {
return new Intl.NumberFormat('zh-CN', {
style: 'currency',
currency: 'CNY'
......@@ -422,7 +542,7 @@ const formatCurrency = (amount) => {
}
// 获取状态标签类型
const getStatusType = (status) => {
const getStatusType = status => {
const types = {
0: 'warning',
1: 'success',
......@@ -434,29 +554,31 @@ import { listType } from '@/api/system/dict/type'
const dictLists = ref([])
// 获取出账状态字典值
const getDictLists = () => {
return new Promise((resolve, reject) => {
listType({typeList: ['csf_fortune_status']}).then(res => {
if (res.code === 200 && res.data) {
const dictData = res.data.find(item => item.dictType === 'csf_fortune_status');
dictLists.value = dictData?.dictItemList || [];
console.log('获取到的字典数据:', dictLists.value);
resolve(dictLists.value);
} else {
dictLists.value = [];
resolve([]);
}
}).catch(error => {
console.error('获取状态列表失败:', error);
dictLists.value = [];
reject(error);
});
});
return new Promise((resolve, reject) => {
listType({ typeList: ['csf_fortune_status'] })
.then(res => {
if (res.code === 200 && res.data) {
const dictData = res.data.find(item => item.dictType === 'csf_fortune_status')
dictLists.value = dictData?.dictItemList || []
console.log('获取到的字典数据:', dictLists.value)
resolve(dictLists.value)
} else {
dictLists.value = []
resolve([])
}
})
.catch(error => {
console.error('获取状态列表失败:', error)
dictLists.value = []
reject(error)
})
})
}
// 返回数据中状态需要转换为字典值
const convertStatusToDict = (status) => {
const dictItem = dictLists.value.find(item => item.itemValue == status);
return dictItem?.itemLabel ?? status;
const convertStatusToDict = status => {
const dictItem = dictLists.value.find(item => item.itemValue == status)
return dictItem?.itemLabel ?? status
}
// 初始化
......@@ -467,6 +589,11 @@ onMounted(() => {
</script>
<style scoped>
.totalData {
margin-bottom: 10px;
font-size: 14px;
color: #000;
}
.financial-billing-page {
padding: 20px;
}
......@@ -493,17 +620,17 @@ onMounted(() => {
.financial-billing-page {
padding: 10px;
}
.search-card {
margin-bottom: 15px;
}
.operation-card {
margin-bottom: 15px;
}
.el-col {
margin-bottom: 10px;
}
}
</style>
\ No newline at end of file
</style>
......@@ -2,14 +2,14 @@
<div class="financial-income-page">
<!-- 查询区域 -->
<el-card class="search-card">
<el-form :model="searchForm" label-width="80px">
<el-form :model="searchForm" label-width="100px">
<el-row :gutter="20">
<el-col :span="6">
<el-col :span="8">
<el-form-item label="保单号">
<el-input v-model="searchForm.policyNo" placeholder="请输入保单号" clearable />
</el-form-item>
</el-col>
<el-col :span="6">
<el-col :span="8">
<el-form-item label="对账公司">
<el-select
v-model="searchForm.reconciliationCompany"
......@@ -37,6 +37,27 @@
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="预计入账日期">
<el-date-picker
v-model="searchForm.expectedDate"
type="date"
value-format="YYYY-MM-DD"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="比对状态" prop="status">
<el-select v-model="searchForm.status" placeholder="请选择状态">
<el-option
v-for="item in dictLists"
:key="item.itemValue"
:label="item.itemLabel"
:value="item.itemValue"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="4">
<div class="search-buttons">
<el-button type="primary" :icon="Search" @click="handleSearch">查询</el-button>
......@@ -72,15 +93,30 @@
<!-- 列表区域 -->
<el-card class="table-card">
<div class="totalData" v-if="getAllSelectedRows().length > 0 || isSearch">
<span v-for="(item, index) in statisticList">
<span :style="{ marginLeft: index == 0 ? ' 0' : '20px' }">{{ item.name }}</span>
<span>{{ item.format ? formatCurrency(item.value) : item.value }}</span>
</span>
</div>
<el-table
ref="tableRef"
v-loading="tableLoading"
:data="tableData"
border
style="width: 100%"
@selection-change="handleSelectionChange"
@sort-change="handleSortChange"
row-key="commissionBizId"
:reserve-selection="true"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column
type="selection"
width="55"
align="center"
:reserve-selection="true"
></el-table-column
>/>
<el-table-column prop="policyNo" label="保单号" min-width="120" align="center" />
<el-table-column
prop="reconciliationCompany"
......@@ -97,7 +133,11 @@
<el-table-column prop="totalPeriod" label="预计总期数" min-width="100" align="center" />
<el-table-column prop="commissionName" label="入账项目" min-width="120" align="center" />
<el-table-column prop="amount" label="入账金额" min-width="100" align="center" />
<el-table-column prop="currency" label="入账币种" min-width="80" align="center" />
<el-table-column prop="currency" label="入账币种" min-width="80" align="center">
<template #default="scope">
<dict-tag :options="currencyTypeOptions" :value="scope.row.currency" />
</template>
</el-table-column>
<el-table-column prop="commissionDate" label="入账日期" min-width="120" align="center" />
<el-table-column prop="status" label="比对状态" min-width="100" align="center">
<template #default="scope">
......@@ -111,14 +151,32 @@
align="center"
show-overflow-tooltip
/>
<el-table-column label="操作" width="180" align="center" fixed="right">
<el-table-column label="操作" width="220" align="center" fixed="right">
<template #default="scope">
<el-button text size="small" type="primary" @click="handleEdit(scope.row)"
>编辑</el-button
>
<el-button text size="small" type="danger" @click="handleDelete(scope.row)"
>删除</el-button
>
<div class="btnCon">
<el-button text size="small" type="primary" @click="handleEdit(scope.row)"
>编辑</el-button
>
<el-button text size="small" type="danger" @click="handleDelete(scope.row)"
>删除</el-button
>
<el-dropdown placement="bottom" style="margin-left: 10px">
<el-button type="primary" link size="small">
更多 <el-icon><ArrowDown /></el-icon
></el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="handleAlignment(scope.row)"
>比对记录</el-dropdown-item
>
<el-dropdown-item @click="operationRecord(scope.row)"
>操作记录</el-dropdown-item
>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</template>
</el-table-column>
</el-table>
......@@ -207,7 +265,7 @@
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-col :span="12">
<el-form-item label="入账日期" prop="commissionDate">
<el-date-picker
v-model="incomeForm.commissionDate"
......@@ -217,6 +275,52 @@
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="结算汇率" prop="amount">
<el-input v-model="incomeForm.amount" placeholder="请输入汇率" />
</el-form-item>
</el-col>
<template v-if="editStatus == 'edit'">
<el-col :span="12">
<el-form-item label="比对状态" prop="status">
<el-select v-model="incomeForm.status" placeholder="请选择状态">
<el-option
v-for="item in dictLists"
:key="item.itemValue"
:label="item.itemLabel"
:value="item.itemValue"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="修改人" prop="amount">
<el-input v-model="incomeForm.amount" placeholder="请输入汇率" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="修改时间" prop="commissionDate">
<el-date-picker
v-model="incomeForm.commissionDate"
type="date"
placeholder="选择日期"
value-format="YYYY-MM-DD"
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="修改内容" prop="remark">
<el-input
v-model="incomeForm.remark"
type="textarea"
:rows="3"
placeholder="请输入备注信息"
/>
</el-form-item>
</el-col>
</template>
<el-col :span="24">
<el-form-item label="备注" prop="remark">
<el-input
......@@ -239,11 +343,97 @@
</span>
</template>
</el-dialog>
<el-dialog title="比对记录" v-model="showAlignmentRecord" width="1000px" append-to-body>
<el-table :data="alignmentList" border>
<el-table-column prop="createTime" label="比对时间" align="center" width="150">
<template #default="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="期数" prop="policyNo" align="center" width="100" fixed="left">
</el-table-column>
<el-table-column
label="总期数"
prop="errorMsg"
align="center"
width="100"
></el-table-column>
<el-table-column
label="比对状态"
prop="errorMsg"
align="center"
width="100"
></el-table-column>
<el-table-column
label="结算汇率"
prop="errorMsg"
align="center"
width="100"
></el-table-column>
<el-table-column
label="入账金额"
prop="errorMsg"
align="center"
width="100"
></el-table-column>
<el-table-column
label="已入账金额"
prop="errorMsg"
align="center"
width="100"
></el-table-column>
<el-table-column
label="待入账金额"
prop="errorMsg"
align="center"
width="100"
></el-table-column>
<el-table-column label="总金额" prop="errorMsg" align="center"></el-table-column>
</el-table>
<pagination
v-show="alignmentPages.total >= 0"
:total="alignmentPages.total"
v-model:page="alignmentPages.pageNo"
v-model:limit="alignmentPages.pageSize"
@pagination="getAlignmentData"
/>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeDialog">关 闭</el-button>
</div>
</template>
</el-dialog>
<el-dialog title="操作记录" v-model="showOperationRecord" width="1000px" append-to-body>
<el-table :data="operationList" border>
<el-table-column prop="createTime" label="修改时间" align="center" width="150">
<template #default="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="修改人" prop="policyNo" align="center" width="150" fixed="left">
</el-table-column>
<el-table-column label="修改内容" prop="errorMsg" align="center"></el-table-column>
</el-table>
<pagination
v-show="operationPages.total >= 0"
:total="operationPages.total"
v-model:page="operationPages.pageNo"
v-model:limit="operationPages.pageSize"
@pagination="getOperationData"
/>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeDialog">关 闭</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ref, reactive, onMounted, nextTick } from 'vue'
import { Search, RefreshLeft, UploadFilled, Plus, Document } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'
// 导入有关来佣的接口
......@@ -251,17 +441,144 @@ import {
getPolicyCommissionList,
downloadPolicyFortune,
generateCommissionRecord,
updatePolicyCommission
updatePolicyCommission,
incomeStatistics
} from '@/api/financial/commission'
import FileUpload from '@/components/FileUpload/index'
import { useRouter } from 'vue-router'
const { proxy } = getCurrentInstance()
const router = useRouter()
import { listType } from '@/api/system/dict/type'
// 添加表格引用
const tableRef = ref()
const statisticList = ref([
{ name: '总金额', value: '0', key: 'totalAmount', format: true },
{ name: '总入账金额', value: '0', key: 'totalPaidAmount', format: true },
{ name: '待入账金额', value: '0', key: 'pendingPaidAmount', format: true },
{ name: '已入账比例', value: '0', key: 'paidAmountRatio', format: false },
{ name: '总保单数', value: '0', key: 'totalPolicyCount', format: false }
])
// 存储所有选中的行数据(用于跨页保持选择)
const allSelectedRows = ref(new Map())
const alignmentList = ref([]) //比对记录列表
const operationList = ref([]) //操作记录列表
const showAlignmentRecord = ref(false) // 是否显示比对记录列表
const showOperationRecord = ref(false) // 是否显示比对记录列表
// 通过dictType=csf_commission_status获取比对状态字典值,获取对象中的dictItemList
const dictLists = ref([])
const currencyTypeOptions = ref([])
const alignmentPages = ref({
total: 0,
pageNo: 1,
pageSize: 5
})
const operationPages = ref({
total: 0,
pageNo: 1,
pageSize: 5
})
const getAlignmentData = () => {}
const getOperationData = () => {}
const isSearch = ref(false)
const editStatus = ref('add')
const closeDialog = () => {
showAlignmentRecord.value = false
alignmentList.value = []
alignmentPages.value = {
pageNo: 1,
pageSize: 5,
total: 0
}
showOperationRecord.value = false
operationList.value = []
operationPages.value = {
pageNo: 1,
pageSize: 5,
total: 0
}
}
// 设置当前页的选中状态
const setCurrentPageSelection = () => {
if (!tableRef.value) return
// 清除当前页的选择
// tableRef.value.clearSelection()
// 设置当前页应该选中的行
tableData.value.forEach(row => {
if (allSelectedRows.value.has(row.commissionBizId)) {
tableRef.value.toggleRowSelection(row, true)
}
})
}
// 获取所有选中的行(包含跨页选择的)
const getAllSelectedRows = () => {
return Array.from(allSelectedRows.value.values())
}
// 更新全局选中状态
const updateAllSelectedRows = () => {
// 获取当前页的所有行的 key(commissionBizId)
const currentPageKeys = tableData.value.map(row => row.commissionBizId)
// 从全局选中中移除当前页不再存在的行
// for (const key of allSelectedRows.value.keys()) {
// if (!currentPageKeys.includes(key)) {
// allSelectedRows.value.delete(key)
// }
// }
// 更新当前页的选中状态
tableData.value.forEach(row => {
const isSelected = selectedRows.value.some(
selectedRow => selectedRow.commissionBizId === row.commissionBizId
)
if (isSelected) {
allSelectedRows.value.set(row.commissionBizId, row)
} else {
allSelectedRows.value.delete(row.commissionBizId)
}
})
getStatistics()
}
const getStatistics = async () => {
try {
let commissionIds = getAllSelectedRows().map(item => item.id)
if (commissionIds.length > 0) {
// 调用接口获取来佣列表
const res = await incomeStatistics({
commissionIds: commissionIds
})
if (res.data) {
statisticList.value.forEach(item => {
item.value = res.data[item.key]
})
}
} else {
isSearch.value = false
}
} catch (error) {
console.error('获取数据失败:', error)
ElMessage.error('统计失败')
}
}
// 清空所有选择
const clearAllSelection = () => {
allSelectedRows.value.clear()
selectedRows.value = []
if (tableRef.value) {
tableRef.value.clearSelection()
}
}
// 格式化金额
const formatCurrency = amount => {
return new Intl.NumberFormat('zh-CN', {
style: 'currency',
currency: 'CNY'
}).format(amount)
}
const getLists = () => {
return new Promise((resolve, reject) => {
listType({ typeList: ['csf_commission_status', 'bx_currency_type'] })
......@@ -271,8 +588,14 @@ const getLists = () => {
dictLists.value = dictData?.dictItemList || []
// 处理币种字典值
const currencyData = res.data.find(item => item.dictType === 'bx_currency_type')
if (currencyData) {
currencyData?.dictItemList.forEach(item => {
item.value = item.itemValue
item.label = item.itemLabel
})
}
currencyTypeOptions.value = currencyData?.dictItemList || []
console.log('获取到的币种字典数据:', currencyTypeOptions.value)
resolve(dictLists.value, currencyTypeOptions.value)
} else {
dictLists.value = []
......@@ -304,7 +627,9 @@ const handleSortChange = column => {
const searchForm = reactive({
policyNo: '',
reconciliationCompany: '',
incomeDateRange: []
incomeDateRange: [],
status: '',
expectedDate: ''
})
// 对账公司选项
......@@ -351,6 +676,7 @@ onMounted(() => {
const initialData = async () => {
await getLists()
fetchTableData()
fetchReconciliationCompanyList()
}
......@@ -364,8 +690,9 @@ const getUploadFileFunc = data => {
ElMessage.error('上传失败')
}
}
// 获取列表数据
// 调用接口获取来佣列表
// 调用接口获取入账列表
const fetchTableData = async () => {
tableLoading.value = true
try {
......@@ -374,12 +701,25 @@ const fetchTableData = async () => {
pageNo: pagination.currentPage,
pageSize: pagination.pageSize,
policyNo: searchForm.policyNo,
status: searchForm.status,
expectedDate: searchForm.expectedDate ? proxy.parseTime(searchForm.expectedDate) : '',
reconciliationCompany: searchForm.reconciliationCompany,
startTime: searchForm.incomeDateRange[0] ? `${searchForm.incomeDateRange[0]} 00:00:00` : '',
endTime: searchForm.incomeDateRange[1] ? `${searchForm.incomeDateRange[1]} 23:59:59` : ''
})
tableData.value = res.data.records
pagination.total = res.data.total
if (res.data.page) {
tableData.value = res.data.page.records
pagination.total = res.data.page.total
}
if (res.data.commissionStatisticsVO && isSearch.value) {
statisticList.value.forEach(item => {
item.value = res.data.commissionStatisticsVO[item.key]
})
}
// 数据加载完成后,设置当前页的选中状态
nextTick(() => {
setCurrentPageSelection()
})
} catch (error) {
console.error('获取数据失败:', error)
ElMessage.error('获取数据失败')
......@@ -391,6 +731,15 @@ const fetchTableData = async () => {
// 处理查询
const handleSearch = () => {
pagination.currentPage = 1
Object.values(searchForm).some(value => {
if (Array.isArray(value) && value.length > 0) {
isSearch.value = true
}
if (value !== '' && value != null) {
isSearch.value = true
}
})
clearAllSelection()
fetchTableData()
ElMessage.success('查询成功')
}
......@@ -399,8 +748,16 @@ const handleSearch = () => {
const resetForm = () => {
searchForm.policyNo = ''
searchForm.reconciliationCompany = ''
searchForm.status = ''
searchForm.expectedDate = ''
searchForm.incomeDateRange = []
isSearch.value = false
pagination.currentPage = 1
pagination.pageSize = 10
// 清空选择
clearAllSelection()
ElMessage.success('已重置筛选条件')
fetchTableData()
}
// 处理分页大小变化
......@@ -412,12 +769,15 @@ const handleSizeChange = val => {
// 处理分页页码变化
const handleCurrentChange = val => {
pagination.currentPage = val
fetchTableData()
}
// 处理表格选择变化
const handleSelectionChange = rows => {
selectedRows.value = rows
// 更新全局选中状态
updateAllSelectedRows()
}
// 下载模板
......@@ -435,7 +795,7 @@ const downloadTemplate = () => {
const handleAdd = () => {
incomeDialogTitle.value = '新增入账记录'
isEditMode.value = false
editStatus.value = 'add'
// 重置表单数据
Object.assign(incomeForm, {
commissionBizId: '',
......@@ -538,7 +898,7 @@ const incomeFormRules = {
const handleEdit = row => {
incomeDialogTitle.value = `编辑入账记录 - ${row.policyNo}`
isEditMode.value = true
editStatus.value = 'edit'
// 填充表单数据
Object.assign(incomeForm, {
commissionBizId: row.commissionBizId,
......@@ -560,9 +920,15 @@ const handleEdit = row => {
incomeDialogVisible.value = true
}
const handleAlignment = row => {
showAlignmentRecord.value = true
}
const operationRecord = () => {
showOperationRecord.value = true
}
// 提交入账表单(新增/编辑共用)
import { addPolicyCommission } from '@/api/financial/commission'
import { computed } from 'vue'
const submitIncomeForm = async () => {
if (!incomeFormRef.value) {
ElMessage.error('请先初始化表单')
......@@ -622,6 +988,11 @@ const handleCloseDialog = done => {
</script>
<style scoped>
.btnCon {
display: flex;
align-items: center;
justify-content: center;
}
.financial-income-page {
padding: 20px;
max-width: 1600px;
......@@ -720,7 +1091,11 @@ const handleCloseDialog = done => {
.table-card {
padding: 15px 20px;
}
.totalData {
margin-bottom: 10px;
font-size: 14px;
color: #000;
}
.pagination {
margin-top: 15px;
text-align: right;
......
......@@ -6,20 +6,12 @@
<el-row :gutter="20">
<el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-form-item label="保单号">
<el-input
v-model="queryParams.policyNo"
placeholder="请输入保单号"
clearable
/>
<el-input v-model="queryParams.policyNo" placeholder="请输入保单号" clearable />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-form-item label="转介人">
<el-input
v-model="queryParams.broker"
placeholder="请输入转介人"
clearable
/>
<el-input v-model="queryParams.broker" placeholder="请输入转介人" clearable />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6">
......@@ -35,6 +27,18 @@
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-form-item label="出账状态">
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable>
<el-option
v-for="item in dictLists"
:key="item.itemValue"
:label="item.itemLabel"
:value="item.itemValue"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-form-item>
<el-button type="primary" @click="handleQuery">查询</el-button>
<el-button @click="resetQuery">重置</el-button>
......@@ -51,12 +55,8 @@
<el-button type="primary" @click="handleCreate">新建薪资记录</el-button>
<el-button @click="handleImport">批量导入</el-button>
</el-col>
<el-col :span="12" style="text-align: right;">
<el-button
type="success"
:disabled="selectedRows.length === 0"
@click="completeBilling"
>
<el-col :span="12" style="text-align: right">
<el-button type="success" :disabled="selectedRows.length === 0" @click="completeBilling">
完成出账
</el-button>
</el-col>
......@@ -65,12 +65,21 @@
<!-- 数据表格 -->
<el-card>
<div class="totalData" v-if="getAllSelectedRows().length > 0 || isSearch">
<span v-for="(item, index) in statisticList">
<span :style="{ marginLeft: index == 0 ? ' 0' : '20px' }">{{ item.name }}</span>
<span>{{ item.format ? formatCurrency(item.value) : item.value }}</span>
</span>
</div>
<el-table
:data="tableData"
@selection-change="handleSelectionChange"
v-loading="loading"
ref="tableRef"
row-key="fortuneAccountBizId"
:reserve-selection="true"
>
<el-table-column type="selection" width="55" />
<el-table-column type="selection" width="55" :reserve-selection="true" />
<el-table-column prop="broker" label="转介人" min-width="120" />
<el-table-column prop="team" label="所属团队" min-width="120" />
<el-table-column prop="amount" label="出账金额" width="120">
......@@ -78,18 +87,23 @@
{{ formatCurrency(row.amount) }}
</template>
</el-table-column>
<el-table-column prop="currency" label="出账币种" width="100" />
<el-table-column prop="currency" label="出账币种" width="100">
<template #default="scope">
<dict-tag :options="currencyTypeOptions" :value="scope.row.currency" />
</template>
</el-table-column>
<el-table-column prop="status" label="出账状态" width="100">
<template #default="{ row }">
<el-tag :type="getStatusType(row.status)">
{{convertStatusToDict(row.status) }}
{{ convertStatusToDict(row.status) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="remark" label="备注" min-width="150" show-overflow-tooltip />
<el-table-column label="操作" width="300" fixed="right">
<template #default="{ row }">
<el-button size="small" @click="handleEdit(row)">修改</el-button>
<el-button size="small" type="primary" @click="handleEdit(row)">修改</el-button>
<el-button size="small" type="primary" @click="handleRevise(row)">修订记录</el-button>
<el-button size="small" type="danger" @click="handleDelete(row)">删除</el-button>
<!-- <el-button size="small" type="info" @click="generateSalarySlip(row)">生成薪资单</el-button> -->
</template>
......@@ -109,11 +123,7 @@
</el-card>
<!-- 新建薪资记录对话框 -->
<el-dialog
title="新建薪资记录"
v-model="createDialogVisible"
width="500px"
>
<el-dialog title="新建薪资记录" v-model="createDialogVisible" width="500px">
<el-form :model="createFormData" label-width="100px">
<el-form-item label="转介人" required>
<el-select v-model="createFormData.referrer" placeholder="请选择转介人">
......@@ -128,16 +138,13 @@
<el-form-item label="出账金额" required>
<el-input-number
v-model="createFormData.amount"
:min="0"
:min="-10000000000000"
:precision="2"
placeholder="请输入出账金额"
/>
</el-form-item>
<el-form-item label="出账项目" required>
<el-input
v-model="createFormData.billingItem"
placeholder="请输入出账项目"
/>
<el-input v-model="createFormData.billingItem" placeholder="请输入出账项目" />
</el-form-item>
<el-form-item label="备注">
<el-input
......@@ -155,31 +162,66 @@
</el-dialog>
<!-- 出账完成弹窗 -->
<el-dialog
title="出账完成"
v-model="billingCompleteDialogVisible"
width="400px"
>
<div style="text-align: center;">
<el-dialog title="出账完成" v-model="billingCompleteDialogVisible" width="400px">
<div style="text-align: center">
<el-icon size="48" color="#67C23A">
<SuccessFilled />
</el-icon>
<p style="margin-top: 16px; font-size: 16px;">出账操作已完成!</p>
<p style="margin-top: 16px; font-size: 16px">出账操作已完成!</p>
</div>
<template #footer>
<!-- <el-button type="primary" @click="generateSalarySlips">生成薪资单</el-button> -->
<el-button @click="billingCompleteDialogVisible = false">关闭</el-button>
</template>
</el-dialog>
<el-dialog title="修订记录" v-model="showReviseRecord" width="1000px" append-to-body>
<el-table :data="reviseList" border>
<el-table-column prop="createTime" label="修订时间" align="center" width="150">
<template #default="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="修订人" prop="policyNo" align="center" width="150">
</el-table-column>
<el-table-column label="修订内容" prop="errorMsg" align="center"></el-table-column>
</el-table>
<pagination
v-show="revisePages.total >= 0"
:total="revisePages.total"
v-model:page="revisePages.pageNo"
v-model:limit="revisePages.pageSize"
@pagination="getReviseData"
/>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeDialog">关 闭</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ref, reactive, onMounted, nextTick } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { SuccessFilled } from '@element-plus/icons-vue'
import { getReferrerFortuneList,updatePolicyFortuneStatus } from '@/api/financial/commission'
import {
getReferrerFortuneList,
updatePolicyFortuneStatus,
salaryStatistics
} from '@/api/financial/commission'
// 添加表格引用
const tableRef = ref()
// 存储所有选中的行数据(用于跨页保持选择)
const allSelectedRows = ref(new Map())
const isSearch = ref(false)
const statisticList = ref([
{ name: '总金额', value: '0', key: 'totalAmount', format: true },
{ name: '总人数', value: '0', key: 'brokerCount', format: false }
])
// 查询参数
const queryParams = reactive({
broker: '',
......@@ -197,7 +239,14 @@ const tableData = ref([])
const total = ref(0)
const loading = ref(false)
const selectedRows = ref([])
const showReviseRecord = ref(false)
const reviseList = ref([])
const currencyTypeOptions = ref([])
const revisePages = reactive({
total: 0,
pageNo: 1,
pageSize: 5
})
// 对话框相关
const createDialogVisible = ref(false)
const billingCompleteDialogVisible = ref(false)
......@@ -217,15 +266,96 @@ const referrerOptions = [
{ label: '王五', value: 'wangwu' },
{ label: '赵六', value: 'zhaoliu' }
]
const getReviseData = () => {}
// 设置当前页的选中状态
const setCurrentPageSelection = () => {
if (!tableRef.value) return
// 清除当前页的选择
// tableRef.value.clearSelection()
// 设置当前页应该选中的行
tableData.value.forEach(row => {
if (allSelectedRows.value.has(row.fortuneAccountBizId)) {
tableRef.value.toggleRowSelection(row, true)
}
})
}
// 获取所有选中的行(包含跨页选择的)
const getAllSelectedRows = () => {
return Array.from(allSelectedRows.value.values())
}
// 更新全局选中状态
const updateAllSelectedRows = () => {
// 获取当前页的所有行的 key(fortuneAccountBizId)
const currentPageKeys = tableData.value.map(row => row.fortuneAccountBizId)
// 从全局选中中移除当前页不再存在的行
// for (const key of allSelectedRows.value.keys()) {
// if (!currentPageKeys.includes(key)) {
// allSelectedRows.value.delete(key)
// }
// }
// 更新当前页的选中状态
tableData.value.forEach(row => {
const isSelected = selectedRows.value.some(
selectedRow => selectedRow.fortuneAccountBizId === row.fortuneAccountBizId
)
if (isSelected) {
allSelectedRows.value.set(row.fortuneAccountBizId, row)
} else {
allSelectedRows.value.delete(row.fortuneAccountBizId)
}
})
// 当勾选项发生变化的时候,拿到最新的统计数据
getStatistics()
}
const getStatistics = async () => {
try {
let fortuneAccountIdList = getAllSelectedRows().map(item => item.id)
if (fortuneAccountIdList.length > 0) {
// 调用接口获取来佣列表
const res = await salaryStatistics({
fortuneAccountIdList: fortuneAccountIdList
})
if (res.data) {
statisticList.value.forEach(item => {
item.value = res.data[item.key]
})
}
} else {
isSearch.value = false
}
} catch (error) {
console.error('获取数据失败:', error)
ElMessage.error('统计失败')
}
}
// 清空所有选择
const clearAllSelection = () => {
allSelectedRows.value.clear()
selectedRows.value = []
if (tableRef.value) {
tableRef.value.clearSelection()
}
}
const closeDialog = () => {
showReviseRecord.value = false
reviseList.value = []
revisePages.value = {
pageNo: 1,
pageSize: 5,
total: 0
}
}
// 初始化
onMounted(() => {
getDictLists()
getList()
})
// 获取数据列表
const getList = async () => {
loading.value = true
......@@ -235,16 +365,28 @@ const getList = async () => {
queryParams.accountDateEnd = queryParams.accountDate[1]
}
const response = await getReferrerFortuneList(queryParams)
tableData.value = response.data.records
total.value = response.data.total
loading.value = false
if (response.data.page) {
tableData.value = response.data.page.records
total.value = response.data.page.total
loading.value = false
}
if (response.data.statisticsVO && isSearch.value) {
statisticList.value.forEach(item => {
item.value = response.data.statisticsVO[item.key]
})
}
// 数据加载完成后,设置当前页的选中状态
nextTick(() => {
setCurrentPageSelection()
})
} catch (error) {
loading.value = false
// ElMessage.error('获取数据失败')
}
}
const getStatusType = (status) => {
const getStatusType = status => {
const types = {
0: 'warning',
1: 'success',
......@@ -256,6 +398,15 @@ const getStatusType = (status) => {
// 查询
const handleQuery = () => {
queryParams.pageNo = 1
Object.values(queryParams).some(value => {
if (Array.isArray(value) && value.length > 0) {
isSearch.value = true
}
if (value !== '' && value != null) {
isSearch.value = true
}
})
clearAllSelection()
getList()
}
......@@ -270,12 +421,17 @@ const resetQuery = () => {
sortField: '',
sortOrder: 'desc'
})
isSearch.value = false
// 清空选择
clearAllSelection()
getList()
}
// 选择行变化
const handleSelectionChange = (selection) => {
const handleSelectionChange = selection => {
selectedRows.value = selection
// 更新全局选中状态
updateAllSelectedRows()
}
// 新建薪资记录
......@@ -290,14 +446,16 @@ const handleCreate = () => {
}
// 编辑薪资记录
const handleEdit = (row) => {
const handleEdit = row => {
// 这里可以打开编辑对话框
ElMessage.info(`编辑转介人:${row.referrer}`)
}
const handleRevise = row => {
showReviseRecord.value = true
}
import { addPolicyFortuneAccount } from '@/api/financial/commission'
const deletePolicyFortuneO = async (fortuneAccountBizId) => {
const deletePolicyFortuneO = async fortuneAccountBizId => {
try {
await deletePolicyFortune({ fortuneAccountBizId })
} catch (error) {
......@@ -306,7 +464,7 @@ const deletePolicyFortuneO = async (fortuneAccountBizId) => {
}
// 删除薪资记录
const handleDelete = async (row) => {
const handleDelete = async row => {
try {
await ElMessageBox.confirm('确认删除这条薪资记录吗?', '提示', {
type: 'warning'
......@@ -332,7 +490,7 @@ const completeBilling = async () => {
ElMessage.warning('请先选择要出账的记录')
return
}
try {
await ElMessageBox.confirm(
`确认完成 ${selectedRows.value.length} 条记录的出账操作吗?`,
......@@ -341,11 +499,9 @@ const completeBilling = async () => {
)
console.log(selectedRows.value)
const arr = selectedRows.value.map(item => item.fortuneAccountBizId)
// 调用出账API
await fetchCompletePolicyFortune(arr)
await fetchCompletePolicyFortune(arr)
} catch (error) {
if (error !== 'cancel') {
ElMessage.error('出账操作失败')
......@@ -354,7 +510,7 @@ const completeBilling = async () => {
}
// 生成薪资单(单条)
const generateSalarySlip = (row) => {
const generateSalarySlip = row => {
// 调用生成薪资单API
// await api.generateSalarySlip(row.id)
ElMessage.success(`已为 ${row.referrer} 生成薪资单`)
......@@ -377,10 +533,10 @@ const submitCreateForm = async () => {
ElMessage.warning('请填写必填字段')
return
}
// 调用保存API
// await api.createSalary(createFormData)
ElMessage.success('新建成功')
createDialogVisible.value = false
getList()
......@@ -390,7 +546,7 @@ const submitCreateForm = async () => {
}
// 格式化金额
const formatCurrency = (amount) => {
const formatCurrency = amount => {
return new Intl.NumberFormat('zh-CN', {
style: 'currency',
currency: 'CNY'
......@@ -401,96 +557,104 @@ import { listType } from '@/api/system/dict/type'
const dictLists = ref([])
// 获取出账状态字典值
const getDictLists = () => {
return new Promise((resolve, reject) => {
listType({typeList: ['csf_fortune_status']}).then(res => {
if (res.code === 200 && res.data) {
const dictData = res.data.find(item => item.dictType === 'csf_fortune_status');
dictLists.value = dictData?.dictItemList || [];
console.log('获取到的字典数据:', dictLists.value);
resolve(dictLists.value);
} else {
dictLists.value = [];
resolve([]);
}
}).catch(error => {
console.error('获取状态列表失败:', error);
dictLists.value = [];
reject(error);
});
});
return new Promise((resolve, reject) => {
listType({ typeList: ['csf_fortune_status', 'bx_currency_type'] })
.then(res => {
if (res.code === 200 && res.data) {
const dictData = res.data.find(item => item.dictType === 'csf_fortune_status')
dictLists.value = dictData?.dictItemList || []
console.log('获取到的字典数据:', dictLists.value)
// 处理币种字典值
const currencyData = res.data.find(item => item.dictType === 'bx_currency_type')
if (currencyData) {
currencyData?.dictItemList.forEach(item => {
item.value = item.itemValue
item.label = item.itemLabel
})
}
currencyTypeOptions.value = currencyData?.dictItemList || []
resolve(dictLists.value, currencyTypeOptions.value)
} else {
dictLists.value = []
currencyTypeOptions.value = []
resolve([], [])
}
})
.catch(error => {
console.error('获取状态列表失败:', error)
dictLists.value = []
reject(error)
})
})
}
// 返回数据中状态需要转换为字典值
const convertStatusToDict = (status) => {
const dictItem = dictLists.value.find(item => item.itemValue == status);
return dictItem?.itemLabel ?? status;
const convertStatusToDict = status => {
const dictItem = dictLists.value.find(item => item.itemValue == status)
return dictItem?.itemLabel ?? status
}
// 更新出账状态
const updateStatus = async (row) => {
try {
const res = await updatePolicyFortuneStatus({
fortuneBizIdList: row,
status: 2
});
console.log(res)
if (res.code === 200) {
// 显示完成弹窗
const updateStatus = async row => {
try {
const res = await updatePolicyFortuneStatus({
fortuneBizIdList: row,
status: 2
})
console.log(res)
if (res.code === 200) {
// 显示完成弹窗
billingCompleteDialogVisible.value = true
getList()
} else {
ElMessage.error(res.msg)
}
} catch (error) {
}
} catch (error) {}
}
// 完成出账
import { completePolicyFortune } from '@/api/financial/commission'
const fetchCompletePolicyFortune = async (row) => {
try {
const res = await completePolicyFortune({
fortuneAccountBizIdList: row
});
console.log(res)
if (res.code === 200) {
// 显示完成弹窗
const fetchCompletePolicyFortune = async row => {
try {
const res = await completePolicyFortune({
fortuneAccountBizIdList: row
})
console.log(res)
if (res.code === 200) {
// 显示完成弹窗
billingCompleteDialogVisible.value = true
getList()
} else {
ElMessage.error(res.msg)
}
} catch (error) {
}
} catch (error) {}
}
// 删除出账
import { deletePolicyFortune } from '@/api/financial/commission'
// 删除出账
const deleteFortune = async (row) => {
try {
const res = await deletePolicyFortune({
fortuneAccountBizId: row
});
console.log(res)
if (res.code === 200) {
// 显示完成弹窗
const deleteFortune = async row => {
try {
const res = await deletePolicyFortune({
fortuneAccountBizId: row
})
console.log(res)
if (res.code === 200) {
// 显示完成弹窗
billingCompleteDialogVisible.value = true
} else {
ElMessage.error(res.msg)
}
} catch (error) {
}
} catch (error) {}
}
</script>
<style scoped>
.totalData {
margin-bottom: 10px;
font-size: 14px;
color: #000;
}
.financial-salary-page {
padding: 20px;
}
......@@ -517,17 +681,17 @@ const deleteFortune = async (row) => {
.financial-salary-page {
padding: 10px;
}
.search-card {
margin-bottom: 15px;
}
.operation-card {
margin-bottom: 15px;
}
.el-col {
margin-bottom: 10px;
}
}
</style>
\ No newline at end of file
</style>
......@@ -28,13 +28,44 @@
<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
<!-- <el-form-item
:label="child.label"
:prop="child.key"
:key="child.key"
:label-width="child.labelWidth"
:label-position="child.labelPosition"
> -->
<el-form-item
:label="
child.key === 'residentialAddress' && child.type === 'arrowRight'
? ''
: child.label
"
:prop="child.key"
:key="child.key"
:label-width="child.labelWidth"
:label-position="child.labelPosition"
>
<!-- 自定义 label 插槽 -->
<template
v-if="child.key === 'residentialAddress' && child.type === 'arrowRight'"
#label
>
<div class="custom-label">
<span>{{ child.label }}</span>
<el-checkbox-group
v-model="form.isCopyAddress"
size="small"
style="margin-left: 8px"
@change="changeAddressStatus(child)"
:disabled="copyAddress"
>
<el-checkbox :value="true" name="isCopyAddress">
同通讯地址
</el-checkbox>
</el-checkbox-group>
</div>
</template>
<el-input
v-if="child.type === 'Input'"
:type="child.inputType"
......@@ -228,7 +259,7 @@ const total = ref(0)
const customerRef = ref(null)
//计算默认显示的日期(18年前的今天)
const defaultDisplayDate = ref(dayjs().subtract(18, 'year').toDate())
// const copyAddress = ref(false) //是否可以复制地址
// 地址组件菜单数据
const addressMenuList = ref([
{
......@@ -288,7 +319,7 @@ const deleteKeyList = ref([
'companyAddress'
]) // 存储需要删除的key
const data = reactive({
form: {},
form: { isCopyAddress: [] },
processedCustomerData: [], // 处理后的表单数据
oldCustomerData: [], // 保存旧的表单Dom,便于撤销操作
rules: {}, //表单验证规则,
......@@ -299,6 +330,31 @@ const data = reactive({
}
})
const { form, rules, processedCustomerData, queryParams, oldCustomerData } = toRefs(data)
const copyAddress = computed(() => {
const residenceAddressIndex = addressQuickList.value.findIndex(
item => item.type === 'residenceAddress'
)
if (residenceAddressIndex !== -1) {
return false
} else {
return true
}
})
const changeAddressStatus = child => {
// 复用地址
if (form.value.isCopyAddress.length > 0 && form.value.isCopyAddress[0]) {
if (child.key == 'residentialAddress') {
form.value[child.key] = form.value['residenceAddress']
// 这里是直接复用地址了,但是地址组件的值是双向绑定的,所以这里需要手动更新地址组件的值
addressQuickList.value.forEach(item => {
if (item.type == 'residenceAddress') {
saveKey.value[child.key] = { ...item, type: child.key }
}
})
}
}
console.log('saveKey.value', saveKey.value)
}
const handleInputChange = child => {
if (
(child.key == 'lastName' || child.key == 'firstName') &&
......@@ -480,11 +536,11 @@ const handleCloseDrawer = () => {
}
// 点击了抽屉的确定
const confirmDrawer = info => {
console.log('抽屉info', info)
// console.log('抽屉info', info)
// info 为抽屉返回的值
if (drawerInfo.value.type == 'arrowRight' && drawerInfo.value.drawerType) {
console.log('drawerInfo.value', drawerInfo.value)
// console.log('drawerInfo.value', drawerInfo.value)
let newObj = info[drawerInfo.value.key]
//要判断drawerType
......@@ -525,6 +581,28 @@ const confirmDrawer = info => {
newObj.type = drawerInfo.value.key
form.value[info.key] = `${newObj.region} ${newObj.city} ${newObj.street} ${newObj.location}`
saveKey.value[info.key] = newObj
console.log('newObj', newObj)
newObj.addressString = `${newObj.region}${newObj.city}${newObj.street}${newObj.location}`
// 检查数组中是否已存在key的地址
// debugger
const existinAddressIndex = addressQuickList.value.findIndex(
item => item.type === newObj.type
)
if (existinAddressIndex !== -1) {
// 更新已存在的电话
addressQuickList.value[existinAddressIndex] = {
...newObj
}
} else {
// 添加新的快捷电话
addressQuickList.value.push(newObj)
}
addressQuickList.value = removeDuplicates(addressQuickList.value, 'addressString')
console.log('填写地址', copyAddress.value)
break
case 'country':
info.objType = drawerInfo.value.drawerType
......@@ -569,9 +647,15 @@ const handleSelectChange = child => {
} else {
resetShow('smokeQuantity', false)
}
break
case 'idType':
// 选择吸烟,展示吸烟数量
if (form.value[child.key] == 'idCard') {
resetShow('idCardAddress', true)
} else {
resetShow('idCardAddress', false)
}
break
default:
break
}
......@@ -610,7 +694,10 @@ const setFormValue = (obj, formData, exportValue) => {
if (obj.smokeQuantity && field.key == 'smokeQuantity') {
field.show = true
}
//证件类型是身份证,身份证地址就显示否则不显示
if (field.key == 'idCardAddress' && obj.idType == 'idCard') {
field.show = true
}
//要判断drawerType,因为抽屉要回显数据
switch (field.drawerType) {
case 'phone':
......@@ -654,7 +741,7 @@ const setFormValue = (obj, formData, exportValue) => {
form.value[
field.key
] = `${addressObj.region} ${addressObj.city} ${addressObj.street} ${addressObj.location}`
addressObj.addressString = `${addressObj.region} ${addressObj.city} ${addressObj.street} ${addressObj.location}`
addressObj.addressString = `${addressObj.region}${addressObj.city}${addressObj.street}${addressObj.location}`
addressObj.objType = field.drawerType
saveKey.value[field.key] = addressObj
if (tempAddressList.length > 0) {
......@@ -717,12 +804,12 @@ const setFormValue = (obj, formData, exportValue) => {
oldObjInfo.value = JSON.parse(JSON.stringify(form.value))
}
processedCustomerData.value = oldCustomerData.value = processedData
console.log('====================================')
console.log('processedCustomerData.value', processedCustomerData.value)
console.log('====================================')
console.log('====================================')
console.log('form', form.value)
console.log('====================================')
// console.log('====================================')
// console.log('processedCustomerData.value', processedCustomerData.value)
// console.log('====================================')
// console.log('====================================')
// console.log('form', form.value)
// console.log('====================================')
}
// 数组去重
function removeDuplicates(arr, key) {
......@@ -730,7 +817,7 @@ function removeDuplicates(arr, key) {
const result = []
for (const item of arr) {
if (!seen.has(item[key])) {
if (!seen.has(item[key]) && item[key]) {
seen.set(item[key], true)
result.push(item)
}
......@@ -872,6 +959,11 @@ watch(
)
</script>
<style lang="scss" scoped>
.custom-label {
width: 100%;
display: flex;
align-items: center;
}
.topBtn {
width: 100%;
display: flex;
......
......@@ -15,407 +15,377 @@
</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"
<div v-for="father in processedFanFormData">
<div>
<div class="fatherLable">
{{ father.fatherTitle }}
<div class="openCon" v-if="father.openIcon" @click="changeOpenStatus(father)">
<el-icon v-if="!father.isOpen"><Hide /></el-icon>
<el-icon v-else><View /></el-icon>
</div>
</div>
<div class="subTitle" v-if="father.subTitle && father.isOpen">
{{ father.subTitle }}
</div>
</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"
clearable
>
<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-option
v-for="item in child.options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
<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-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"
@change="changeCheck(father, child)"
>
<el-checkbox
v-for="item in child.options"
:key="item.value"
:label="item.value"
>
<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"
{{ 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"
clearable
>
<el-option
v-for="item in searchOptions[child.key] || []"
:key="item.value"
:label="item.label"
:value="item.value"
/>
<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"
>
<el-option
v-for="item in searchOptions[child.key] || []"
:key="item.userBizId"
:label="item.realName"
:value="item.userBizId"
/>
</el-select>
</el-form-item>
</div>
</el-col>
</template>
</el-row>
<!-- 有子孙的dom -->
<el-row v-if="father.child == 'yes'" :gutter="20">
<template v-for="(child, childIndex) in father.data" :key="child.id">
<el-col :span="child.span">
<div class="childLabel" v-if="father.key == 'familyMembers'">
</el-select>
</el-form-item>
</div>
</el-col>
</template>
</el-row>
<el-row v-if="father.showTable && father.isOpen">
<el-table :data="father.data" border>
<template v-if="father.key == 'familyMembers'">
<el-table-column label="亲属" prop="childTitle" width="100px" align="center">
<template #default="scope">
{{
child.type == '4' ? `${child.childTitle}-${childIndex - 2}` : child.childTitle
scope.row.type == '4'
? `${scope.row.childTitle}-${scope.$index - 2}`
: scope.row.childTitle
}}
</div>
<div
class="childLabel"
v-if="
father.key == 'existingSecurityOwner' ||
father.key == 'existingSecurityInsured' ||
father.key == 'investment'
"
>
{{ `${child.childTitle}-${childIndex + 1}` }}
</div>
</el-col>
<template v-for="grandchildren in child.children" :key="grandchildren.key">
<el-col
:sm="grandchildren.sm"
:lg="grandchildren.lg"
class="formItem"
v-if="grandchildren.show && form[father.key] && form[father.key][childIndex]"
>
<el-form-item
:label="grandchildren.label"
:prop="grandchildren.key"
:key="grandchildren.key"
:label-width="grandchildren.labelWidth"
:label-position="grandchildren.labelPosition"
</template>
</el-table-column>
<el-table-column label="年龄" prop="age" align="center">
<template #default="scope">
<el-input
v-model="scope.row.age"
size="default"
placeholder="请输入"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column label="是否需要供养" prop="needProvide" align="center">
<template #default="scope">
<el-select
v-model="scope.row.needProvide"
placeholder="请选择"
:disabled="editStatus"
clearable
>
<el-input
v-if="grandchildren.domType === 'Input'"
:type="grandchildren.inputType"
v-model="form[father.key][childIndex][grandchildren.key]"
:placeholder="grandchildren.placeholder"
maxlength="30"
:disabled="grandchildren.disabled"
/>
<el-select
v-if="grandchildren.domType === 'Select'"
v-model="form[father.key][childIndex][grandchildren.key]"
:placeholder="grandchildren.placeholder"
:disabled="grandchildren.disabled"
>
<el-option
v-for="item in grandchildren.options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-date-picker
style="width: 100%"
v-if="grandchildren.domType === 'DatePicker'"
v-model="form[father.key][childIndex][grandchildren.key]"
type="date"
:placeholder="grandchildren.placeholder"
:disabled="grandchildren.disabled"
<el-option
v-for="item in scope.row.options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-form-item>
</el-col>
</template>
<el-col
v-if="child.delete"
:span="3"
style="margin-left: 10px"
@click="deleteChildren(father, childIndex)"
</el-select>
</template>
</el-table-column>
<el-table-column
width="60px"
v-if="father.data && father.data.some(item => item.type === '4')"
align="center"
label="操作"
>
<el-icon class="deleteIcon"><Delete /></el-icon>
</el-col>
<template #default="scope">
<el-icon
v-if="scope.row.type == '4'"
@click="deleteChildren(father, scope.$index)"
class="deleteIcon"
><Delete
/></el-icon>
</template>
</el-table-column>
</template>
<el-col
:span="24"
v-if="father.addFamilyChildren"
style="display: flex; justify-content: flex-end"
>
<el-button
:disabled="editStatus"
type="primary"
icon="Plus"
@click="addChildren(father)"
>添加儿女</el-button
>
</el-col>
</el-row>
<el-row v-if="father.showTable">
<template
><div class="subTitle" v-if="father.subTitle">{{ father.subTitle }}</div></template
v-if="
father.key == 'existingSecurityOwner' || father.key == 'existingSecurityInsured'
"
>
<el-table :data="father.data" border>
<template v-if="father.key == 'familyMembers' && form[father.key].length > 0">
<el-table-column label="亲属" prop="childTitle" width="100px" align="center">
<template #default="scope">
{{
scope.row.type == '4'
? `${scope.row.childTitle}-${scope.$index - 2}`
: scope.row.childTitle
}}
</template>
</el-table-column>
<el-table-column label="年龄" prop="age" align="center">
<template #default="scope">
<el-input
v-model="scope.row.age"
size="default"
placeholder="请输入"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column label="是否需要供养" prop="needProvide" align="center">
<template #default="scope">
<el-select
v-model="scope.row.needProvide"
placeholder="请选择"
:disabled="editStatus"
>
<el-option
v-for="item in scope.row.options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column
width="50px"
v-if="father.data && father.data.some(item => item.type === '4')"
align="center"
>
<template #default="scope">
<el-icon
v-if="scope.row.type == '4'"
@click="deleteChildren(father, scope.$index)"
class="deleteIcon"
><Delete
/></el-icon>
</template>
</el-table-column>
</template>
<template
v-if="
(father.key == 'existingSecurityOwner' ||
father.key == 'existingSecurityInsured') &&
form[father.key].length > 0
"
>
<el-table-column label="保险公司" prop="insurer" align="center">
<template #default="scope">
<el-input
size="default"
placeholder="请输入"
v-model="scope.row.insurer"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column label="保障类型" prop="insuranceType" align="center">
<template #default="scope">
<el-input
v-model="scope.row.insuranceType"
size="default"
placeholder="请输入"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column label="保额" prop="sumInsured" align="center">
<template #default="scope">
<el-input
v-model="scope.row.sumInsured"
size="default"
placeholder="请输入"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column label="保险公司" prop="insurer" align="center">
<template #default="scope">
<el-input
size="default"
placeholder="请输入"
v-model="scope.row.insurer"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column label="保障类型" prop="insuranceType" align="center">
<template #default="scope">
<el-input
v-model="scope.row.insuranceType"
size="default"
placeholder="请输入"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column label="保额" prop="sumInsured" align="center">
<template #default="scope">
<el-input
v-model="scope.row.sumInsured"
size="default"
placeholder="请输入"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column label="币种" prop="currency" align="center">
<template #default="scope">
<el-select
v-model="scope.row.currency"
placeholder="请选择"
:disabled="editStatus"
>
<el-option
v-for="item in scope.row.options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column label="保单签发日期" prop="policyIssueDate" align="center">
<template #default="scope">
<el-date-picker
style="width: 100%"
v-model="scope.row.policyIssueDate"
type="date"
placeholder="请输入"
:disabled="editStatus"
:disabled-date="disabledDate"
/>
</template>
</el-table-column>
</template>
<template v-if="father.key == 'investment' && form[father.key].length > 0">
<el-table-column label="地址" prop="address" align="center">
<template #default="scope">
<el-input
size="default"
placeholder="请输入"
v-model="scope.row.address"
:disabled="editStatus"
<el-table-column label="币种" prop="currency" align="center">
<template #default="scope">
<el-select
v-model="scope.row.currency"
placeholder="请选择"
:disabled="editStatus"
clearable
>
<el-option
v-for="item in scope.row.options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</template>
</el-table-column>
<el-table-column label="市值" prop="marketValue" align="center">
<template #default="scope">
<el-input
v-model="scope.row.marketValue"
size="default"
placeholder="请输入"
:disabled="editStatus"
</el-select>
</template>
</el-table-column>
<el-table-column label="保单签发日期" prop="policyIssueDate" align="center">
<template #default="scope">
<el-date-picker
style="width: 100%"
v-model="scope.row.policyIssueDate"
type="date"
placeholder="请输入"
:disabled="editStatus"
:disabled-date="disabledDate"
/>
</template>
</el-table-column>
<el-table-column width="60px" align="center" label="操作">
<template #default="scope">
<el-icon @click="deleteChildren(father, scope.$index)" class="deleteIcon"
><Delete
/></el-icon>
</template>
</el-table-column>
</template>
<template v-if="father.key == 'investment'">
<el-table-column label="地址" prop="address" align="center">
<template #default="scope">
<el-input
size="default"
placeholder="请输入"
v-model="scope.row.address"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column label="市值" prop="marketValue" align="center">
<template #default="scope">
<el-input
v-model="scope.row.marketValue"
size="default"
placeholder="请输入"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column label="币种" prop="currency" align="center">
<template #default="scope">
<el-select
v-model="scope.row.currency"
placeholder="请选择"
:disabled="editStatus"
clearable
>
<el-option
v-for="item in scope.row.options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</template>
</el-table-column>
<el-table-column label="币种" prop="currency" align="center">
<template #default="scope">
<el-select
v-model="scope.row.currency"
placeholder="请选择"
:disabled="editStatus"
>
<el-option
v-for="item in scope.row.options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
</el-table-column>
</template>
</el-select>
</template>
</el-table-column>
<el-table-column width="60px" align="center" label="操作">
<template #default="scope">
<el-icon @click="deleteChildren(father, scope.$index)" class="deleteIcon"
><Delete
/></el-icon>
</template>
</el-table-column>
</template>
<template v-if="father.key == 'primaryResidence'">
<el-table-column label="自住用途之房地产地址" prop="address" align="center">
<template #default="scope">
<el-input
size="default"
placeholder="请输入"
v-model="scope.row.address"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column label="自住用途之房地产市值" prop="marketValue" align="center">
<template #default="scope">
<el-input
v-model="scope.row.marketValue"
size="default"
placeholder="请输入"
:disabled="editStatus"
<template v-if="father.key == 'primaryResidence'">
<el-table-column label="自住用途之房地产地址" prop="address" align="center">
<template #default="scope">
<el-input
size="default"
placeholder="请输入"
v-model="scope.row.address"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column label="自住用途之房地产市值" prop="marketValue" align="center">
<template #default="scope">
<el-input
v-model="scope.row.marketValue"
size="default"
placeholder="请输入"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column label="币种" prop="currency" align="center">
<template #default="scope">
<el-select
v-model="scope.row.currency"
placeholder="请选择"
:disabled="editStatus"
clearable
>
<el-option
v-for="item in scope.row.options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</template>
</el-table-column>
<el-table-column label="币种" prop="currency" align="center">
<template #default="scope">
<el-select
v-model="scope.row.currency"
placeholder="请选择"
:disabled="editStatus"
>
<el-option
v-for="item in scope.row.options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
</el-table-column>
</template>
</el-table>
<el-col
:span="24"
v-if="father.addFamilyChildren"
style="display: flex; justify-content: center"
</el-select>
</template>
</el-table-column>
<el-table-column width="60px" align="center" label="操作">
<template #default="scope">
<el-icon @click="deleteChildren(father, scope.$index)" class="deleteIcon"
><Delete
/></el-icon>
</template>
</el-table-column>
</template>
<template v-if="father.key == 'taxList'">
<el-table-column label="税务国家" prop="taxCountry" align="center">
<template #default="scope">
<el-input
size="default"
placeholder="请输入"
v-model="scope.row.taxCountry"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column label="税务编号" prop="taxNumber" align="center">
<template #default="scope">
<el-input
v-model="scope.row.taxNumber"
size="default"
placeholder="请输入"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column width="60px" align="center" label="操作">
<template #default="scope">
<el-icon @click="deleteChildren(father, scope.$index)" class="deleteIcon"
><Delete
/></el-icon>
</template>
</el-table-column>
</template>
</el-table>
<el-col
:span="24"
v-if="father.addChildren"
style="display: flex; justify-content: center"
>
<el-button
:disabled="editStatus"
style="margin-top: 10px"
type="primary"
icon="Plus"
@click="addChildren(father)"
>{{ father.addChildrenTxt }}</el-button
>
<el-button
:disabled="editStatus"
style="margin-top: 10px"
type="primary"
icon="Plus"
@click="addChildren(father)"
>添加儿女</el-button
>
</el-col>
</el-row>
</div>
</el-row>
</el-col>
</el-row>
</div>
<el-row>
<el-col>
......@@ -445,9 +415,9 @@
</div>
</template>
<script setup name="fanForm">
import { processUserName } from '@/utils/common'
import useDictStore from '@/store/modules/dict'
import fanFormDomData from '@/formJson/fnaForm'
import { getDicts } from '@/api/system/dict/data'
import { watch, nextTick } from 'vue'
import { addfanForm, getfanFormDetail, editFanForm, getCustomerList } from '@/api/sign/fna'
import { listTenantUser } from '@/api/common'
......@@ -495,6 +465,28 @@ const {
tempFanFormValue,
tempFanFormData
} = toRefs(data)
const changeCheck = (father, child) => {
if (child.key == 'liquidAssetType') {
resetShow('otherLiquidAsset', form.value[father.key][child.key].includes('G'))
}
}
const changeOpenStatus = father => {
const processedData = JSON.parse(JSON.stringify(processedFanFormData.value))
for (const section of processedData) {
if (
father.key == 'familyMembers' &&
section.key == father.key &&
section.moudleType == 'family'
) {
section.isOpen = !father.isOpen
}
if (section.moudleType == 'finance' && father.key !== 'familyMembers') {
section.isOpen = !father.isOpen
}
}
processedFanFormData.value = processedData
console.log('processedFanFormData.value', processedFanFormData.value)
}
const disabledDate = time => {
return time.getTime() > Date.now()
}
......@@ -514,7 +506,16 @@ const searchSelectList = async (query, fieldKey) => {
}
const response = await listTenantUser(params)
searchOptions.value[fieldKey] = response.data.records
if (response.code == 200) {
let result = processUserName(response.data.records)
result = result.map(item => {
return {
value: item.userBizId,
label: item.showName
}
})
searchOptions.value[fieldKey] = result
}
}
// 可以添加其他字段的处理,可以放其他的字段得请求,目前只有accountName,以后有了其他的在填充
else if (fieldKey === 'otherField') {
......@@ -652,10 +653,6 @@ const processFormData = async () => {
}
// 添加表单子级dom
const addChildren = father => {
if (editStatus.value) {
proxy.$modal.confirm(`请先点击编辑再添加儿女`, { showCancel: '0', title: '填写提示' })
return
}
const processedData = JSON.parse(JSON.stringify(processedFanFormData.value))
let obj = {
type: '4',
......@@ -666,10 +663,50 @@ const addChildren = father => {
needProvide: '',
options: noYesList.value
}
let obj2 = {
id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识
span: 24, //栅格布局份数
insurer: '',
insuranceType: '',
sumInsured: '',
policyIssueDate: '',
currency: '',
options: fetchDictData('bx_currency_type')
}
let obj3 = {
id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识
span: 24, //栅格布局份数
address: '',
currency: '',
marketValue: '',
options: fetchDictData('bx_currency_type')
}
let obj4 = {
id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识
span: 24, //栅格布局份数
taxCountry: '',
taxNumber: ''
}
for (const section of processedData) {
if (father.key == 'familyMembers' && section.key == father.key) {
section.data.push(obj)
}
if (father.key == 'existingSecurityOwner' && section.key == father.key) {
section.data.push(obj2)
}
if (father.key == 'existingSecurityInsured' && section.key == father.key) {
section.data.push(obj2)
}
if (father.key == 'investment' && section.key == father.key) {
section.data.push(obj3)
}
if (father.key == 'primaryResidence' && section.key == father.key) {
section.data.push(obj3)
}
if (father.key == 'taxList' && section.key == father.key) {
section.data.push(obj4)
}
}
//更新form表单对应的数据,以便收集填写的值
form.value[father.key].push(obj)
......@@ -677,13 +714,29 @@ const addChildren = father => {
}
const deleteChildren = (father, childIndex) => {
if (editStatus.value) {
proxy.$modal.confirm(`请先点击编辑再删除儿女`, { showCancel: '0', title: '填写提示' })
proxy.$modal.confirm(`请先点击编辑再进行删除操作`, { showCancel: '0', title: '填写提示' })
return
}
const processedData = JSON.parse(JSON.stringify(processedFanFormData.value))
for (const section of processedData) {
if (father.key == 'familyMembers' && section.key == father.key) {
section.data.splice(childIndex, 1)
}
if (father.key == 'taxList' && section.key == father.key) {
section.data.splice(childIndex, 1)
}
if (
(father.key == 'existingSecurityOwner' || father.key == 'existingSecurityInsured') &&
section.key == father.key
) {
section.data.splice(childIndex, 1)
}
if (
(father.key == 'investment' || father.key == 'primaryResidence') &&
section.key == father.key
) {
section.data.splice(childIndex, 1)
}
}
//更新form表单对应的数据,以便收集填写的值
form.value[father.key].splice(childIndex, 1)
......@@ -783,9 +836,9 @@ const setFormValue = (obj, formData) => {
for (const key in newForm) {
//回显的数据有的没填写就会是null,收集表单值得时候和dom对应不上,对于null值得项要根据section得keyType给form正确得数据类型
if (!newForm[key]) {
if (section.keyType == 'Array') {
if (section.keyType == 'Array' && key == section.key) {
newForm[key] = []
} else if (section.keyType == 'Object') {
} else if (section.keyType == 'Object' && key == section.key) {
newForm[key] = {}
}
}
......@@ -823,6 +876,7 @@ const setFormValue = (obj, formData) => {
}
}
}
}
}
}
......@@ -871,8 +925,12 @@ const setFormValue = (obj, formData) => {
for (const section of processedData) {
for (const key1 in obj) {
if (section.data) {
//key1 !== 'familyMembers' &&
if (key1 !== 'familyMembers' && key1 == section.key && section.keyType == 'Array') {
if (
obj[key1] &&
key1 !== 'familyMembers' &&
key1 == section.key &&
section.keyType == 'Array'
) {
section.data = obj[key1].map(item => {
for (const key2 in item) {
if (key2 == 'currency') {
......@@ -885,7 +943,12 @@ const setFormValue = (obj, formData) => {
...item
}
})
} else if (key1 == 'familyMembers' && key1 == section.key && section.keyType == 'Array') {
} else if (
key1 == 'familyMembers' &&
key1 == section.key &&
section.keyType == 'Array' &&
obj[key1]
) {
section.data = form.value[key1].map(item => {
for (const key2 in item) {
if (key2 == 'needProvide') {
......@@ -897,6 +960,18 @@ const setFormValue = (obj, formData) => {
}
})
}
// 流动资产包含其他的时候,显示其他说明
if (section.key == 'liquidAssets') {
for (const field of section.data) {
if (
field.key == 'otherLiquidAsset' &&
obj[section.key]['liquidAssetType'] &&
obj[section.key]['liquidAssetType'].includes('G')
) {
field.show = true
}
}
}
}
}
}
......@@ -933,11 +1008,11 @@ const isObject = value => {
// 表单提交
const submitForm = saveType => {
console.log('dom', processedFanFormData.value)
console.log('表单值', form.value)
// 深拷贝原始数据
let result = JSON.parse(JSON.stringify(form.value))
let resDom = JSON.parse(JSON.stringify(processedFanFormData.value))
console.log('result', result)
// return
proxy.$refs['fanFormRef'].validate((valid, fields) => {
......@@ -954,6 +1029,13 @@ const submitForm = saveType => {
if (isObject(result[key])) {
for (const key2 in result[key]) {
if (isArray(result[key][key2])) {
if (
key == 'liquidAssets' &&
key2 == 'liquidAssetType' &&
!result[key][key2].includes('G')
) {
result[key]['otherLiquidAsset'] = ''
}
result[key][key2] = result[key][key2].join(',')
}
}
......@@ -1076,19 +1158,30 @@ watch(
justify-content: space-between;
margin-bottom: 10px;
}
.fatherLable {
font-size: 18px;
border-left: 4px solid #165dff;
padding-left: 5px;
margin-bottom: 5px;
display: flex;
align-items: center;
.openCon {
margin-left: 10px;
cursor: pointer;
}
}
.subTitle {
font-size: 15px;
/* padding-left: 8px; */
margin-bottom: 10px;
}
.deleteIcon {
color: red;
font-size: 18px;
padding-top: 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; */
......@@ -1114,11 +1207,6 @@ watch(
color: #a8abb2;
}
}
.deleteIcon {
color: red;
font-size: 18px;
padding-top: 10px;
}
}
.tabButton {
box-shadow: 0 -1px 14px #00000014;
......@@ -1181,7 +1269,7 @@ watch(
margin-right: 10px;
}
@media only screen and (min-width: 768px) {
/* @media only screen and (min-width: 768px) {
.formInput {
margin-top: 30px !important;
}
......@@ -1191,5 +1279,5 @@ watch(
.formInput {
margin-top: 30px !important;
}
}
} */
</style>
......@@ -129,7 +129,7 @@
</div>
</template>
<script setup name="FnaEdit">
import { onUnmounted } from 'vue'
import { processUserName } from '@/utils/common'
import AppointmentEdit from '@/views/sign/appointment/appointmentEdit'
import useUserStore from '@/store/modules/user'
import useDictStore from '@/store/modules/dict'
......@@ -209,7 +209,14 @@ const getDictsData = async () => {
}
const response1 = await listTenantUser(params1)
if (response1.code == 200) {
dictStore.setTenantUserList(response1.data.records)
let result = processUserName(response1.data.records)
result = result.map(item => {
return {
value: item.userBizId,
label: item.showName
}
})
dictStore.setTenantUserList(result)
}
const params2 = {
loginTenantBizId: userStore.projectInfo.tenantBizId,
......
......@@ -124,6 +124,7 @@
:customerInfo="customerInfo"
:idsObj="idsObj"
:apiInsurantInfoDto="appointmentSummeryInfo.apiInsurantInfoDto"
:currentPolicyholderInfo="currentPolicyholderInfo"
:appointmentStatus="appointmentSummeryInfo.status"
@handleSuccessEdit="getAppointmentInfo(idsObj.appointmentBizId)"
ref="insuredInfoRef"
......@@ -171,6 +172,7 @@
ref="questionnairesInfoRef"
:pageSource="pageSource"
:showSubmitBtn="showSubmitBtn"
:foldInsurantInfo="foldInsurantInfo"
/>
</div>
<div v-if="tab.name === 'fna'">
......@@ -244,6 +246,13 @@
:policyNo="policyNo"
/>
</div>
<div v-if="tab.name === 'expectedFortune'">
<expectedFortuneInfo
:activeName="activeName"
:policyBizId="route.query.policyBizId"
:policyNo="policyNo"
/>
</div>
</div>
</el-tab-pane>
</el-tabs>
......@@ -298,6 +307,7 @@ import PolicyBrokerInfo from '@/views/sign/underwritingMain/components/brokerInf
import PolicyMailing from '@/views/sign/underwritingMain/components/policyMailing.vue' //新单跟进里的保单附件
import VerifyPolicyInfo from '@/views/sign/underwritingMain/components/verifyPolicyInfo.vue' //新单跟进里的保单附件
import ExpectedCommission from '@/views/sign/underwritingMain/components/expectedCommission.vue' //新单跟进里的保单附件
import expectedFortuneInfo from '@/views/sign/underwritingMain/components/expectedFortuneInfo.vue' //新单跟进里得预计发佣
import useUserStore from '@/store/modules/user'
import useDictStore from '@/store/modules/dict'
import { getCustomerDetail } from '@/api/sign/fna'
......@@ -346,6 +356,7 @@ const customerInfo = ref({})
const idsObj = ref({}) //各个模块的bizId
const appointmentSummeryInfo = ref({}) //预约详情总信息
const currentFile = ref(null)
const foldInsurantInfo = ref(false) //健康信息中得受保人信息是否隐藏
const processInfo = ref({
fnaNo: '暂无',
status: '未完成',
......@@ -355,7 +366,7 @@ const processInfo = ref({
const execlDialog = ref(false)
const isEmbed = ref(false) //是否作为组件插入
const policyNo = ref('') //新单跟进保单号
const currentPolicyholderInfo = ref({}) //存储下投保人信息,受保人模块要用到
const tabsList = ref([
{
label: '预约信息',
......@@ -569,6 +580,9 @@ function getCustomerInfo(customerBizId) {
getCustomerDetail(customerBizId).then(res => {
if (res.code == 200) {
customerInfo.value = res.data
if (customerInfo.value.smoke) {
customerInfo.value.smoke = Number(customerInfo.value.smoke)
}
}
})
}
......@@ -649,6 +663,54 @@ const getDictsData = async () => {
}
// Tab切换前的验证
const beforeTabLeave = (activeTabName, oldTabName) => {
// 受保人如果选择了本人,使用投保人得信息填充
// oldTabName == 'policyholder' &&
if (activeTabName == 'insurantInfo') {
currentPolicyholderInfo.value = policyHolderInfoRef.value[0].providePolicyholderInfoData()
} else if (
oldTabName !== 'policyholder' &&
activeTabName == 'insurantInfo' &&
showSubmitBtn.value &&
Object.keys(currentPolicyholderInfo.value).length == 0
) {
currentPolicyholderInfo.value = appointmentSummeryInfo.value.apiPolicyholderInfoDto
}
console.log('预约切换tab', currentPolicyholderInfo.value)
// 健康信息模块,如果投保人选择了本人以及受保人选择了本人,健康信息展示投保人/受保人
let policyHolderResult = policyHolderInfoRef.value[0].handleFormValues()
let insuredResult = insuredInfoRef.value[0].handleFormValues()
console.log('policyHolderResult', policyHolderResult)
console.log('insuredResult', insuredResult)
foldInsurantInfo.value = false
if (activeTabName == 'questionnaires') {
// 投保人和受保人都点击过可以拿到最新填写得表单值
if (
policyHolderResult.customerType &&
policyHolderResult.customerType == 'INDIVIDUAL' &&
insuredResult.policyholderRel &&
insuredResult.policyholderRel == 'MYSELF'
) {
foldInsurantInfo.value = true
} else if (
!policyHolderResult.customerType &&
!insuredResult.policyholderRel &&
showSubmitBtn.value
) {
// 如果投保人和受保人都没有点击过,则使用预约单里得信息
let policyHolderInfo = appointmentSummeryInfo.value.apiPolicyholderInfoDto
let insuredInfo = appointmentSummeryInfo.value.apiInsurantInfoDto
if (
policyHolderInfo.customerType &&
policyHolderInfo.customerType == 'INDIVIDUAL' &&
insuredInfo.policyholderRel &&
insuredInfo.policyholderRel == 'MYSELF'
) {
foldInsurantInfo.value = true
}
}
}
return true
}
......@@ -672,6 +734,7 @@ const handleSubmit = type => {
if (appointmentInfoRef.value) {
submitAppointmentObj.value.apiAppointmentInfoDto =
appointmentInfoRef.value[0].handleFormValues()
if (!submitAppointmentObj.value.apiAppointmentInfoDto) return
}
if (productPlanRef.value) {
submitAppointmentObj.value.apiProductPlanInfoDto = productPlanRef.value[0].handleSubmitForm()
......@@ -1027,6 +1090,12 @@ if (route.query.source == 'policyList') {
key: 'expectedCommission'
},
{
label: '预计发佣',
name: 'expectedFortune',
id: 1,
key: 'expectedFortune'
},
{
label: '保单信息',
name: 'policyInfo',
id: 2,
......
......@@ -321,22 +321,22 @@ const disabledDate = (time, child) => {
// 默认禁用今天及今天之前
return inputDate.isBefore(today, 'day') || inputDate.isSame(today, 'day')
break
case 'arrivalTime':
// 如果允许选择今天,只禁用今天之前的日期
return inputDate.isBefore(today, 'day')
break
case 'departureTime':
// 获取开始日期(需要从表单数据中获取)
const startTime1 = form.value.arrivalTime
if (startTime1) {
const arrivalDate = dayjs(startTime1).startOf('day')
// 只禁用到达日期之前的日期,允许选择同一天
return inputDate.isBefore(arrivalDate, 'day')
} else {
// 如果没有选择到达时间,禁用今天之前的日期
return inputDate.isBefore(today, 'day')
}
break
// case 'arrivalTime':
// // 如果允许选择今天,只禁用今天之前的日期
// return inputDate.isBefore(today, 'day')
// break
// case 'departureTime':
// // 获取开始日期(需要从表单数据中获取)
// const startTime1 = form.value.arrivalTime
// if (startTime1) {
// const arrivalDate = dayjs(startTime1).startOf('day')
// // 只禁用到达日期之前的日期,允许选择同一天
// return inputDate.isBefore(arrivalDate, 'day')
// } else {
// // 如果没有选择到达时间,禁用今天之前的日期
// return inputDate.isBefore(today, 'day')
// }
// break
case 'confirmAppointmentTime':
return inputDate.isBefore(today, 'day')
break
......@@ -392,57 +392,74 @@ const handleDateChange = child => {
if (child.key == 'openAccountStartTime' && form.value['openAccountStartTime']) {
resetShow({ type: 'child', key: 'openAccountEndTime', status: false, flag: 'disabled' })
disabledDate(form.value['openAccountStartTime'], { key: 'openAccountEndTime' })
return
}
if (child.key == 'arrivalTime' && form.value['arrivalTime']) {
resetShow({ type: 'child', key: 'departureTime', status: false, flag: 'disabled' })
disabledDate(form.value['arrivalTime'], { key: 'departureTime' })
// resetShow({ type: 'child', key: 'departureTime', status: false, flag: 'disabled' })
// disabledDate(form.value['arrivalTime'], { key: 'departureTime' })
// 离港时间在到港时间之前
if (
child.key == 'arrivalTime' &&
form.value['departureTime'] &&
!dayjs(form.value['arrivalTime']).isBefore(dayjs(form.value['departureTime']))
) {
proxy.$message.error('到港时间应在离港时间之前!!')
}
if (child.key === 'confirmAppointmentTime' && form.value[child.key]) {
if (form.value['arrivalTime']) {
const appointmentTimestamp = dayjs(form.value['confirmAppointmentTime']).valueOf()
const arrivalTimestamp = dayjs(form.value['arrivalTime']).valueOf()
if (appointmentTimestamp < arrivalTimestamp) {
proxy.$modal.msgError('预约时间早于到港时间,请重新选择预约时间')
form.value['confirmAppointmentTime'] = ''
return
} else if (appointmentTimestamp > arrivalTimestamp) {
} else {
proxy.$modal.msgError('预约时间应晚于到港时间,请重新选择预约时间')
form.value['confirmAppointmentTime'] = ''
return
}
}
resetShow({ type: 'child', key: 'newPolicyButton', status: true, flag: 'show' })
} else if (child.key === 'confirmAppointmentTime' && !form.value[child.key]) {
if (
child.key == 'departureTime' &&
form.value['arrivalTime'] &&
dayjs(form.value['departureTime']).isBefore(dayjs(form.value['arrivalTime']))
) {
proxy.$message.error('离港时间应在到港时间之后!!')
}
if (child.key === 'confirmAppointmentTime' && !form.value[child.key]) {
resetShow({ type: 'child', key: 'newPolicyButton', status: false, flag: 'show' })
} else if (child.key === 'arrivalTime') {
if (form.value['confirmAppointmentTime']) {
const appointmentTimestamp = dayjs(form.value['confirmAppointmentTime']).valueOf()
const arrivalTimestamp = dayjs(form.value['arrivalTime']).valueOf()
if (appointmentTimestamp < arrivalTimestamp) {
proxy.$modal.msgError('预约时间早于到港时间,请重新选择到港时间')
form.value['arrivalTime'] = ''
form.value['departureTime'] = ''
resetShow({ type: 'child', key: 'departureTime', status: true, flag: 'disabled' })
} else if (appointmentTimestamp > arrivalTimestamp) {
console.log('预约时间晚于到港时间')
} else {
proxy.$modal.msgError('到港时间应早于预约时间,请重新选择到港时间')
form.value['arrivalTime'] = ''
form.value['departureTime'] = ''
resetShow({ type: 'child', key: 'departureTime', status: true, flag: 'disabled' })
}
}
} else if (child.key === 'confirmAppointmentTime') {
if (form.value['arrivalTime']) {
const appointmentTimestamp = dayjs(form.value['confirmAppointmentTime']).valueOf()
const arrivalTimestamp = dayjs(form.value['arrivalTime']).valueOf()
console.log('appointmentTimestamp', appointmentTimestamp)
console.log('arrivalTimestamp', arrivalTimestamp)
}
} else if (child.key === 'confirmAppointmentTime' && form.value[child.key]) {
resetShow({ type: 'child', key: 'newPolicyButton', status: true, flag: 'show' })
}
// if (child.key === 'confirmAppointmentTime' && form.value[child.key]) {
// if (form.value['arrivalTime']) {
// const appointmentTimestamp = dayjs(form.value['confirmAppointmentTime']).valueOf()
// const arrivalTimestamp = dayjs(form.value['arrivalTime']).valueOf()
// if (appointmentTimestamp < arrivalTimestamp) {
// proxy.$modal.msgError('预约时间早于到港时间,请重新选择预约时间')
// form.value['confirmAppointmentTime'] = ''
// return
// } else if (appointmentTimestamp > arrivalTimestamp) {
// } else {
// proxy.$modal.msgError('预约时间应晚于到港时间,请重新选择预约时间')
// form.value['confirmAppointmentTime'] = ''
// return
// }
// }
// resetShow({ type: 'child', key: 'newPolicyButton', status: true, flag: 'show' })
// } else if (child.key === 'confirmAppointmentTime' && !form.value[child.key]) {
// resetShow({ type: 'child', key: 'newPolicyButton', status: false, flag: 'show' })
// } else if (child.key === 'arrivalTime') {
// if (form.value['confirmAppointmentTime']) {
// const appointmentTimestamp = dayjs(form.value['confirmAppointmentTime']).valueOf()
// const arrivalTimestamp = dayjs(form.value['arrivalTime']).valueOf()
// if (appointmentTimestamp < arrivalTimestamp) {
// proxy.$modal.msgError('预约时间早于到港时间,请重新选择到港时间')
// form.value['arrivalTime'] = ''
// form.value['departureTime'] = ''
// resetShow({ type: 'child', key: 'departureTime', status: true, flag: 'disabled' })
// } else if (appointmentTimestamp > arrivalTimestamp) {
// console.log('预约时间晚于到港时间')
// } else {
// proxy.$modal.msgError('到港时间应早于预约时间,请重新选择到港时间')
// form.value['arrivalTime'] = ''
// form.value['departureTime'] = ''
// resetShow({ type: 'child', key: 'departureTime', status: true, flag: 'disabled' })
// }
// }
// } else if (child.key === 'confirmAppointmentTime') {
// if (form.value['arrivalTime']) {
// const appointmentTimestamp = dayjs(form.value['confirmAppointmentTime']).valueOf()
// const arrivalTimestamp = dayjs(form.value['arrivalTime']).valueOf()
// console.log('appointmentTimestamp', appointmentTimestamp)
// console.log('arrivalTimestamp', arrivalTimestamp)
// }
// }
}
// 获取字典数据
const fetchDictData = dictType => {
......@@ -693,9 +710,11 @@ const handleEditStatus = status => {
} else {
if (!form.value['openAccountStartTime'] && field.key == 'openAccountEndTime') {
field.disabled = true
} else if (!form.value['arrivalTime'] && field.key == 'departureTime') {
field.disabled = true
} else {
}
// else if (!form.value['arrivalTime'] && field.key == 'departureTime') {
// field.disabled = true
// }
else {
field.disabled = false
}
}
......@@ -753,7 +772,7 @@ const setFormValue = (obj, formData) => {
// 开始时间是否在结束时间之前
if (obj['arrivalTime'] && !dayjs(obj['arrivalTime']).isBefore(dayjs(obj[field.key]))) {
form.value[field.key] = ''
field.disabled = true
// field.disabled = true
}
}
//要判断drawerType,因为抽屉要回显数据
......@@ -928,6 +947,16 @@ const handleFormValues = () => {
}
}
}
if (submitObj['departureTime']) {
// 开始时间是否在结束时间之前
if (
submitObj['arrivalTime'] &&
!dayjs(submitObj['arrivalTime']).isBefore(dayjs(submitObj['departureTime']))
) {
proxy.$message.error('预约信息模块--离港时间必须晚于到港时间!!')
return undefined
}
}
return submitObj
}
......@@ -941,7 +970,7 @@ const submitForm = () => {
console.log('submitObj', submitObj)
console.log('====================================')
// return
if (!submitObj) return
if (props.idsObj.appointmentBizId) {
editAppointmentInfo(submitObj).then(res => {
if (res.code == 200) {
......@@ -973,15 +1002,6 @@ const resetForm = () => {
.catch(() => {})
}
// 获取流程详情
function getCustomerInfo(customerBizId, formData) {
getCustomerDetail(customerBizId).then(async res => {
if (res.code == 200) {
// 回显值
setFormValue(res.data, formData)
}
})
}
watch(
() => props.activeName,
......
......@@ -368,7 +368,7 @@ const addBeneficiary = () => {
// 删除受益人
const deleteBeneficiary = (l1, level1) => {
console.log('====================================')
console.log('l1', form.value.apiBeneficiaryInfoDtoList[l1])
console.log('l1', form.value.apiBeneficiaryInfoDtoList[l1])
console.log('====================================')
if (editStatus.value) {
proxy.$modal.confirm(`编辑状态下才能删除`, { showCancel: '0', title: '填写提示' })
......@@ -390,15 +390,20 @@ const deleteBeneficiary = (l1, level1) => {
emit('handleSuccessEdit')
}
})
} else if (form.value.apiBeneficiaryInfoDtoList[l1].policyBeneficiaryBizId && props.pageSource == 'policyList') {
delPolicyBeneficiary(form.value.apiBeneficiaryInfoDtoList[l1].policyBeneficiaryBizId).then(res => {
if (res.code == 200) {
proxy.$message.success('新单跟进-受益人删除成功')
processedBeneficiaryData.value.splice(l1, 1)
form.value.apiBeneficiaryInfoDtoList.splice(l1, 1)
emit('policyEditSuccess')
} else if (
form.value.apiBeneficiaryInfoDtoList[l1].policyBeneficiaryBizId &&
props.pageSource == 'policyList'
) {
delPolicyBeneficiary(form.value.apiBeneficiaryInfoDtoList[l1].policyBeneficiaryBizId).then(
res => {
if (res.code == 200) {
proxy.$message.success('新单跟进-受益人删除成功')
processedBeneficiaryData.value.splice(l1, 1)
form.value.apiBeneficiaryInfoDtoList.splice(l1, 1)
emit('policyEditSuccess')
}
}
})
)
} else {
proxy.$message.success('受益人删除成功')
processedBeneficiaryData.value.splice(l1, 1)
......@@ -610,6 +615,8 @@ const confirmDrawer = info => {
form.value.apiBeneficiaryInfoDtoList[drawerInfo.value.l1][
drawerInfo.value.key
] = `${newObj.region} ${newObj.city} ${newObj.street} ${newObj.location}`
newObj.addressString = `${newObj.region} ${newObj.city} ${newObj.street} ${newObj.location}`
// 检查数组中是否已存在相同ID的地址
const existingIndex = phoneOraddressKey.value.findIndex(
item => item.id === newObj.id && item.type === newObj.type
......@@ -622,6 +629,24 @@ const confirmDrawer = info => {
// 添加新地址
phoneOraddressKey.value.push({ ...newObj })
}
newObj.addressString = `${newObj.region} ${newObj.city} ${newObj.street} ${newObj.location}`
// 检查数组中是否已存在key的地址
// debugger
const existinAddressIndex = addressQuickList.value.findIndex(
item => item.type === newObj.type
)
if (existinAddressIndex !== -1) {
// 更新已存在的电话
addressQuickList.value[existinAddressIndex] = {
...newObj
}
} else {
// 添加新的快捷电话
addressQuickList.value.push(newObj)
}
addressQuickList.value = removeDuplicates(addressQuickList.value, 'addressString')
break
case 'country':
......
......@@ -21,9 +21,15 @@
<div v-for="(level1, l1) in questionnairesDom" :key="level1.firstCategory">
<el-row style="margin-bottom: 10px">
<div class="formBox">
<div class="fatherLable">{{ level1.firstCategoryName }}</div>
<div class="fatherLable">
<span>{{ level1.firstCategoryName }}</span>
<div class="openCon" v-if="level1.showIcon" @click="changeOpenStatus(level1)">
<el-icon v-if="!level1.showMoudle"><Hide /></el-icon>
<el-icon v-else><View /></el-icon>
</div>
</div>
<el-row :gutter="20">
<el-row :gutter="20" v-if="level1.showMoudle">
<template
v-for="(level2, l2) in level1.secondCategoryDtoList"
:key="level2.secondCategory"
......@@ -218,6 +224,7 @@ const props = defineProps({
customerInfo: { type: Object, default: () => ({}) },
//客户详情回显表单用
showSubmitBtn: { type: Boolean, default: false }, //父组件状态,新增、修改
foldInsurantInfo: { type: Boolean, default: false }, //是否隐藏受保人信息
pageSource: { type: String, default: '' } //页面来源
})
const emit = defineEmits(['handleSuccessEdit'])
......@@ -226,7 +233,7 @@ const loading = ref(false)
const errorFields = ref([]) // 存储校验失败的字段信息
const editStatus = ref(true) // 表单是否可编辑,若是修改初始不可编辑
const oldObjInfo = ref({}) // 修改时存储原始数据,便于撤销操作
const showInsurant = ref(false) //是否显示受保人信息
const data = reactive({
form: [],
tempSecondHolderForm: [], //由于切换tab的时候,表单数据会重置,所以需要
......@@ -241,6 +248,16 @@ const data = reactive({
})
const { form, rules, questionnairesDom, queryParams, oldAppointmentData, tempSecondHolderForm } =
toRefs(data)
const changeOpenStatus = level1 => {
console.log('level1', level1)
let newDom = JSON.parse(JSON.stringify(questionnairesDom.value))
newDom.forEach((item, index) => {
if (item.firstCategory == level1.firstCategory) {
item.showMoudle = !item.showMoudle
}
})
questionnairesDom.value = newDom
}
const addMedical = (l1, l2, l3) => {
form.value[l1]['secondCategoryDtoList'][l2]['questionsDtoList'][l3]['answerSessionsDto'][
'questionTextJsonDtoList'
......@@ -453,22 +470,7 @@ const submitForm = () => {
}
})
}
const resetForm = () => {
proxy.$modal
.confirm('是否确认撤销所作操作?')
.then(function () {
if (props.customerBizId) {
form.value = { ...oldObjInfo.value }
editStatus.value = true
} else {
// resetShow('smokeQuantity', false)
proxy.$refs['heathFormRef'].resetFields()
}
questionnairesDom.value = JSON.parse(JSON.stringify(oldAppointmentData.value))
})
.catch(() => {})
}
const getQuestionnairesInfo = () => {
loading.value = true
let id = ''
......@@ -482,17 +484,30 @@ const getQuestionnairesInfo = () => {
}
getQuestionnaires(id).then(res => {
if (res.code == 200) {
let result = res.data.firstAndSecondCategoryDtoList
let result = []
if (props.foldInsurantInfo) {
result = [res.data.firstAndSecondCategoryDtoList[0]]
} else {
result = res.data.firstAndSecondCategoryDtoList
}
let first_category = fetchDictData('wj_question_first_category')
let second_category = fetchDictData('wj_question_second_category')
form.value = {}
result.forEach((level1, l1) => {
// form.value[level1.firstCategory] = {}
first_category.forEach((first, i) => {
if (level1.firstCategory == first.value) {
if (level1.firstCategory == first.value && !props.foldInsurantInfo) {
level1.firstCategoryName = first.label
} else if (props.foldInsurantInfo && level1.firstCategory == 'POLICYHOLDER') {
level1.firstCategoryName = '投保人 / 受保人'
}
})
if (level1.firstCategory == 'POLICYHOLDER') {
// level1.showIcon = true
level1.showMoudle = true
} else if (level1.firstCategory == 'INSURED_PERSON') {
level1.showIcon = true
level1.showMoudle = false
}
level1.secondCategoryDtoList.forEach((level2, l2) => {
level2.sm = 24
level2.lg = 24
......@@ -586,6 +601,7 @@ watch(
editStatus.value = true
}
getQuestionnairesInfo()
console.log('foldInsurantInfo', props.foldInsurantInfo)
}
}
)
......@@ -620,6 +636,13 @@ defineExpose({
font-size: 18px;
border-left: 4px solid #165dff;
padding-left: 5px;
margin-bottom: 5px;
display: flex;
align-items: center;
.openCon {
margin-left: 10px;
cursor: pointer;
}
}
.fatherDes {
font-size: 14px;
......@@ -705,7 +728,7 @@ defineExpose({
}
}
.tabButton {
box-shadow: 0 -1px 14px #00000014;
/* box-shadow: 0 -1px 14px #00000014; */
width: 100%;
display: flex;
align-items: center;
......
......@@ -55,7 +55,6 @@
:label-position="child.labelPosition"
:rules="getRules(child)"
>
<!-- @input="handleInputChange(father, child)" -->
<el-input
v-if="child.domType === 'Input'"
:type="child.inputType"
......@@ -223,6 +222,7 @@ const props = defineProps({
apiInsurantInfoDto: { type: Object, default: () => ({}) }, //父组件传递过来的预约信息的详情
appointmentStatus: { type: Number }, //父组件传递过来的预约的状态
customerInfo: { type: Object, default: () => ({}) }, //客户详情回显表单用
currentPolicyholderInfo: { type: Object, default: () => ({}) }, //当前保单的投保人信息
showSubmitBtn: { type: Boolean, default: false }, //父组件状态,新增、修改
pageSource: { type: String, default: '' } //页面来源
})
......@@ -349,16 +349,7 @@ const getRules = child => {
return rules
}
const handleInputChange = (father, child) => {
switch (child.key) {
case 'nameEn':
validateEnglish(form.value[child.key], child.key)
break
default:
break
}
}
const handleDateChange = child => {
let age = null
if (child.key == 'birthday') {
......@@ -433,16 +424,6 @@ const fetchDictData = dictType => {
return []
}
}
// // 添加英文校验函数
// const validateEnglish = (rule, value, callback) => {
// if (value && !/^[A-Za-z]*$/.test(value)) {
// // 清空非英文字符
// form.value.firstNamePinyin = ''
// callback(new Error('只能输入英文字母'))
// } else {
// callback()
// }
// }
const mergeObjects = (obj1, obj2) => {
const result = Object.assign({}, obj1)
......@@ -461,14 +442,20 @@ const mergeObjects = (obj1, obj2) => {
* exportValue:是否从导入联系人列表中导入客户信息到当前表单
*/
const processFormData = async obj => {
form.value = {}
saveKey.value = {}
let tempPhoneList = []
let tempAddressList = []
form.value = {}
saveKey.value = {}
addressQuickList.value = []
phoneQuickList.value = []
// if (!obj.exportValue) {
// form.value = {}
// saveKey.value = {}
// addressQuickList.value = []
// phoneQuickList.value = []
// }
// 深拷贝原始数据
// const processedData = JSON.parse(JSON.stringify(policyDomData))
const processedData = JSON.parse(JSON.stringify(obj.domdata))
for (const section of processedData) {
......@@ -576,7 +563,7 @@ const processFormData = async obj => {
for (const key1 in field) {
if (obj.customerInfo.addressList && obj.customerInfo.addressList.length > 0) {
obj.customerInfo.addressList.forEach(item => {
if (key1 == item.type) {
if (field.customerKey == item.type) {
addressObj = item
}
})
......@@ -619,6 +606,7 @@ const processFormData = async obj => {
}
}
}
//当tab切换走,在切换回来的时候,需要把之前保存的值赋值回来
if (
JSON.stringify(tempPolicyForm.value) !== '{}' &&
......@@ -649,7 +637,11 @@ const processFormData = async obj => {
}
}
if (props.showSubmitBtn) {
field.disabled = true
if (obj.source && obj.source == 'policyholderRel' && field.key !== 'age') {
field.disabled = false
} else {
field.disabled = true
}
} else {
if (field.key == 'age') {
field.disabled = true
......@@ -660,7 +652,6 @@ const processFormData = async obj => {
}
}
}
addressQuickList.value = tempAddressList
tempPhoneList.forEach(item => {
for (const key in saveKey.value) {
......@@ -696,11 +687,20 @@ const processFormData = async obj => {
if (form.value.smokingAllowed) {
form.value.smokingAllowed = Number(form.value.smokingAllowed)
}
editStatus.value = true
} else {
editStatus.value = false
}
// // 投保人为本人时,信息从投保人带入
// if (obj.source && obj.source == 'policyholderRel') {
// form.value = {
// ...obj.customerInfo,
// policyholderRel: form.value.policyholderRel
// }
// if (form.value.smokingAllowed) {
// form.value.smokingAllowed = Number(form.value.smokingAllowed)
// }
// }
if (form.value['birthday']) {
let age = calculateExactAge(proxy.formatToDate(form.value.birthday))
if (age >= 0) {
......@@ -715,8 +715,6 @@ const processFormData = async obj => {
//弹出右侧抽屉
const handleFoucs = child => {
if (child.disabled) return
console.log('saveKey.value', saveKey.value)
console.log('child', child)
drawerInfo.value = JSON.parse(JSON.stringify(child))
switch (child.drawerType) {
......@@ -810,7 +808,25 @@ const confirmDrawer = info => {
form.value[info.key] = `${newObj.region} ${newObj.city} ${newObj.street} ${newObj.location}`
saveKey.value[info.key] = newObj
newObj.addressString = `${newObj.region} ${newObj.city} ${newObj.street} ${newObj.location}`
// 检查数组中是否已存在key的地址
// debugger
const existinAddressIndex = addressQuickList.value.findIndex(
item => item.type === newObj.type
)
if (existinAddressIndex !== -1) {
// 更新已存在的电话
addressQuickList.value[existinAddressIndex] = {
...newObj
}
} else {
// 添加新的快捷电话
addressQuickList.value.push(newObj)
}
addressQuickList.value = removeDuplicates(addressQuickList.value, 'addressString')
console.log('填写地址', addressQuickList.value)
break
case 'country':
info.objType = drawerInfo.value.drawerType
......@@ -861,13 +877,10 @@ const handleSelectChange = (father, child) => {
case 'customerType':
if (form.value[child.key] == 'COMPANY') {
showContacts.value = false
console.log(' commonObj.value', commonObj.value)
for (const section of processedinsuredData.value) {
if (section.key == 'company') {
console.log(11111)
for (const key1 in saveKey.value) {
for (const key2 in commonObj.value) {
console.log(key1, key2)
if (key1 == key2) {
saveKey.value[key1]['fatherKey'] = section.key
}
......@@ -908,6 +921,32 @@ const handleSelectChange = (father, child) => {
}
break
case 'policyholderRel':
//选择投保人为本人得时候,带入投保人得信息
if (form.value['policyholderRel'] == 'MYSELF') {
form.value = JSON.parse(JSON.stringify(props.currentPolicyholderInfo.form))
saveKey.value = JSON.parse(JSON.stringify(props.currentPolicyholderInfo.saveKey))
form.value['policyholderRel'] = 'MYSELF'
if (form.value['customerType'] == 'COMPANY') {
resetShow({ type: 'father', key: 'person', status: false })
resetShow({ type: 'father', key: 'company', status: true })
} else if (form.value['customerType'] == 'INDIVIDUAL') {
resetShow({ type: 'father', key: 'person', status: true })
resetShow({ type: 'father', key: 'company', status: false })
}
// 选择吸烟,展示吸烟数量
if (form.value['smokingAllowed'] == '1') {
resetShow({ type: 'child', key: 'smokingVolume', status: true })
} else {
resetShow({ type: 'child', key: 'smokingVolume', status: false })
}
if (form.value['isVip'] == '1') {
resetShow({ type: 'child', key: 'vipRemark', status: true })
} else {
resetShow({ type: 'child', key: 'vipRemark', status: false })
}
}
break
default:
break
......@@ -1077,8 +1116,10 @@ const submitForm = () => {
proxy.$refs['insuredInfoFormRef'].validate((valid, fields) => {
if (valid) {
let submitObj = handleFormValues()
if (props.idsObj.appointmentBizId&&
(props.pageSource == 'fnaList' || props.pageSource == 'appointmentList')) {
if (
props.idsObj.appointmentBizId &&
(props.pageSource == 'fnaList' || props.pageSource == 'appointmentList')
) {
submitObj['appointmentBizId'] = props.apiInsurantInfoDto.appointmentBizId
submitObj['id'] = props.apiInsurantInfoDto.id
submitObj['insurantBizId'] = props.apiInsurantInfoDto.insurantBizId
......@@ -1112,22 +1153,6 @@ const submitForm = () => {
}
})
}
const resetForm = () => {
proxy.$modal
.confirm('是否确认撤销所作操作?')
.then(function () {
if (props.customerBizId) {
form.value = { ...oldObjInfo.value }
editStatus.value = true
} else {
// resetShow('smokeQuantity', false)
proxy.$refs['insuredInfoFormRef'].resetFields()
}
processedinsuredData.value = JSON.parse(JSON.stringify(oldAppointmentData.value))
})
.catch(() => {})
}
watch(
() => props.activeName,
......@@ -1153,6 +1178,9 @@ watch(
})
}
}, 500)
console.log('====================================')
console.log('受保人拿到投保人信息', props.currentPolicyholderInfo)
console.log('====================================')
}
}
)
......
......@@ -211,7 +211,7 @@ const props = defineProps({
idsObj: { type: Object, default: () => ({}) }, //父组件传递过来的id对象
apiPolicyholderInfoDto: { type: Object, default: () => ({}) }, //父组件传递过来的预约信息的详情
appointmentStatus: { type: Number }, //父组件传递过来的预约的状态
customerInfo: { type: Object, default: () => ({}) }, //客户详情回显表单用
customerInfo: { type: Object, default: () => ({}) }, //客户详情新增时带入表单
showSubmitBtn: { type: Boolean, default: false }, //父组件状态,新增、修改
pageSource: { type: String, default: '' } //页面来源
})
......@@ -343,16 +343,7 @@ const getRules = child => {
return rules
}
const handleInputChange = (father, child) => {
switch (child.key) {
case 'nameEn':
validateEnglish(form.value[child.key], child.key)
break
default:
break
}
}
const handleDateChange = child => {
let age = null
if (child.key == 'birthday') {
......@@ -409,7 +400,6 @@ const handleExport = row => {
customerInfo: row,
exportValue: true
})
// setFormValue(row, processedPolicyData.value, true)
openList.value = false
}
......@@ -569,7 +559,11 @@ const processFormData = async obj => {
for (const key1 in field) {
if (obj.customerInfo.addressList && obj.customerInfo.addressList.length > 0) {
obj.customerInfo.addressList.forEach(item => {
if (key1 == item.type) {
// 之前得写法
// if (key1 == item.type) {
// addressObj = item
// }
if (field.customerKey == item.type) {
addressObj = item
}
})
......@@ -641,7 +635,7 @@ const processFormData = async obj => {
}
}
}
// props.idsObj.appointmentBizId
if (props.showSubmitBtn) {
field.disabled = true
} else {
......@@ -801,6 +795,25 @@ const confirmDrawer = info => {
newObj.type = drawerInfo.value.key
form.value[info.key] = `${newObj.region} ${newObj.city} ${newObj.street} ${newObj.location}`
saveKey.value[info.key] = newObj
newObj.addressString = `${newObj.region} ${newObj.city} ${newObj.street} ${newObj.location}`
// 检查数组中是否已存在key的地址
// debugger
const existinAddressIndex = addressQuickList.value.findIndex(
item => item.type === newObj.type
)
if (existinAddressIndex !== -1) {
// 更新已存在的电话
addressQuickList.value[existinAddressIndex] = {
...newObj
}
} else {
// 添加新的快捷电话
addressQuickList.value.push(newObj)
}
addressQuickList.value = removeDuplicates(addressQuickList.value, 'addressString')
console.log('填写地址', addressQuickList.value)
break
case 'country':
info.objType = drawerInfo.value.drawerType
......@@ -1056,6 +1069,12 @@ const handleFormValues = () => {
return submitObj
}
const providePolicyholderInfoData = () => {
return {
form: JSON.parse(JSON.stringify(form.value)),
saveKey: JSON.parse(JSON.stringify(saveKey.value))
}
}
// 表单提交
const submitForm = () => {
proxy.$refs['policyholderInfoFormRef'].validate((valid, fields) => {
......@@ -1099,22 +1118,6 @@ const submitForm = () => {
}
})
}
const resetForm = () => {
proxy.$modal
.confirm('是否确认撤销所作操作?')
.then(function () {
if (props.customerBizId) {
form.value = { ...oldObjInfo.value }
editStatus.value = true
} else {
// resetShow('smokeQuantity', false)
proxy.$refs['policyholderInfoFormRef'].resetFields()
}
processedPolicyData.value = JSON.parse(JSON.stringify(oldAppointmentData.value))
})
.catch(() => {})
}
watch(
() => props.activeName,
......@@ -1136,6 +1139,7 @@ watch(
} else {
processFormData({
domdata: policyDomData,
customerInfo: props.customerInfo,
exportValue: null
})
}
......@@ -1147,7 +1151,8 @@ watch(
// 暴露给父组件
defineExpose({
handleFormValues,
handleEditStatus
handleEditStatus,
providePolicyholderInfoData
})
</script>
<style lang="scss" scoped>
......
......@@ -714,7 +714,6 @@ const handleSelectChange = (father, child) => {
// 选是,展示日期
if (form.value[father.key][child.key] == '1') {
resetShow('policyEffectiveDate', true)
// form.value[father.key]['policyEffectiveDate'] = ''
} else {
resetShow('policyEffectiveDate', false)
}
......@@ -925,11 +924,7 @@ const setFormValue = (obj, formData) => {
for (const field of section.data) {
if (key == 'apiProductPlanMainInfoDto') {
for (const key2 in newForm[key]) {
if (
field.key == 'policyEffectiveDate' &&
newForm[key][field.key] &&
newForm[key]['isBacktrack'] == '1'
) {
if (field.key == 'policyEffectiveDate' && newForm[key]['isBacktrack'] == '1') {
field.show = true
}
}
......
......@@ -73,6 +73,13 @@
<dict-tag :options="csf_ap_status" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column label="最终预约时间" align="center" width="180">
<template #default="scope">
<span>{{
scope.row.confirmAppointmentTime ? parseTime(scope.row.confirmAppointmentTime) : '--'
}}</span>
</template>
</el-table-column>
<el-table-column label="产品名称" align="center" prop="productName" width="150" />
<el-table-column label="保险公司" align="center" prop="companyName" width="150" />
<el-table-column label="业务员" align="center" prop="businessRepresentName1" width="150" />
......@@ -88,7 +95,20 @@
</template>
</el-table-column>
<el-table-column label="时间" align="center" prop="time" width="240" show-overflow-tooltip>
<el-table-column
label="意向预约时间"
align="center"
prop="intentionAppointmentTime"
width="240"
show-overflow-tooltip
>
<template #default="scope">
<span>{{
scope.row.intentionAppointmentTime
? parseTime(scope.row.intentionAppointmentTime)
: '--'
}}</span>
</template>
</el-table-column>
<!-- sortable -->
<el-table-column label="创建时间" align="center" prop="createTime" width="150">
......
......@@ -493,10 +493,7 @@ const handleEditStatus = () => {
}
processedFanFormData.value = processedData
}
//给表单赋值 方便表单回显 obj 为表单数据
const setFormValue = (obj, formData) => {
loading.value = true
}
// 获取校验失败的字段信息
const getInvalidFields = fields => {
......
......@@ -29,8 +29,8 @@
/>
</template>
</el-table-column>
<!-- sortable -->
<el-table-column label="来佣金额" prop="amount" align="center" width="120">
<!-- <el-table-column label="来佣金额" prop="amount" align="center" width="120">
<template #default="scope">
<el-input
v-model="scope.row.amount"
......@@ -39,8 +39,17 @@
placeholder="请输入"
/>
</template>
</el-table-column> -->
<el-table-column label="来佣比例" prop="ratio" align="center" width="120">
<template #default="scope">
<el-input
v-model="scope.row.ratio"
size="default"
type="number"
placeholder="请输入"
/>
</template>
</el-table-column>
<!-- sortable -->
<el-table-column label="佣金期数" prop="commissionPeriod" align="center" width="120">
<template #default="scope">
<el-input
......
<template>
<div>
<div>
<el-row>
<el-col :span="24">
<el-form :model="queryParams" ref="queryRef" :inline="true">
<el-form-item label="转介人姓名" prop="broker">
<el-input
v-model="queryParams.broker"
placeholder="请输入转介人姓名"
clearable
@clear="resetQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="getTableList">查询</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-col>
<el-col :span="24" style="margin-bottom: 10px" v-if="props.policyNo">
<el-button type="primary" icon="Plus" @click="getGenerate">生成预计发佣</el-button>
<el-button type="warning" @click="getOperationData">生成发佣日志信息</el-button>
</el-col>
<el-table :data="tableList" border @sort-change="sortChange">
<el-table-column label="转介人" prop="broker" align="center" width="180" fixed="left">
</el-table-column>
<el-table-column
label="发佣名称"
prop="fortuneName"
align="center"
width="180"
></el-table-column>
<el-table-column
label="发佣类型"
prop="fortuneType"
align="center"
width="180"
></el-table-column>
<el-table-column
label="发佣金额"
prop="amount"
align="center"
width="180"
></el-table-column>
<el-table-column label="发佣币种" prop="currency" align="center" width="160">
<template #default="scope">
<dict-tag :options="fetchDictData('bx_currency_type')" :value="scope.row.currency" />
</template>
</el-table-column>
<el-table-column
label="团队名称"
prop="team"
align="center"
width="180"
></el-table-column>
<el-table-column label="发佣期数" prop="fortunePeriod" align="center" width="180">
<template #default="scope">
{{ scope.row.fortunePeriod ? `第${scope.row.fortunePeriod}年` : '--' }}
</template>
</el-table-column>
<el-table-column label="发佣总期数" prop="fortuneTotalPeriod" align="center" width="180">
<template #default="scope">
{{ scope.row.fortuneTotalPeriod ? `${scope.row.fortuneTotalPeriod}年` : '--' }}
</template>
</el-table-column>
</el-table>
<el-col :span="24">
<pagination
v-show="total >= 0"
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getTableList"
/>
</el-col>
<!-- <el-col :span="24" align="center" style="margin-top: 10px">
<el-button type="success" size="large" @click="submitTable">提交</el-button>
</el-col> -->
</el-row>
<el-dialog :title="commissionTitle" v-model="editCommission" width="800px" append-to-body>
<el-table :data="operationList" border>
<el-table-column label="保单号" prop="policyNo" align="center" width="180" fixed="left">
</el-table-column>
<el-table-column label="状态" prop="status" align="center" width="180">
<template #default="scope">
<dict-tag :options="tagStatus" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column
label="发佣日志信息"
prop="errorMsg"
align="center"
width="180"
></el-table-column>
<el-table-column prop="createTime" label="日志时间" align="center">
<template #default="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
</el-table>
<pagination
v-show="operationPages.total >= 0"
:total="operationPages.total"
v-model:page="operationPages.pageNo"
v-model:limit="operationPages.pageSize"
@pagination="getOperationData"
/>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeDialog"> </el-button>
</div>
</template>
</el-dialog>
</div>
</div>
</template>
<script setup name="policyInfo">
import useDictStore from '@/store/modules/dict'
import { watch } from 'vue'
import { getAllCompanys } from '@/api/common'
import {
getExpectedFortuneList,
editSigalCommission,
editMultipleCommission,
delCommissionExpected,
getExpectedFortuneLog,
expectedFortuneGenerate
} from '@/api/sign/underwritingMain'
import useUserStore from '@/store/modules/user'
const userStore = useUserStore()
const dictStore = useDictStore() //获取字典数据
const props = defineProps({
activeName: { type: String, default: '' }, //tab名称
policyBizId: { type: String, default: '' }, //提交状态,新增、修改
policyNo: { type: String, default: '' }, //提交状态,新增、修改
dictTypeLists: { type: Array, default: () => [] } //多个字典值数据
})
const emit = defineEmits(['handleSuccess'])
const { proxy } = getCurrentInstance()
const loading = ref(false)
const editStatus = ref(false) // 表单是否可编辑,若是修改初始不可编辑
const searchOptions = ref({}) // 存储不同key对应的选项
const searchLoadingStates = ref({}) // 存储不同key对应的加载状态
const total = ref(0)
const oldTotal = ref(0)
const tableList = ref([])
const isEditing = ref(false)
const commissionTitle = ref('生成发佣日志信息')
const editCommission = ref(false)
const isClickGenerate = ref(false)
const operationList = ref([])
const tagStatus = ref([
{ label: '失败', value: '1', elTagType: 'danger' },
{ label: '进行中', value: '2', elTagType: 'warning' },
{ label: '成功', value: '0', elTagType: 'success' }
])
const operationPages = ref({
pageNo: 1,
pageSize: 5,
total: 0
})
const data = reactive({
form: {},
queryParams: {
pageNo: 1,
pageSize: 10,
// sortField: 'commissionPeriod',
// sortOrder: 'ascend',
policyNo: props.policyNo || ''
}
})
const { queryParams, form } = toRefs(data)
const closeDialog = () => {
editCommission.value = false
operationList.value = []
operationPages.value = {
pageNo: 1,
pageSize: 5,
total: 0
}
}
/** 重置按钮操作 */
function resetQuery() {
proxy.resetForm('queryRef')
queryParams.value = {
pageNo: 1,
pageSize: 10,
policyNo: props.policyNo || ''
}
getTableList()
}
const sortChange = ({ prop, order }) => {
if (isEditing.value) {
return // 编辑期间不进行排序
}
if (order == 'ascending') {
queryParams.value.sortOrder = 'ascend'
} else {
queryParams.value.sortOrder = 'descend'
}
if (prop) {
queryParams.value.sortField = prop
}
// 重新获取表格数据
getTableList()
}
// 搜索方法
const searchSelectList = async (query, fieldKey) => {
// 设置该字段的加载状态
searchLoadingStates.value[fieldKey] = true
try {
// 根据不同的字段key调用不同的API
if (fieldKey === 'reconciliationCompany') {
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
})
}
} catch (error) {
console.error(`${fieldKey} 搜索失败`, error)
searchOptions.value[fieldKey] = []
} finally {
searchLoadingStates.value[fieldKey] = false
}
}
// 获取字典数据
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 getOperationData = () => {
let data = {
pageNo: operationPages.value.pageNo,
pageSize: operationPages.value.pageSize,
policyNo: props.policyNo
}
getExpectedFortuneLog(data).then(res => {
if (res.code == 200) {
operationList.value = res.data.records
operationPages.value.total = res.data.total
editCommission.value = true
} else {
proxy.$message.error(res.msg)
}
})
}
const getGenerate = () => {
expectedFortuneGenerate({ policyNo: props.policyNo }).then(res => {
isClickGenerate.value = true //代表之前已经点击过生成发佣按钮
if (res.code == 200) {
proxy.$message.success(res.msg)
} else {
proxy.$message.error(res.msg)
}
})
}
// 处理单个提交
const handleUpdate = row => {
let obj = JSON.parse(JSON.stringify(row))
if (obj.commissionDate) {
obj.commissionDate = proxy.formatToDate(obj.commissionDate)
}
if (obj.commissionName) {
obj.commissionType = obj.commissionName
}
dictStore.insureCompanyList.forEach(item => {
if (obj.reconciliationCompany && obj.reconciliationCompany == item.value) {
obj.reconciliationCompany = item.label
obj.reconciliationCompanyBizId = item.value
}
})
editSigalCommission(obj).then(res => {
if (res.code == 200) {
proxy.$message.success('提交成功')
getTableList()
}
})
}
const submitTable = () => {
if (tableList.value.length == 0) {
proxy.$message.warning('请先添加来佣')
return
}
let result = JSON.parse(JSON.stringify(tableList.value))
result.forEach(item => {
if (item.commissionDate) {
item.commissionDate = proxy.formatToDate(item.commissionDate)
}
if (item.commissionName) {
item.commissionType = item.commissionName
}
dictStore.insureCompanyList.forEach(item1 => {
if (item.reconciliationCompany && item.reconciliationCompany == item1.value) {
item.reconciliationCompany = item1.label
item.reconciliationCompanyBizId = item1.value
}
})
})
editMultipleCommission({ commissionExpectedAddDtoList: result }).then(res => {
if (res.code == 200) {
proxy.$message.success('提交成功')
getTableList()
}
})
}
const handleDetele = (row, index) => {
if (row.commissionExpectedBizId) {
proxy.$modal
.confirm('是否确认删除此来佣?')
.then(function () {
return delCommissionExpected(row.commissionExpectedBizId)
})
.then(res => {
if (res.code == 200) {
proxy.$modal.msgSuccess('删除成功')
getTableList()
}
})
.catch(() => {})
} else {
tableList.value.splice(index, 1)
if (total.value > 0) {
total.value = total.value - 1
} else {
total.value = 0
}
proxy.$modal.msgSuccess('删除成功')
}
}
const getTableList = () => {
loading.value = true
try {
getExpectedFortuneList(queryParams.value).then(response => {
if (response.code == 200) {
total.value = oldTotal.value = response.data.total
tableList.value = response.data.records
loading.value = false
if (isClickGenerate.value && tableList.value.length == 0) {
proxy.$message.warning('暂无发佣数据,请查看生成发佣日志信息')
}
}
})
} catch (error) {
tableList.value = []
} finally {
loading.value = false
}
}
watch(
() => props.activeName,
newVal => {
if (newVal === 'expectedFortune') {
searchOptions.value['reconciliationCompany'] = dictStore.insureCompanyList
getTableList()
}
}
)
</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;
}
.deleteIcon {
color: red;
font-size: 18px;
padding-top: 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;
}
}
}
.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>
......@@ -14,11 +14,11 @@
</div>
</el-col>
</el-row>
<el-form ref="fanFormRef" :model="form" :rules="rules">
<el-form ref="fanFormRef" :model="form">
<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> -->
<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">
......@@ -109,6 +109,110 @@
</el-col>
</template>
</el-row>
<el-row v-if="father.showTable">
<el-table :data="father.data" border>
<template v-if="father.key == 'signerList'">
<el-table-column label="姓名" prop="signer" align="center">
<template #header>
<span class="required-label">姓名</span>
</template>
<template #default="scope">
<el-input
size="default"
placeholder="请输入"
v-model="scope.row.signer"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column label="手机号" prop="phone" align="center">
<template #header>
<span class="required-label">手机号</span>
</template>
<template #default="scope">
<el-input
v-model="scope.row.phone"
size="default"
placeholder="请输入"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column label="执业编码" prop="registrationNumber" align="center">
<template #header>
<span class="required-label">执业编码</span>
</template>
<template #default="scope">
<el-input
v-model="scope.row.registrationNumber"
size="default"
placeholder="请输入"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column label="邮箱" prop="email" align="center">
<template #default="scope">
<el-input
v-model="scope.row.email"
size="default"
placeholder="请输入"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column label="证件类型" prop="idType" align="center">
<template #default="scope">
<el-select
v-model="scope.row.idType"
placeholder="请选择"
:disabled="editStatus"
clearable
>
<el-option
v-for="item in fetchDictData('csf_id_type')"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column label="证件号" prop="idNo" align="center">
<template #default="scope">
<el-input
v-model="scope.row.idNo"
size="default"
placeholder="请输入"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column width="60px" align="center" label="操作">
<template #default="scope">
<el-icon @click="deleteChildren(father, scope.$index)" class="deleteIcon"
><Delete
/></el-icon>
</template>
</el-table-column>
</template>
</el-table>
<el-col
:span="24"
v-if="father.addChildren"
style="display: flex; justify-content: center"
>
<el-button
:disabled="editStatus"
style="margin-top: 10px"
type="primary"
icon="Plus"
@click="addChildren(father)"
>{{ father.addChildrenTxt }}</el-button
>
</el-col>
</el-row>
</div>
</el-row>
......@@ -134,9 +238,8 @@
<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,
......@@ -194,6 +297,40 @@ const {
const disabledDate = time => {
return time.getTime() > Date.now()
}
const addChildren = father => {
const processedData = JSON.parse(JSON.stringify(processedFanFormData.value))
let obj = {
span: 24, //栅格布局份数
signer: '',
phone: '',
email: '',
idType: '',
idNo: '',
dictType: 'csf_id_type',
registrationNumber: ''
}
for (const section of processedData) {
if (section.key == 'signerList') {
section.data.push(obj)
}
}
processedFanFormData.value = processedData
}
const deleteChildren = (father, childIndex) => {
if (editStatus.value) {
proxy.$modal.confirm(`请先点击编辑再进行删除操作`, { showCancel: '0', title: '填写提示' })
return
}
const processedData = JSON.parse(JSON.stringify(processedFanFormData.value))
for (const section of processedData) {
if (father.key == 'signerList' && section.key == father.key) {
section.data.splice(childIndex, 1)
}
}
//更新form表单对应的数据,以便收集填写的值
processedFanFormData.value = processedData
}
// 搜索方法
const searchSelectList = async (query, fieldKey) => {
// 设置该字段的加载状态
......@@ -321,7 +458,17 @@ const processFormData = () => {
}
//给表单赋值各模块key,对应表单的father.key便于收集值
if (section.keyType == 'Array') {
form.value[section.key] = []
if (section.key == 'signerList' && props.policyFollowUpdateDto.signerList) {
section.data = props.policyFollowUpdateDto.signerList
if (section.data.length > 0) {
section.data.forEach((item, index) => {
if (item.mobileCode) {
item.phone = item.mobileCode + '' + item.phone
}
})
}
}
// form.value[section.key] = []
if (section.key == 'brokerList') {
form.value[section.key] = section.data
}
......@@ -371,17 +518,13 @@ const processFormData = () => {
// tab切走在切回来时,表单会重置,所以这里需要把表单的值赋回去
editStatus.value = false
}
processedFanFormData.value = oldFanFormData.value = processedData
if (Object.keys(tempFanFormValue.value).length > 0) {
form.value = JSON.parse(JSON.stringify(tempFanFormValue.value))
processedFanFormData.value = JSON.parse(JSON.stringify(tempFanFormData.value))
}
processedFanFormData.value = oldFanFormData.value = processedData
// if (tempFanFormData.value.length > 0) {
// processedFanFormData.value = oldFanFormData.value = JSON.parse(
// JSON.stringify(tempFanFormData.value)
// )
// } else {
// processedFanFormData.value = oldFanFormData.value = processedData
// }
loading.value = false
}
// 根据联动重置表单项的显示与否
......@@ -469,11 +612,53 @@ const isArray = value => {
const isObject = value => {
return typeof value === 'object' && value !== null && !Array.isArray(value)
}
// 自定义校验方法
const validateTableData = () => {
for (const father of processedFanFormData.value) {
if (father.key === 'signerList' && father.data) {
for (let i = 0; i < father.data.length; i++) {
const row = father.data[i]
// 校验姓名
if (!row.signer || row.signer.trim() === '') {
proxy.$message.error(`签单人-第 ${i + 1} 行姓名不能为空`)
return false
}
// 校验手机号
if (!row.phone || row.phone.trim() === '') {
proxy.$message.error(`签单人-第 ${i + 1} 行手机号不能为空`)
return false
}
// 校验手机号格式
// const phoneRegex = /^1[3-9]\d{9}$/
// if (!phoneRegex.test(row.phone)) {
// proxy.$message.error(`签单人-第 ${i + 1} 行手机号格式不正确`)
// return false
// }
// 校验执业编码
if (!row.registrationNumber || row.registrationNumber.trim() === '') {
proxy.$message.error(`签单人-第 ${i + 1} 行执业编码不能为空`)
return false
}
}
}
}
return true
}
// 处理表单填写得数据
const handleFormValues = () => {
let submitObj = JSON.parse(JSON.stringify(form.value))
const pattern = /Date$/ // 以Time结尾
// debugger
for (const section of processedFanFormData.value) {
if (section.key == 'signerList' && section.keyType == 'Array') {
submitObj.policyFollowUpdateDto[section.key] = section.data
}
}
//处理表单数据
for (const key1 in form.value) {
// 对象数据格式
......@@ -500,29 +685,19 @@ const handleFormValues = () => {
}
}
}
// 数组数据格式
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 => {
if (!validateTableData()) {
return
}
let submitObj = handleFormValues()
console.log('保单信息', submitObj)
// return
proxy.$refs['fanFormRef'].validate((valid, fields) => {
if (valid) {
if (props.policyBizId) {
......@@ -552,6 +727,7 @@ const getPolicyDetail = () => {
getPolicyfollow(props.policyBizId).then(res => {
if (res.code == 200) {
form.value.policyFollowUpdateDto = res.data.policyFollowUpdateDto
processFormData()
}
})
}
......@@ -570,6 +746,11 @@ watch(
)
</script>
<style lang="scss" scoped>
.required-label::before {
content: '*';
color: #f56c6c;
margin-right: 4px;
}
.domEmpty {
width: 100%;
height: 100%;
......
......@@ -9,6 +9,7 @@
</div>
</template>
<script setup name="FollowUpDetail">
import { processUserName } from '@/utils/common'
import AppointmentEdit from '@/views/sign/appointment/appointmentEdit'
import { getPolicyfollow, getPolicyInfo } from '@/api/sign/underwritingMain'
import useUserStore from '@/store/modules/user'
......@@ -39,7 +40,14 @@ const getDictsData = async () => {
}
const response1 = await listTenantUser(params1)
if (response1.code == 200) {
dictStore.setTenantUserList(response1.data.records)
let result = processUserName(response1.data.records)
result = result.map(item => {
return {
value: item.userBizId,
label: item.showName
}
})
dictStore.setTenantUserList(result)
}
const params2 = {
loginTenantBizId: userStore.projectInfo.tenantBizId,
......
......@@ -83,9 +83,7 @@
:show-file-list="false"
accept=".xlsx, .xls"
>
<el-button type="success" :icon="UploadFilled" size="default">
上传Excel文件
</el-button>
<el-button type="success" size="default"> 上传Excel文件 </el-button>
</el-upload>
<el-button text @click="downloadTemplate" size="default" class="download-template-btn">
下载模板
......@@ -136,6 +134,15 @@
<span>{{ convertStatusToDict(1, scope.row.status) }}</span>
</template>
</el-table-column>
<el-table-column prop="coolingOffEndDate" label="冷静期结束日期" width="150" align="center">
<template #default="scope">
<span>{{
scope.row.coolingOffEndDate ? parseTime(scope.row.coolingOffEndDate) : '--'
}}</span>
</template>
</el-table-column>
<el-table-column prop="coolingOffDays" label="冷静期天数" width="150" align="center">
</el-table-column>
<el-table-column prop="policyNo" label="保单号" width="150" align="center" sortable />
<el-table-column prop="customerName" label="客户名称" width="100" align="center" sortable />
<el-table-column prop="signDate" label="签单日期" width="150" align="center" sortable>
......@@ -162,7 +169,11 @@
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="currency" label="币种" width="100" align="center" sortable>
<template #default="scope">
<dict-tag :options="currencyTypeOptions" :value="scope.row.currency" />
</template>
</el-table-column>
<el-table-column prop="initialPremium" label="首期保费" width="150" align="center" sortable>
<template #default="scope">
{{ numberWithCommas(scope.row.initialPremium) }}
......@@ -171,16 +182,37 @@
<el-table-column
label="操作"
align="center"
width="250"
width="200"
class-name="small-padding fixed-width"
fixed="right"
>
<template #default="scope">
<el-button text size="primary" @click="handleView(scope.row)"> 查看 </el-button>
<el-button text size="primary" @click="handleStatus(scope.row)"> 跟进 </el-button>
<div class="btnCon">
<el-button link type="primary" size="small" @click="handleReport(scope.row)">
生成签约单完成报告
</el-button>
<el-dropdown placement="bottom" style="margin-left: 10px">
<el-button type="primary" link size="small">
更多 <el-icon><ArrowDown /></el-icon
></el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="handleView(scope.row)">查看</el-dropdown-item>
<el-dropdown-item @click="handleStatus(scope.row)">跟进</el-dropdown-item>
<el-dropdown-item @click="handleEditStatus(scope.row)"
>修改状态</el-dropdown-item
>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
<!-- <el-button text size="primary" @click="handleView(scope.row)"> 查看 </el-button> -->
<!-- <el-button text size="primary" @click="handleStatus(scope.row)"> 跟进 </el-button>
<el-button text type="warning" @click="handleEditStatus(scope.row)">
修改状态
</el-button>
</el-button> -->
</template>
</el-table-column>
</el-table>
......@@ -236,7 +268,11 @@
</el-dialog>
</div>
</template>
<!-- {
"code": 200,
"msg": "生成预计发佣正在处理....,稍后查看预计发佣列表",
"data": null
} -->
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
......@@ -244,7 +280,8 @@ import axios from 'axios'
import {
getPolicyFollowList,
getExpectedCommissionList,
changePolicyStatus
changePolicyStatus,
policyFollowReport
} from '@/api/sign/underwritingMain'
import { getToken } from '@/utils/auth'
import { listType } from '@/api/system/dict/type'
......@@ -259,6 +296,7 @@ const router = useRouter()
const policyFollowStatusList = ref([])
const commissionStatusList = ref([])
const fortuneStatusList = ref([])
const currencyTypeOptions = ref([])
const currentPolicyRow = ref({}) //当前保单
const editStatus = ref(false) //新单信息状态
const data = reactive({
......@@ -287,7 +325,12 @@ const submitForm = () => {
}
const getLists = () => {
listType({
typeList: ['csf_policy_follow_status', 'csf_expected_commission_status', 'csf_fortune_status']
typeList: [
'csf_policy_follow_status',
'csf_expected_commission_status',
'csf_fortune_status',
'bx_currency_type'
]
})
.then(res => {
if (res.code === 200 && res.data) {
......@@ -299,10 +342,20 @@ const getLists = () => {
commissionStatusList.value = commissionStatusData?.dictItemList || []
const fortuneStatusData = res.data.find(item => item.dictType === 'csf_fortune_status')
fortuneStatusList.value = fortuneStatusData?.dictItemList || []
// 处理币种字典值
const currencyData = res.data.find(item => item.dictType === 'bx_currency_type')
if (currencyData) {
currencyData?.dictItemList.forEach(item => {
item.value = item.itemValue
item.label = item.itemLabel
})
}
currencyTypeOptions.value = currencyData?.dictItemList || []
} else {
policyFollowStatusList.value = []
commissionStatusList.value = []
fortuneStatusList.value = []
currencyTypeOptions.value = []
}
})
.catch(error => {
......@@ -378,7 +431,34 @@ const handleView = async row => {
fetchExpectedCommissionList(row.policyNo)
getPolicyFortuneLists(row.policyNo)
}
const handleReport = async row => {
try {
const res = await policyFollowReport(row.policyBizId)
console.log('pdf请求', res)
// 创建 Blob 对象
const blob = new Blob([res], { type: 'application/pdf' })
// 创建对象 URL
const url = window.URL.createObjectURL(blob)
// 在新窗口打开
window.open(url, '_blank')
//下载得方式
// const blob = new Blob([res], { type: 'application/pdf' })
// const url = window.URL.createObjectURL(blob)
// // 创建下载链接
// const link = document.createElement('a')
// link.href = url
// link.download = '签约单.pdf' // 设置文件名
// link.click()
// // 清理 URL 对象
// window.URL.revokeObjectURL(url)
} catch (error) {
console.error('导出失败:', error)
}
}
// 处理详情弹窗关闭
const handleDetailClose = () => {
viewDialogVisible.value = false
......@@ -668,6 +748,11 @@ const handleEditStatus = row => {
</script>
<style scoped>
.btnCon {
display: flex;
align-items: center;
justify-content: center;
}
.data-management-page {
padding: 20px;
/* max-width: 1600px; */
......
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