Commit 8e126c60 by yuzhenWang

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

封装页面组件

See merge request !28
parents 0fa1d35c 34364a66
......@@ -214,3 +214,11 @@ export function incomeCompareRecords(data) {
data: data
})
}
// 保单号列表
export function policyData(data) {
return request({
url: '/csf/api/CommissionExpected/list/page',
method: 'post',
data: data
})
}
......@@ -213,3 +213,11 @@ export function changePolicyStatus(data) {
})
}
// 签单人姓名列表
export function signName(data) {
return request({
url: '/csf/api/CommissionExpected/list/page',
method: 'post',
data: data
})
}
......@@ -11,7 +11,8 @@ body {
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial,
sans-serif;
}
label {
......@@ -91,7 +92,7 @@ div:focus {
visibility: hidden;
display: block;
font-size: 0;
content: " ";
content: ' ';
clear: both;
height: 0;
}
......@@ -105,7 +106,8 @@ aside {
display: block;
line-height: 32px;
font-size: 16px;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell,
'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
color: #2c3e50;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
......@@ -122,7 +124,8 @@ aside {
//main-container全局样式
.app-container {
padding: 20px;
padding: 10px;
box-sizing: border-box;
}
.components-container {
......@@ -131,7 +134,7 @@ aside {
}
.text-center {
text-align: center
text-align: center;
}
.sub-navbar {
......@@ -142,7 +145,13 @@ aside {
text-align: right;
padding-right: 20px;
transition: 600ms ease position;
background: linear-gradient(90deg, rgba(32, 182, 249, 1) 0%, rgba(32, 182, 249, 1) 0%, rgba(33, 120, 241, 1) 100%, rgba(33, 120, 241, 1) 100%);
background: linear-gradient(
90deg,
rgba(32, 182, 249, 1) 0%,
rgba(32, 182, 249, 1) 0%,
rgba(33, 120, 241, 1) 100%,
rgba(33, 120, 241, 1) 100%
);
.subtitle {
font-size: 20px;
......
<template>
<div class="commonDialog-container">
<el-dialog
style="padding: 0 !important"
v-model="showDialog"
:width="dialogWidth"
append-to-body
:close-on-click-modal="closeOnClickModal"
:before-close="handleClose"
center
:show-close="false"
>
<template #header>
<div class="titleBox">{{ dialogTitle }}</div>
</template>
<slot class="content"></slot>
<template #footer>
<div class="dialog-footer">
<!-- 取消按钮 -->
<el-button type="info" plain v-if="showCancle" @click="close">{{ cancleText }}</el-button>
<!-- 确认按钮 -->
<el-button type="primary" v-if="showConfirm" @click="confirm">{{
confirmText
}}</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { ref, computed, watch, nextTick, onMounted, defineExpose } from 'vue'
const props = defineProps({
dialogTitle: {
type: String,
default: ''
},
cancleText: {
type: String,
default: '取消'
},
showCancle: {
type: Boolean,
default: true
},
confirmText: {
type: String,
default: '确认'
},
showConfirm: {
type: Boolean,
default: true
},
dialogWidth: {
type: [String, Number],
default: '500px'
},
// 是否点击遮罩层关闭弹窗
closeOnClickModal: {
type: Boolean,
default: true
},
// 打开弹窗
openDialog: {
type: Boolean,
default: true
},
// 打开弹窗
center: {
type: Boolean,
default: true
}
})
const showDialog = ref(props.openDialog)
const emit = defineEmits(['confirm', 'close'])
const close = () => {
showDialog.value = false
emit('close')
}
const confirm = () => {
showDialog.value = false
emit('confirm')
}
const handleClose = done => {
close()
done()
}
watch(
() => props.openDialog,
val => {
showDialog.value = val
}
)
</script>
<style scoped lang="scss">
.commonDialog-container {
width: 100%;
}
.titleBox {
width: 100%;
background: rgba(0, 82, 217, 0.05);
display: flex;
justify-content: center;
align-items: center;
padding: 15px 0;
}
.dialog-footer {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
padding: 20px 0;
}
</style>
<template>
<div class="commonPage-container">
<!-- 条件查询区 -->
<el-card class="cardStyle" v-if="showSearchForm">
<el-row>
<!-- 查询条件插槽 -->
<div ref="searchFormRef" class="search-form-container" :class="{ expanded: isExpanded }">
<slot name="searchForm"></slot>
</div>
<!-- 更多/收起按钮区域 -->
<el-col :span="24" v-if="hasMoreCondition">
<div class="moreBtn">
<el-button v-if="!isExpanded" type="primary" link @click="toggleExpand">
更多<el-icon><Bottom /></el-icon>
</el-button>
<el-button v-else type="primary" link @click="toggleExpand">
收起<el-icon><Top /></el-icon>
</el-button>
</div>
</el-col>
</el-row>
</el-card>
<!-- 表格区域 -->
<el-card class="cardStyle">
<el-row>
<!-- 按钮区域 -->
<el-col :span="24" class="operationBtn">
<div class="operationLeft">
<template v-for="left in leftOperationBtns" :key="left.label">
<el-button
:type="left.type || 'primary'"
:icon="left.icon"
:size="left.size || 'default'"
@click="left.click"
:disabled="left.disabled"
:loading="left.loading"
>
{{ left.label }}
</el-button>
</template>
</div>
<div class="operationRight">
<template v-for="right in rightOperationBtns" :key="right.label">
<el-button
:type="right.type || 'primary'"
:icon="right.icon"
:size="right.size || 'default'"
@click="right.click"
:disabled="right.disabled"
:loading="right.loading"
>
{{ right.label }}
</el-button>
</template>
</div>
</el-col>
<!-- 表格插槽 -->
<slot name="table"></slot>
</el-row>
</el-card>
</div>
</template>
<script setup>
import { ref, computed, watch, nextTick, onMounted, defineExpose } from 'vue'
import { Bottom, Top } from '@element-plus/icons-vue'
const props = defineProps({
// 操作按钮列表
operationBtnList: {
type: Array,
default: () => []
},
// 是否显示查询表单
showSearchForm: {
type: Boolean,
default: true
},
// 分页相关
showPagination: {
type: Boolean,
default: false
},
total: {
type: Number,
default: 0
},
currentPage: {
type: Number,
default: 1
},
pageSize: {
type: Number,
default: 10
},
pageSizes: {
type: Array,
default: () => [10, 20, 50, 100]
},
paginationLayout: {
type: String,
default: 'total, sizes, prev, pager, next, jumper'
},
// 默认显示的查询条件数量
defaultVisibleConditions: {
type: Number,
default: 6
}
})
const emit = defineEmits(['size-change', 'current-change', 'btn-click', 'search-toggle'])
// 响应式数据
const isExpanded = ref(false)
const hasMoreCondition = ref(false)
const searchFormRef = ref(null)
const currentPage = ref(props.currentPage)
const pageSize = ref(props.pageSize)
// 计算属性
const leftOperationBtns = computed(() => {
return props.operationBtnList.filter(btn => btn.direction === 'left' || !btn.direction)
})
const rightOperationBtns = computed(() => {
return props.operationBtnList.filter(btn => btn.direction === 'right')
})
// 方法
const toggleExpand = () => {
isExpanded.value = !isExpanded.value
}
const checkConditions = () => {
if (!searchFormRef.value) return
nextTick(() => {
// 查找表单中的所有表单项
const formItems = searchFormRef.value.querySelectorAll('.el-form-item')
const formButtons = searchFormRef.value.querySelectorAll('.el-button')
const totalItems = formItems.length + formButtons.length
hasMoreCondition.value = totalItems > props.defaultVisibleConditions
if (!isExpanded.value && hasMoreCondition.value) {
// 隐藏超出默认数量的条件
let visibleCount = 0
let hiddenCount = 0
// 处理表单项
formItems.forEach((item, index) => {
if (visibleCount < props.defaultVisibleConditions) {
item.style.display = ''
visibleCount++
} else {
item.style.display = 'none'
hiddenCount++
}
})
// 处理按钮项
formButtons.forEach((button, index) => {
if (visibleCount < props.defaultVisibleConditions) {
button.style.display = ''
visibleCount++
} else {
button.style.display = 'none'
hiddenCount++
}
})
} else {
// 显示所有条件
formItems.forEach(item => (item.style.display = ''))
formButtons.forEach(button => (button.style.display = ''))
}
})
}
const handleBtnClick = btn => {
emit('btn-click', btn)
if (btn.click && typeof btn.click === 'function') {
btn.click()
}
}
// 暴露给父组件的方法
defineExpose({
checkConditions,
toggleExpand
})
// 监听器
watch(isExpanded, () => {
checkConditions()
})
watch(
() => props.currentPage,
val => {
currentPage.value = val
}
)
watch(
() => props.pageSize,
val => {
pageSize.value = val
}
)
// 生命周期
onMounted(() => {
if (props.showSearchForm) {
checkConditions()
}
})
</script>
<style scoped>
.commonPage-container {
width: 100%;
}
.cardStyle {
margin-bottom: 10px;
border: none !important;
}
.moreBtn {
display: flex;
align-items: center;
justify-content: center;
margin-top: 10px;
}
.operationBtn {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 10px;
}
.operationLeft,
.operationRight {
display: flex;
gap: 10px;
flex-wrap: wrap;
}
.pagination-container {
display: flex;
justify-content: center;
margin-top: 20px;
padding-top: 20px;
border-top: 1px solid var(--el-border-color-lighter);
}
/* 搜索表单容器样式 */
.search-form-container {
display: flex;
flex-wrap: wrap;
gap: 12px;
width: 100%;
align-items: flex-end;
}
/* 响应式调整 */
@media (max-width: 768px) {
.operationBtn {
flex-direction: column;
gap: 10px;
}
.operationLeft,
.operationRight {
width: 100%;
justify-content: center;
}
.search-form-container {
flex-direction: column;
}
.search-form-container :deep(.el-form-item) {
width: 100% !important;
}
}
</style>
......@@ -235,8 +235,8 @@ const policyInfo = [
lg: 8 //栅格布局份数
},
{
label: '首期交保费',
key: 'initialPremiumDue',
label: '首期交保费',
key: 'initialPremiumPaid',
domType: 'Input',
inputType: 'number',
required: false,
......@@ -251,8 +251,8 @@ const policyInfo = [
lg: 8 //栅格布局份数
},
{
label: '首期交保费',
key: 'initialPremiumPaid',
label: '首期交保费',
key: 'initialPremiumDue',
domType: 'Input',
inputType: 'number',
required: false,
......@@ -266,6 +266,7 @@ const policyInfo = [
sm: 8, //栅格布局份数
lg: 8 //栅格布局份数
},
{
label: '最晚缴费日期',
key: 'latestPaymentDate',
......
import { signName } from '../../api/sign/underwritingMain'
const useDictStore = defineStore('dict', {
state: () => ({
dict: new Array(),
......@@ -6,7 +8,8 @@ const useDictStore = defineStore('dict', {
additionalProductList: [], //附加险产品数据
insureCompanyList: [], //保险公司数据
clientUserList: [], //用户数据,转介人
dictTypeLists: [] //字典列表,根据请求得不同会变化,所以使用之前需要使用useDictLists请求数据
dictTypeLists: [], //字典列表,根据请求得不同会变化,所以使用之前需要使用useDictLists请求数据
signNameList: []
}),
actions: {
// 获取字典
......@@ -77,6 +80,10 @@ const useDictStore = defineStore('dict', {
// 设置字典列表
setDictTypeLists(typeList) {
this.dictTypeLists = typeList
},
// 设置签单人姓名列表
setSignNameList(nameList) {
this.signNameList = nameList
}
}
})
......
......@@ -13,8 +13,8 @@ export default function deepClone(obj) {
return clonedObj
}
}
// 处理用户名相同的情况
export function processUserName(users) {
// 处理用户名重名时返回姓名+手机号
export function processSameUserName(users) {
const nameCountMap = new Map()
// 统计 realName 重复情况
......@@ -46,3 +46,32 @@ export function processUserName(users) {
}
})
}
// 处理用户名返回姓名+手机号(手机号固定11位)
export function processUserName(users) {
return users.map(user => {
processUserName
const mobile = user.mobile || ''
if (mobile.length === 11) {
const prefix = mobile.substring(0, 3)
const suffix = mobile.substring(7)
return {
...user,
showName: `${user.realName || ''} ${prefix}****${suffix}`
}
} else if (mobile) {
// 非11位手机号,显示部分信息
const prefix = mobile.substring(0, Math.min(3, mobile.length))
const suffix = mobile.substring(Math.max(mobile.length - 2, 0))
return {
...user,
showName: `${user.realName || ''} ${prefix}***${suffix}`
}
} else {
return {
...user,
showName: user.realName || ''
}
}
})
}
......@@ -239,7 +239,31 @@
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="保单号" prop="policyNo">
<el-input v-model="incomeForm.policyNo" placeholder="请输入保单号" />
<el-select
v-model="incomeForm.policyNo"
filterable
remote
reserve-keyword
placeholder="请输入保单号"
:remote-method="searchPolicy"
:loading="policyLoading"
@change="plilcyChange"
remote-show-suffix
>
<el-option
v-if="policyOptions.length === 0"
disabled
value=""
label="暂无数据"
style="color: #909399; text-align: center"
/>
<el-option
v-for="item in policyOptions"
:key="item.policyBizId"
:label="item.policyNo"
:value="item.policyNo"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
......@@ -256,12 +280,16 @@
</el-col>
<el-col :span="12">
<el-form-item label="当前期数" prop="commissionPeriod">
<el-input-number v-model="incomeForm.commissionPeriod" :min="1" />
<el-input-number
v-model="incomeForm.commissionPeriod"
:min="1"
@change="periodChange"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="总期数" prop="totalPeriod">
<el-input-number v-model="incomeForm.totalPeriod" :min="1" />
<el-input-number v-model="incomeForm.totalPeriod" :min="1" :disabled="true" />
</el-form-item>
</el-col>
<el-col :span="12">
......@@ -437,7 +465,8 @@ import {
updatePolicyCommission,
incomeStatistics,
incomeEditRecords,
incomeCompareRecords
incomeCompareRecords,
policyData
} from '@/api/financial/commission'
import FileUpload from '@/components/FileUpload/index'
......@@ -449,8 +478,8 @@ import { listType } from '@/api/system/dict/type'
// 添加表格引用
const tableRef = ref()
const statisticList = ref([
{ name: '金额', value: '0', key: 'totalAmount', format: true },
{ name: '入账金额', value: '0', key: 'totalPaidAmount', format: true },
{ name: '合计应入账金额', value: '0', key: 'totalAmount', format: true },
{ name: '合计实际入账金额', value: '0', key: 'totalPaidAmount', format: true },
{ name: '待入账金额', value: '0', key: 'pendingPaidAmount', format: true },
{ name: '已入账比例', value: '0', key: 'paidAmountRatio', format: false },
{ name: '总保单数', value: '0', key: 'totalPolicyCount', format: false }
......@@ -478,6 +507,46 @@ const currentRowOperation = ref({})
const isSearch = ref(false)
const editStatus = ref('add')
const policyLoading = ref(false)
const policyOptions = ref([])
// 搜索保单方法
const searchPolicy = query => {
policyLoading.value = true
try {
const params = {
policyNo: query,
pageNo: 1,
pageSize: 10
}
policyData(params).then(response => {
policyOptions.value = response.data.records
})
} catch (error) {
console.error('保单号搜索失败', error)
policyOptions.value = []
} finally {
policyLoading.value = false
}
}
const plilcyChange = () => {
policyOptions.value.forEach(item => {
if (incomeForm.policyNo == item.policyNo) {
incomeForm.premium = item.premium
incomeForm.totalPeriod = item.totalPeriod
}
})
}
const periodChange = () => {
if (
incomeForm.totalPeriod &&
incomeForm.commissionPeriod &&
incomeForm.commissionPeriod > incomeForm.totalPeriod
) {
ElMessage.error('当前期数不能大于总期数')
incomeForm.commissionPeriod = '1'
}
}
const getAlignmentData = () => {
let data = {
commissionBizId: currentRowOperation.value.commissionBizId,
......@@ -864,7 +933,7 @@ const handleAdd = () => {
currency: 'HKD',
commissionDate: '',
remark: '',
exchangeRate: '',
exchangeRate: '7.80',
premium: '',
status: ''
})
......
......@@ -477,6 +477,7 @@ const processFormData = async () => {
editStatus.value = true
} else {
editStatus.value = false
form.value.customerType = 'INDIVIDUAL'
processedCustomerData.value = oldCustomerData.value = processedData
}
}
......
......@@ -876,7 +876,6 @@ const setFormValue = (obj, formData) => {
}
}
}
}
}
}
......
<template>
<div class="app-container">
<!-- 步骤条 -->
<!-- <el-row style="margin-bottom: 30px">
<el-col :span="24">
<Step :stepList="stepList"></Step>
</el-col>
</el-row> -->
<!-- 条件查询 -->
<el-row>
<el-col :span="24">
<el-form
:model="queryParams"
ref="queryRef"
:inline="true"
v-show="showSearch"
label-width="70px"
>
<el-form-item
><el-button type="primary" icon="Plus" @click="handleAdd"
>新建流程</el-button
></el-form-item
>
<el-form-item label="创建时间" style="width: 300px">
<el-date-picker
v-model="dateRange"
value-format="YYYY-MM-DD"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item label="流程编号" prop="fnaNo">
<el-input
v-model="queryParams.fnaNo"
placeholder="请输入流程编号"
clearable
style="width: 150px"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="客户姓名" prop="customerName">
<el-input
v-model="queryParams.customerName"
placeholder="请输入姓名"
clearable
style="width: 140px"
@keyup.enter="handleQuery"
/>
</el-form-item>
<CommonPage
:operationBtnList="operationBtnList"
:showSearchForm="true"
:show-pagination="false"
>
<!-- 查询条件插槽 -->
<template #searchForm>
<el-form :model="queryParams" ref="queryRef" label-width="78px">
<el-row :gutter="50">
<el-col :span="8">
<el-form-item label="创建时间">
<el-date-picker
v-model="dateRange"
value-format="YYYY-MM-DD"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
@clear="clearDateRange"
style="width: 100%"
></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="流程编号" prop="fnaNo">
<el-input
v-model="queryParams.fnaNo"
placeholder="请输入流程编号"
clearable
@keyup.enter="handleQuery"
style="width: 100%"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="客户姓名" prop="customerName">
<el-input
v-model="queryParams.customerName"
placeholder="请输入姓名"
clearable
@keyup.enter="handleQuery"
style="width: 100%"
/>
</el-form-item>
</el-col>
<el-form-item label="状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="请选择"
clearable
style="width: 110px"
>
<el-option
v-for="dict in csf_fna_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">查询</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
<el-col :span="8">
<el-form-item label="状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="请选择"
clearable
style="width: 100%"
>
<el-option
v-for="dict in csf_fna_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-col>
</el-row>
</template>
<el-table
v-loading="loading"
:data="tenantList"
@selection-change="tableSelect"
@sort-change="sortChange"
>
<!-- <el-table-column type="selection" width="55" /> -->
<el-table-column type="index" width="50" label="序号" />
<el-table-column label="客户姓名" align="center" prop="customerName" width="100" />
<el-table-column label="状态" align="center" width="150">
<template #default="scope">
<span v-if="scope.row.status == 'UNCOMPLETED'">
<span style="color: #ff7d00" class="iconfont icon-yanqiweiwancheng"></span> 未完成
</span>
<span v-if="scope.row.status == 'COMPLETED'"
><span style="color: #43cf7c" class="iconfont icon-yiwancheng"></span> 已完成
</span>
<span v-if="scope.row.status == 'DRAFT'"
><span style="color: #86909c" class="iconfont icon-genjinjilu"></span> 草稿
</span>
</template>
</el-table-column>
<el-table-column
label="流程编号"
align="center"
prop="fnaNo"
width="200"
show-overflow-tooltip
/>
<el-table-column
label="预约编号"
align="center"
prop="appointmentNo"
width="200"
show-overflow-tooltip
/>
<el-table-column label="新单编号" align="center" prop="policyId" />
<el-table-column label="保单号" align="center" prop="policyNo" width="150" />
<!-- 表格插槽 -->
<template #table>
<el-table
v-loading="loading"
:data="tenantList"
@selection-change="tableSelect"
@sort-change="sortChange"
>
<el-table-column type="index" width="50" label="序号" />
<el-table-column label="客户姓名" align="center" prop="customerName" width="100" />
<el-table-column label="状态" align="center" width="150">
<template #default="scope">
<span v-if="scope.row.status == 'UNCOMPLETED'">
<span style="color: #ff7d00" class="iconfont icon-yanqiweiwancheng"></span> 未完成
</span>
<span v-if="scope.row.status == 'COMPLETED'"
><span style="color: #43cf7c" class="iconfont icon-yiwancheng"></span> 已完成
</span>
<span v-if="scope.row.status == 'DRAFT'"
><span style="color: #86909c" class="iconfont icon-genjinjilu"></span> 草稿
</span>
</template>
</el-table-column>
<el-table-column
label="流程编号"
align="center"
prop="fnaNo"
width="200"
show-overflow-tooltip
/>
<el-table-column
label="预约编号"
align="center"
prop="appointmentNo"
width="200"
show-overflow-tooltip
/>
<el-table-column label="新单编号" align="center" prop="policyId" />
<el-table-column label="保单号" align="center" prop="policyNo" width="150" />
<el-table-column label="创建时间" sortable align="center" prop="createTime" width="200">
<template #default="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column
label="操作"
align="center"
width="250"
class-name="small-padding fixed-width"
fixed="right"
>
<template #default="scope">
<el-button type="primary" link @click="handleUpdate(scope.row)">修改</el-button>
<el-button type="success" link @click="handleCopy(scope.row)">生成副本</el-button>
<el-button v-if="!scope.row.policyNo" type="danger" link @click="handleDelete(scope.row)"
>删除</el-button
<el-table-column label="创建时间" sortable align="center" prop="createTime" width="200">
<template #default="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column
label="操作"
align="center"
width="250"
class-name="small-padding fixed-width"
fixed="right"
>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total >= 0"
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
<template #default="scope">
<el-button type="primary" link @click="handleUpdate(scope.row)">修改</el-button>
<el-button type="success" link @click="handleCopy(scope.row)">生成副本</el-button>
<el-button
v-if="!scope.row.policyNo"
type="danger"
link
@click="handleDelete(scope.row)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<div style="width: 100%; display: flex; justify-content: flex-end; margin-bottom: 30px">
<pagination
v-show="total >= 0"
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
style="text-align: right"
/>
</div>
</template>
</CommonPage>
<!-- 下一步到预约 -->
<div class="bottomBtn">
<el-button type="primary" @click="goToAppointment">下一步</el-button>
......@@ -149,15 +152,10 @@
</template>
<script setup name="FnaList">
import Step from '@/views/components/moduleStep'
import CommonPage from '@/components/commonPage'
import { getFnaList, deleteFna, subProcess } from '@/api/sign/fna'
import useUserStore from '@/store/modules/user'
const stepList = ref([
{ title: 'FNA', id: 1, finish: false, todo: true, unFinish: false },
{ title: '预约', id: 2, todo: false, finish: false, unFinish: true },
{ title: '新单跟进', id: 3, finish: false, todo: false, unFinish: true }
])
const userStore = useUserStore()
const router = useRouter()
const { proxy } = getCurrentInstance()
......@@ -165,16 +163,13 @@ const { csf_fna_status } = proxy.useDict('csf_fna_status')
const tenantList = ref([])
const loading = ref(true)
const showSearch = ref(true)
const ids = ref([])
const total = ref(0)
const dateRange = ref([])
const selectIdsList = ref([])
const data = reactive({
form: {},
queryParams: {
pageNo: 1,
pageSize: 8,
pageSize: 10,
startTime: '',
endTime: '',
sortField: '',
......@@ -183,6 +178,35 @@ const data = reactive({
})
const { queryParams, form, rules } = toRefs(data)
const operationBtnList = ref([
{
label: '新建流程',
icon: 'Plus',
type: 'primary',
direction: 'left',
size: 'small',
click: handleAdd
},
{
label: '搜索',
icon: 'Search',
type: 'primary',
direction: 'right',
size: 'small',
click: handleQuery
},
{
label: '重置',
icon: 'Refresh',
type: 'info',
direction: 'right',
size: 'small',
click: resetQuery
}
])
const clearDateRange = () => {
dateRange.value = []
}
const handleCopy = row => {
// { fnaBizId: row.fnaBizId }
subProcess({ fnaBizId: row.fnaBizId }).then(response => {
......@@ -191,7 +215,6 @@ const handleCopy = row => {
proxy.$modal.msgSuccess('生成副本成功')
}
})
}
const sortChange = ({ prop, order }) => {
if (order == 'ascending') {
......@@ -216,6 +239,9 @@ function getList() {
if (dateRange.value.length > 0) {
queryParams.value.startTime = `${dateRange.value[0]} 00:00:00`
queryParams.value.endTime = `${dateRange.value[1]} 23:59:59`
} else {
queryParams.value.startTime = ''
queryParams.value.endTime = ''
}
loading.value = true
try {
......@@ -282,7 +308,7 @@ function handleAdd() {
function handleUpdate(row) {
router.push({
path: '/sign/FnaList/edit',
query: { fnaBizId: row.fnaBizId, type: 'edit', status: row.status, source:'fnaList'}
query: { fnaBizId: row.fnaBizId, type: 'edit', status: row.status, source: 'fnaList' }
})
}
......@@ -290,8 +316,15 @@ getList()
</script>
<style lang="scss" scoped>
.bottomBtn {
width: 100%;
box-sizing: border-box;
width: 95%;
text-align: right;
margin-top: 20px;
position: fixed;
bottom: 0;
background-color: #fff;
z-index: 999;
border-top: 1px solid rgb(247 247 247);
padding: 10px 20px;
}
</style>
......@@ -318,7 +318,7 @@ import {
editAppointmentDetail,
uploadExcel
} from '@/api/sign/appointment'
import { getPolicyfollow, getPolicyInfo } from '@/api/sign/underwritingMain'
import { getPolicyfollow, getPolicyInfo, signName } from '@/api/sign/underwritingMain'
import { listTenantUser, getInsuranceProductList, getAdditionalProductList } from '@/api/common'
import { Check } from '@element-plus/icons-vue'
import { ref, nextTick, onUnmounted } from 'vue'
......@@ -588,6 +588,28 @@ function getCustomerInfo(customerBizId) {
}
// 获取各个流程所需要得字典数据
const getDictsData = async () => {
if (route.query.source == 'policyList') {
const params4 = {
pageNo: 1,
pageSize: 10,
policyNo: ''
}
const response4 = await signName(params4)
if (response4.code == 200) {
response4.data.records = response4.data.records.map(item => {
// return {
// ...item,
// label: item.productName,
// value: item.additionalProductBizId
// }
return item
})
dictStore.setSignNameList(response4.data.records)
console.log('response4', response4.data.records)
}
return
}
// 获取租户用户列表
const params1 = {
tenantBizId: userStore.projectInfo.tenantBizId,
......@@ -631,6 +653,7 @@ const getDictsData = async () => {
})
dictStore.setAdditionalProductList(response3.data.records)
}
proxy.useDictLists([
'csf_employment',
'sys_no_yes',
......@@ -1082,6 +1105,7 @@ if (route.query.source == 'policyList') {
idsObj.value.appointmentBizId = route.query.appointmentBizId
isEmbed.value = route.query.embed
getDictsData()
tabsList.value = [
{
label: '预计来佣',
......
<template>
<div class="app-container">
<!-- 步骤条 -->
<!-- <el-row style="margin-bottom: 30px">
<el-col :span="24">
<Step :stepList="stepList"></Step>
</el-col>
</el-row> -->
<!-- 条件查询 -->
<el-row>
<el-col :span="24">
<el-form
:model="queryParams"
ref="queryRef"
:inline="true"
v-show="showSearch"
label-width="100px"
>
<el-form-item label="确认预约时间" style="width: 300px">
<el-date-picker
v-model="dateRange"
value-format="YYYY-MM-DD"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
@clear="clearDate"
></el-date-picker>
</el-form-item>
<el-form-item label="预约编号" prop="appointmentNo">
<el-input
v-model="queryParams.appointmentNo"
placeholder="请输入预约编号"
clearable
style="width: 150px"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="预约状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="请选择"
clearable
style="width: 110px"
>
<el-option
v-for="dict in csf_ap_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">查询</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
<CommonPage
:operationBtnList="operationBtnList"
:showSearchForm="true"
:show-pagination="false"
>
<!-- 查询条件插槽 -->
<template #searchForm>
<el-form :model="queryParams" ref="queryRef" label-width="100px">
<el-row :gutter="30">
<el-col :span="10">
<el-form-item label="确认预约时间">
<el-date-picker
v-model="dateRange"
value-format="YYYY-MM-DD"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
@clear="clearDate"
style="width: 100%"
></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="7">
<el-form-item label="预约编号" prop="appointmentNo">
<el-input
style="width: 100%"
v-model="queryParams.appointmentNo"
placeholder="请输入预约编号"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
</el-col>
<el-col :span="7">
<el-form-item label="预约状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="请选择"
clearable
style="width: 100%"
>
<el-option
v-for="dict in csf_ap_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-col>
</el-row>
</template>
<el-table
v-loading="loading"
:data="tenantList"
@selection-change="tableSelect"
@sort-change="sortChange"
>
<!-- <el-table-column type="selection" width="55" /> -->
<el-table-column type="index" label="序号" width="50" />
<el-table-column label="预约编号" align="center" prop="appointmentNo" width="200" />
<el-table-column label="预约状态" align="center">
<template #default="scope">
<dict-tag :options="csf_ap_status" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column label="最终预约时间" align="center" width="180">
<template #default="scope">
<span>{{
scope.row.confirmAppointmentTime ? parseTime(scope.row.confirmAppointmentTime) : '--'
}}</span>
</template>
</el-table-column>
<el-table-column label="产品名称" align="center" prop="productName" width="150" />
<el-table-column label="保险公司" align="center" prop="companyName" width="150" />
<el-table-column label="业务员" align="center" prop="businessRepresentName1" width="150" />
<!-- 表格插槽 -->
<template #table>
<el-table
v-loading="loading"
:data="tenantList"
@selection-change="tableSelect"
@sort-change="sortChange"
>
<el-table-column type="index" label="序号" width="50" />
<el-table-column label="预约编号" align="center" prop="appointmentNo" width="200" />
<el-table-column label="预约状态" align="center">
<template #default="scope">
<dict-tag :options="csf_ap_status" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column label="最终预约时间" align="center" width="180">
<template #default="scope">
<span>{{
scope.row.confirmAppointmentTime
? parseTime(scope.row.confirmAppointmentTime)
: '--'
}}</span>
</template>
</el-table-column>
<el-table-column label="产品名称" align="center" prop="productName" width="150" />
<el-table-column label="保险公司" align="center" prop="companyName" width="150" />
<el-table-column
label="业务员"
align="center"
prop="businessRepresentName1"
width="150"
/>
<el-table-column label="投保人" align="center" prop="policyholder" width="150" />
<el-table-column label="受保人" align="center" prop="insurant" width="150" />
<el-table-column label="供款年期" align="center" prop="paymentTerm" width="100" />
<el-table-column label="每期保费" align="center" prop="eachIssuePremium" width="100" />
<el-table-column label="投保人" align="center" prop="policyholder" width="150" />
<el-table-column label="受保人" align="center" prop="insurant" width="150" />
<el-table-column label="供款年期" align="center" prop="paymentTerm" width="100" />
<el-table-column label="每期保费" align="center" prop="eachIssuePremium" width="100" />
<el-table-column label="货币" align="center" width="150">
<template #default="scope">
<dict-tag :options="bx_currency_type" :value="scope.row.currency" />
</template>
</el-table-column>
<el-table-column label="货币" align="center" width="150">
<template #default="scope">
<dict-tag :options="bx_currency_type" :value="scope.row.currency" />
</template>
</el-table-column>
<el-table-column
label="意向预约时间"
align="center"
prop="intentionAppointmentTime"
width="240"
show-overflow-tooltip
>
<template #default="scope">
<span>{{
scope.row.intentionAppointmentTime
? parseTime(scope.row.intentionAppointmentTime)
: '--'
}}</span>
</template>
</el-table-column>
<!-- sortable -->
<el-table-column label="创建时间" align="center" prop="createTime" width="150">
<template #default="scope">
<span>{{ formatToDate(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column
label="操作"
align="left"
width="250"
class-name="small-padding fixed-width"
fixed="right"
>
<template #default="scope">
<el-button link type="primary" @click="handleUpdate(scope.row)">修改</el-button>
<el-button
link
type="primary"
v-if="scope.row.status == 2 || scope.row.status == 3"
@click="getAppointmentInfo(scope.row.appointmentBizId)"
>查看行程单</el-button
<el-table-column
label="意向预约时间"
align="center"
prop="intentionAppointmentTime"
width="240"
show-overflow-tooltip
>
<el-button link type="primary" @click="handleExprot(scope.row)">导出</el-button>
<el-button
link
type="danger"
v-if="scope.row.status === 0"
@click="handleDelete(scope.row)"
>删除</el-button
<template #default="scope">
<span>{{
scope.row.intentionAppointmentTime
? parseTime(scope.row.intentionAppointmentTime)
: '--'
}}</span>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" width="150">
<template #default="scope">
<span>{{ formatToDate(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column
label="操作"
align="left"
width="250"
class-name="small-padding fixed-width"
fixed="right"
>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total >= 0"
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
<template #default="scope">
<el-button link type="primary" @click="handleUpdate(scope.row)">修改</el-button>
<el-button
link
type="primary"
v-if="scope.row.status == 2 || scope.row.status == 3"
@click="getAppointmentInfo(scope.row.appointmentBizId)"
>查看行程单</el-button
>
<el-button link type="primary" @click="handleExprot(scope.row)">导出</el-button>
<el-button
link
type="danger"
v-if="scope.row.status === 0"
@click="handleDelete(scope.row)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<div style="width: 100%; display: flex; justify-content: flex-end; margin-bottom: 30px">
<pagination
v-show="total >= 0"
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</div>
</template>
</CommonPage>
<!-- 下一步到预约 -->
<div class="bottomBtn">
<el-button type="success" @click="goToAppointment('previousStep')">上一步</el-button>
<el-button type="primary" @click="goToAppointment('nextStep')">下一步</el-button>
</div>
<!-- 展示行程单详情 -->
<el-dialog v-model="dialogVisible" width="70%">
<CommonDialog
dialogTitle="香港行程安排"
confirmText="下载行程单"
cancleText="关闭"
dialogWidth="70%"
:openDialog="dialogVisible"
@confirm="handleExprotPdf"
@close="dialogVisible = false"
>
<div class="dialogBox">
<div class="dialogTitle">香港行程安排</div>
<div class="dialogItem" v-for="item in detailData">
<div class="dialogItemTitle">{{ item.title }}</div>
<DetailPanel
......@@ -177,24 +191,16 @@
</div>
<div class="remarkEmpty" v-else>暂无备注</div>
</div>
<div class="exprotBtn">
<el-button
:loading="exportLoading"
type="primary"
style="margin-top: 15px"
@click="handleExprotPdf"
>下载行程单</el-button
>
</div>
</div>
</el-dialog>
</CommonDialog>
</div>
</template>
<script setup name="Appointment">
import CommonPage from '@/components/commonPage'
import DetailPanel from '@/components/DetailPanel'
import { onMounted, onActivated, ref } from 'vue'
import Step from '@/views/components/moduleStep'
import CommonDialog from '@/components/commonDialog'
import {
getAppointmentList,
getAppointmentExprot,
......@@ -203,11 +209,7 @@ import {
getItineraryExprot
} from '@/api/sign/appointment'
import useUserStore from '@/store/modules/user'
const stepList = ref([
{ title: 'FNA', id: 1, finish: true, todo: false, unFinish: false },
{ title: '预约', id: 2, todo: true, finish: false, unFinish: false },
{ title: '新单跟进', id: 3, finish: false, todo: false, unFinish: true }
])
const userStore = useUserStore()
const router = useRouter()
const { proxy } = getCurrentInstance()
......@@ -221,11 +223,29 @@ const total = ref(0)
const dateRange = ref([])
const detailData = ref([]) //行程单-行程信息
const exportLoading = ref(false)
const operationBtnList = ref([
{
label: '搜索',
icon: 'Search',
type: 'primary',
direction: 'right',
size: 'small',
click: handleQuery
},
{
label: '重置',
icon: 'Refresh',
type: 'info',
direction: 'right',
size: 'small',
click: resetQuery
}
])
const data = reactive({
form: {},
queryParams: {
pageNo: 1,
pageSize: 8,
pageSize: 10,
startTime: '',
endTime: ''
}
......@@ -256,7 +276,6 @@ const handleExprotPdf = () => {
link.click()
document.body.removeChild(link)
exportLoading.value = false
// proxy.$message.success('行程单下载成功')
dialogVisible.value = false
} else {
proxy.$message.error('行程单下载失败')
......@@ -517,20 +536,23 @@ function handleUpdate(row) {
getList()
</script>
<style lang="scss" scoped>
/* ::v-deep .el-step__head.is-success {
color: none !important;
background-color: #e8f3ff !important;
border: none !important;
} */
/* ::v-deep .el-step__icon {
background-color: #e8f3ff !important;
} */
.app-container {
box-sizing: border-box;
}
.bottomBtn {
width: 100%;
box-sizing: border-box;
width: 95%;
text-align: right;
margin-top: 20px;
position: fixed;
bottom: 0;
background-color: #fff;
z-index: 999;
border-top: 1px solid rgb(247 247 247);
padding: 10px 20px;
}
.dialogBox {
padding: 0 15px;
.dialogTitle {
display: flex;
align-items: center;
......
......@@ -528,11 +528,15 @@ watch(
newVal => {
if (newVal === 'expectedCommission') {
searchOptions.value['reconciliationCompany'] = dictStore.insureCompanyList
getTableList()
if (props.policyNo) {
getTableList()
}
}
}
)
getTableList()
if (props.policyNo) {
getTableList()
}
</script>
<style lang="scss" scoped>
.domEmpty {
......
......@@ -117,12 +117,37 @@
<span class="required-label">姓名</span>
</template>
<template #default="scope">
<el-input
<!-- <el-input
size="default"
placeholder="请输入"
v-model="scope.row.signer"
:disabled="editStatus"
/>
/> -->
<el-select
v-model="scope.row.signer"
filterable
remote
reserve-keyword
placeholder="请选择"
:remote-method="searchName"
:loading="nameLoading"
remote-show-suffix
:disabled="editStatus"
>
<el-option
v-if="nameOptions.length === 0"
disabled
value=""
label="暂无数据"
style="color: #909399; text-align: center"
/>
<el-option
v-for="item in nameOptions"
:key="item.policyBizId"
:label="item.policyNo"
:value="item.policyNo"
/>
</el-select>
</template>
</el-table-column>
<el-table-column label="手机号" prop="phone" align="center">
......@@ -246,7 +271,7 @@ import {
getAllCompanys,
getClientUser
} from '@/api/common'
import { updatePolicyfollow, getPolicyfollow } from '@/api/sign/underwritingMain'
import { updatePolicyfollow, getPolicyfollow, signName } from '@/api/sign/underwritingMain'
import useUserStore from '@/store/modules/user'
const userStore = useUserStore()
const dictStore = useDictStore() //获取字典数据
......@@ -294,6 +319,28 @@ const {
tempFanFormValue,
tempFanFormData
} = toRefs(data)
const nameLoading = ref(false)
const nameOptions = ref([])
// 搜索签单人姓名方法
const searchName = query => {
nameLoading.value = true
try {
const params = {
policyNo: query,
pageNo: 1,
pageSize: 10
}
signName(params).then(response => {
nameOptions.value = response.data.records
})
} catch (error) {
console.error('保单号搜索失败', error)
nameOptions.value = []
} finally {
nameLoading.value = false
}
}
const disabledDate = time => {
return time.getTime() > Date.now()
}
......@@ -451,7 +498,8 @@ const processFormData = () => {
loading.value = true
// 深拷贝原始数据
const processedData = JSON.parse(JSON.stringify(policyInfo))
// 给签单员姓名加options
nameOptions.value = dictStore.signNameList
for (const section of processedData) {
if (section.fatherRequired) {
rules.value[section.key] = {}
......
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