Commit de175da7 by Sweet Zhang

Merge branch 'test' into dev

parents 14446ff2 dd858657
......@@ -579,7 +579,7 @@ async function loadRemoteOptionsForInit(item) {
// ==================== 加载远程 API 选项(首次 focus 时加载,无搜索词) ====================
async function loadRemoteOptions(item) {
const { prop, api, requestParams, keywordField, debounceWait, ...rest } = item
if (!api || remoteOptions.value[prop]?.length > 0) return
if (!api ) return
try {
remoteLoading.value[prop] = true
......@@ -728,6 +728,43 @@ defineExpose({
})
localModel.value = { ...resetData }
nextTick(() => formRef.value?.clearValidate())
},
// ✅ 新增:强制刷新某个字段的远程选项
async refreshRemoteOptions(targetProp) {
console.log(`[SearchForm] 收到刷新请求: ${targetProp}`)
// 1. 查找配置项
const item = internalConfig.value.find(i => i.prop === targetProp)
if (!item) {
console.warn(`[SearchForm] 未找到 prop 为 ${targetProp} 的配置项`)
return
}
if (item.type !== 'select' || !item.api) {
console.warn(`[SearchForm] 字段 ${targetProp} 不是远程 Select 或没有 API`)
return
}
console.log(`[SearchForm] 开始强制加载 ${targetProp} 的数据,API: ${item.api}`)
// 2. 关键:在调用前,先清空旧数据,防止子组件内部的 "已加载则跳过" 逻辑生效
// 如果你的 loadRemoteOptions 里有 "if (remoteOptions.value[prop]?.length > 0) return"
// 这里必须先清空
remoteOptions.value[targetProp] = []
remoteLoading.value[targetProp] = true // 手动开启 loading
try {
// 3. 调用内部加载函数
// 注意:直接调用 loadRemoteOptions,它会读取最新的 requestParams
await loadRemoteOptions(item)
console.log(`[SearchForm] ${targetProp} 加载完成`)
} catch (error) {
console.error(`[SearchForm] ${targetProp} 加载失败`, error)
throw error
} finally {
remoteLoading.value[targetProp] = false
}
}
})
</script>
......
......@@ -215,23 +215,24 @@ const detailDialogVisible = ref(false)
// 应付明细列表
const payableReportListTableColumns = ref([
{ prop: 'fortuneBizType', label: '应付款类型', sortable: true, width: '120', formatter: (row) => getFortuneBizTypeLabel(row.fortuneBizType) || '-' },
{ prop: 'payableNo', label: '应付账款编号', sortable: true, width: '120', formatter: (row) => row.payableNo || '-' },
{ prop: 'policyNo', label: '保单号', sortable: true, width: '120', formatter: (row) => row.policyNo || '-' },
// { prop: 'fortuneBizType', label: '应付款类型', sortable: true, width: '120', formatter: (row) => getFortuneBizTypeLabel(row.fortuneBizType) || '-' },
// { prop: 'payableNo', label: '应付账款编号', sortable: true, width: '120', formatter: (row) => row.payableNo || '-' },
{ prop: 'policyNo', label: '保单号', sortable: true, width: '130', formatter: (row) => row.policyNo || '-' },
{ prop: 'broker', label: '转介人', sortable: true, width: '120', formatter: (row) => row.broker || '-' },
{ prop: 'fortuneName', label: '出账项目', sortable: true, width: '120', formatter: (row) => row.fortuneName || '-' },
{ prop: 'status', label: '出账状态', sortable: true, width: '120', formatter: (row) => getDictLabel('csf_expected_fortune_status', row.status) || '-' },
{ prop: 'currency', label: '出账币种', sortable: true, width: '120', formatter: (row) => row.currency || '-' },
{ prop: 'fortunePeriod', label: '出账期数', sortable: true, width: '120', formatter: (row) => row.fortunePeriod || '-' },
{ prop: 'fortuneTotalPeriod', label: '出账总期数', sortable: true, width: '120', formatter: (row) => row.fortuneTotalPeriod || '-' },
{ prop: 'currency', label: '出账币种', sortable: true, width: '100', formatter: (row) => row.currency || '-' },
{ prop: 'fortunePeriod', label: '出账期数', sortable: true, width: '100', formatter: (row) => row.fortunePeriod || '-' },
{ prop: 'fortuneTotalPeriod', label: '出账总期数', sortable: true, width: '100', formatter: (row) => row.fortuneTotalPeriod || '-' },
{ prop: 'payoutDate', label: '出账日(估)', sortable: true, width: '120', formatter: (row) => row.payoutDate || '-' },
{ prop: 'actualPayoutDate', label: '出账日(实)', sortable: true, width: '120', formatter: (row) => row.actualPayoutDate || '-' },
{ prop: 'commissionRatio', label: '出账比例', sortable: true, width: '120', formatter: (row) => (row.commissionRatio || 0) + '%' || '-' },
{ prop: 'amount', label: '应出账金额(估)', sortable: true, width: '120', formatter: (row) => formatCurrency(row.amount || 0) },
{ prop: 'commissionRatio', label: '发佣率(对应职级)', sortable: true, width: '120', formatter: (row) => (row.commissionRatio || 0) + '%' || '-' },
{ prop: 'hkdAmount', label: '应出账金额(估)', sortable: true, width: '120', formatter: (row) => formatCurrency(row.hkdAmount || 0) },
{ prop: 'paidRatio', label: '已出账比例', sortable: true, width: '120', formatter: (row) => (row.paidRatio || 0) + '%' || '-' },
{ prop: 'paidAmount', label: '已出账金额', sortable: true, width: '120', formatter: (row) => formatCurrency(row.paidAmount || 0) },
{ prop: 'unpaidRatio', label: '待出账比例', sortable: true, width: '120', formatter: (row) => (row.unpaidRatio || 0) + '%' || '-' },
{ prop: 'unpaidAmount', label: '待出账金额(估)', sortable: true, width: '120', formatter: (row) => formatCurrency(row.unpaidAmount || 0) },
{ prop: 'brokerRatio', label: '持有比例', sortable: true, width: '120', formatter: (row) => (row.brokerRatio || 0) + '%' || '-' },
{ prop: 'brokerRatio', label: '持有比例', sortable: true, width: '100', formatter: (row) => (row.brokerRatio || 0) + '%' || '-' },
{ prop: 'premium', label: '期交保费', sortable: true, width: '120', formatter: (row) => formatCurrency(row.premium || 0) },
{ prop: 'insuranceCompany', label: '保险公司', sortable: true, width: '120', formatter: (row) => row.insuranceCompany || '-' },
{ prop: 'productName', label: '产品计划', sortable: true, width: '120', formatter: (row) => row.productName || '-' },
......
......@@ -32,7 +32,7 @@
<!-- 应收款管理列表 -->
<el-table :data="tableData" height="400" border highlight-current-row style="width: 100%"
v-loading="loading">
<el-table-column v-for="(column, index) in receivableReportTableColumns" :key="index"
<el-table-column v-for="(column, index) in receivableReportTableColumns" :key="index" :fixed="column.fixed"
:prop="column.prop" :label="column.label" :width="column.width" :sortable="column.sortable"
:formatter="column.formatter" />
<el-table-column fixed="right" label="操作" min-width="120">
......@@ -106,7 +106,7 @@
</div>
<el-table :data="receivableReportTableData" border style="width: 100%;margin-bottom: 10px;min-height: 300px;">
<el-table-column v-for="item in receivableReportItemTableColumns" :key="item.property" :prop="item.prop"
:label="item.label" :width="item.width" />
:label="item.label" :width="item.width" :formatter="item.formatter" />
<el-table-column fixed="right" label="操作" min-width="120">
<template #default="{ row }">
<el-popover placement="right" :width="200" trigger="click">
......@@ -744,13 +744,13 @@ onMounted(async () => {
}
})
// 格式化函数(每次渲染都会调用,所以能拿到最新字典)
const formatStatus = (row, column) => {
const formatStatus = (row,column) => {
return getDictLabel('csf_expected_commission_status', row.status) // 实时查缓存
}
const detailDialogVisible = ref(false)
const receivableReportTableData = ref([])
const receivableReportTableColumns = ref([
{ prop: 'policyNo', label: '保单号', sortable: true, width: '150', formatter: (row) => row.policyNo || '-' },
{ prop: 'policyNo', label: '保单号', sortable: true, width: '150',fixed:'left', formatter: (row) => row.policyNo || '-' },
{ prop: 'reconciliationCompany', label: '对账公司', sortable: true, width: '150', formatter: (row) => row.reconciliationCompany || '-' },
{ prop: 'commissionPeriod', label: '入账期数', sortable: true, width: '120', formatter: (row) => row.commissionPeriod || '-' },
{ prop: 'totalPeriod', label: '入账总期数', sortable: true, width: '120', formatter: (row) => row.totalPeriod || '-' },
......@@ -761,10 +761,10 @@ const receivableReportTableColumns = ref([
{ prop: 'paidAmount', label: '已入账金额HKD', sortable: true, width: '120', formatter: (row) => formatCurrency(row.paidAmount || 0) },
{ prop: 'unpaidRatio', label: '待入账比例', sortable: true, width: '120', formatter: (row) => (row.unpaidRatio || 0) + '%' || '-' },
{ prop: 'unpaidAmount', label: '待入账金额HKD', sortable: true, width: '120', formatter: (row) => formatCurrency(row.unpaidAmount || 0) },
{ prop: 'exchangeRate', label: '结算汇率(估)', sortable: true, width: '120', formatter: (row) => formatCurrency(row.exchangeRate || 0) },
{ prop: 'exchangeRate', label: '结算汇率(估)', sortable: true, width: '120'},
{ prop: 'insuranceCompany', label: '保险公司', sortable: true, width: '120', formatter: (row) => row.insuranceCompany || '-' },
{ prop: 'productName', label: '产品计划', sortable: true, width: '120', formatter: (row) => row.productName || '-' },
{ prop: 'premium', label: '期交保费', sortable: true, width: '120', formatter: (row) => row.productName || '-' },
{ prop: 'premium', label: '期交保费', sortable: true, width: '120', formatter: (row) => row.premium || '-' },
{ prop: 'policyCurrency', label: '保单币种', sortable: true, width: '120', formatter: (row) => row.policyCurrency || '-' },
])
const receivableReportItemTableColumns = ref([
......@@ -772,7 +772,7 @@ const receivableReportItemTableColumns = ref([
{ prop: 'receivableNo', label: '应收款编号', sortable: true, width: '150', formatter: (row) => row.receivableNo || '-' },
{ prop: 'policyNo', label: '保单号', sortable: true, width: '150', formatter: (row) => row.policyNo || '-' },
{ prop: 'reconciliationCompany', label: '对账公司', sortable: true, width: '150', formatter: (row) => row.reconciliationCompany || '-' },
{ prop: 'status', label: '入账状态', sortable: true, width: '120', formatter: (row) => formatStatus(row.status) || '-' },
{ prop: 'status', label: '入账状态', sortable: true, width: '120', formatter: (row) => formatStatus(row) || '-' },
{ prop: 'commissionPeriod', label: '入账期数', sortable: true, width: '120', formatter: (row) => row.commissionPeriod || '-' },
{ prop: 'totalPeriod', label: '入账总期数', sortable: true, width: '120', formatter: (row) => row.totalPeriod || '-' },
{ prop: 'commissionName', label: '入账项目', sortable: true, width: '130', formatter: (row) => row.commissionName || '-' },
......@@ -783,7 +783,7 @@ const receivableReportItemTableColumns = ref([
{ prop: 'paidAmount', label: '已入账金额', sortable: true, width: '120', formatter: (row) => formatCurrency(row.paidAmount || 0) },
{ prop: 'pendingRatio', label: '待入账比例', sortable: true, width: '120', formatter: (row) => (row.pendingRatio || 0) + '%' || '-' },
{ prop: 'pendingAmount', label: '待入账金额', sortable: true, width: '120', formatter: (row) => formatCurrency(row.pendingAmount || 0) },
{ prop: 'defaultExchangeRate', label: '结算汇率(估)', sortable: true, width: '120', formatter: (row) => formatCurrency(row.defaultExchangeRate || 0) },
{ prop: 'defaultExchangeRate', label: '结算汇率(估)', sortable: true, width: '120'},
{ prop: 'insuranceCompany', label: '保险公司', sortable: true, width: '120', formatter: (row) => row.insuranceCompany || '-' },
{ prop: 'productName', label: '产品计划', sortable: true, width: '120', formatter: (row) => row.productName || '-' },
{ prop: 'premium', label: '期交保费', sortable: true, width: '120', formatter: (row) => formatCurrency(row.premium || 0) },
......
......@@ -593,8 +593,6 @@ const remittanceConfig = [
validator: (rule, value, callback) => {
if (value === '' || value == null) {
callback(new Error('请输入付款金额'))
} else if (!/^\d+$/.test(String(value))) {
callback(new Error('只能输入正整数'))
} else {
callback()
}
......@@ -636,7 +634,7 @@ const remittanceConfig = [
label: '付款银行',
api: '/base/api/bank/page',
keywordField: 'policyNo',
requestParams: { pageNo: 1, pageSize: 20 },
requestParams: { pageNo: 1, pageSize: 50 },
debounceWait: 500, // 自定义防抖时间
valueKey: 'bankBizId',
......
......@@ -45,7 +45,7 @@
</CommonPage>
<!-- 弹窗-->
<CommonDialog dialogTitle='修改状态' dialogWidth='80%' :openDialog=editStatusDialogFlag :showAction='true'
:showClose='true' @close='editStatusDialogFlag = false' @confirm='handleEditStatusSubmit'>
:showClose='true' @close='editStatusDialogFlag = false' @confirm='handleEditStatusSubmit' v-loading="statusLoading">
<SearchForm ref="editStatusFormRef" :config="editStatusFormConfig" v-model="editStatusFormData" />
</CommonDialog>
......@@ -69,7 +69,7 @@
<!-- 查看详情、更新数据 -->
<CommonDialog :dialogTitle='mode === "viewDetail" ? "查看详情" : "更新数据"' dialogWidth='80%'
:openDialog=viewDetailDialogFlag :showAction='false' :showClose='true' @close='viewDetailDialogFlag = false'
:openDialog=viewDetailDialogFlag :showAction='false' :showClose='true' @close='viewDetailDialogFlag=false'
@confirm='handleUpdateSubmit'>
<PolicyDetail v-model="policyDetailFormData" :policyBizId="selectedRow.policyBizId" :mode="mode"
ref="policyDetailFormRef" @submit="onSubmit" @cancel="viewDetailDialogFlag = false"
......@@ -82,7 +82,7 @@
<script setup>
import { ref, reactive, computed, watch, nextTick } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { ElMessage, ElMessageBox } from 'element-plus'
import CommonPage from '@/components/commonPage'
import SearchForm from '@/components/SearchForm/SearchForm.vue'
import CommonDialog from '@/components/commonDialog'
......@@ -94,7 +94,7 @@ import {
getExpectedCommissionList,
changePolicyStatus,
policyFollowReport,
saveMailingInfo, updatePolicyfollow, batchSaveBrokers, saveInitialPayment
saveMailingInfo, updatePolicyfollow, batchSaveBrokers, saveInitialPayment,updatePolicyProduct
} from '@/api/sign/underwritingMain'
import PolicyDetail from './policyDetail.vue'
......@@ -106,11 +106,13 @@ const currentPage = ref(1)
const pageSize = ref(10)
const pageTotal = ref(0)
const loading = ref(false)
const statusLoading = ref(false)
// 搜索表单数据
const searchFormData = reactive({})
const selectedRow = ref(null)
// 弹窗相关
const editStatusDialogFlag = ref(false)
// 修改状态
const editStatusFormData = ref({})
const editStatusFormRef = ref(null)
......@@ -139,6 +141,7 @@ const viewRelatedDetail = (row) => {
}
// 提交修改状态
const handleEditStatusSubmit = async () => {
statusLoading.value = true;
try {
await editStatusFormRef.value.validate()
const res = await changePolicyStatus({
......@@ -146,13 +149,16 @@ const handleEditStatusSubmit = async () => {
...editStatusFormData.value
})
if (res.code === 200) {
statusLoading.value = false;
ElMessage.success('修改状态成功')
editStatusDialogFlag.value = false
loadTableData()
} else {
statusLoading.value = false;
ElMessage.error(res.msg || '修改状态失败')
}
} catch (error) {
statusLoading.value = false;
console.error('修改状态失败', error)
}
}
......@@ -177,7 +183,7 @@ const onSubmit = async (data) => {
} else {
ElMessage.error(res.msg || '保存邮寄信息失败')
}
} else if (data.activeTab === 'basic' || data.activeTab === 'productPlan') {
} else if (data.activeTab === 'basic') {
params = {
policyBizId: selectedRow.value.policyBizId,
...data,
......@@ -186,10 +192,25 @@ const onSubmit = async (data) => {
const res = await updatePolicyfollow(params)
if (res.code === 200) {
ElMessage.success(data.activeTab === 'basic' ? '保存基本信息成功' : '保存产品计划成功')
loadTableData()
// viewDetailDialogFlag.value = false
} else {
ElMessage.error(res.msg || (data.activeTab === 'basic' ? '保存基本信息失败' : '保存产品计划失败'))
}
} else if (data.activeTab === 'productPlan') {
params = {
policyBizId: selectedRow.value.policyBizId,
...data,
activeTab: undefined
}
const res = await updatePolicyProduct(params)
if (res.code === 200) {
ElMessage.success('保存产品计划成功')
loadTableData()
// viewDetailDialogFlag.value = false
} else {
ElMessage.error(res.msg || ('保存产品计划失败'))
}
} else if (data.activeTab === 'introducer') {
params = {
policyBizId: selectedRow.value.policyBizId,
......
......@@ -6,7 +6,7 @@
<el-tabs v-model="activeTab" @tab-click="handleTabClick" :before-leave="handleBeforeLeave">
<el-tab-pane label="基础信息" name="basic"></el-tab-pane>
<el-tab-pane label="产品计划" name="productPlan"></el-tab-pane>
<el-tab-pane label="首期缴费" name="firstPayment"></el-tab-pane>
<!-- <el-tab-pane label="首期缴费" name="firstPayment"></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="related"></el-tab-pane>
......@@ -51,7 +51,7 @@
</div>
<!-- 附加计划(可编辑表格) -->
<div class="section">
<!-- <div class="section">
<h3 class="sectionTitle">附加计划</h3>
<EditableTable
v-model="localData.additionalPlans"
......@@ -59,11 +59,10 @@
@batch-save="handleBatchSave"
:disabled="props.mode === 'viewDetail'"
/>
</div>
</div> -->
</div>
<!-- 首期缴费 Tab 内容 -->
<div v-else-if="activeTab === 'firstPayment'" class="tab-content">
<!-- 签单信息 -->
<div class="section">
<h3 class="sectionTitle">缴费信息</h3>
<SearchForm
......@@ -498,7 +497,8 @@ const policyInfoFormConfig = ref([
reconciliationCompany: 'name',
reconciliationCode:'code',
}
},
rules: [{ required: true, message: '请选择出单经纪公司', trigger: 'blur' }],
},
{
type: 'input',
......@@ -613,11 +613,11 @@ const basicPlanFormConfig = ref([
{
type: 'select',
prop: 'productCate',
label: '保险险种',
label: '保险种类',
api: '/insurance/base/api/insuranceCategory/page',
keywordField: 'name',
requestParams: { pageNo: 1, pageSize: 20 },
placeholder: '输入保险险种名称搜索',
placeholder: '输入保险种类名称搜索',
debounceWait: 500, // 自定义防抖时间
valueKey: 'insuranceCategoryBizId',
labelKey: 'name',
......@@ -650,7 +650,7 @@ const basicPlanFormConfig = ref([
valueKey: 'productName',
labelKey: 'productName',
transform: res => {
console.log('======子组件选择选项后,父组件接收的值 :', res?.data.records || [])
console.log('======子组件选择选项后,父组件接收的值产品名称:', res?.data.records || [])
return res?.data.records || []
},
onChangeExtraFields: {
......@@ -668,6 +668,12 @@ const basicPlanFormConfig = ref([
},
{
type: 'input',
prop: 'issueNumber',
label: '供款期数',
inputType: 'decimal'
},
{
type: 'input',
prop: 'guaranteePeriod',
label: '保障期限'
},
......@@ -677,12 +683,6 @@ const basicPlanFormConfig = ref([
label: '保额(重疾险)'
},
{
type: 'input',
prop: 'issueNumber',
label: '供款期数',
inputType: 'decimal'
},
{
type: 'select',
prop: 'policyCurrency',
label: '保单币种',
......@@ -694,7 +694,6 @@ const basicPlanFormConfig = ref([
label: '每期保费',
inputType: 'decimal',
decimalDigits: 2,
visible: formData => formData.commissionBizType == 'R',
rules: [
{ required: true, message: '请输入金额', trigger: 'blur' },
{ pattern: /^\d+(\.\d{1,2})?$/, message: '最多两位小数', trigger: 'blur' }
......@@ -706,7 +705,6 @@ const basicPlanFormConfig = ref([
label: '保单征费',
inputType: 'decimal',
decimalDigits: 2,
visible: formData => formData.commissionBizType == 'R',
rules: [
{ required: true, message: '请输入金额', trigger: 'blur' },
{ pattern: /^\d+(\.\d{1,2})?$/, message: '最多两位小数', trigger: 'blur' }
......@@ -719,6 +717,13 @@ const basicPlanFormConfig = ref([
dictType: 'sys_no_yes'
},
{
type: 'input',
prop: 'prepaymentPeriod',
label: '预缴年期',
inputType: 'decimal',
visible: formData => formData.isPrepay == '1'
},
{
type: 'select',
prop: 'isTraceable',
label: '是否追溯',
......@@ -727,7 +732,8 @@ const basicPlanFormConfig = ref([
{
type: 'date',
prop: 'retroactiveDate',
label: '回溯日期'
label: '回溯日期',
visible: formData => formData.isTraceable == '1'
},
{
type: 'select',
......@@ -1199,21 +1205,47 @@ const viewRecordDetail = e => {
})
}
const handleSelectChange = async (prop, value, item, type) => {
await nextTick()
// console.log('======子组件选择选项后,父组件接收的值 :', basicPlanFormData.value)
console.log('🔔 父组件收到 selectChange:', prop, value, type)
await nextTick() // 确保 DOM 和响应式数据更新
if (type === 'basicPlan') {
const params = {
tenantBizId: userStore.projectInfo.tenantBizId,
projectBizId: userStore.projectInfo.projectBizId,
fieldBizId: 'field_olk1qZe81qHHKXbw',
fieldValueBizId: 'field_value_uOfJH5ucA2YwJpbn',
insuranceCompanyBizIdList: [basicPlanFormData.value.insuranceCompanyBizId],
categoryCodeList: [basicPlanFormData.value.insuranceCategoryCode],
pageNo: 1,
pageSize: 100
// 只有当改变的是“保险公司”时,才刷新“产品名称”
if (prop === 'insuranceCompanyBizId') {
console.log('🔄 检测到保险公司变更,准备刷新产品列表...')
// 1. 检查 Ref 是否存在
if (!basicPlanFormRef.value) {
console.error('❌ basicPlanFormRef 为空,无法调用方法')
return
}
// 2. 检查方法是否存在
if (typeof basicPlanFormRef.value.refreshRemoteOptions !== 'function') {
console.error('❌ refreshRemoteOptions 方法未暴露或不存在')
console.log('当前暴露的方法:', Object.keys(basicPlanFormRef.value))
return
}
try {
// 3. 可选:先清空产品字段的值,避免选中了旧公司的产品
basicPlanFormData.value.productName = ''
basicPlanFormData.value.productLaunchBizId = ''
basicPlanFormData.value.insuranceCategoryCode = '' // 如果分类也依赖公司,可能也要清空
console.log('🚀 正在调用子组件 refreshRemoteOptions...')
// 4. 调用刷新
await basicPlanFormRef.value.refreshRemoteOptions('productName')
console.log('✅ 产品列表刷新指令执行完毕')
// ElMessage.success('产品列表已更新')
} catch (err) {
console.error('💥 刷新产品列表出错:', err)
ElMessage.error('产品列表更新失败,请重试')
}
}
console.log('====父组件拿到值,去调用产品列表查询接口', params)
getProductLists(params)
}
}
......
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