Commit 8f8977d8 by Sweet Zhang

对接保单来佣和发佣

parent 35ccd9f3
...@@ -50,9 +50,10 @@ export function getPolicyFortuneList(data) { ...@@ -50,9 +50,10 @@ export function getPolicyFortuneList(data) {
export function downloadPolicyFortune(data) { export function downloadPolicyFortune(data) {
return request({ return request({
url: '/csf/api/fortune/download', url: '/csf/api/fortune/download/raw',
method: 'post', method: 'post',
data: data data: data,
responseType: 'blob'
}) })
} }
...@@ -75,3 +76,15 @@ export function getReferrerFortuneList(data) { ...@@ -75,3 +76,15 @@ export function getReferrerFortuneList(data) {
data: data data: data
}) })
} }
// 删除来佣数据
// /csf/api/commission/delete
export function deletePolicyCommission(data) {
return request({
url: '/csf/api/commission/delete',
method: 'post',
data: data
})
}
...@@ -7,4 +7,23 @@ export function getPolicyFollowList(data) { ...@@ -7,4 +7,23 @@ export function getPolicyFollowList(data) {
method: 'post', method: 'post',
data: data data: data
}) })
}
// 获取预计来佣列表
// /csf/api/commission/list/page/commission_expected
export function getExpectedCommissionList(data) {
return request({
url: '/csf/api/policy/list/page/commission_expected',
method: 'post',
data: data
})
}
// 更新至保单库
export function updateToPolicyLib(data) {
return request({
url: '/csf/api/policy_follow/addToPolicy',
method: 'post',
data: data
})
} }
\ No newline at end of file
<template> <template>
<div class="upload-file"> <div class="upload-file">
<el-upload <el-upload
multiple :multiple = "multiple"
:action="uploadFileUrl" :action="uploadFileUrl"
:before-upload="handleBeforeUpload" :before-upload="handleBeforeUpload"
:file-list="fileList" :file-list="fileList"
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
v-if="!disabled" v-if="!disabled"
> >
<!-- 上传按钮 --> <!-- 上传按钮 -->
<el-button size="mini" type="primary">{{ uploadBtnText }}</el-button> <el-button size="small" type="primary">{{ uploadBtnText }}</el-button>
<!-- 上传提示 --> <!-- 上传提示 -->
<div class="el-upload__tip" v-if="showTip"> <div class="el-upload__tip" v-if="showTip">
请上传 请上传
...@@ -98,6 +98,10 @@ export default { ...@@ -98,6 +98,10 @@ export default {
drag: { drag: {
type: Boolean, type: Boolean,
default: true default: true
},
multiple:{
type: Boolean,
default: true
} }
}, },
data() { data() {
...@@ -116,14 +120,17 @@ export default { ...@@ -116,14 +120,17 @@ export default {
if (this.drag && !this.disabled) { if (this.drag && !this.disabled) {
this.$nextTick(() => { this.$nextTick(() => {
const element = this.$refs.uploadFileList?.$el || this.$refs.uploadFileList const element = this.$refs.uploadFileList?.$el || this.$refs.uploadFileList
Sortable.create(element, { // 添加元素存在性检查,防止undefined错误
ghostClass: 'file-upload-darg', if (element) {
onEnd: (evt) => { Sortable.create(element, {
const movedItem = this.fileList.splice(evt.oldIndex, 1)[0] ghostClass: 'file-upload-darg',
this.fileList.splice(evt.newIndex, 0, movedItem) onEnd: (evt) => {
this.$emit("input", this.listToString(this.fileList)) const movedItem = this.fileList.splice(evt.oldIndex, 1)[0]
} this.fileList.splice(evt.newIndex, 0, movedItem)
}) this.$emit("input", this.listToString(this.fileList))
}
})
}
}) })
} }
}, },
...@@ -224,7 +231,7 @@ export default { ...@@ -224,7 +231,7 @@ export default {
} }
this.uploadList = [] this.uploadList = []
this.number = 0 this.number = 0
this.$emit("input", this.uploadList.length > 0 ? this.listToString(this.fileList):code) this.$emit("uploadEnd", this.uploadList.length > 0 ? this.listToString(this.fileList):code)
this.$modal.closeLoading() this.$modal.closeLoading()
}, },
// 获取文件名称 // 获取文件名称
...@@ -275,4 +282,4 @@ export default { ...@@ -275,4 +282,4 @@ export default {
.el-upload__tip{ .el-upload__tip{
margin-left: 10px; margin-left: 10px;
} }
</style> </style>
\ No newline at end of file
<template>
<el-dialog
:model-value="visible"
:title="title"
width="80%"
top="5vh"
:close-on-click-modal="false"
class="detail-dialog"
@update:model-value="handleVisibleChange"
@close="handleClose"
>
<el-tabs v-model="activeTab" class="detail-tabs">
<!-- 保单信息 -->
<el-tab-pane label="保单信息" name="policy">
<el-descriptions :column="2" border>
<el-descriptions-item label="保单号">{{ detailData.policyNo || '-' }}</el-descriptions-item>
<el-descriptions-item label="客户名称">{{ detailData.customerName || '-' }}</el-descriptions-item>
<el-descriptions-item label="签单日期">{{ detailData.signDate || '-' }}</el-descriptions-item>
<el-descriptions-item label="签单人">{{ detailData.signer || '-' }}</el-descriptions-item>
<el-descriptions-item label="供款年期">{{ detailData.paymentTerm || '-' }}</el-descriptions-item>
<el-descriptions-item label="产品名称">{{ detailData.productName || '-' }}</el-descriptions-item>
<el-descriptions-item label="保险公司">{{ detailData.insurer || '-' }}</el-descriptions-item>
<el-descriptions-item label="对账公司">{{ detailData.reconciliationCompany || '-' }}</el-descriptions-item>
<el-descriptions-item label="保单持有人">{{ detailData.policyHolder || '-' }}</el-descriptions-item>
<el-descriptions-item label="受保人">{{ detailData.insured || '-' }}</el-descriptions-item>
<el-descriptions-item label="币种">{{ detailData.currency || '-' }}</el-descriptions-item>
<el-descriptions-item label="首期保费">{{ numberWithCommas(detailData.initialPremium || 0) }}</el-descriptions-item>
<el-descriptions-item label="新单状态">{{ convertStatusToDict(detailData.status) || '-' }}</el-descriptions-item>
</el-descriptions>
</el-tab-pane>
<!-- 入账信息 -->
<el-tab-pane label="入账信息" name="income">
<el-table :data="expectedCommissionList" border size="small">
<el-table-column type="index" width="30" />
<el-table-column prop="reconciliationCompany" label="对账公司" align="center" />
<el-table-column prop="commissionPeriod" label="佣金期数" align="center" />
<el-table-column prop="totalPeriod" label="总佣金期数" align="center" />
<el-table-column prop="commissionName" label="来佣名称" align="center" />
<!-- <el-table-column prop="commissionType" label="来佣类型" align="center" /> -->
<el-table-column prop="amount" label="来佣金额" align="center" />
<el-table-column prop="currency" label="币种" align="center" />
<el-table-column prop="commissionDate" label="来佣日期" align="center" />
<el-table-column prop="commissionStatusLabel" label="来佣状态" align="center" />
<el-table-column prop="remark" label="备注" align="center" />
<el-table-column prop="creatorId" label="创建人" align="center" />
<el-table-column prop="updaterId" label="更新人" align="center" />
<el-table-column prop="createTime" label="创建时间" align="center" />
<el-table-column prop="updateTime" label="更新时间" align="center" />
<!-- <template #append>
<div style="padding: 20px;display: flex;justify-content: end;">
<el-pagination
v-model:current-page="currentPage1"
:page-size="pageSize1"
background
layout="total, prev, pager, next"
:total="total1"
@current-change="handleCurrentChange('expectedCommissionList')"
/>
</div>
</template> -->
</el-table>
</el-tab-pane>
<!-- 出账信息 -->
<el-tab-pane label="出账信息" name="expense">
<el-descriptions :column="2" border>
<el-descriptions-item label="出账状态">{{ detailData.expenseStatus || '-' }}</el-descriptions-item>
<el-descriptions-item label="出账金额">{{ numberWithCommas(detailData.expenseAmount || 0) }}</el-descriptions-item>
<el-descriptions-item label="出账日期">{{ detailData.expenseDate || '-' }}</el-descriptions-item>
<el-descriptions-item label="出账银行">{{ detailData.expenseBank || '-' }}</el-descriptions-item>
<el-descriptions-item label="出账账号">{{ detailData.expenseAccount || '-' }}</el-descriptions-item>
<el-descriptions-item label="出账凭证号">{{ detailData.expenseVoucherNo || '-' }}</el-descriptions-item>
<el-descriptions-item label="出账备注">{{ detailData.expenseRemark || '-' }}</el-descriptions-item>
</el-descriptions>
</el-tab-pane>
<!-- 转介人信息 -->
<el-tab-pane label="转介人信息" name="broker">
<el-table :data="detailData.brokerList" border size="small">
<el-table-column prop="brokerName" label="姓名" align="center" />
<el-table-column prop="team" label="团队" align="center" />
<el-table-column prop="brokerRatio" label="介绍费占比" align="center" />
<el-table-column prop="remark" label="备注" align="center" />
</el-table>
</el-tab-pane>
<!-- 其他信息 -->
<el-tab-pane label="其他信息" name="other">
<el-descriptions :column="2" border>
<el-descriptions-item label="创建时间">{{ detailData.createTime || '-' }}</el-descriptions-item>
<el-descriptions-item label="更新时间">{{ detailData.updateTime || '-' }}</el-descriptions-item>
<el-descriptions-item label="创建人">{{ detailData.createBy || '-' }}</el-descriptions-item>
<el-descriptions-item label="更新人">{{ detailData.updateBy || '-' }}</el-descriptions-item>
<el-descriptions-item label="备注信息" :span="2">{{ detailData.remark || '-' }}</el-descriptions-item>
</el-descriptions>
</el-tab-pane>
</el-tabs>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleClose">关闭</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
import { ref, watch } from 'vue'
import { numberWithCommas } from '@/utils/index.js'
// 定义props
const props = defineProps({
visible: {
type: Boolean,
default: false
},
detailData: {
type: Object,
default: () => ({})
},
title: {
type: String,
default: '数据详情'
},
policyFollowStatusList: {
type: Array,
default: () => []
},
expectedCommissionList: {
type: Array,
default: () => []
},
})
// 定义emits
const emit = defineEmits(['update:visible', 'close', 'current-change'])
// 响应式数据
const activeTab = ref('policy')
const currentPage1 = ref(1)
const total1 = ref(1000)
const pageSize1 = ref(100)
// 监听visible变化
watch(() => props.visible, (newVal) => {
if (newVal) {
activeTab.value = 'policy'
}
})
// 处理visible变化
const handleVisibleChange = (value) => {
emit('update:visible', value)
}
// 状态转换函数
const convertStatusToDict = (status) => {
const dictItem = props.policyFollowStatusList.find(item => item.itemValue == status)
return dictItem?.itemLabel ?? status
}
// 关闭弹窗
const handleClose = () => {
emit('update:visible', false)
emit('close')
}
// 表格分页当前页改变
const handleCurrentChange = (val) => {
console.log(`当前页: ${val}`)
emit('current-change', val,currentPage1.value)
}
</script>
<style scoped>
.detail-dialog {
max-height: 80vh;
}
.detail-tabs {
max-height: 60vh;
overflow-y: auto;
}
.detail-tabs .el-tab-pane {
padding: 20px;
}
.broker-section {
margin-top: 20px;
}
.broker-section h4 {
margin-bottom: 15px;
color: #303133;
font-weight: 600;
}
/* 响应式调整详情弹窗 */
@media (max-width: 768px) {
.detail-dialog {
width: 95% !important;
}
.detail-tabs .el-descriptions {
font-size: 12px;
}
}
</style>
\ No newline at end of file
{
"id": 5,
"fnaFormBizId": "fna_form_8VXGgMskIU3uZWG7",
"customerBizId": "customer_bkr6dz9BkYGar48o",
"personalData": {
"accountName": "user_1002",
"registrationNumber": "11",
"number": null,
"customerName": "11",
"taxCountry": "11",
"employment": "PRAT_TIME",
"otherEmployment": null,
"isRetired": "1",
"retiredAge": null
},
"familyMembers": [
{
"type": "1",
"needProvide": "1",
"age": "11"
},
{
"type": "2",
"needProvide": "1",
"age": "11"
},
{
"type": "3",
"needProvide": "1",
"age": "11"
},
{
"type": "4",
"needProvide": "1",
"age": "11"
}
],
"existingSecurityOwner": [],
"existingSecurityInsured": [],
"incomeExpense": {
"monthlyIncome": null,
"monthlyExpense": null
},
"liquidAssets": {
"liquidAssets": null,
"liquidAssetType": null,
"otherLiquidAsset": null
},
"primaryResidence": null,
"investment": null,
"companyBusinessData": {
"averageNetProfit": null,
"estimatedTotalAssets": null,
"currency": null,
"assetPercentage": null
},
"other": {
"premiumFundingSource": null
}
}
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { de } from 'element-plus/es/locales.mjs'
export function formatIsoToDateTime(isoStr) { export function formatIsoToDateTime(isoStr) {
// 处理 null/undefined 情况,避免报错 // 处理 null/undefined 情况,避免报错
...@@ -23,3 +24,10 @@ export const getNowTime = (format = DATE_TIME_FORMAT) => { ...@@ -23,3 +24,10 @@ export const getNowTime = (format = DATE_TIME_FORMAT) => {
if (!date) return '' if (!date) return ''
return dayjs().format(format) return dayjs().format(format)
} }
export default {
formatIsoToDateTime,
formatToDateTime,
formatToDate,
getNowTime
}
...@@ -378,7 +378,7 @@ export const selectComponents = [ ...@@ -378,7 +378,7 @@ export const selectComponents = [
'color-format': '', 'color-format': '',
disabled: false, disabled: false,
required: true, required: true,
size: 'default', size: '', // 将 'default' 改为 '' 或 'small'
regList: [], regList: [],
changeTag: true, changeTag: true,
document: 'https://element-plus.org/zh-CN/component/color-picker', document: 'https://element-plus.org/zh-CN/component/color-picker',
...@@ -449,4 +449,4 @@ export const trigger = { ...@@ -449,4 +449,4 @@ export const trigger = {
'el-time-picker': 'change', 'el-time-picker': 'change',
'el-date-picker': 'change', 'el-date-picker': 'change',
'el-rate': 'change', 'el-rate': 'change',
} }
\ No newline at end of file
...@@ -387,4 +387,9 @@ export function camelCase(str) { ...@@ -387,4 +387,9 @@ export function camelCase(str) {
export function isNumberStr(str) { export function isNumberStr(str) {
return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str) return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str)
} }
// 数字千分位格式化,保留2位小数
export function numberWithCommas(x, fixed = 2) {
return x.toFixed(fixed).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
}
...@@ -61,7 +61,6 @@ ...@@ -61,7 +61,6 @@
:uploadBtnText="'批量导入'" :uploadBtnText="'批量导入'"
@input = 'getUploadFileFunc' @input = 'getUploadFileFunc'
:responseType="'onlyStatus'" :responseType="'onlyStatus'"
/> />
</el-col> </el-col>
<el-col :span="12" style="text-align: right;"> <el-col :span="12" style="text-align: right;">
...@@ -76,8 +75,19 @@ ...@@ -76,8 +75,19 @@
</el-row> </el-row>
</el-card> </el-card>
<!-- 数据表格 --> <!-- 数据表格 -->
<el-card> <el-card>
<!-- 增加勾选后下载按钮 -->
<el-col :span="24" style="text-align: right;" v-if="selectedRows.length > 0">
<el-button
type="primary"
@click="downloadSelected"
>
下载选中项
</el-button>
</el-col>
<el-table <el-table
:data="tableData" :data="tableData"
@selection-change="handleSelectionChange" @selection-change="handleSelectionChange"
...@@ -206,7 +216,7 @@ const queryParams = reactive({ ...@@ -206,7 +216,7 @@ const queryParams = reactive({
company: '', company: '',
billingDate: [], billingDate: [],
pageNum: 1, pageNum: 1,
pageSize: 10 pageSize: 100
}) })
// 表格数据 // 表格数据
...@@ -238,7 +248,42 @@ const companyOptions = [ ...@@ -238,7 +248,42 @@ const companyOptions = [
{ label: '公司B', value: 'company_b' }, { label: '公司B', value: 'company_b' },
{ label: '公司C', value: 'company_c' } { label: '公司C', value: 'company_c' }
] ]
// 下载选中项
const downloadSelected = async () => {
if (selectedRows.value.length === 0) {
ElMessage.warning('请选择要下载的项')
return
}
try {
// API调用
const response = await downloadPolicyFortune({
fortuneBizIdList: selectedRows.value.map(row => row.fortuneBizId)
})
if (response) {
ElMessage.success('下载成功')
// 触发文件下载
// 处理下载响应
const blob = response instanceof Blob ? response : new Blob([response], { type: 'application/vnd.ms-excel;charset=utf-8' })
// 创建Blob对象,指定正确的MIME类型
const url = window.URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = url
// 不需要指定文件名,浏览器会自动使用默认文件名
link.download = `出账管理_${new Date().getTime()}.xlsx`
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
window.URL.revokeObjectURL(url)
} else {
ElMessage.error('下载失败')
}
} catch (error) {
ElMessage.error('下载失败')
}
}
const getUploadFileFunc = (data) => { const getUploadFileFunc = (data) => {
console.log(data)
if(data===200){ if(data===200){
ElMessage.success('上传成功'); ElMessage.success('上传成功');
getList() getList()
...@@ -333,7 +378,7 @@ const handleView = (row) => { ...@@ -333,7 +378,7 @@ const handleView = (row) => {
} }
const generateBillingList = () => { const generateBillingList = async () => {
if (selectedRows.value.length === 0) { if (selectedRows.value.length === 0) {
ElMessage.warning('请先选择要生成清单的记录') ElMessage.warning('请先选择要生成清单的记录')
return return
...@@ -344,32 +389,29 @@ const generateBillingList = () => { ...@@ -344,32 +389,29 @@ const generateBillingList = () => {
{ {
type: 'warning' type: 'warning'
} }
).then(() => { ).then(async () => {
console.log('开始生成出账清单') console.log('开始生成出账清单')
const response = await downloadPolicyFortuneAccount({
// 调用下载API
downloadPolicyFortuneAccount({
fortuneBizIdList: selectedRows.value.map(item => item.fortuneBizId) fortuneBizIdList: selectedRows.value.map(item => item.fortuneBizId)
}).then((res)=>{
console.log(res)
if(res){
// 处理下载响应
const blob = res instanceof Blob ? res : new Blob([res], { type: 'application/vnd.ms-excel;charset=utf-8' })
// 创建Blob对象,指定正确的MIME类型
const url = window.URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = url
// 不需要指定文件名,浏览器会自动使用默认文件名
link.download = `出账清单_${new Date().getTime()}.xlsx`
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
window.URL.revokeObjectURL(url)
}else{
ElMessage.error('下载失败')
}
}) })
console.log(response)
// 调用下载API
if(response){
// 处理下载响应
const blob = response instanceof Blob ? response : new Blob([response], { type: 'application/vnd.ms-excel;charset=utf-8' })
// 创建Blob对象,指定正确的MIME类型
const url = window.URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = url
// 不需要指定文件名,浏览器会自动使用默认文件名
link.download = `出账清单_${new Date().getTime()}.xlsx`
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
window.URL.revokeObjectURL(url)
}else{
ElMessage.error('下载失败')
}
selectedRows.value = [] selectedRows.value = []
}).catch((error) => { }).catch((error) => {
if (error !== 'cancel') { if (error !== 'cancel') {
......
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
<div class="import-actions"> <div class="import-actions">
<FileUpload :fileType="['xlsx', 'xls']" <FileUpload :fileType="['xlsx', 'xls']"
:action="'/csf/api/commission/upload/excel'" :action="'/csf/api/commission/upload/excel'"
@input = 'getUploadFileFunc' @uploadEnd = 'getUploadFileFunc'
:responseType="'onlyStatus'" :responseType="'onlyStatus'"
/> />
...@@ -74,16 +74,22 @@ ...@@ -74,16 +74,22 @@
border border
style="width: 100%" style="width: 100%"
@selection-change="handleSelectionChange" @selection-change="handleSelectionChange"
@sort-change="handleSortChange"
> >
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column prop="policyNo" label="保单号" min-width="120" align="center" /> <el-table-column prop="policyNo" label="保单号" min-width="120" align="center" />
<el-table-column prop="reconciliationCompany" label="对账公司" min-width="120" align="center" /> <el-table-column prop="reconciliationCompany" label="对账公司" min-width="120" align="center" />
<el-table-column prop="currentPeriod" label="当前入账期数" min-width="100" align="center" /> <el-table-column prop="commissionPeriod" label="当前入账期数" min-width="100" align="center" />
<el-table-column prop="totalPeriod" label="预计总期数" min-width="100" align="center" /> <el-table-column prop="totalPeriod" label="预计总期数" min-width="100" align="center" />
<el-table-column prop="commissionName" label="入账项目" min-width="120" align="center" /> <el-table-column prop="commissionName" label="入账项目" min-width="120" align="center" />
<el-table-column prop="amount" label="入账金额" min-width="100" align="center" /> <el-table-column prop="amount" label="入账金额" min-width="100" align="center" />
<el-table-column prop="currency" label="入账币种" min-width="80" align="center" /> <el-table-column prop="currency" label="入账币种" min-width="80" align="center" />
<el-table-column prop="commissionDate" label="入账日期" min-width="120" align="center" /> <el-table-column prop="commissionDate" label="入账日期" min-width="120" align="center" />
<el-table-column prop="status" label="比对状态" min-width="100" align="center">
<template #default="scope">
<span>{{convertStatusToDict(scope.row.status) }}</span>
</template>
</el-table-column>>
<el-table-column prop="remark" label="备注" min-width="150" align="center" show-overflow-tooltip /> <el-table-column prop="remark" label="备注" min-width="150" align="center" show-overflow-tooltip />
<el-table-column label="操作" width="180" align="center" fixed="right"> <el-table-column label="操作" width="180" align="center" fixed="right">
<template #default="scope"> <template #default="scope">
...@@ -217,7 +223,43 @@ import * as XLSX from 'xlsx' ...@@ -217,7 +223,43 @@ import * as XLSX from 'xlsx'
import { getPolicyCommissionList, downloadPolicyFortune ,generateCommissionRecord,updatePolicyCommission} from "@/api/financial/commission" import { getPolicyCommissionList, downloadPolicyFortune ,generateCommissionRecord,updatePolicyCommission} from "@/api/financial/commission"
import FileUpload from "@/components/FileUpload/index" import FileUpload from "@/components/FileUpload/index"
import { useRouter } from 'vue-router'
const router = useRouter()
import { listType } from '@/api/system/dict/type'
// 通过dictType=csf_commission_status获取比对状态字典值,获取对象中的dictItemList
const dictLists = ref([]);
const getLists = () => {
return new Promise((resolve, reject) => {
listType({typeList: ['csf_commission_status']}).then(res => {
if (res.code === 200 && res.data) {
const dictData = res.data.find(item => item.dictType === 'csf_commission_status');
dictLists.value = dictData?.dictItemList || [];
console.log('获取到的字典数据:', dictLists.value);
resolve(dictLists.value);
} else {
dictLists.value = [];
resolve([]);
}
}).catch(error => {
console.error('获取状态列表失败:', error);
dictLists.value = [];
reject(error);
});
});
}
// 返回数据中状态需要转换为字典值
const convertStatusToDict = (status) => {
const dictItem = dictLists.value.find(item => item.itemValue == status);
return dictItem?.itemLabel ?? status;
}
// 增加通过表格排序,排序字段sortField,升降序sortOrder
const handleSortChange = (column) => {
pagination.sortField = column.prop
pagination.sortOrder = column.order === 'ascending' ? 'ascend' : 'descend'
fetchTableData()
}
// 搜索表单数据 // 搜索表单数据
const searchForm = reactive({ const searchForm = reactive({
...@@ -249,13 +291,19 @@ const pagination = reactive({ ...@@ -249,13 +291,19 @@ const pagination = reactive({
const selectedFile = ref(null) const selectedFile = ref(null)
const importLoading = ref(false) const importLoading = ref(false)
// 页面加载时获取数据
onMounted(() => { onMounted(() => {
fetchTableData() // 获取字典值后,再调用接口获取来佣列表
initialData();
}) })
const initialData = async () => {
await getLists();
fetchTableData();
}
const getUploadFileFunc = (data) => { const getUploadFileFunc = (data) => {
console.log(data)
if(data===200){ if(data===200){
ElMessage.success('上传成功'); ElMessage.success('上传成功');
fetchTableData() fetchTableData()
...@@ -350,7 +398,7 @@ const handleAdd = () => { ...@@ -350,7 +398,7 @@ const handleAdd = () => {
ElMessage.info('打开新增入账对话框') ElMessage.info('打开新增入账对话框')
} }
import { deletePolicyCommission } from '@/api/financial/commission'
// 删除 // 删除
const handleDelete = (row) => { const handleDelete = (row) => {
ElMessageBox.confirm( ElMessageBox.confirm(
...@@ -362,10 +410,19 @@ const handleDelete = (row) => { ...@@ -362,10 +410,19 @@ const handleDelete = (row) => {
type: 'warning' type: 'warning'
} }
).then(() => { ).then(() => {
ElMessage.success('删除成功') // 调用删除接口
fetchTableData() deletePolicyCommission({
}).catch(() => { commissionBizId: row.commissionBizId
ElMessage.info('已取消删除') }).then((res) => {
if(res.code === 200){
ElMessage.success('删除成功')
fetchTableData()
}else{
ElMessage.error('删除失败')
}
}).catch(() => {
ElMessage.error('删除失败')
})
}) })
} }
...@@ -381,9 +438,9 @@ const handleGenerateBilling = async () => { ...@@ -381,9 +438,9 @@ const handleGenerateBilling = async () => {
await generateCommissionRecord({ await generateCommissionRecord({
commissionBizIdList: selectedRows.value.map(row => row.commissionBizId) commissionBizIdList: selectedRows.value.map(row => row.commissionBizId)
}) })
ElMessage.success('生成成功,正在前往出账管理页面') ElMessage.success('生成成功')
// 这里可以添加路由跳转到 financialBilling 组件 // 这里可以添加路由跳转到 financialBilling 组件
// router.push('/financial/billing') // router.push('/financialCenter/financial/billing')
} catch (error) { } catch (error) {
console.error('生成失败:', error) console.error('生成失败:', error)
ElMessage.error('生成失败') ElMessage.error('生成失败')
......
...@@ -4,18 +4,18 @@ ...@@ -4,18 +4,18 @@
<el-card class="search-card"> <el-card class="search-card">
<!-- 第一行筛选条件 --> <!-- 第一行筛选条件 -->
<el-row :gutter="20" class="search-row"> <el-row :gutter="20" class="search-row">
<el-col :span="8"> <!-- <el-col :span="8">
<div class="form-item"> <div class="form-item">
<label class="form-label">新单编号</label> <label class="form-label">新单编号</label>
<el-input <el-input
v-model="searchForm.newOrderNo" v-model="searchForm.newOrderNo"
placeholder="请输入" placeholder="请输入"
clearable clearable
size="medium" size="default"
@keyup.enter="handleSearch" @keyup.enter="handleSearch"
/> />
</div> </div>
</el-col> </el-col> -->
<el-col :span="8"> <el-col :span="8">
<div class="form-item"> <div class="form-item">
<label class="form-label">保单号</label> <label class="form-label">保单号</label>
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
v-model="searchForm.policyNo" v-model="searchForm.policyNo"
placeholder="请输入" placeholder="请输入"
clearable clearable
size="medium" size="default"
@keyup.enter="handleSearch" @keyup.enter="handleSearch"
/> />
</div> </div>
...@@ -35,11 +35,26 @@ ...@@ -35,11 +35,26 @@
v-model="searchForm.customerName" v-model="searchForm.customerName"
placeholder="请输入" placeholder="请输入"
clearable clearable
size="medium" size="default"
@keyup.enter="handleSearch" @keyup.enter="handleSearch"
/> />
</div> </div>
</el-col> </el-col>
<el-col :span="8">
<div class="form-item">
<label class="form-label">新单状态</label>
<el-select
v-model="searchForm.newOrderStatus"
placeholder="请选择"
clearable
size="default"
>
<!-- 增加全部,默认传空字符串 -->
<el-option label="全部" value=" " />
<el-option v-for="item in policyFollowStatusList" :key="item.itemValue" :label="item.itemLabel" :value="item.itemValue" />
</el-select>
</div>
</el-col>
</el-row> </el-row>
<!-- 第二行筛选条件 --> <!-- 第二行筛选条件 -->
...@@ -53,32 +68,15 @@ ...@@ -53,32 +68,15 @@
range-separator="至" range-separator="至"
start-placeholder="开始日期" start-placeholder="开始日期"
end-placeholder="结束日期" end-placeholder="结束日期"
size="medium" size="default"
/> />
</div> </div>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8" class="search-buttons">
<div class="form-item">
<label class="form-label">新单状态</label>
<el-select
v-model="searchForm.newOrderStatus"
placeholder="请选择"
clearable
size="medium"
>
<!-- 增加全部,默认传空字符串 -->
<el-option label="全部" value=" " />
<el-option v-for="item in policyFollowStatusList" :key="item.itemValue" :label="item.itemLabel" :value="item.itemValue" />
</el-select>
</div>
</el-col>
</el-row>
<el-row>
<el-col :span="24" class="search-buttons">
<el-button <el-button
type="primary" type="primary"
@click="handleSearch" @click="handleSearch"
size="medium" size="default"
:icon="Search" :icon="Search"
class="search-btn" class="search-btn"
> >
...@@ -86,7 +84,7 @@ ...@@ -86,7 +84,7 @@
</el-button> </el-button>
<el-button <el-button
@click="resetForm" @click="resetForm"
size="medium" size="default"
:icon="RefreshLeft" :icon="RefreshLeft"
> >
重置 重置
...@@ -94,13 +92,14 @@ ...@@ -94,13 +92,14 @@
<!-- <el-button <!-- <el-button
type="info" type="info"
@click="toggleAdvancedSearch" @click="toggleAdvancedSearch"
size="medium" size="default"
:icon="expandSearch ? ArrowUp : ArrowDown" :icon="expandSearch ? ArrowUp : ArrowDown"
> >
{{ expandSearch ? '收起筛选' : '更多筛选' }} {{ expandSearch ? '收起筛选' : '更多筛选' }}
</el-button> --> </el-button> -->
</el-col> </el-col>
</el-row> </el-row>
<!-- 可展开的高级筛选区域 --> <!-- 可展开的高级筛选区域 -->
<el-collapse v-model="activeNames" v-if="expandSearch" class="advanced-search"> <el-collapse v-model="activeNames" v-if="expandSearch" class="advanced-search">
...@@ -113,7 +112,7 @@ ...@@ -113,7 +112,7 @@
v-model="searchForm.productType" v-model="searchForm.productType"
placeholder="请选择" placeholder="请选择"
clearable clearable
size="small" size="default"
> >
<el-option label="全部" value="" /> <el-option label="全部" value="" />
<el-option label="寿险" value="life" /> <el-option label="寿险" value="life" />
...@@ -130,7 +129,7 @@ ...@@ -130,7 +129,7 @@
v-model="searchForm.salesman" v-model="searchForm.salesman"
placeholder="请选择" placeholder="请选择"
clearable clearable
size="small" size="default"
> >
<el-option label="全部" value="" /> <el-option label="全部" value="" />
<el-option label="张三" value="zhangsan" /> <el-option label="张三" value="zhangsan" />
...@@ -146,7 +145,7 @@ ...@@ -146,7 +145,7 @@
v-model="searchForm.premium" v-model="searchForm.premium"
placeholder="请输入" placeholder="请输入"
clearable clearable
size="small" size="default"
/> />
</div> </div>
</el-col> </el-col>
...@@ -170,7 +169,7 @@ ...@@ -170,7 +169,7 @@
<el-button <el-button
type="success" type="success"
:icon="UploadFilled" :icon="UploadFilled"
size="medium" size="default"
> >
上传Excel文件 上传Excel文件
</el-button> </el-button>
...@@ -178,7 +177,7 @@ ...@@ -178,7 +177,7 @@
<el-button <el-button
text text
@click="downloadTemplate" @click="downloadTemplate"
size="small" size="default"
class="download-template-btn" class="download-template-btn"
> >
下载模板 下载模板
...@@ -195,7 +194,7 @@ ...@@ -195,7 +194,7 @@
<el-button <el-button
type="primary" type="primary"
@click="handleImport" @click="handleImport"
size="medium" size="default"
:loading="importLoading" :loading="importLoading"
class="confirm-import-btn" class="confirm-import-btn"
> >
...@@ -208,11 +207,12 @@ ...@@ -208,11 +207,12 @@
<!-- 列表区域 --> <!-- 列表区域 -->
<el-card class="table-card"> <el-card class="table-card">
<!-- <div class="table-actions"> <div class="table-actions">
<el-button <el-button type="primary" @click="handleUpdateToPolicyLib">更新至保单库</el-button>
<!-- <el-button
type="danger" type="danger"
:icon="Delete" :icon="Delete"
size="small" size="default"
@click="handleDeleteSelected" @click="handleDeleteSelected"
:disabled="selectedRows.length === 0" :disabled="selectedRows.length === 0"
> >
...@@ -221,12 +221,12 @@ ...@@ -221,12 +221,12 @@
<el-button <el-button
type="primary" type="primary"
:icon="Plus" :icon="Plus"
size="small" size="default"
@click="handleAdd" @click="handleAdd"
> >
新增 新增
</el-button> </el-button> -->
</div> --> </div>
<el-table <el-table
v-loading="tableLoading" v-loading="tableLoading"
:data="tableData" :data="tableData"
...@@ -241,7 +241,7 @@ ...@@ -241,7 +241,7 @@
<!-- 新单状态需要通过policyFollowStatusList和value匹配,显示label --> <!-- 新单状态需要通过policyFollowStatusList和value匹配,显示label -->
<el-table-column prop="status" label="新单状态" min-width="100" align="center" sortable> <el-table-column prop="status" label="新单状态" min-width="100" align="center" sortable>
<template #default="scope"> <template #default="scope">
<span>{{ convertStatusToDict(scope.row.status) }}</span> <span>{{ convertStatusToDict(1,scope.row.status) }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="policyNo" label="保单号" min-width="100" align="center" sortable/> <el-table-column prop="policyNo" label="保单号" min-width="100" align="center" sortable/>
...@@ -249,47 +249,18 @@ ...@@ -249,47 +249,18 @@
<el-table-column prop="signDate" label="签单日期" min-width="100" align="center" sortable/> <el-table-column prop="signDate" label="签单日期" min-width="100" align="center" sortable/>
<el-table-column prop="signer" label="签单人" min-width="100" align="center" sortable/> <el-table-column prop="signer" label="签单人" min-width="100" align="center" sortable/>
<el-table-column prop="paymentTerm" label="供款年期" min-width="100" align="center" sortable/> <el-table-column prop="paymentTerm" label="供款年期" min-width="100" align="center" sortable/>
<el-table-column prop="paymentPremium" label="期交保费" min-width="100" align="center" sortable/>
<el-table-column prop="productName" label="产品名称" min-width="100" align="center" sortable/> <el-table-column prop="productName" label="产品名称" min-width="100" align="center" sortable/>
<el-table-column prop="insurer " label="保险公司" min-width="100" align="center" sortable/> <el-table-column prop="insurer" label="保险公司" min-width="100" align="center" sortable/>
<el-table-column prop="reconciliationCompany" label="对账公司" min-width="100" align="center" sortable/> <el-table-column prop="reconciliationCompany" label="对账公司" min-width="100" align="center" sortable/>
<el-table-column prop="policyHolder" label="保单持有人" min-width="100" align="center" sortable/> <el-table-column prop="policyHolder" label="保单持有人" min-width="100" align="center" sortable/>
<el-table-column prop="insured" label="受保人" min-width="100" align="center" sortable/> <el-table-column prop="insured" label="受保人" min-width="100" align="center" sortable/>
<el-table-column prop="currency" label="币种" min-width="100" align="center" sortable/> <el-table-column prop="currency" label="币种" min-width="100" align="center" sortable/>
<el-table-column prop="initialPremium" label="首期保费" min-width="100" align="center" sortable/> <el-table-column prop="initialPremium" label="首期保费" min-width="100" align="center" sortable>
<!-- 转介人信息列 -->
<el-table-column label="转介人信息" min-width="150" align="center" sortable>
<template #default="scope"> <template #default="scope">
<div v-if="scope.row.brokerList && scope.row.brokerList.length > 0"> {{ numberWithCommas(scope.row.initialPremium) }}
<el-popover
placement="top-start"
title="转介人详情"
:width="300"
trigger="hover"
>
<template #reference>
<el-button text size="small" type="primary">
查看转介人({{ scope.row.brokerList.length }})
</el-button>
</template>
<div class="broker-details">
<div
v-for="(broker, index) in scope.row.brokerList"
:key="index"
class="broker-item"
>
<p><strong>姓名:</strong> {{ broker.brokerName || '未填写' }}</p>
<p><strong>团队:</strong> {{ broker.team || '未填写' }}</p>
<p><strong>备注:</strong> {{ broker.remark || '无' }}</p>
<el-divider v-if="index < scope.row.brokerList.length - 1" />
</div>
</div>
</el-popover>
</div>
<span v-else class="no-broker">无转介人</span>
</template> </template>
</el-table-column> </el-table-column>
<!-- <el-table-column <el-table-column
label="操作" label="操作"
min-width="180" min-width="180"
align="center" align="center"
...@@ -297,29 +268,21 @@ ...@@ -297,29 +268,21 @@
<template #default="scope"> <template #default="scope">
<el-button <el-button
text text
size="small" size="default"
@click="handleView(scope.row)" @click="handleView(scope.row)"
> >
查看 查看
</el-button> </el-button>
<el-button <el-button
text text
size="small" size="default"
type="primary" type="primary"
@click="handleEdit(scope.row)" @click="handleEdit(scope.row)"
> >
编辑 编辑
</el-button> </el-button>
<el-button
text
size="small"
type="danger"
@click="handleDelete(scope.row)"
>
删除
</el-button>
</template> </template>
</el-table-column> --> </el-table-column>
</el-table> </el-table>
<!-- 分页 --> <!-- 分页 -->
...@@ -335,7 +298,18 @@ ...@@ -335,7 +298,18 @@
/> />
</div> </div>
</el-card> </el-card>
<!-- 使用查看数据详情组件 -->
<PolicyDetailDialog
:visible="viewDialogVisible"
:detail-data="currentRow"
:policy-follow-status-list="policyFollowStatusList"
title="新单跟进详情"
:expected-commission-list="expectedCommissionList"
@close="handleDetailClose"
/>
</div> </div>
</template> </template>
<script setup> <script setup>
...@@ -344,19 +318,26 @@ import { Search, RefreshLeft, UploadFilled, Delete, Plus, Document } from '@elem ...@@ -344,19 +318,26 @@ import { Search, RefreshLeft, UploadFilled, Delete, Plus, Document } from '@elem
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import * as XLSX from 'xlsx' import * as XLSX from 'xlsx'
import axios from 'axios' import axios from 'axios'
import { getPolicyFollowList } from '@/api/sign/underwritingMain' import { getPolicyFollowList, getExpectedCommissionList } from '@/api/sign/underwritingMain'
import { getToken } from "@/utils/auth" import { getToken } from "@/utils/auth"
import { listType } from '@/api/system/dict/type' import { listType } from '@/api/system/dict/type'
import date from '@/utils/date'
import PolicyDetailDialog from '@/components/PolicyDetailDialog/index.vue'
import { numberWithCommas } from '@/utils/index.js'
// 通过dictType=csf_policy_follow_status获取新单状态字典值,获取对象中的dictItemList // 通过dictType=csf_policy_follow_status获取新单状态字典值,获取对象中的dictItemList
const policyFollowStatusList = ref([]); const policyFollowStatusList = ref([]);
const commissionStatusList = ref([]);
const getLists = ()=>{ const getLists = ()=>{
listType({typeList: ['csf_policy_follow_status']}).then(res => { listType({typeList: ['csf_policy_follow_status','csf_expected_commission_status']}).then(res => {
if (res.code === 200 && res.data) { if (res.code === 200 && res.data) {
const statusData = res.data.find(item => item.dictType === 'csf_policy_follow_status'); const statusData = res.data.find(item => item.dictType === 'csf_policy_follow_status');
policyFollowStatusList.value = statusData?.dictItemList || []; policyFollowStatusList.value = statusData?.dictItemList || [];
const commissionStatusData = res.data.find(item => item.dictType === 'csf_expected_commission_status');
commissionStatusList.value = commissionStatusData?.dictItemList || [];
} else { } else {
policyFollowStatusList.value = []; policyFollowStatusList.value = [];
commissionStatusList.value = [];
} }
}).catch(error => { }).catch(error => {
console.error('获取状态列表失败:', error); console.error('获取状态列表失败:', error);
...@@ -364,8 +345,9 @@ const getLists = ()=>{ ...@@ -364,8 +345,9 @@ const getLists = ()=>{
}) })
} }
// 返回数据中状态需要转换为字典值 // 返回数据中状态需要转换为字典值
const convertStatusToDict = (status) => { const convertStatusToDict = (type=1,status) => {
const dictItem = policyFollowStatusList.value.find(item => item.status === status) const arr = type === 1 ? policyFollowStatusList : commissionStatusList
const dictItem = arr.value.find(item => item.itemValue == status)
return dictItem?.itemLabel ?? status return dictItem?.itemLabel ?? status
} }
...@@ -392,12 +374,16 @@ const toggleAdvancedSearch = () => { ...@@ -392,12 +374,16 @@ const toggleAdvancedSearch = () => {
expandSearch.value = !expandSearch.value expandSearch.value = !expandSearch.value
} }
// 预计来佣列表
const expectedCommissionList = ref([])
// 表格数据 // 表格数据
const tableData = ref([]) const tableData = ref([])
const tableLoading = ref(false) const tableLoading = ref(false)
const selectedRows = ref([]) const selectedRows = ref([])
// 查看详情弹窗相关
const viewDialogVisible = ref(false)
const currentRow = ref({})
// 分页数据 // 分页数据
const pagination = reactive({ const pagination = reactive({
currentPage: 1, // 当前页码(对应接口的pageNo) currentPage: 1, // 当前页码(对应接口的pageNo)
...@@ -406,6 +392,21 @@ const pagination = reactive({ ...@@ -406,6 +392,21 @@ const pagination = reactive({
sortField: '', // 排序字段 sortField: '', // 排序字段
sortOrder: '' // 排序方向 sortOrder: '' // 排序方向
}) })
// 处理查看
const handleView = async (row) => {
console.log('查看详情:', row)
currentRow.value = { ...row}
viewDialogVisible.value = true
fetchExpectedCommissionList(row.policyNo)
}
// 处理详情弹窗关闭
const handleDetailClose = () => {
viewDialogVisible.value = false
console.log('详情弹窗已关闭')
}
// Excel导入相关 // Excel导入相关
const selectedFile = ref(null) const selectedFile = ref(null)
const importLoading = ref(false) const importLoading = ref(false)
...@@ -436,8 +437,8 @@ const fetchTableData = async () => { ...@@ -436,8 +437,8 @@ const fetchTableData = async () => {
// 签单时间范围需要根据后端要求的参数名进行调整 // 签单时间范围需要根据后端要求的参数名进行调整
// 例如:如果后端需要startSignDate和endSignDate // 例如:如果后端需要startSignDate和endSignDate
...(searchForm.signDateRange && searchForm.signDateRange.length === 2 && { ...(searchForm.signDateRange && searchForm.signDateRange.length === 2 && {
startSignDate: searchForm.signDateRange[0], startSignDate: date.formatToDate(searchForm.signDateRange[0]) + ' 00:00:00',
endSignDate: searchForm.signDateRange[1] endSignDate: date.formatToDate(searchForm.signDateRange[1]) + ' 23:59:59'
}) })
} }
...@@ -450,7 +451,7 @@ const fetchTableData = async () => { ...@@ -450,7 +451,7 @@ const fetchTableData = async () => {
tableData.value = result.records.map(record => ({ tableData.value = result.records.map(record => ({
...record ...record
})) }))
console.log('tableData',tableData.value) // console.log('tableData',tableData.value)
// 更新分页信息 // 更新分页信息
pagination.total = result.total pagination.total = result.total
...@@ -471,8 +472,42 @@ const fetchTableData = async () => { ...@@ -471,8 +472,42 @@ const fetchTableData = async () => {
} finally { } finally {
tableLoading.value = false tableLoading.value = false
} }
}// 获取预计来佣列表
const fetchExpectedCommissionList = async (policyNo,pageNo=1,pageSize=100) => {
try {
// 构造接口请求参数
const params = {
pageNo: pageNo, // 注意:如果后端是从0开始的页码,需要减1
pageSize: pageSize,
policyNo: policyNo,
}
// 调用后台接口
const response = await getExpectedCommissionList(params)
// 处理接口响应
if (response.code === 200) {
const result = response.data
// 将接口返回的数据映射到表格
expectedCommissionList.value = result.records.map(record => ({
...record,
commissionStatusLabel: convertStatusToDict(2,record.status)
}))
} else {
// 接口返回错误信息
ElMessage.error(`获取数据失败: ${response.data.msg || '未知错误'}`)
expectedCommissionList.value = []
}
} catch (error) {
// 捕获网络或其他异常
console.error('请求失败:', error)
ElMessage.error('网络异常,请稍后重试')
expectedCommissionList.value = []
} finally {
}
} }
// 增加通过表格排序,排序字段sortField,升降序sortOrder // 增加通过表格排序,排序字段sortField,升降序sortOrder
const handleSortChange = (column) => { const handleSortChange = (column) => {
pagination.sortField = column.prop pagination.sortField = column.prop
...@@ -652,12 +687,30 @@ const downloadTemplate = () => { ...@@ -652,12 +687,30 @@ const downloadTemplate = () => {
// ElMessage.info(`编辑 ID: ${row.id} 的数据`) // ElMessage.info(`编辑 ID: ${row.id} 的数据`)
// // 实际项目中这里会打开编辑数据的对话框 // // 实际项目中这里会打开编辑数据的对话框
// } // }
import { updateToPolicyLib } from '@/api/sign/underwritingMain'
// 处理查看 // 处理更新至保单库
// const handleView = (row) => { const handleUpdateToPolicyLib = () => {
// ElMessage.info(`查看 ID: ${row.id} 的数据详情`) ElMessageBox.confirm(
// // 实际项目中这里会打开查看数据详情的对话框 `确定要更新选中的 ${selectedRows.value.length} 条数据至保单库吗?`,
// } '更新确认',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
).then(() => {
// 调用更新至保单库接口
updateToPolicyLib({
policyNoList: selectedRows.value.map(row => row.policyNo).join(',')
}).then(response => {
if (response.code === 200) {
ElMessage.success('更新成功')
} else {
ElMessage.error(`更新失败: ${response.msg || '未知错误'}`)
}
})
})
}
// 格式化文件大小 // 格式化文件大小
......
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