Commit 8b7c1013 by Sweet Zhang

新单跟进修改

parent 6c77f9e8
......@@ -2,26 +2,28 @@
<template>
<div class="form-page">
<el-form ref="formRef" :model="localData" label-width="120px" size="default">
<!-- 完整Tab列表:通用Tab + 自定义Tab -->
<el-tabs v-model="activeTab" @tab-click="handleTabClick" :before-leave="handleBeforeLeave">
<!-- 自定义已实现的Tab -->
<!-- 完整Tab列表 -->
<el-tabs
ref="tabsRef"
v-model="activeTab"
@tab-click="handleTabClick"
:before-leave="handleBeforeLeave"
class="appointmentTabPaneBox"
>
<el-tab-pane label="基础信息" name="basic"></el-tab-pane>
<!-- 复用预约页面的通用Tab -->
<el-tab-pane label="产品计划" name="productPlan"></el-tab-pane>
<el-tab-pane label="投保人" name="policyholder"></el-tab-pane>
<el-tab-pane label="受保人" name="insured"></el-tab-pane>
<el-tab-pane label="受益人" name="beneficiary"></el-tab-pane>
<el-tab-pane label="第二持有人" name="secondHolder"></el-tab-pane>
<el-tab-pane label="预约附件" name="appointmentAttachment"></el-tab-pane>
<!-- 自定义已实现的Tab -->
<el-tab-pane label="介绍人" name="introducer"></el-tab-pane>
<el-tab-pane label="邮寄信息" name="postal"></el-tab-pane>
<el-tab-pane label="关联记录" name="relatedRecords"></el-tab-pane>
<el-tab-pane label="新单附件" name="policyAttachment"></el-tab-pane>
<el-tab-pane label="产品计划" name="productPlan"></el-tab-pane>
<el-tab-pane label="投保人" name="policyholder"></el-tab-pane>
<el-tab-pane label="受保人" name="insured"></el-tab-pane>
<el-tab-pane label="受益人" name="beneficiary"></el-tab-pane>
<el-tab-pane label="第二持有人" name="secondHolder"></el-tab-pane>
<el-tab-pane label="预约附件" name="appointmentAttachment"></el-tab-pane>
<el-tab-pane label="介绍人" name="introducer"></el-tab-pane>
<el-tab-pane label="邮寄信息" name="postal"></el-tab-pane>
<el-tab-pane label="关联记录" name="relatedRecords"></el-tab-pane>
<el-tab-pane label="新单附件" name="policyAttachment"></el-tab-pane>
</el-tabs>
<!-- 1. 基础信息 Tab(你已实现的部分) -->
<!-- 1. 基础信息 Tab(保留你的原有代码) -->
<div v-if="activeTab === 'basic'" class="tab-content">
<div class="section">
<h3 class="sectionTitle">基础信息</h3>
......@@ -43,95 +45,92 @@
</div>
</div>
<!-- 2. 产品计划 Tab(复用预约页面组件) -->
<!-- 2. 产品计划 Tab(完全匹配你的传参格式) -->
<div v-else-if="activeTab === 'productPlan'" class="tab-content">
<div class="section">
<h3 class="sectionTitle">产品计划</h3>
<!-- 复用预约页面的ProductPlan组件 -->
<!-- 完全匹配预约页面的ProductPlan传参 -->
<ProductPlan
:activeName="activeName"
:formStatus="formStatus"
:idsObj="idsObj"
:apiProductPlanInfoDto="policySummeryInfo.apiProductPlanInfoDto"
:appointmentStatus="policySummeryInfo.status"
ref="productPlanRef"
:formData="productPlanFormData"
:disabled="props.mode === 'viewDetail'"
@form-change="handleProductPlanChange"
@save="handleProductPlanSave"
@policyEditSuccess="getPolicyDetail"
:pageSource="pageSource"
:showSubmitBtn="showSubmitBtn"
:tabIndex="tabsList.findIndex(t => t.name === 'productPlan')"
anchorContainer=".appointmentTabPaneBox"
:fatherTabName="activeTab"
:isEditMode="props.mode !== 'viewDetail'"
:affixOffset="pageSource == 'fnaList' ? 360 : 250"
:isExportAppointment="isExportPolicy"
/>
</div>
</div>
<!-- 3. 投保人 Tab(复用预约页面组件) -->
<!-- 3. 投保人/受保人/受益人/第二持有人/预约附件 Tab(保留结构,后续按需补传参) -->
<div v-else-if="activeTab === 'policyholder'" class="tab-content">
<div class="section">
<h3 class="sectionTitle">投保人信息</h3>
<!-- 复用预约页面的Customer组件(投保人) -->
<!-- 这里补充你预约页面投保人组件的真实传参 -->
<Customer
ref="policyholderRef"
type="policyholder"
:formData="policyholderFormData"
:disabled="props.mode === 'viewDetail'"
@form-change="handlePolicyholderChange"
:isEditMode="props.mode !== 'viewDetail'"
:policyBizId="props.policyBizId"
v-model="policyholderFormData"
/>
</div>
</div>
<!-- 4. 受保人 Tab(复用预约页面组件) -->
<div v-else-if="activeTab === 'insured'" class="tab-content">
<div class="section">
<h3 class="sectionTitle">受保人信息</h3>
<!-- 复用预约页面的Customer组件(受保人) -->
<Customer
ref="insuredRef"
type="insured"
:formData="insuredFormData"
:disabled="props.mode === 'viewDetail'"
@form-change="handleInsuredChange"
:isEditMode="props.mode !== 'viewDetail'"
:policyBizId="props.policyBizId"
v-model="insuredFormData"
/>
</div>
</div>
<!-- 5. 受益人 Tab(复用预约页面组件) -->
<div v-else-if="activeTab === 'beneficiary'" class="tab-content">
<div class="section">
<h3 class="sectionTitle">受益人信息</h3>
<!-- 复用预约页面的Beneficiary组件 -->
<Beneficiary
ref="beneficiaryRef"
:formData="beneficiaryFormData"
:disabled="props.mode === 'viewDetail'"
@form-change="handleBeneficiaryChange"
:isEditMode="props.mode !== 'viewDetail'"
:policyBizId="props.policyBizId"
v-model="beneficiaryFormData"
/>
</div>
</div>
<!-- 6. 第二持有人 Tab(复用预约页面组件) -->
<div v-else-if="activeTab === 'secondHolder'" class="tab-content">
<div class="section">
<h3 class="sectionTitle">第二持有人信息</h3>
<!-- 复用预约页面的SecondHolder组件 -->
<SecondHolder
ref="secondHolderRef"
:formData="secondHolderFormData"
:disabled="props.mode === 'viewDetail'"
@form-change="handleSecondHolderChange"
:isEditMode="props.mode !== 'viewDetail'"
:policyBizId="props.policyBizId"
v-model="secondHolderFormData"
/>
</div>
</div>
<!-- 7. 预约附件 Tab(复用预约页面组件) -->
<div v-else-if="activeTab === 'appointmentAttachment'" class="tab-content">
<div class="section">
<h3 class="sectionTitle">预约附件</h3>
<!-- 复用预约页面的FileUpload组件 -->
<FileUpload
ref="appointmentAttachmentRef"
type="appointment"
:isEditMode="props.mode !== 'viewDetail'"
:bizId="props.policyBizId"
:disabled="props.mode === 'viewDetail'"
@upload-success="handleAppointmentAttachmentUpload"
type="appointment"
/>
</div>
</div>
<!-- 8. 介绍人 Tab(你已实现的部分) -->
<!-- 以下是你已实现的Tab(保留不变) -->
<div v-else-if="activeTab === 'introducer'" class="tab-content">
<div class="section">
<h3 class="sectionTitle">介绍人信息</h3>
......@@ -146,8 +145,6 @@
/>
</div>
</div>
<!-- 9. 邮寄信息 Tab(你已实现的部分) -->
<div v-else-if="activeTab === 'postal'" class="tab-content">
<div class="section">
<h3 class="sectionTitle">邮寄信息</h3>
......@@ -159,8 +156,6 @@
/>
</div>
</div>
<!-- 10. 关联记录 Tab(你已实现的部分) -->
<div v-else-if="activeTab === 'relatedRecords'" class="tab-content">
<div class="section">
<h3 class="sectionTitle">关联记录</h3>
......@@ -184,8 +179,6 @@
</el-table>
</div>
</div>
<!-- 11. 新单附件 Tab(你已实现的部分) -->
<div v-else-if="activeTab === 'policyAttachment'" class="tab-content">
<div class="section">
<h3 class="sectionTitle">附件</h3>
......@@ -239,7 +232,7 @@
</div>
</el-form>
<!-- 文件上传弹窗(新单附件) -->
<!-- 文件上传弹窗 -->
<CommonDialog
dialogTitle="文件导入"
dialogWidth="80%"
......@@ -268,19 +261,17 @@ import { ref, reactive, watch, nextTick, onMounted, computed } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Upload } from '@element-plus/icons-vue'
// ========== 1. 导入你已实现的组件 ==========
// ========== 1. 组件导入(保留你的原有导入) ==========
import SearchForm from '@/components/SearchForm/SearchForm.vue'
import CommonDialog from '@/components/commonDialog'
import EditableTable from '@/components/csf-common/EditableTable.vue'
// ========== 2. 导入预约页面的通用组件 ==========
import ProductPlan from '@/views/sign/appointment/components/productPlan.vue'
import Customer from '@/views/sign/FnaList/components/customer' // 投保人/受保人通用
import Customer from '@/views/sign/FnaList/components/customer'
import Beneficiary from '@/views/sign/appointment/components/beneficiaryInfo.vue'
import SecondHolder from '@/views/sign/appointment/components/secondHolderInfo.vue'
import FileUpload from '@/views/sign/appointment/components/fileUpload.vue' // 预约附件上传
import FileUpload from '@/views/sign/appointment/components/fileUpload.vue'
// ========== 3. 导入API和工具函数 ==========
// ========== 2. API和工具函数导入(保留你的原有导入) ==========
import { getPolicyfollow, getProductPlan, getPolicyholder,getInsurant,getBeneficiary,getSecondHolder,getAppointmentFiles,updatePolicyfollow } from '@/api/sign/underwritingMain'
import { uploadOssFileList } from '@/api/common'
import { getProcessDetail } from '@/api/sign/fna'
......@@ -288,12 +279,12 @@ import { loadDicts, getDictLabel } from '@/utils/useDict'
import { formatToDate } from '@/utils/date'
import useUserStore from '@/store/modules/user'
// ========== 4. 核心变量定义 ==========
// ========== 3. 核心变量定义(新增ProductPlan所需的所有参数) ==========
const { proxy } = getCurrentInstance()
const router = useRouter()
const userStore = useUserStore()
// 加载字典(复用预约页面的字典)
// 加载字典
proxy.useDictLists([
'sys_no_yes',
'csf_ap_frequency',
......@@ -305,7 +296,39 @@ proxy.useDictLists([
'receipt_status'
])
// 响应式数据
// ========== 4. ProductPlan组件所需的完整参数(完全匹配你的传参) ==========
const activeName = ref('productPlan') // 激活的子标签名
const formStatus = ref('edit') // 表单状态(edit/view)
const idsObj = ref({
policyBizId: props.policyBizId, // 核心:新单跟进的保单ID
fnaBizId: '',
appointmentBizId: ''
})
// 保单汇总信息(适配ProductPlan的apiProductPlanInfoDto)
const policySummeryInfo = ref({
apiProductPlanInfoDto: {},
status: '' // 预约状态
})
const pageSource = ref('newOrder') // 页面来源:新单跟进
const showSubmitBtn = ref(false) // 是否显示提交按钮(新单跟进不需要)
// Tab列表(匹配tabIndex计算)
const tabsList = ref([
{ name: 'basic', label: '基础信息' },
{ name: 'productPlan', label: '产品计划' },
{ name: 'policyholder', label: '投保人' },
{ name: 'insured', label: '受保人' },
{ name: 'beneficiary', label: '受益人' },
{ name: 'secondHolder', label: '第二持有人' },
{ name: 'appointmentAttachment', label: '预约附件' },
{ name: 'introducer', label: '介绍人' },
{ name: 'postal', label: '邮寄信息' },
{ name: 'relatedRecords', label: '关联记录' },
{ name: 'policyAttachment', label: '新单附件' }
])
const isExportPolicy = ref(false) // 是否导出保单
const tabsRef = ref(null) // tabs组件ref
// ========== 5. 原有变量(保留不变) ==========
const files = ref('')
const fileUploadDialogFlag = ref(false)
const tabDirty = ref({
......@@ -322,7 +345,7 @@ const tabDirty = ref({
policyAttachment: false
})
// ========== 5. Props & Emits ==========
// ========== 6. Props & Emits(保留不变) ==========
const props = defineProps({
modelValue: {
type: Object,
......@@ -340,27 +363,15 @@ const props = defineProps({
const emit = defineEmits(['update:modelValue', 'submit', 'cancel', 'saveSuccess'])
// ========== 6. 通用Tab表单数据(复用预约页面结构) ==========
// 产品计划
// ========== 7. 通用Tab表单数据(保留) ==========
const productPlanRef = ref(null)
const productPlanFormData = ref({})
// 投保人
const policyholderRef = ref(null)
const policyholderFormData = ref({})
// 受保人
const insuredRef = ref(null)
const insuredFormData = ref({})
// 受益人
const beneficiaryRef = ref(null)
const beneficiaryFormData = ref({})
// 第二持有人
const secondHolderRef = ref(null)
const secondHolderFormData = ref({})
// 预约附件
const appointmentAttachmentRef = ref(null)
// ========== 7. 你已实现的变量(保留不变) ==========
// 介绍人配置
// ========== 8. 你已实现的变量(完全保留) ==========
const introducerTableData = ref([])
const introducerConfig = ref([
{
......@@ -432,7 +443,6 @@ const introducerConfig = ref([
}
])
// 基础信息(你已实现)
const basicInfoFormRef = ref()
const basicInfoFormData = ref({})
const basicInfoFormConfig = ref([
......@@ -456,7 +466,6 @@ const basicInfoFormConfig = ref([
{ type: 'select', prop: 'signLocation', label: '签单地点', dictType: 'csf_ap_meeting_point' }
])
// 保单信息(你已实现)
const policyInfoFormRef = ref()
const policyInfoFormData = ref({})
const policyInfoFormConfig = ref([
......@@ -503,7 +512,6 @@ const policyInfoFormConfig = ref([
}
])
// 邮寄信息(你已实现)
const postalFormRef = ref(null)
const postalFormData = ref({})
const postalFormConfig = ref([
......@@ -524,7 +532,6 @@ const postalFormConfig = ref([
}
])
// 关联记录 & 新单附件(你已实现)
const relatedTableData = ref([])
const attachmentTableData = ref([])
const attachmentTableColumns = ref([
......@@ -534,62 +541,23 @@ const attachmentTableColumns = ref([
{ prop: 'creatorName', label: '上传人', sortable: true, width: '150', formatter: row => row.creatorName || '-' }
])
// 本地表单数据
const defaultFormData = () => ({})
const localData = ref(defaultFormData())
const formRef = ref()
const activeTab = ref('basic')
// ========== 8. 通用Tab事件处理(复用预约页面逻辑) ==========
// 产品计划数据变更
const handleProductPlanChange = (data) => {
productPlanFormData.value = data
// ========== 9. ProductPlan所需的回调方法 ==========
// 产品计划编辑成功后刷新保单详情
const getPolicyDetail = () => {
// 重新加载新单跟进数据
getPolicyfollowDetail()
// 重新加载产品计划数据
loadProductPlanData()
ElMessage.success('产品计划修改成功')
tabDirty.value.productPlan = true
}
// 产品计划保存
const handleProductPlanSave = async () => {
if (productPlanRef.value) {
const validData = await productPlanRef.value.validate()
if (validData) {
tabDirty.value.productPlan = false
ElMessage.success('产品计划保存成功')
}
}
}
// 投保人数据变更
const handlePolicyholderChange = (data) => {
policyholderFormData.value = data
tabDirty.value.policyholder = true
}
// 受保人数据变更
const handleInsuredChange = (data) => {
insuredFormData.value = data
tabDirty.value.insured = true
}
// 受益人数据变更
const handleBeneficiaryChange = (data) => {
beneficiaryFormData.value = data
tabDirty.value.beneficiary = true
}
// 第二持有人数据变更
const handleSecondHolderChange = (data) => {
secondHolderFormData.value = data
tabDirty.value.secondHolder = true
}
// 预约附件上传成功
const handleAppointmentAttachmentUpload = () => {
tabDirty.value.appointmentAttachment = true
ElMessage.success('预约附件上传成功')
}
// ========== 9. 原有方法(保留+适配通用Tab) ==========
// Tab切换前确认
// ========== 10. 原有方法(适配ProductPlan参数) ==========
const handleBeforeLeave = async (newTabName, oldTabName) => {
if (tabDirty.value[oldTabName]) {
try {
......@@ -606,7 +574,6 @@ const handleBeforeLeave = async (newTabName, oldTabName) => {
return true
}
// 获取Tab标签名
const getTabLabel = (name) => {
const labels = {
basic: '基础信息',
......@@ -624,25 +591,25 @@ const getTabLabel = (name) => {
return labels[name] || name
}
// Tab点击事件(适配通用Tab)
const handleTabClick = (tab) => {
const tabName = tab.props.name
// 通用Tab加载逻辑
// 产品计划Tab加载逻辑(适配新参数)
if (tabName === 'productPlan') {
loadProductPlanData() // 加载产品计划数据
// 更新idsObj的policyBizId
idsObj.value.policyBizId = props.policyBizId
// 加载产品计划数据
loadProductPlanData()
} else if (tabName === 'policyholder') {
loadPolicyholderData() // 加载投保人数据
loadPolicyholderData()
} else if (tabName === 'insured') {
loadInsuredData() // 加载受保人数据
loadInsuredData()
} else if (tabName === 'beneficiary') {
loadBeneficiaryData() // 加载受益人数据
loadBeneficiaryData()
} else if (tabName === 'secondHolder') {
loadSecondHolderData() // 加载第二持有人数据
loadSecondHolderData()
} else if (tabName === 'appointmentAttachment') {
loadAppointmentAttachmentData() // 加载预约附件数据
}
// 你已实现的Tab逻辑
else if (tabName === 'postal') {
loadAppointmentAttachmentData()
} else if (tabName === 'postal') {
postalFormConfig.value = postalFormConfig.value.map(item => ({
...item,
disabled: props.mode === 'viewDetail'
......@@ -651,26 +618,24 @@ const handleTabClick = (tab) => {
getRelationRecord(localData.value.fnaBizId || props.modelValue.fnaBizId)
} else if (tabName === 'policyAttachment') {
getAttachmentListDetail(props.policyBizId)
} else if (tabName === 'basic') {
// 基础信息逻辑
}
}
// ========== 10. 通用Tab数据加载(复用预约页面API) ==========
// 加载产品计划数据
// ========== 11. 产品计划数据加载(适配新参数) ==========
const loadProductPlanData = () => {
if (!props.policyBizId) return
getProductPlan({ policyBizId: props.policyBizId }).then(res => {
if (res.code === 200) {
productPlanFormData.value = res.data || {}
// 适配policySummeryInfo的格式
policySummeryInfo.value.apiProductPlanInfoDto = res.data || {}
policySummeryInfo.value.status = localData.value.status || ''
}
})
}
// 加载投保人数据
// ========== 12. 其他通用Tab数据加载(保留) ==========
const loadPolicyholderData = () => {
if (!props.policyBizId) return
// 复用预约页面的投保人查询API
getPolicyholder(props.policyBizId).then(res => {
if (res.code === 200) {
policyholderFormData.value = res.data || {}
......@@ -678,10 +643,8 @@ const loadPolicyholderData = () => {
})
}
// 加载受保人数据
const loadInsuredData = () => {
if (!props.policyBizId) return
// 复用预约页面的受保人查询API
getInsurant(props.policyBizId).then(res => {
if (res.code === 200) {
insuredFormData.value = res.data || {}
......@@ -689,10 +652,8 @@ const loadInsuredData = () => {
})
}
// 加载受益人数据
const loadBeneficiaryData = () => {
if (!props.policyBizId) return
// 复用预约页面的受益人查询API
getBeneficiary(props.policyBizId).then(res => {
if (res.code === 200) {
beneficiaryFormData.value = res.data || {}
......@@ -700,10 +661,8 @@ const loadBeneficiaryData = () => {
})
}
// 加载第二持有人数据
const loadSecondHolderData = () => {
if (!props.policyBizId) return
// 复用预约页面的第二持有人查询API
getSecondHolder(props.policyBizId).then(res => {
if (res.code === 200) {
secondHolderFormData.value = res.data || {}
......@@ -711,10 +670,8 @@ const loadSecondHolderData = () => {
})
}
// 加载预约附件数据
const loadAppointmentAttachmentData = () => {
if (!props.policyBizId) return
// 复用预约页面的附件查询API
getAppointmentFiles({ policyBizId: props.policyBizId }).then(res => {
if (res.code === 200) {
appointmentAttachmentRef.value?.setFileList(res.data || [])
......@@ -722,7 +679,7 @@ const loadAppointmentAttachmentData = () => {
})
}
// ========== 11. 原有方法(保留不变) ==========
// ========== 13. 你已实现的方法(完全保留) ==========
const handleBatchSave = (validRows) => {
console.log('批量提交:', validRows)
introducerTableData.value = validRows
......@@ -733,29 +690,22 @@ const handleSubmit = () => {
formRef.value?.validate(async (valid) => {
if (!valid) return
// 收集所有数据(通用Tab + 自定义Tab
// 收集所有数据(包含产品计划
const submitData = {
policyBizId: props.policyBizId,
// 自定义Tab数据
...basicInfoFormData.value,
...policyInfoFormData.value,
...postalFormData.value,
brokerList: introducerTableData.value,
// 通用Tab数据
...productPlanFormData.value,
policyholder: policyholderFormData.value,
insured: insuredFormData.value,
beneficiary: beneficiaryFormData.value,
secondHolder: secondHolderFormData.value
// 产品计划数据(从ProductPlan组件获取)
productPlan: productPlanRef.value ? productPlanRef.value.getFormData() : {}
}
try {
// 调用新单跟进保存接口
const res = await updatePolicyfollow(submitData)
if (res.code === 200) {
ElMessage.success('保存成功')
emit('saveSuccess', res.data)
// 重置dirty状态
Object.keys(tabDirty.value).forEach(key => tabDirty.value[key] = false)
}
} catch (error) {
......@@ -782,6 +732,11 @@ const getPolicyfollowDetail = () => {
policyInfoFormData.value = { ...transformToFormData(data, policyInfoFormConfig.value) }
postalFormData.value = { ...transformToFormData(data, postalFormConfig.value) }
introducerTableData.value = data.brokerList || []
// 同步更新产品计划的状态参数
policySummeryInfo.value.status = data.status || ''
idsObj.value.fnaBizId = data.fnaBizId || ''
idsObj.value.appointmentBizId = data.appointmentBizId || ''
}
})
}
......@@ -842,21 +797,24 @@ const viewRecordDetail = (e) => {
})
}
// ========== 12. 初始化 ==========
// ========== 14. 初始化(适配ProductPlan参数) ==========
onMounted(async () => {
if (props.modelValue) {
localData.value = { ...defaultFormData(), ...props.modelValue }
}
// 加载新单跟进基础数据
// 初始化idsObj的policyBizId
idsObj.value.policyBizId = props.policyBizId
// 加载基础数据
getPolicyfollowDetail()
// 初始化通用Tab禁用状态
if (props.mode === 'viewDetail') {
// 通用Tab组件禁用
productPlanFormData.value.disabled = true
policyholderFormData.value.disabled = true
insuredFormData.value.disabled = true
beneficiaryFormData.value.disabled = true
secondHolderFormData.value.disabled = true
// 初始化formStatus
formStatus.value = props.mode === 'viewDetail' ? 'view' : 'edit'
})
// 监听props变化,同步更新idsObj
watch(() => props.policyBizId, (newVal) => {
if (newVal) {
idsObj.value.policyBizId = newVal
}
})
......@@ -867,7 +825,7 @@ watch(() => props.modelValue, (newVal) => {
}
}, { deep: true })
// 监听localData变化,同步到父组件
// 监听localData变化
watch(() => localData.value, (newVal) => {
emit('update:modelValue', newVal)
}, { deep: true })
......@@ -920,4 +878,9 @@ watch(() => localData.value, (newVal) => {
padding: 15px 10px;
border-radius: 4px;
}
/* 适配anchorContainer锚点容器样式 */
.appointmentTabPaneBox {
position: relative;
}
</style>
\ No newline at end of file
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