Commit 66ff3719 by Sweet Zhang

新单跟进对接

parent 2c8f3e88
......@@ -216,7 +216,7 @@ function handleUploadSuccess(response, file, fileList, item) {
handleModelChange([...fileList], item)
ElMessage.success(`文件 ${file.name} 上传成功`)
console.log('上传成功', item)
// console.log('上传成功', item)
}
function handleExceed(files, fileList) {
ElMessage.warning('超出文件数量限制')
......@@ -367,7 +367,7 @@ watch(
},
{ immediate: true }
)
console.log('🚀 子组件 props.modelValue 初始值:', props.modelValue)
// console.log('🚀 子组件 props.modelValue 初始值:', props.modelValue)
// 监听 modelValue(用于后续外部更新)
watch(
......@@ -385,8 +385,6 @@ function syncModelFromProps(newModelValue, newConfig) {
if (!newModelValue || !newConfig) return {}
const synced = {}
console.log('newConfig---------------------', newConfig)
console.log('newModelValue---------------------', newModelValue)
// 1. 同步主字段
for (const item of newConfig) {
const key = item.prop
......@@ -466,7 +464,7 @@ function syncModelFromProps(newModelValue, newConfig) {
synced[key] = newModelValue[key]
}
}
console.log('🚀 子组件 props.modelValue 同步后:', synced)
// console.log('🚀 子组件 props.modelValue 同步后:', synced)
return synced
}
function getNestedValue(obj, path) {
......@@ -484,35 +482,35 @@ function markDictLoaded(prop) {
function handleModelChange(value, item) {
console.group('🔄 handleModelChange')
console.log('输入 value:', value)
console.log('item:', item)
console.log('当前 localModel:', localModel.value)
// console.log('输入 value:', value)
// console.log('item:', item)
// console.log('当前 localModel:', localModel.value)
const newModel = { ...localModel.value, [item.prop]: value }
if (item?.type === 'select' && item.onChangeExtraFields) {
const options = getSelectOptions(item)
console.log('可用 options:', options)
// console.log('可用 options:', options)
const opt = options.find(o => o.value === value)
console.log('匹配的 opt:', opt)
// console.log('匹配的 opt:', opt)
if (opt?.raw) {
for (const [targetProp, sourceKey] of Object.entries(item.onChangeExtraFields)) {
const extraValue = opt.raw[sourceKey]
newModel[targetProp] = extraValue
console.log(`✅ 设置 ${targetProp} =`, extraValue)
// console.log(`✅ 设置 ${targetProp} =`, extraValue)
}
}
}
console.log('🆕 newModel:', newModel)
console.log('📦 props.modelValue:', props.modelValue)
console.log('isEqualShallow?', isEqualShallow(props.modelValue, newModel))
// console.log('🆕 newModel:', newModel)
// console.log('📦 props.modelValue:', props.modelValue)
// console.log('isEqualShallow?', isEqualShallow(props.modelValue, newModel))
localModel.value = newModel
nextTick(() => {
if (!isEqualShallow(props.modelValue, newModel)) {
console.log('📤 emit update:modelValue:', newModel)
// console.log('📤 emit update:modelValue:', newModel)
emit('update:modelValue', newModel)
} else {
console.log('🚫 跳过 emit:认为相等')
......
......@@ -152,22 +152,22 @@ watch(drawer, val => {
})
</script>
<style lang="scss" scoped>
::v-deep .el-drawer__header {
:deep(.el-drawer__header ) {
margin-bottom: 0 !important;
}
::v-deep .el-drawer__footer {
:deep(.el-drawer__footer ) {
padding: 0;
}
.addressInput ::v-deep .el-input__wrapper {
.addressInput :deep(.el-input__wrapper ) {
box-shadow: none !important;
}
.addressInput ::v-deep .el-input__inner::placeholder {
.addressInput :deep(.el-input__inner::placeholder ) {
text-align: right;
}
.addressInput ::v-deep .el-input__inner {
.addressInput :deep(.el-input__inner ) {
text-align: right;
}
.addressInput ::v-deep .el-input__wrapper {
.addressInput :deep(.el-input__wrapper ) {
padding: 0 !important;
}
.drawerContent {
......
......@@ -250,17 +250,17 @@ watch(countryDrawer, val => {
})
</script>
<style lang="scss" scoped>
::v-deep .el-drawer__header {
:deep(.el-drawer__header ) {
margin-bottom: 0 !important;
}
.searchInput ::v-deep .el-input__wrapper {
.searchInput :deep(.el-input__wrapper ) {
box-shadow: none !important;
background-color: #fafbfd !important;
}
.searchInput ::v-deep .el-input__inner::placeholder {
.searchInput :deep(.el-input__inner::placeholder ) {
text-align: left !important;
}
.searchInput ::v-deep .el-input__inner {
.searchInput :deep(.el-input__inner ) {
text-align: left !important;
}
.countryContent {
......@@ -339,7 +339,7 @@ watch(countryDrawer, val => {
box-sizing: border-box;
margin-left: 20px;
border-left: 2px solid #d8ebff;
::v-deep(.el-anchor) {
:deep(.el-anchor) {
.el-anchor__link {
padding: 4px 0;
......@@ -354,7 +354,7 @@ watch(countryDrawer, val => {
}
}
}
::v-deep(.el-anchor__marker) {
:deep(.el-anchor__marker) {
height: 10px !important;
left: -6px !important;
border-radius: 50% !important;
......
......@@ -174,22 +174,22 @@ watch(
)
</script>
<style lang="scss" scoped>
::v-deep .el-drawer__header {
:deep(.el-drawer__header ) {
margin-bottom: 0 !important;
}
::v-deep .el-drawer__footer {
:deep(.el-drawer__footer ) {
padding: 0;
}
.phoneInput ::v-deep .el-input__wrapper {
.phoneInput :deep(.el-input__wrapper ) {
box-shadow: none !important;
}
.phoneInput ::v-deep .el-input__inner::placeholder {
.phoneInput :deep(.el-input__inner::placeholder ) {
text-align: right;
}
.phoneInput ::v-deep .el-input__inner {
.phoneInput :deep(.el-input__inner ) {
text-align: right;
}
.phoneInput ::v-deep .el-input__wrapper {
.phoneInput :deep(.el-input__wrapper ) {
padding: 0 !important;
}
.drawerContent {
......
......@@ -529,11 +529,11 @@ const handleSuccess = info => {
getDictsData()
</script>
<style lang="scss" scoped>
::v-deep .el-card {
:deep(.el-card ) {
border: none !important;
}
::v-deep .el-input-group__append,
.el-input-group__prepend {
:deep(.el-input-group__append ),
:deep(.el-input-group__prepend ) {
background-color: #fff !important;
}
......
......@@ -1403,11 +1403,11 @@ onUnmounted(() => {
})
</script>
<style lang="scss" scoped>
::v-deep .el-card {
:deep(.el-card ) {
border: none !important;
}
::v-deep .el-input-group__append,
.el-input-group__prepend {
:deep(.el-input-group__append ),
:deep(.el-input-group__prepend ) {
background-color: #fff !important;
}
.noembed-container {
......
......@@ -177,11 +177,11 @@ if (route.query.type == 'edit') {
getDictsData()
</script>
<style lang="scss" scoped>
::v-deep .el-card {
:deep(.el-card ) {
border: none !important;
}
::v-deep .el-input-group__append,
.el-input-group__prepend {
:deep(.el-input-group__append ),
:deep(.el-input-group__prepend ) {
background-color: #fff !important;
}
......
......@@ -70,7 +70,7 @@
<!-- 查看详情、更新数据 -->
<CommonDialog :dialogTitle='mode === "viewDetail" ? "查看详情" : "更新数据"' dialogWidth='80%' :openDialog=viewDetailDialogFlag :showAction='false'
:showClose='true' @close='viewDetailDialogFlag = false' @confirm='handleUpdateSubmit'>
<PolicyDetail v-model="policyDetailFormData" @submit="onSubmit" @cancel="showDialog = false"/>
<PolicyDetail v-model="policyDetailFormData" ref="policyDetailFormRef" @submit="onSubmit" @cancel="showDialog = false"/>
</CommonDialog>
......@@ -78,7 +78,7 @@
</template>
<script setup>
import { ref, reactive, computed, watch } from 'vue'
import { ref, reactive, computed, watch ,nextTick} from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import CommonPage from '@/components/commonPage'
import SearchForm from '@/components/SearchForm/SearchForm.vue'
......@@ -94,7 +94,7 @@ import {
} from '@/api/sign/underwritingMain'
import PolicyDetail from './policyDetail.vue'
const policyDetailFormRef = ref(null)
const policyDetailFormData = ref({})
const userStore = useUserStore()
// 分页相关
......@@ -267,7 +267,6 @@ const searchConfig = ref([
labelKey: 'abbreviation',
multiple: true,
transform: (res) => {
console.log(res)
return res?.data.records || []
}
}, {
......@@ -303,7 +302,7 @@ const searchConfig = ref([
const loadTableData = async () => {
loading.value = true
searchParams.value = searchFormRef.value.getFormData() || {}
console.log(searchParams.value)
// console.log(searchParams.value)
try {
const params = {
...searchParams.value,
......@@ -343,9 +342,12 @@ const handleSelect = async (e, row) => {
case 'viewDetail':
// ElMessage.info('查看详情')
viewDetailDialogFlag.value = true
policyDetailFormData.value = JSON.parse(JSON.stringify(selectedRow.value))
// 赋值已有数据(深拷贝避免引用问题)
// Object.assign(formData, JSON.parse(JSON.stringify(mockEditData)))
// 等待 DOM 更新完成
await nextTick()
if(policyDetailFormRef.value) {
// 调用子组件详情查询接口
const data = await policyDetailFormRef.value.getPolicyfollowDetail(row.policyBizId)
}
break
case 'updateData':
ElMessage.info('更新数据')
......
......@@ -93,13 +93,13 @@
v-model="firstPremiumFormData" />
<h3 class="sectionTitle">首期对账信息</h3>
<el-table :data="firstPremiumTableData" border style="width: 100%">
<el-table-column prop="date" label="申请对账日期" width="180" />
<el-table-column prop="name" label="对账状态" width="180" />
<el-table-column prop="address" label="缴费方式" width="180" />
<el-table-column prop="address" label="汇款币种" width="180" />
<el-table-column prop="address" label="汇款日期" width="180" />
<el-table-column prop="address" label="认定金额" width="180" />
<el-table-column prop="address" label="认定币种" width="180" />
<el-table-column prop="createTime" label="申请对账日期" width="180" />
<el-table-column prop="reconciliationStatus" label="对账状态" width="180" />
<el-table-column prop="paymentMethod" label="缴费方式" width="180" />
<el-table-column prop="paymentAmount" label="汇款金额" width="180" />
<el-table-column prop="paymentCurrency" label="汇款币种" width="180" />
<el-table-column prop="recognizedAmount" label="认定金额" width="180" />
<el-table-column prop="recognizedCurrency" label="认定币种" width="180" />
</el-table>
</div>
</div>
......@@ -145,6 +145,7 @@
<h3 class="sectionTitle">关联记录</h3>
<el-table :data="relatedTableData" border style="width: 100%">
<el-table-column prop="date" label="流程编号" width="180" />
<el-table-column prop="policyNo" label="保单号" width="180" />
<el-table-column prop="name" label="客户姓名" width="180" />
<el-table-column prop="address" label="创建时间" width="180" />
<el-table-column fixed="right" label="操作" min-width="120">
......@@ -201,6 +202,8 @@ import { ref, reactive, watch, nextTick, onMounted } from 'vue'
import SearchForm from '@/components/SearchForm/SearchForm.vue'
import { Delete, Edit, Search, Share, Upload } from '@element-plus/icons-vue'
import { getPolicyfollow, updatePolicyfollow, saveMailingInfo, batchSaveBrokers, saveInitialPayment } from '@/api/sign/underwritingMain'
import { premiumReconciliationList } from '@/api/sign/policy'
import { loadDicts, getDictLabel } from '@/utils/useDict'
const basicInfoFormRef = ref()
const basicInfoFormData = ref({})
const basicInfoFormConfig = ref([
......@@ -277,6 +280,7 @@ const policyInfoFormConfig = ref([
type: 'select',
prop: 'directPaymentEnabled',
label: '是否开通直接支付',
dictType: 'sys_no_yes'
}, {
type: 'input',
prop: 'policyHolder',
......@@ -323,7 +327,7 @@ const basicPlanFormConfig = ref([
}
}, {
type: 'select',
prop: 'paymentFrequency',
prop: 'productCate',
label: '保险险种',
}, {
type: 'select',
......@@ -572,7 +576,9 @@ const deleteRow = (index) => {
}
const handleTabClick = (tab) => {
console.log('切换到 Tab:', tab.name)
if (tab.props.name === 'firstPayment') {
getPremiumReconciliationList(localData.value.policyNo)
}
}
const handleSubmit = () => {
......@@ -612,6 +618,11 @@ const getPolicyfollowDetail = (policyBizId) => {
basicPlanFormData.value = transformToFormData(res.data, basicPlanFormConfig.value);
basicInfoFormData.value = transformToFormData(res.data, basicInfoFormConfig.value);
firstPremiumFormData.value = transformToFormData(res.data, firstPremiumFormConfig.value);
console.log('policyInfoFormData', policyInfoFormData.value)
console.log('basicPlanFormData', basicPlanFormData.value)
console.log('basicInfoFormData', basicInfoFormData.value)
console.log('firstPremiumFormData', firstPremiumFormData.value)
}
})
}
......@@ -620,29 +631,65 @@ const getPolicyfollowDetail = (policyBizId) => {
const transformToFormData = (apiData, formConfig) => {
const formData = {};
// 遍历表单配置,逐个赋值
formConfig.forEach(item => {
const { prop } = item;
const { prop, dictType } = item;
// 根据 prop 决定如何从 apiData 取值
switch (prop) {
let value = null;
// 特殊映射(按需添加)
switch (prop) {
case 'signLocation':
formData[prop] = apiData.signLocation || null;
value = apiData.signLocation;
break;
default:
// 如果 prop 和后端字段同名,可以直接赋值
formData[prop] = apiData[prop] ?? null;
value = apiData[prop];
}
// 处理字典字段:如果配置了 dictType,且值是 number,转为 string
if (dictType && typeof value === 'number') {
value = String(value);
}
formData[prop] = value ?? null;
});
return formData;
};
// 获取首期保费对账列表
const getPremiumReconciliationList = (policyNo) => {
// if (!policyNo) {
// return
// }
const params = {
policyNo: policyNo,
pageNo: 1,
pageSize: 100,
}
premiumReconciliationList(params).then(res => {
if (res.code === 200) {
firstPremiumTableData.value = res.data.records || []
console.log('premiumReconciliationList', res.data)
// premiumReconciliationListData.value = res.data || []
}
})
}
// 页面加载时调用
onMounted(() => {
getPolicyfollowDetail(localData.value.policyBizId)
onMounted(async () => {
try {
await loadDicts(['sys_no_yes', 'csf_ap_frequency', 'bx_currency_type', 'csf_ap_first_issue', 'csf_ap_dividend', 'csf_fortune_status', 'csf_ap_mailing_method', 'receipt_status'])
} catch (error) {
console.error('字典加载失败', error)
} finally {
}
})
defineExpose({
getPolicyfollowDetail
})
</script>
<style scoped>
......
......@@ -1226,20 +1226,20 @@ getUserList()
}
/* 选项卡头部:消除默认样式,重构凹陷效果 */
::v-deep .el-tabs__header {
:deep(.el-tabs__header ) {
line-height: 1; /* 重置行高,避免影响高度计算 */
padding: 0; /* 清除默认内边距 */
}
/* 选项卡导航容器:核心凹陷逻辑 */
::v-deep .el-tabs__nav {
:deep(.el-tabs__nav ) {
display: flex;
margin: 0; /* 清除默认 margin */
border-bottom: 1px solid var(--border-color); /* 底部边框 */
}
/* 选项卡 item 基础样式 */
::v-deep .el-tabs__item {
:deep(.el-tabs__item ) {
position: relative;
padding: 12px 24px;
margin-right: 0; /* 清除默认间距 */
......@@ -1253,7 +1253,7 @@ getUserList()
}
/* 激活态:凹陷 + 高亮 */
::v-deep .el-tabs__item.is-active {
:deep(.el-tabs__item.is-active ) {
color: var(--active-tab-color);
background-color: var(--active-tab-bg);
/* 上、左、右边框 + 底部无边框,模拟“凹陷” */
......@@ -1266,23 +1266,23 @@ getUserList()
}
/* 未激活态:悬浮效果 */
::v-deep .el-tabs__item:not(.is-active):hover {
:deep(.el-tabs__item:not(.is-active):hover ) {
color: #409eff;
background-color: #eaf2ff;
}
/* 左侧边框处理(仅第一个 tab 左侧圆角) */
::v-deep .el-tabs__item:first-child {
:deep(.el-tabs__item:first-child ) {
border-top-left-radius: var(--radius);
}
/* 右侧边框处理(仅最后一个 tab 右侧圆角) */
::v-deep .el-tabs__item:last-child {
:deep(.el-tabs__item:last-child ) {
border-top-right-radius: var(--radius);
}
/* 激活态:覆盖父容器的底部边框,实现“凹陷” */
::v-deep .el-tabs__item.is-active::before {
:deep(.el-tabs__item.is-active::before ) {
content: "";
position: absolute;
bottom: -1px; /* 覆盖父容器的 border-bottom */
......@@ -1293,7 +1293,7 @@ getUserList()
}
/* 内容区域:和选项卡无缝衔接 */
::v-deep .el-tabs__content {
:deep(.el-tabs__content ) {
padding: 20px;
background-color: #fff;
border: 1px solid var(--border-color);
......
......@@ -1617,20 +1617,20 @@ getList()
}
/* 选项卡头部:消除默认样式,重构凹陷效果 */
::v-deep .el-tabs__header {
:deep(.el-tabs__header ) {
line-height: 1; /* 重置行高,避免影响高度计算 */
padding: 0; /* 清除默认内边距 */
}
/* 选项卡导航容器:核心凹陷逻辑 */
::v-deep .el-tabs__nav {
:deep(.el-tabs__nav ) {
display: flex;
margin: 0; /* 清除默认 margin */
border-bottom: 1px solid var(--border-color); /* 底部边框 */
}
/* 选项卡 item 基础样式 */
::v-deep .el-tabs__item {
:deep(.el-tabs__item ) {
position: relative;
padding: 12px 24px;
margin-right: 0; /* 清除默认间距 */
......@@ -1644,7 +1644,7 @@ getList()
}
/* 激活态:凹陷 + 高亮 */
::v-deep .el-tabs__item.is-active {
:deep(.el-tabs__item.is-active ) {
color: var(--active-tab-color);
background-color: var(--active-tab-bg);
/* 上、左、右边框 + 底部无边框,模拟“凹陷” */
......@@ -1657,23 +1657,23 @@ getList()
}
/* 未激活态:悬浮效果 */
::v-deep .el-tabs__item:not(.is-active):hover {
:deep(.el-tabs__item:not(.is-active):hover ) {
color: #409eff;
background-color: #eaf2ff;
}
/* 左侧边框处理(仅第一个 tab 左侧圆角) */
::v-deep .el-tabs__item:first-child {
:deep(.el-tabs__item:first-child ) {
border-top-left-radius: var(--radius);
}
/* 右侧边框处理(仅最后一个 tab 右侧圆角) */
::v-deep .el-tabs__item:last-child {
:deep(.el-tabs__item:last-child ) {
border-top-right-radius: var(--radius);
}
/* 激活态:覆盖父容器的底部边框,实现“凹陷” */
::v-deep .el-tabs__item.is-active::before {
:deep(.el-tabs__item.is-active::before ) {
content: '';
position: absolute;
bottom: -1px; /* 覆盖父容器的 border-bottom */
......@@ -1684,7 +1684,7 @@ getList()
}
/* 内容区域:和选项卡无缝衔接 */
::v-deep .el-tabs__content {
:deep(.el-tabs__content ) {
padding: 20px;
background-color: #fff;
border: 1px solid var(--border-color);
......
......@@ -375,10 +375,10 @@ const gap = ref('10px')
</script>
<style lang="scss" scoped>
::v-deep .el-card {
:deep(.el-card ) {
border: none !important;
}
::v-deep .el-carousel__button {
:deep(.el-carousel__button ) {
width: 10px !important ;
}
.app-container {
......
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