Commit 77e2d6d1 by yuzhenWang

切换分支

parent 26ba6893
......@@ -161,3 +161,11 @@ export function searchScopeList(data) {
data: data
})
}
// 得到计算值
export function calculateFieldValue(data) {
return request({
url: '/csf/api/common/calculate/fieldValue',
method: 'post',
data: data
})
}
<template>
<div>
<el-affix :offset="affixOffset">
<el-anchor
:direction="direction"
:type="type"
:offset="anchorOffset"
@click="handleAnchorClick"
>
<el-anchor-link
v-for="item in anchorList"
:href="'#' + item.title"
:title="item.name"
@click="e => handleLinkClick(e, item.title)"
/>
</el-anchor>
</el-affix>
</div>
</template>
<script setup>
import { ref, onMounted, getCurrentInstance } from 'vue'
const props = defineProps({
direction: {
type: String,
default: 'vertical'
},
type: {
type: String,
default: 'default'
},
anchorOffset: {
type: Number,
default: 30
},
affixOffset: {
type: Number,
default: 60
},
anchorList: {
type: Array,
default: () => {
return []
}
},
// 新增:滚动容器的选择器
scrollContainerSelector: {
type: String,
default: ''
},
// 新增:滚动到元素时额外的偏移量
scrollOffset: {
type: Number,
default: 0
},
domIndex: {
type: Number,
default: 1
}
})
const emit = defineEmits(['anchor-click'])
// 处理锚点点击
const handleAnchorClick = e => {
// 阻止默认的锚点跳转
e.preventDefault()
}
// 处理链接点击
const handleLinkClick = (e, anchorId) => {
e.preventDefault()
e.stopPropagation()
emit('anchor-click', anchorId)
// 延迟执行滚动,确保 DOM 已经更新
setTimeout(() => {
scrollToAnchor(anchorId)
}, 50)
}
// 滚动到锚点
const scrollToAnchor = anchorId => {
const targetElement = document.getElementById(anchorId)
if (!targetElement) return
let scrollContainer
if (props.scrollContainerSelector) {
scrollContainer = document.querySelectorAll(props.scrollContainerSelector)
}
if (scrollContainer.length > 0) {
// 计算在容器内的相对位置
const containerRect = scrollContainer[props.domIndex].getBoundingClientRect()
const targetRect = targetElement.getBoundingClientRect()
// 计算滚动位置
const scrollTop =
targetRect.top -
containerRect.top +
scrollContainer[props.domIndex].scrollTop -
props.scrollOffset
// 平滑滚动
scrollContainer[props.domIndex].scrollTo({
top: scrollTop,
behavior: 'smooth'
})
} else {
// 如果没有指定容器,使用默认滚动
targetElement.scrollIntoView({
behavior: 'smooth',
block: 'start'
})
}
}
// 暴露方法给父组件
defineExpose({
scrollToAnchor
})
</script>
<template>
<div class="cardOneContainer">
<el-card class="cardStyle">
<template #header>
<div class="cardOneheader">
<div class="cardOneLeft">
<div class="mainTitle">{{ title }}</div>
<slot name="headerRight"></slot>
</div>
<div class="subTitle" v-if="desTitle">{{ desTitle }}</div>
</div>
</template>
<slot name="content"></slot>
</el-card>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
const props = defineProps({
title: {
type: String,
default: ''
},
desTitle: {
type: String,
default: ''
}
})
</script>
<style lang="scss" scoped>
.cardOneContainer {
width: 100%;
box-sizing: border-box;
}
.cardStyle {
width: 100%;
margin-bottom: 10px;
border: none !important;
/* :deep (.el-card__header) {
border: none !important;
} */
}
.headerStyle {
border: none !important;
}
.cardOneheader {
width: 100%;
}
.cardOneLeft {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
}
.mainTitle {
font-size: 18px;
/* border-left: 4px solid #0052d9; */
padding-left: 5px;
display: flex;
align-items: center;
/* border-top-left-radius: 2px;
border-bottom-left-radius: 2px;
border-bottom-right-radius: 2px; */
}
.mainTitle::before {
content: '';
display: inline-block;
width: 4px;
height: 22px;
background: #0052d9;
margin-right: 5px;
border-radius: 4px;
}
.subTitle {
background: rgba(0, 119, 238, 0.05);
width: 100%;
padding: 10px 10px;
font-size: 14px;
color: rgba(56, 56, 56, 1);
display: flex;
align-items: center;
margin-top: 5px;
border-radius: 3px;
}
</style>
const customer = [
// 基础信息
{
fatherTitle: '客户',
fatherTitle: '基础信息',
type: 'object',
key: 'personInfo',
anchorKey: 'personInfo',
showTable: false,
data: [
// {
// label: '姓氏',
// key: 'lastName',
// type: 'Input',
// inputType: 'text',
// required: false,
// maxLength: 5,
// disabled: false,
// placeholder: '请输入',
// show: true,
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 8, //栅格布局份数
// lg: 8 //栅格布局份数
// },
// {
// label: '名字',
// key: 'firstName',
// type: 'Input',
// inputType: 'text',
// required: false,
// maxLength: 10,
// disabled: false,
// placeholder: '请输入',
// show: true,
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 8, //栅格布局份数
// lg: 8 //栅格布局份数
// },
{
label: '名字',
key: 'name',
type: 'Input',
label: '名字(中文)',
key: 'nameCn',
domType: 'Input',
unit: '历史客户',
unitColor: 'rgba(0, 82, 217, 1)',
inputType: 'text',
required: false,
required: true,
maxLength: 15,
disabled: false,
placeholder: '请输入2~6位汉字',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '姓名(拼音/英文)',
key: 'namePyEn',
domType: 'Input',
inputType: 'text',
required: true,
maxLength: 30,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
......@@ -50,29 +41,13 @@ const customer = [
lg: 8 //栅格布局份数
},
// {
// label: '姓氏拼音',
// key: 'lastNamePinyin',
// type: 'Input',
// inputType: 'text',
// required: false,
// maxLength: 30,
// disabled: false,
// placeholder: '请输入',
// show: true,
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 8, //栅格布局份数
// lg: 8 //栅格布局份数
// },
// {
// label: '姓名拼音',
// key: 'pinyin',
// type: 'Input',
// inputType: 'text',
// required: false,
// maxLength: 30,
// label: '称谓',
// key: 'title',
// domType: 'Select',
// required: true,
// disabled: false,
// placeholder: '请输入',
// placeholder: '请选择',
// dictType: 'csf_customer_title',
// show: true,
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
......@@ -80,14 +55,13 @@ const customer = [
// lg: 8 //栅格布局份数
// },
{
label: '名字-英文',
key: 'firstNamePinyin',
type: 'Input',
inputType: 'text',
label: '证件类型',
key: 'documentType',
domType: 'Select',
required: true,
maxLength: 30,
disabled: false,
placeholder: '请输入',
placeholder: '请选择',
dictType: 'csf_id_type',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
......@@ -95,24 +69,26 @@ const customer = [
lg: 8 //栅格布局份数
},
{
label: '称谓',
key: 'title',
type: 'Select',
label: '证件号码',
key: 'idNumber',
domType: 'Input',
inputType: 'text',
required: true,
maxLength: 20,
disabled: false,
placeholder: '请选择',
dictType: 'csf_customer_title',
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '性别',
key: 'gender',
type: 'Select',
required: false,
domType: 'Select',
required: true,
disabled: false,
placeholder: '请选择',
dictType: 'sys_gender',
......@@ -124,8 +100,8 @@ const customer = [
},
{
label: '生日',
key: 'birthdate',
type: 'DatePicker',
key: 'birthday',
domType: 'DatePicker',
required: true,
disabled: false,
placeholder: '请选择',
......@@ -138,7 +114,7 @@ const customer = [
{
label: '年龄',
key: 'age',
type: 'Input',
domType: 'Input',
inputType: 'number',
maxLength: 30,
required: true,
......@@ -151,31 +127,28 @@ const customer = [
lg: 8 //栅格布局份数
},
{
label: '移动电话',
key: 'phone',
type: 'arrowRight',
label: '国籍(国家/地区)',
key: 'nationality',
domType: 'arrowRight',
required: true,
disabled: false,
placeholder: '请填写',
show: true,
drawerType: 'phone',
phone: {},
code: 'areaCode',
value: '',
drawerType: 'country',
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '邮箱',
key: 'email',
type: 'Input',
label: '出生地',
key: 'birthplace',
domType: 'Input',
inputType: 'text',
maxLength: 30,
required: true,
required: false,
maxLength: 300,
disabled: false,
placeholder: '请输入',
placeholder: '请输入出生地(省市)',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
......@@ -183,9 +156,9 @@ const customer = [
lg: 8 //栅格布局份数
},
{
label: '是否吸烟',
key: 'smoke',
type: 'Select',
label: '是否拥有其他国家公民身份(如美国、日本等)',
key: 'isOtherCountry',
domType: 'Select',
required: false,
disabled: false,
placeholder: '请选择',
......@@ -197,85 +170,70 @@ const customer = [
lg: 8 //栅格布局份数
},
{
label: '吸烟数量(支/天)',
key: 'smokeQuantity',
type: 'Input',
inputType: 'number',
maxLength: 30,
required: false,
label: '是否吸烟',
key: 'smokingStatus',
domType: 'Select',
required: true,
disabled: false,
placeholder: '请输入',
show: false,
placeholder: '请选择',
dictType: 'sys_no_yes',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
// {
// label: '公司类型',
// key: 'companyType',
// type: 'Select',
// label: '吸烟数量(支/天)',
// key: 'smokeQuantity',
// domType: 'Input',
// inputType: 'number',
// maxLength: 30,
// required: false,
// disabled: false,
// placeholder: '请选择',
// dictType: 'sys_status',
// show: true
// placeholder: '请输入',
// show: false,
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 8, //栅格布局份数
// lg: 8 //栅格布局份数
// },
{
label: '客户类型',
key: 'customerType',
type: 'Select',
required: false,
label: '婚姻状况',
key: 'maritalStatus',
domType: 'Select',
required: true,
disabled: false,
placeholder: '请选择',
dictType: 'csf_customer_type',
dictType: 'csf_marriage',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
// {
// label: '客户来源',
// key: 'source',
// type: 'Select',
// required: false,
// disabled: false,
// placeholder: '请选择',
// dictType: 'sys_status',
// show: true
// },
{
label: '行业',
key: 'companyType',
type: 'Input',
inputType: 'text',
maxLength: 300,
label: '教育程度',
key: 'educationLevel',
domType: 'Select',
required: true,
disabled: false,
placeholder: '请输入',
placeholder: '请选择',
dictType: 'csf_education',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
}
]
},
{
fatherTitle: '基本情况',
type: 'object',
key: 'basic',
// description: '证件信息至少填写一项',
data: [
{
label: '婚姻状况',
key: 'marriage',
type: 'Select',
label: '是否退休',
key: 'isRetirement',
domType: 'Select',
required: true,
disabled: false,
placeholder: '请选择',
dictType: 'csf_marriage',
dictType: 'sys_no_yes',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
......@@ -283,59 +241,141 @@ const customer = [
lg: 8 //栅格布局份数
},
{
label: '国籍(国家/地区)',
key: 'country',
type: 'arrowRight',
required: true,
label: '退休年龄',
key: 'retirementAge',
domType: 'Input',
inputType: 'number',
maxLength: 30,
required: false,
disabled: false,
placeholder: '请填写',
placeholder: '请输入',
show: false,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '风险偏好',
key: 'riskAppetite',
domType: 'Select',
required: false,
disabled: false,
placeholder: '请选择',
dictType: 'csf_ap_risk',
show: true,
drawerType: 'country',
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '出生地',
key: 'birthplace',
type: 'Input',
label: '体重(KG)',
key: 'weight',
domType: 'Input',
inputType: 'number',
required: false,
maxLength: 300,
disabled: false,
placeholder: '请输入身高(kg)',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '身高(CM)',
key: 'height',
domType: 'Input',
inputType: 'number',
required: false,
maxLength: 300,
disabled: false,
placeholder: '请输入身高(cm)',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: 'BMI',
key: 'bmi',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 300,
disabled: false,
placeholder: '请输入出生地(省市)',
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
}
]
},
// 税务信息
{
fatherTitle: '税务信息',
keyType: 'Array', //用于表单收集值时,判断是数组还是对象
key: 'apiTaxationDtoList',
anchorKey: 'apiTaxationDtoList',
moudleType: 'apiTaxationDtoList',
dataLength: 1, //设置dataLength,用于控制子级dom的个数,子级保存一个样例数据,便于加子级数据
showTable: true,
addChildren: true, //是否可以新增子级dom
addChildrenTxt: '税务', //新增按钮得文本
fatherRequired: false, //父级必填,代表个人资料这个模块有必填项
isOpen: false, //dom是否展开
data: [
// {
// id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识
// span: 24, //栅格布局份数
// taxCountry: '',
// taxNumber: ''
// }
]
},
// 联系信息
{
label: '教育程度',
key: 'education',
type: 'Select',
fatherTitle: '联系信息',
type: 'object',
key: 'contactInfo',
anchorKey: 'contactInfo',
showTable: false,
data: [
{
label: '移动电话',
key: 'mobile',
domType: 'arrowRight',
required: true,
disabled: false,
placeholder: '请选择',
dictType: 'csf_education',
placeholder: '请填写',
show: true,
drawerType: 'phone',
mobile: {},
code: 'mobileCode',
value: '',
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '住宅电话',
key: 'residenceTelephone',
type: 'arrowRight',
key: 'residenceMobile',
domType: 'arrowRight',
required: false,
disabled: false,
placeholder: '请填写',
show: true,
drawerType: 'phone',
residenceTelephone: {},
code: 'residenceAreaCode',
residenceMobile: {},
code: 'residenceMobileCode',
maxLength: 20,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
......@@ -344,8 +384,8 @@ const customer = [
},
{
label: '固定电话',
key: 'fixedPhone',
type: 'Input',
key: 'landline',
domType: 'Input',
inputType: 'number',
required: false,
disabled: false,
......@@ -358,13 +398,14 @@ const customer = [
lg: 8 //栅格布局份数
},
{
label: '是否长期出国',
key: 'longtimeAbroad',
type: 'Select',
required: false,
label: '邮箱',
key: 'email',
domType: 'Input',
inputType: 'text',
maxLength: 30,
required: true,
disabled: false,
placeholder: '请选择',
dictType: 'sys_no_yes',
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
......@@ -372,15 +413,31 @@ const customer = [
lg: 8 //栅格布局份数
},
{
label: '证件地址',
key: 'certificateAddress',
domType: 'Input',
inputType: 'text',
required: true,
maxLength: 20,
disabled: false,
placeholder: '请输入',
show: false,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '通讯地址',
key: 'residenceAddress',
type: 'arrowRight',
key: 'mailingAddress',
domType: 'arrowRight',
required: false,
disabled: false,
placeholder: '请填写',
show: true,
drawerType: 'address',
residenceAddress: {},
mailingAddress: {},
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
......@@ -389,7 +446,7 @@ const customer = [
{
label: '住宅地址',
key: 'residentialAddress',
type: 'arrowRight',
domType: 'arrowRight',
required: false,
disabled: false,
placeholder: '请填写',
......@@ -400,38 +457,41 @@ const customer = [
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '通讯地址邮政编号',
key: 'mailingAddressCode',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 300,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
}
// {
// label: '邮寄地址',
// key: 'mailingAddress',
// type: 'arrowRight',
// required: false,
// disabled: false,
// placeholder: '请填写',
// show: true,
// drawerType: 'address',
// mailingAddress: {},
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 8, //栅格布局份数
// lg: 8 //栅格布局份数
// }
]
},
// 工作信息
{
fatherTitle: '证件信息',
fatherTitle: '工作信息',
type: 'object',
key: 'pid',
// description: '证件信息至少填写一项',
key: 'companyInfo',
anchorKey: 'companyInfo',
showTable: false,
data: [
{
label: '证件类型',
key: 'idType',
type: 'Select',
required: true,
label: '就业情况',
key: 'employmentStatus',
domType: 'Select',
required: false,
disabled: false,
placeholder: '请选择',
dictType: 'csf_id_type',
dictType: 'sys_no_yes',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
......@@ -439,12 +499,12 @@ const customer = [
lg: 8 //栅格布局份数
},
{
label: '证件号码',
key: 'idCard',
type: 'Input',
label: '公司/学校名称',
key: 'csName',
domType: 'Input',
inputType: 'text',
required: true,
maxLength: 20,
required: false,
maxLength: 300,
disabled: false,
placeholder: '请输入',
show: true,
......@@ -454,31 +514,70 @@ const customer = [
lg: 8 //栅格布局份数
},
{
label: '身份证地址',
key: 'idCardAddress',
type: 'Input',
label: '行业',
key: 'industry',
domType: 'Input',
inputType: 'text',
maxLength: 300,
required: false,
maxLength: 20,
disabled: false,
placeholder: '请输入',
show: false,
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
}
]
},
{
fatherTitle: '公司信息',
type: 'object',
key: 'companyInfo',
data: [
label: '现时每月收入',
key: 'currentMonthlyIncome',
domType: 'Input',
unit: 'HKD',
inputType: 'number',
required: false,
maxLength: 300,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '总工作年期',
key: 'totalWorkingYears',
domType: 'Input',
inputType: 'number',
required: false,
maxLength: 300,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '公司名称',
key: 'companyName',
type: 'Input',
label: '受雇于现职年期',
key: 'currentTenure',
domType: 'Input',
inputType: 'number',
required: false,
maxLength: 300,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '职位',
key: 'position',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 300,
......@@ -492,25 +591,29 @@ const customer = [
},
{
label: '公司电话',
key: 'companyTelephone',
type: 'arrowRight',
key: 'companyMobile',
commonKey: true,
customerKey: 'companyTelephone',
customerCode: 'companyAreaCode',
domType: 'arrowRight',
required: false,
disabled: false,
placeholder: '请填写',
show: true,
drawerType: 'phone',
companyTelephone: {},
code: 'companyAreaCode',
companyMobile: {}, //带有区号得电话一定要有一个和key一样得对象用于收集区号和号码
code: 'companyMobileCode',
maxLength: 20,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
labelWidth: '180px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '公司地址',
key: 'companyAddress',
type: 'arrowRight',
customerKey: 'companyAddress',
domType: 'arrowRight',
required: false,
disabled: false,
placeholder: '请填写',
......@@ -523,9 +626,9 @@ const customer = [
lg: 8 //栅格布局份数
},
{
label: '公司地址邮编',
key: 'companyAddressPostcode',
type: 'Input',
label: '公司地址邮编',
key: 'companyAddressCode',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 20,
......@@ -536,16 +639,27 @@ const customer = [
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
}
]
},
// 财务信息
{
label: '职位',
key: 'position',
type: 'Input',
inputType: 'text',
fatherTitle: '财务信息',
type: 'object',
key: 'financeInfo',
anchorKey: 'financeInfo',
showTable: false,
data: [
{
label: '平均每月收入',
key: 'monthIncome',
domType: 'Input',
unit: 'HKD',
inputType: 'number',
required: false,
maxLength: 300,
disabled: false,
placeholder: '请输入',
placeholder: '请输入平均每月收入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
......@@ -553,9 +667,26 @@ const customer = [
lg: 8 //栅格布局份数
},
{
label: '工作年期',
key: 'workYear',
type: 'Input',
label: '平均每月支出',
key: 'monthExpenditure',
domType: 'Input',
unit: 'HKD',
inputType: 'number',
required: false,
maxLength: 300,
disabled: false,
placeholder: '请输入平均每月支出',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '总流动资产',
key: 'totalCurrentAssets',
domType: 'Input',
unit: 'HKD',
inputType: 'number',
required: false,
maxLength: 300,
......@@ -568,9 +699,10 @@ const customer = [
lg: 8 //栅格布局份数
},
{
label: '现时每月收入',
key: 'salary',
type: 'Input',
label: '总负债额',
key: 'totalDebt',
domType: 'Input',
unit: 'HKD',
inputType: 'number',
required: false,
maxLength: 300,
......@@ -583,6 +715,90 @@ const customer = [
lg: 8 //栅格布局份数
}
]
},
//其他信息
{
fatherTitle: '其他信息',
type: 'object',
key: 'otherInfo',
anchorKey: 'otherInfo',
showTable: false,
showMoudle: true, //模块是否展示
data: [
{
label: '旅行',
key: 'travel',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 300,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '运动',
key: 'exercise',
domType: 'Select',
required: false,
disabled: false,
placeholder: '请选择',
dictType: 'csf_ap_exercise',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '游戏',
key: 'game',
domType: 'Select',
required: false,
disabled: false,
placeholder: '请选择',
dictType: 'csf_ap_game',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '电影/戏剧',
key: 'movieDrama',
domType: 'Select',
required: false,
disabled: false,
placeholder: '请选择',
dictType: 'csf_ap_movie',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '美食',
key: 'delicacy',
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 300,
disabled: false,
placeholder: '请输入',
show: true,
labelPosition: 'top', //标签的位置
labelWidth: '120px', //标签宽度
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
}
]
}
]
export default customer
<template>
<div>
<div v-if="processedCustomerData.length > 0">
<el-row>
<el-col :span="24">
<div class="topBtn">
<el-button type="warning" icon="DocumentAdd" @click="exportInfo"
>从已有列表中导入</el-button
>
<div v-if="processedCustomerData.length > 0" class="customerContainer">
<div class="editBtn">
<el-button
v-if="props.customerBizId"
type="primary"
icon="EditPen"
@click="handleEditStatus"
style="margin-left: 10px"
>编辑</el-button
>
</div>
</el-col>
</el-row>
<div class="customerLeft" v-if="customerRightRef">
<CommonAnchor
:anchorList="anchorList"
:affixOffset="250"
:anchorOffset="10"
:scrollContainerSelector="'.tabPaneBox'"
:scrollOffset="10"
:domIndex="1"
/>
</div>
<div class="customerRight" ref="customerRightRef">
<el-form ref="customerRef" :model="form" :rules="rules" label-width="120px">
<el-row v-for="father in processedCustomerData" style="margin-bottom: 10px">
<el-row v-for="(father, fIndex) in processedCustomerData" :id="father.anchorKey">
<div class="formBox">
<div class="fatherLable">{{ father.fatherTitle }}</div>
<div class="fatherDes">{{ father.description }}</div>
<el-row :gutter="20">
<CardOne :title="father.fatherTitle">
<template #content>
<el-row :gutter="20" v-if="!father.showTable">
<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="child.key"
:key="child.key"
:label-width="child.labelWidth"
:label-position="child.labelPosition"
> -->
<el-form-item
:label="
child.key === 'residentialAddress' && child.type === 'arrowRight'
......@@ -48,7 +43,9 @@
>
<!-- 自定义 label 插槽 -->
<template
v-if="child.key === 'residentialAddress' && child.type === 'arrowRight'"
v-if="
child.key === 'residentialAddress' && child.type === 'arrowRight'
"
#label
>
<div class="custom-label">
......@@ -67,16 +64,20 @@
</div>
</template>
<el-input
v-if="child.type === 'Input'"
v-if="child.domType === 'Input'"
:type="child.inputType"
v-model="form[child.key]"
:placeholder="child.placeholder"
maxlength="30"
:disabled="child.disabled"
@change="handleInputChange(child)"
/>
>
<template #append v-if="child.unit" @click="handleAppendInput(child)">
<span :style="{ color: child.unitColor }">{{ child.unit }}</span>
</template>
</el-input>
<el-select
v-if="child.type === 'Select'"
v-if="child.domType === 'Select'"
v-model="form[child.key]"
:placeholder="child.placeholder"
@change="handleSelectChange(child)"
......@@ -91,9 +92,11 @@
</el-select>
<el-date-picker
style="width: 100%"
v-if="child.type === 'DatePicker'"
v-if="child.domType === 'DatePicker'"
v-model="form[child.key]"
type="date"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
:placeholder="child.placeholder"
:disabled="child.disabled"
:disabled-date="time => disabledDate(time, child)"
......@@ -102,7 +105,7 @@
/>
<el-input
v-if="child.type === 'arrowRight'"
v-if="child.domType === 'arrowRight'"
v-model="form[child.key]"
:placeholder="child.placeholder"
@click="handleFoucs(child)"
......@@ -116,6 +119,54 @@
</el-col>
</template>
</el-row>
<el-row v-if="father.showTable">
<el-col :span="24" v-if="father.addChildren">
<el-button
:disabled="editStatus"
type="primary"
icon="Plus"
size="small"
style="margin-bottom: 10px"
@click="addChildren(father)"
>{{ father.addChildrenTxt }}</el-button
>
</el-col>
<el-table :data="father.data" border v-if="father.data.length > 0">
<template v-if="father.key == 'apiTaxationDtoList'">
<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="taxId" align="center">
<template #default="scope">
<el-input
v-model="scope.row.taxId"
size="default"
placeholder="请输入"
:disabled="editStatus"
/>
</template>
</el-table-column>
<el-table-column width="60px" align="center" label="操作">
<template #default="scope">
<el-icon
class="deleteIcon"
@click="deleteChildren(father, scope.$index)"
><Delete
/></el-icon>
</template>
</el-table-column>
</template>
</el-table>
</el-row>
</template>
</CardOne>
</div>
</el-row>
......@@ -142,6 +193,8 @@
</el-col>
</el-row>
</el-form>
</div>
<el-dialog title="客户信息" v-model="openList" width="600px" append-to-body>
<div>
<el-form :model="queryParams" ref="queryRef" :inline="true" label-width="68px">
......@@ -184,7 +237,7 @@
</div>
<div class="infoItem">
<span>出生日期:</span>
<span> {{ formatToDate(item.birthdate) || '暂无' }}</span>
<span> {{ formatToDate(item.birthday) || '暂无' }}</span>
</div>
</div>
</div>
......@@ -213,6 +266,7 @@
@close="handleCloseDrawer"
@confirmCountry="confirmDrawer"
/>
<!-- 历史客户的弹窗 -->
</div>
</template>
<script setup name="customer">
......@@ -224,7 +278,8 @@ import customerDomData from '@/formJson/customer'
import Country from '@/views/components/country'
import Phone from '@/views/components/phone'
import Address from '@/views/components/address'
import CommonAnchor from '@/components/commonAnchor'
import CardOne from '@/components/formCard/cardOne'
import { watch } from 'vue'
import {
addCustomer,
......@@ -237,12 +292,18 @@ import useDictStore from '@/store/modules/dict'
const dictStore = useDictStore() //获取字典数据
const props = defineProps({
activeName: { type: String, default: '' }, //tab名称
tabPaneRef: {
type: Object,
default: null
},
fearthStatus: { type: String, default: '' }, //父组件状态,新增、修改
customerBizId: { type: String, default: '' } //提交状态,新增、修改
})
const emit = defineEmits(['handleSuccess'])
const { proxy } = getCurrentInstance()
const { csf_id_type, sys_gender } = proxy.useDict('csf_id_type', 'sys_gender')
const anchorList = ref([]) //锚点列表
const customerRightRef = ref(null)
const showPhoneDrawer = ref(false) //电话抽屉开关
const showAddressDrawer = ref(false) //地址抽屉开关
const showCountryDrawer = ref(false) //国家/地区抽屉开关
......@@ -330,6 +391,40 @@ const data = reactive({
}
})
const { form, rules, processedCustomerData, queryParams, oldCustomerData } = toRefs(data)
const handleAppendInput = child => {}
// 添加表单子级dom
const addChildren = father => {
const processedData = JSON.parse(JSON.stringify(processedCustomerData.value))
let obj4 = {
id: Date.now() + Math.floor(Math.random() * 1000), //唯一标识
span: 24, //栅格布局份数
taxCountry: '',
taxNumber: ''
}
for (const section of processedData) {
if (father.key == 'apiTaxationDtoList' && section.key == father.key) {
section.data.push(obj4)
}
}
//更新form表单对应的数据,以便收集填写的值
// form.value[father.key].push(obj)
processedCustomerData.value = processedData
}
const deleteChildren = (father, childIndex) => {
if (editStatus.value) {
proxy.$modal.confirm(`请先点击编辑再进行删除操作`, { showCancel: '0', title: '填写提示' })
return
}
const processedData = JSON.parse(JSON.stringify(processedCustomerData.value))
for (const section of processedData) {
if (father.key == 'apiTaxationDtoList' && section.key == father.key) {
section.data.splice(childIndex, 1)
}
}
processedCustomerData.value = processedData
}
const copyAddress = computed(() => {
const residenceAddressIndex = addressQuickList.value.findIndex(
item => item.type === 'residenceAddress'
......@@ -366,15 +461,15 @@ const handleInputChange = child => {
}
const handleDateChange = child => {
let age = null
if (child.key == 'birthdate') {
age = calculateExactAge(proxy.formatToDate(form.value.birthdate))
if (child.key == 'birthday') {
age = calculateExactAge(proxy.formatToDate(form.value.birthday))
if (age >= 18) {
form.value.age = age
}
}
}
const disabledDate = (time, child) => {
if (child.key == 'birthdate') {
if (child.key == 'birthday') {
// 计算18年前的今天
const eighteenYearsAgo = dayjs().subtract(18, 'year')
// 禁用今天之后的日期和18年前的今天之后的日期
......@@ -441,10 +536,12 @@ const fetchDictData = dictType => {
}
// 处理表单配置,添加字典数据
const processFormData = async () => {
anchorList.value = []
// 深拷贝原始数据
const processedData = JSON.parse(JSON.stringify(customerDomData))
for (const section of processedData) {
anchorList.value.push({ title: section.anchorKey, name: section.fatherTitle })
if (section.data) {
for (const field of section.data) {
if (field.dictType) {
......@@ -452,7 +549,7 @@ const processFormData = async () => {
field.options = fetchDictData(field.dictType)
}
if (field.required) {
if (field.key === 'firstNamePinyin') {
if (field.key === 'namePyEn') {
rules.value[field.key] = [
{ required: true, message: `${field.label}不能为空`, trigger: 'blur' },
{ validator: validateEnglish, trigger: 'change' }
......@@ -480,6 +577,9 @@ const processFormData = async () => {
form.value.customerType = 'INDIVIDUAL'
processedCustomerData.value = oldCustomerData.value = processedData
}
console.log('====================================')
console.log('anchorList.value', anchorList.value)
console.log('====================================')
}
//弹出右侧抽屉
......@@ -623,40 +723,25 @@ const confirmDrawer = info => {
handleCloseDrawer()
}
// 根据联动重置表单项的显示与否
const resetShow = (key, status) => {
for (const section of processedCustomerData.value) {
if (section.data) {
for (const field of section.data) {
if (field.key == key) {
// 获取字典数据
field.show = status
if (!status) {
form.value[key] = ''
}
}
}
}
}
}
const handleSelectChange = child => {
switch (child.key) {
case 'smoke':
// 选择吸烟,展示吸烟数量
if (form.value[child.key] == '1') {
resetShow('smokeQuantity', true)
} else {
resetShow('smokeQuantity', false)
}
break
case 'idType':
// 选择吸烟,展示吸烟数量
if (form.value[child.key] == 'idCard') {
resetShow('idCardAddress', true)
} else {
resetShow('idCardAddress', false)
}
break
// case 'smokingStatus':
// // 选择吸烟,展示吸烟数量
// if (form.value[child.key] == '1') {
// resetShow('smokeQuantity', true)
// } else {
// resetShow('smokeQuantity', false)
// }
// break
// case 'idType':
// // 选择吸烟,展示吸烟数量
// if (form.value[child.key] == 'idCard') {
// resetShow('idCardAddress', true)
// } else {
// resetShow('idCardAddress', false)
// }
// break
default:
break
}
......@@ -690,11 +775,15 @@ const setFormValue = (obj, formData, exportValue) => {
// 深拷贝原始数据
const processedData = JSON.parse(JSON.stringify(formData))
for (const section of processedData) {
// 这里还要回显受供养人数,等调试的时候再加
// if (section.key == 'personInfo') {
// section.data.push()
// }
if (section.data) {
for (const field of section.data) {
if (obj.smokeQuantity && field.key == 'smokeQuantity') {
field.show = true
}
// if (obj.smokeQuantity && field.key == 'smokeQuantity') {
// field.show = true
// }
//证件类型是身份证,身份证地址就显示否则不显示
if (field.key == 'idCardAddress' && obj.idType == 'idCard') {
field.show = true
......@@ -788,8 +877,8 @@ const setFormValue = (obj, formData, exportValue) => {
}
}
})
if (form.value['birthdate']) {
let age = calculateExactAge(proxy.formatToDate(form.value.birthdate))
if (form.value['birthday']) {
let age = calculateExactAge(proxy.formatToDate(form.value.birthday))
if (age >= 18) {
form.value.age = age
}
......@@ -805,12 +894,6 @@ 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('====================================')
}
// 数组去重
function removeDuplicates(arr, key) {
......@@ -841,9 +924,10 @@ const getInvalidFields = fields => {
}
// 表单提交
const submitForm = () => {
//提交得时候要处理税务国家得数据。表格得值收集在processedCustomerData中,所以需要从processedCustomerData中取值
let submitObj = { ...form.value }
let addressList = []
submitObj['birthdate'] = proxy.formatToDate(submitObj['birthdate'])
submitObj['birthday'] = proxy.formatToDate(submitObj['birthday'])
proxy.$refs['customerRef'].validate((valid, fields) => {
if (valid) {
......@@ -876,7 +960,7 @@ const submitForm = () => {
}
}
}
submitObj['birthdate'] = proxy.formatToDate(submitObj['birthdate'])
submitObj['birthday'] = proxy.formatToDate(submitObj['birthday'])
submitObj['addressList'] = addressList
// 删除多余字段
deleteKeyList.value.forEach(item => {
......@@ -933,7 +1017,7 @@ const resetForm = () => {
form.value = { ...oldObjInfo.value }
editStatus.value = true
} else {
resetShow('smokeQuantity', false)
// resetShow('smokeQuantity', false)
proxy.$refs['customerRef'].resetFields()
}
processedCustomerData.value = JSON.parse(JSON.stringify(oldCustomerData.value))
......@@ -954,12 +1038,40 @@ watch(
() => props.activeName,
newVal => {
if (newVal === 'customer') {
customerRightRef.value = null
processFormData()
}
}
)
</script>
<style lang="scss" scoped>
.customerContainer {
display: flex;
height: 100%;
box-sizing: border-box;
position: relative;
}
.editBtn {
position: fixed;
right: 3.5%;
top: 22%;
z-index: 999;
}
.customerLeft {
width: 15%;
height: 100vh;
}
.customerRight {
width: calc(100% - 15%);
border-left: 3px solid rgb(247 247 247);
padding-left: 10px;
box-sizing: border-box;
}
.deleteIcon {
color: red;
font-size: 18px;
padding-top: 10px;
}
.custom-label {
width: 100%;
display: flex;
......
<template>
<div class="app-container">
<!-- <div>
<el-button type="primary" icon="Back" @click="handleBack" style="margin-bottom: 10px"
>返回</el-button
>
</div> -->
<el-card shadow="never">
<div class="cardHeader">
<div class="left">
......@@ -25,22 +19,8 @@
</div>
</div>
</div>
<!-- <div class="right">
<el-button
:disabled="!(processInfo.customerBizId && processInfo.fnaFormBizId)"
type="success"
:icon="Check"
>{{ processInfo.appointmentBizId ? '已预约' : '立即预约' }}</el-button
>
<el-button
:disabled="!(processInfo.customerBizId && processInfo.fnaFormBizId)"
type="primary"
plain
>生成副本</el-button
>
</div> -->
</div>
<div class="tabsBox">
<div class="tabsBox" ref="tabPaneRef">
<el-tabs v-model="activeName" class="demo-tabs" :before-leave="beforeTabLeave">
<el-tab-pane v-for="tab in tabsList" :key="tab.name" :label="tab.label" :name="tab.name">
<div :class="{ tabPaneBox: activeName !== 'appointment' }">
......@@ -98,6 +78,7 @@
:fearthStatus="route.query.type"
:customerBizId="processInfo.customerBizId"
@handleSuccess="handleSuccess"
:tabPaneRef="tabPaneRef"
/>
<div v-if="tab.name === 'fnaform'">
<FanForm
......@@ -155,6 +136,7 @@ const processInfo = ref({
const updateStatus = ref(false)
const dictTypeLists = ref([])
const customerInfo = ref({})
const tabPaneRef = ref(null)
const tabsList = ref([
{
label: '总览',
......@@ -181,15 +163,15 @@ const tabsList = ref([
id: 3,
status: '0',
key: 'appointmentBizId'
},
{
label: '关联新单',
name: 'newpolicy',
id: 4,
status: '0',
key: 'policyBizld'
}
// {
// label: '关联新单',
// name: 'newpolicy',
// id: 4,
// status: '0',
// key: 'policyBizld'
// }
// {
// label: '关联保单',
// name: 'policy',
// id: 5,
......@@ -533,11 +515,40 @@ getDictsData()
}
}
}
/* .tabPaneBox {
height: calc(100vh - 275px);
overflow-y: auto;
padding-right: 10px;
} */
.tabPaneBox {
/* height: calc(100vh - 317px); */
height: calc(100vh - 275px);
overflow-y: auto;
padding-right: 10px;
position: relative;
}
/* 确保滚动区域有正确的滚动行为 */
.tabPaneBox {
scroll-behavior: smooth;
-webkit-overflow-scrolling: touch;
}
/* 隐藏滚动条但保留功能 */
.tabPaneBox::-webkit-scrollbar {
width: 6px;
}
.tabPaneBox::-webkit-scrollbar-track {
background: #f1f1f1;
}
.tabPaneBox::-webkit-scrollbar-thumb {
background: #c1c1c1;
border-radius: 3px;
}
.tabPaneBox::-webkit-scrollbar-thumb:hover {
background: #a8a8a8;
}
.overviewBox {
display: flex;
......
......@@ -7,7 +7,7 @@
>
<!-- 查询条件插槽 -->
<template #searchForm>
<el-form :model="queryParams" ref="queryRef" label-width="78px">
<el-form :model="queryParams" ref="queryRef" label-width="78px" label-position="top">
<el-row :gutter="20">
<el-col :sm="12" :lg="6" :xs="24">
<el-form-item label="创建时间">
......@@ -176,15 +176,16 @@ const operationBtnList = ref([
icon: 'Plus',
type: 'primary',
direction: 'left',
size: 'small',
size: 'large',
click: handleAdd
},
{
label: '搜索',
icon: 'Search',
type: 'primary',
direction: 'right',
size: 'small',
size: 'large',
click: handleQuery
},
{
......@@ -192,7 +193,7 @@ const operationBtnList = ref([
icon: 'Refresh',
type: 'info',
direction: 'right',
size: 'small',
size: 'large',
click: resetQuery
}
])
......
......@@ -467,7 +467,7 @@ function resetQuery() {
proxy.resetForm('queryRef')
queryParams.value = {
pageNo: 1,
pageSize: 8,
pageSize: 10,
startTime: '',
endTime: ''
}
......@@ -487,21 +487,6 @@ function handleDelete(row) {
})
.catch(() => {})
}
/** 重置操作表单 */
function reset() {
form.value = {
pageNo: 1,
pageSize: 8
}
proxy.resetForm('tenantRef')
}
/** 新增按钮操作 */
function handleAdd() {
router.push('/sign/FnaList/edit?type=add')
}
/** 修改按钮操作 */
function handleUpdate(row) {
// 对预约status进行转换,到编辑页面在转换会有时机问题
......
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