Commit bb98a375 by yuzhenWang

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

Feature 20250827wyz 写业务

See merge request !82
parents 5acadb8b efbc9102
<template>
<el-form ref="formRef" :model="localModel" :rules="formRules" label-width="auto" v-bind="$attrs"
:validate-on-rule-change="false">
<el-form
ref="formRef"
:model="localModel"
:rules="formRules"
label-width="auto"
v-bind="$attrs"
:validate-on-rule-change="false"
>
<el-row :gutter="20">
<el-col v-for="item in visibleConfig" :key="item.prop" :span="item.span || 6">
<el-form-item :label="item.label" :prop="item.prop" :class="{ 'search-form-item': isSearch }"
:label-position="item.labelPosition || 'top'">
<el-form-item
:label="item.label"
:prop="item.prop"
:class="{ 'search-form-item': isSearch }"
:label-position="item.labelPosition || 'top'"
>
<!-- Input -->
<el-input v-if="item.type === 'input'" v-model="localModel[item.prop]"
:placeholder="item.placeholder || `请输入${item.label}`" :clearable="true" :disabled="item.disabled"
@input="val => handleNumberInput(val, item)" @change="val => handleModelChange(val, item)" />
<el-input
v-if="item.type === 'input'"
v-model="localModel[item.prop]"
:placeholder="item.placeholder || `请输入${item.label}`"
:clearable="true"
:disabled="item.disabled"
@input="val => handleNumberInput(val, item)"
@change="val => handleModelChange(val, item)"
/>
<!-- Select (支持 dictType / api / options) -->
<el-select v-else-if="item.type === 'select'" v-model="localModel[item.prop]" :multiple="!!item.multiple"
:placeholder="item.placeholder || `请选择${item.label}`" :clearable="true" filterable :disabled="item.disabled"
:loading="remoteLoading[item.prop] || false" @change="val => handleModelChange(val, item)"
@focus="() => loadRemoteOptions(item)" @filter-change="keyword => handleFilterChange(keyword, item)">
<el-option v-for="opt in getSelectOptions(item)" :key="opt.value" :label="opt.label" :value="opt.value" />
<el-select
v-else-if="item.type === 'select'"
v-model="localModel[item.prop]"
:multiple="!!item.multiple"
:placeholder="item.placeholder || `请选择${item.label}`"
:clearable="true"
filterable
:disabled="item.disabled"
:loading="remoteLoading[item.prop] || false"
@change="val => handleModelChange(val, item)"
@focus="() => loadRemoteOptions(item)"
@filter-change="keyword => handleFilterChange(keyword, item)"
>
<el-option
v-for="opt in getSelectOptions(item)"
:key="opt.value"
:label="opt.label"
:value="opt.value"
/>
</el-select>
<!-- Date -->
<el-date-picker v-else-if="item.type === 'date'" v-model="localModel[item.prop]" type="date"
:placeholder="`选择${item.label}`" :disabled="item.disabled" :value-format="item.valueFormat || 'YYYY-MM-DD'"
style="width: 100%" :disabled-date="getDisabledDateFn(item)"
@change="val => handleModelChange(val, item)" />
<el-date-picker
v-else-if="item.type === 'date'"
v-model="localModel[item.prop]"
type="date"
:placeholder="`选择${item.label}`"
:disabled="item.disabled"
:value-format="item.valueFormat || 'YYYY-MM-DD'"
style="width: 100%"
:disabled-date="getDisabledDateFn(item)"
@change="val => handleModelChange(val, item)"
/>
<!-- Month -->
<el-date-picker v-else-if="item.type === 'month'" v-model="localModel[item.prop]" type="month"
:placeholder="`选择${item.label}`" :value-format="item.valueFormat || 'YYYY-MM'" style="width: 100%"
:disabled="item.disabled" :disabled-date="getDisabledDateFn(item)"
@change="val => handleModelChange(val, item)" />
<el-date-picker
v-else-if="item.type === 'month'"
v-model="localModel[item.prop]"
type="month"
:placeholder="`选择${item.label}`"
:value-format="item.valueFormat || 'YYYY-MM'"
style="width: 100%"
:disabled="item.disabled"
:disabled-date="getDisabledDateFn(item)"
@change="val => handleModelChange(val, item)"
/>
<!-- Daterange -->
<el-date-picker v-else-if="item.type === 'daterange'" v-model="localModel[item.prop]" type="daterange"
range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期"
:value-format="item.valueFormat || 'YYYY-MM-DD'" :disabled="item.disabled"
:disabled-date="getDisabledDateFn(item)" style="width: 100%"
@change="val => handleModelChange(val, item)" />
<el-date-picker
v-else-if="item.type === 'daterange'"
v-model="localModel[item.prop]"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
:value-format="item.valueFormat || 'YYYY-MM-DD'"
:disabled="item.disabled"
:disabled-date="getDisabledDateFn(item)"
style="width: 100%"
@change="val => handleModelChange(val, item)"
/>
<!-- Checkbox Group -->
<el-checkbox-group v-else-if="item.type === 'checkbox-group'" v-model="localModel[item.prop]"
:disabled="item.disabled" @change="val => handleModelChange(val, item)">
<el-checkbox-group
v-else-if="item.type === 'checkbox-group'"
v-model="localModel[item.prop]"
:disabled="item.disabled"
@change="val => handleModelChange(val, item)"
>
<el-checkbox v-for="opt in getSelectOptions(item)" :key="opt.value" :label="opt.value">
{{ opt.label }}
</el-checkbox>
</el-checkbox-group>
<!-- textarea -->
<el-input v-else-if="item.type === 'textarea'" v-model="localModel[item.prop]" style="width: 240px" autosize
:disabled="item.disabled" type="textarea" placeholder="请输入" :clearable="true"
@change="val => handleModelChange(val, item)" />
<el-input
v-else-if="item.type === 'textarea'"
v-model="localModel[item.prop]"
style="width: 240px"
autosize
:disabled="item.disabled"
type="textarea"
placeholder="请输入"
:clearable="true"
@change="val => handleModelChange(val, item)"
/>
<!-- Upload 回显值得时候数据格式至少是[{url: '必须要传', name: 'name不是必须的根据需要传值'}]-->
<el-upload v-else-if="item.type === 'upload'" v-model:file-list="localModel[item.prop]" :action="item.action"
:headers="item.headers" :multiple="!!item.multiple" :limit="item.limit || (item.multiple ? 999 : 1)"
:accept="item.accept" :list-type="item.listType || 'text'" :disabled="item.disabled" :auto-upload="true"
:show-file-list="item.showFileList" :on-exceed="handleExceed"
<el-upload
v-else-if="item.type === 'upload'"
v-model:file-list="localModel[item.prop]"
:action="item.action"
:headers="item.headers"
:multiple="!!item.multiple"
:limit="item.limit || (item.multiple ? 999 : 1)"
:accept="item.accept"
:list-type="item.listType || 'text'"
:disabled="item.disabled"
:auto-upload="true"
:show-file-list="item.showFileList"
:on-exceed="handleExceed"
:before-upload="file => beforeUpload(file, item)"
:on-success="(res, file, fileList) => handleUploadSuccess(res, file, fileList, item)"
:on-error="(err, file, fileList) => handleUploadError(err, file, fileList, item)"
:on-remove="(file, fileList) => handleUploadRemove(file, fileList, item)">
:on-remove="(file, fileList) => handleUploadRemove(file, fileList, item)"
>
<el-icon class="iconStyle" :size="20" v-if="item.uploadType === 'image'">
<Upload />
</el-icon>
<el-button v-else size="small" type="primary" :link="item.link" :disabled="item.disabled">
<el-button
v-else
size="small"
type="primary"
:link="item.link"
:disabled="item.disabled"
>
{{ '点击上传文件' }}
</el-button>
<template #tip v-if="item.maxSize || item.accept">
......@@ -579,7 +659,7 @@ async function loadRemoteOptionsForInit(item) {
// ==================== 加载远程 API 选项(首次 focus 时加载,无搜索词) ====================
async function loadRemoteOptions(item) {
const { prop, api, requestParams, keywordField, debounceWait, ...rest } = item
if (!api ) return
if (!api) return
try {
remoteLoading.value[prop] = true
......@@ -660,6 +740,46 @@ function handleFilterChange(keyword, item) {
}
// ==================== 数字输入处理 ====================
// function handleNumberInput(value, item) {
// const { inputType = 'text', decimalDigits = 2, prop } = item
// if (!prop) return
// let result = String(value ?? '').trim()
// if (inputType === 'integer') {
// // 只保留数字
// result = result.replace(/[^\d]/g, '')
// } else if (inputType === 'decimal') {
// // 1. 只保留数字和小数点
// result = result.replace(/[^\d.]/g, '')
// // 2. 去掉开头的小数点(不允许 ".5" → 改为 "0.5" 更好,但这里先简单处理)
// if (result.startsWith('.')) {
// result = '0.' + result.slice(1)
// }
// // 3. 保证最多一个小数点
// const parts = result.split('.')
// if (parts.length > 2) {
// result = parts[0] + '.' + parts.slice(1).join('')
// }
// // 4. 限制小数位数(但保留结尾的小数点!)
// if (result.includes('.')) {
// const [intPart, decPart] = result.split('.')
// // 如果小数部分超过限制,截断
// if (decPart.length > decimalDigits) {
// result = intPart + '.' + decPart.slice(0, decimalDigits)
// }
// // ✅ 不再删除结尾的 '.'
// }
// }
// // 防止重复赋值(可选优化)
// if (localModel.value[prop] !== result) {
// localModel.value = { ...localModel.value, [prop]: result }
// }
// }
function handleNumberInput(value, item) {
const { inputType = 'text', decimalDigits = 2, prop } = item
if (!prop) return
......@@ -667,9 +787,52 @@ function handleNumberInput(value, item) {
let result = String(value ?? '').trim()
if (inputType === 'integer') {
// 只保留数字
result = result.replace(/[^\d]/g, '')
// 只保留数字和负号
result = result.replace(/[^-\d]/g, '')
// 如果有多个负号或者负号不在开头,则移除多余的负号
if ((result.match(/-/g) || []).length > 1) {
result = result.replace(/-/g, '').replace(/^/, '-') // 仅保留一个负号在最前面
}
} else if (inputType === 'decimalNumber') {
// 可以输入正数,负数,小数
// 1. 只保留数字、小数点和负号
result = result.replace(/[^-\d.]/g, '')
// 2. 处理负号:确保最多只有一个负号且必须在开头
if ((result.match(/-/g) || []).length > 1) {
result = result.replace(/-/g, '') // 移除所有负号
if (result.startsWith('-')) {
result = '-' + result.slice(1) // 确保负号在最前面
} else {
result = '-' + result // 如果原本没有负号但需要保留数值,可以省略此步骤
}
}
// 3. 去掉开头的小数点(不允许 ".5" → 改为 "0.5" 更好)
if (result.startsWith('.')) {
result = '0' + result
} else if (result.startsWith('-.')) {
result = '-0' + result.slice(2)
}
// 4. 保证最多一个小数点
const parts = result.split('.')
if (parts.length > 2) {
result = parts[0] + '.' + parts.slice(1).join('')
}
// 5. 限制小数位数(但保留结尾的小数点!)
if (result.includes('.')) {
const [intPart, decPart] = result.split('.')
// 如果小数部分超过限制,截断
if (decPart.length > decimalDigits) {
result = intPart + '.' + decPart.slice(0, decimalDigits)
}
// ✅ 不再删除结尾的 '.'
}
} else if (inputType === 'decimal') {
// 可以输入正整数和小数
// 1. 只保留数字和小数点
result = result.replace(/[^\d.]/g, '')
......@@ -729,29 +892,29 @@ defineExpose({
localModel.value = { ...resetData }
nextTick(() => formRef.value?.clearValidate())
},
// ✅ 新增:强制刷新某个字段的远程选项
async refreshRemoteOptions(targetProp) {
// ✅ 新增:强制刷新某个字段的远程选项
async refreshRemoteOptions(targetProp) {
console.log(`[SearchForm] 收到刷新请求: ${targetProp}`)
// 1. 查找配置项
const item = internalConfig.value.find(i => i.prop === targetProp)
if (!item) {
console.warn(`[SearchForm] 未找到 prop 为 ${targetProp} 的配置项`)
return
}
if (item.type !== 'select' || !item.api) {
console.warn(`[SearchForm] 字段 ${targetProp} 不是远程 Select 或没有 API`)
return
}
console.log(`[SearchForm] 开始强制加载 ${targetProp} 的数据,API: ${item.api}`)
// 2. 关键:在调用前,先清空旧数据,防止子组件内部的 "已加载则跳过" 逻辑生效
// 如果你的 loadRemoteOptions 里有 "if (remoteOptions.value[prop]?.length > 0) return"
// 这里必须先清空
remoteOptions.value[targetProp] = []
remoteOptions.value[targetProp] = []
remoteLoading.value[targetProp] = true // 手动开启 loading
try {
......
......@@ -92,7 +92,7 @@ const customer = [
unitColor: 'rgba(0, 82, 217, 1)',
inputType: 'text',
required: true,
maxLength: 15,
maxLength: 30,
disabled: false,
placeholder: '请输入2~6位汉字',
show: true,
......@@ -108,7 +108,7 @@ const customer = [
domType: 'Input',
inputType: 'text',
required: true,
maxLength: 30,
maxLength: 100,
disabled: false,
placeholder: '请输入',
show: true,
......@@ -118,36 +118,6 @@ const customer = [
lg: 8 //栅格布局份数
},
// {
// label: '证件类型',
// key: 'documentType',
// domType: 'Select',
// required: true,
// disabled: false,
// placeholder: '请选择',
// dictType: 'csf_id_type',
// show: true,
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 12, //栅格布局份数
// lg: 8 //栅格布局份数
// },
// {
// label: '证件号码',
// key: 'idNumber',
// domType: 'Input',
// inputType: 'text',
// required: true,
// maxLength: 20,
// disabled: false,
// placeholder: '请输入',
// show: true,
// labelPosition: 'top', //标签的位置
// labelWidth: '120px', //标签宽度
// sm: 12, //栅格布局份数
// lg: 8 //栅格布局份数
// },
{
label: '性别',
key: 'gender',
......@@ -179,7 +149,9 @@ const customer = [
label: '年龄',
key: 'age',
domType: 'Input',
inputType: 'number',
inputType: 'text',
valueType: 'decimal', //输入值的格式
valueType: '',
maxLength: 30,
required: true,
disabled: true,
......@@ -294,7 +266,8 @@ const customer = [
label: '退休年龄',
key: 'retirementAge',
domType: 'Input',
inputType: 'number',
inputType: 'text',
valueType: 'decimal', //输入值的格式
maxLength: 30,
required: false,
disabled: false,
......@@ -324,7 +297,8 @@ const customer = [
label: '体重(KG)',
key: 'weight',
domType: 'Input',
inputType: 'number',
inputType: 'text',
valueType: 'decimal', //输入值的格式
required: false,
maxLength: 300,
disabled: false,
......@@ -339,7 +313,8 @@ const customer = [
label: '身高(CM)',
key: 'height',
domType: 'Input',
inputType: 'number',
inputType: 'text',
valueType: 'decimal', //输入值的格式
required: false,
maxLength: 300,
disabled: false,
......@@ -369,7 +344,8 @@ const customer = [
label: '受供养人数目',
key: 'dependentsNum',
domType: 'Input',
inputType: 'number',
inputType: 'text',
valueType: 'integer', //输入值的格式
required: false,
maxLength: 300,
disabled: false,
......@@ -468,7 +444,7 @@ const customer = [
label: '固定电话',
key: 'landline',
domType: 'Input',
inputType: 'number',
inputType: 'text',
required: false,
disabled: false,
placeholder: '请填写',
......@@ -616,7 +592,8 @@ const customer = [
key: 'currentMonthlyIncome',
domType: 'Input',
unit: 'HKD',
inputType: 'number',
inputType: 'text',
valueType: 'decimal', //输入值的格式
required: false,
maxLength: 300,
disabled: false,
......@@ -631,7 +608,8 @@ const customer = [
label: '总工作年期',
key: 'totalWorkingYears',
domType: 'Input',
inputType: 'number',
inputType: 'text',
valueType: 'decimal', //输入值的格式
required: false,
maxLength: 300,
disabled: false,
......@@ -646,7 +624,8 @@ const customer = [
label: '受雇于现职年期',
key: 'currentTenure',
domType: 'Input',
inputType: 'number',
inputType: 'text',
valueType: 'decimal', //输入值的格式
required: false,
maxLength: 300,
disabled: false,
......@@ -714,7 +693,7 @@ const customer = [
domType: 'Input',
inputType: 'text',
required: false,
maxLength: 20,
maxLength: 50,
disabled: false,
placeholder: '请输入',
show: true,
......@@ -739,7 +718,8 @@ const customer = [
key: 'monthIncome',
domType: 'Input',
unit: 'HKD',
inputType: 'number',
inputType: 'text',
valueType: 'decimal', //输入值的格式
required: false,
maxLength: 300,
disabled: false,
......@@ -755,7 +735,8 @@ const customer = [
key: 'monthExpenditure',
domType: 'Input',
unit: 'HKD',
inputType: 'number',
inputType: 'text',
valueType: 'decimal', //输入值的格式
required: false,
maxLength: 300,
disabled: false,
......@@ -771,7 +752,8 @@ const customer = [
key: 'totalCurrentAssets',
domType: 'Input',
unit: 'HKD',
inputType: 'number',
inputType: 'text',
valueType: 'decimalNumber', //输入值的格式
required: false,
maxLength: 300,
disabled: false,
......@@ -787,7 +769,8 @@ const customer = [
key: 'totalDebt',
domType: 'Input',
unit: 'HKD',
inputType: 'number',
inputType: 'text',
valueType: 'decimalNumber', //输入值的格式
required: false,
maxLength: 300,
disabled: false,
......
// 格式化金额为货币格式
export function formatCurrency(value,currency='') {
if (value === undefined || value === null) return currency + '0.00'
export function formatCurrency(value, currency = '') {
if (value === undefined || value === null) return currency + '0.00'
return currency + value.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,')
}
export function numberFormat(value, item) {
const { valueType = 'text', decimalDigits = 2 } = item
// if (!value) return
let result = String(value ?? '').trim()
if (valueType === 'integer') {
// 只保留数字和负号
result = result.replace(/[^-\d]/g, '')
// 如果有多个负号或者负号不在开头,则移除多余的负号
if ((result.match(/-/g) || []).length > 1) {
result = result.replace(/-/g, '').replace(/^/, '-') // 仅保留一个负号在最前面
}
} else if (valueType === 'decimalNumber') {
// 可以输入正数,负数,小数
// 1. 只保留数字、小数点和负号
result = result.replace(/[^-\d.]/g, '')
// 2. 处理负号:确保最多只有一个负号且必须在开头
if ((result.match(/-/g) || []).length > 1) {
result = result.replace(/-/g, '') // 移除所有负号
if (result.startsWith('-')) {
result = '-' + result.slice(1) // 确保负号在最前面
} else {
result = '-' + result // 如果原本没有负号但需要保留数值,可以省略此步骤
}
}
// 3. 去掉开头的小数点(不允许 ".5" → 改为 "0.5" 更好)
if (result.startsWith('.')) {
result = '0' + result
} else if (result.startsWith('-.')) {
result = '-0' + result.slice(2)
}
// 4. 保证最多一个小数点
const parts = result.split('.')
if (parts.length > 2) {
result = parts[0] + '.' + parts.slice(1).join('')
}
// 5. 限制小数位数(但保留结尾的小数点!)
if (result.includes('.')) {
const [intPart, decPart] = result.split('.')
// 如果小数部分超过限制,截断
if (decPart.length > decimalDigits) {
result = intPart + '.' + decPart.slice(0, decimalDigits)
}
// ✅ 不再删除结尾的 '.'
}
} else if (valueType === 'decimal') {
// 可以输入正整数和小数
// 1. 只保留数字和小数点
result = result.replace(/[^\d.]/g, '')
// 2. 去掉开头的小数点(不允许 ".5" → 改为 "0.5" 更好,但这里先简单处理)
if (result.startsWith('.')) {
result = '0.' + result.slice(1)
}
// 3. 保证最多一个小数点
const parts = result.split('.')
if (parts.length > 2) {
result = parts[0] + '.' + parts.slice(1).join('')
}
// 4. 限制小数位数(但保留结尾的小数点!)
if (result.includes('.')) {
const [intPart, decPart] = result.split('.')
// 如果小数部分超过限制,截断
if (decPart.length > decimalDigits) {
result = intPart + '.' + decPart.slice(0, decimalDigits)
}
}
}
return result
}
export default {
formatCurrency
}
\ No newline at end of file
formatCurrency,
numberFormat
}
<template>
<div class='container'>
<CommonPage :operationBtnList='operationBtnList' :visibleDefaultButtons="visibleDefaultButtons"
:showSearchForm='true' :show-pagination='true' :total='pageTotal' :current-page='currentPage'
:page-size='pageSize' @size-change='handleSizeChange' @current-change='handleCurrentChange'>
<div class="container">
<CommonPage
:operationBtnList="operationBtnList"
:visibleDefaultButtons="visibleDefaultButtons"
:showSearchForm="true"
:show-pagination="true"
:total="pageTotal"
:current-page="currentPage"
:page-size="pageSize"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
>
<!-- 搜索区域 -->
<template #searchForm>
<SearchForm ref="searchFormRef" :config="searchConfig" />
......@@ -16,7 +24,13 @@
<el-card shadow="hover" class="statistics-card">
<div class="card-content">
<div class="card-label">入账金额</div>
<div class="card-value">{{ statisticsData.totalInAmount ? formatCurrency(statisticsData.totalInAmount) : 0 }}</div>
<div class="card-value">
{{
statisticsData.totalInAmount
? formatCurrency(statisticsData.totalInAmount)
: 0
}}
</div>
</div>
</el-card>
</el-col>
......@@ -24,7 +38,9 @@
<el-card shadow="hover" class="statistics-card">
<div class="card-content">
<div class="card-label">总保单数</div>
<div class="card-value">{{ statisticsData.totalPolicyCount ? statisticsData.totalPolicyCount : 0 }}</div>
<div class="card-value">
{{ statisticsData.totalPolicyCount ? statisticsData.totalPolicyCount : 0 }}
</div>
</div>
</el-card>
</el-col>
......@@ -32,7 +48,11 @@
<el-card shadow="hover" class="statistics-card">
<div class="card-content">
<div class="card-label">总保费(HKD)</div>
<div class="card-value">{{ statisticsData.totalPremium ? formatCurrency(statisticsData.totalPremium) : 0 }}</div>
<div class="card-value">
{{
statisticsData.totalPremium ? formatCurrency(statisticsData.totalPremium) : 0
}}
</div>
</div>
</el-card>
</el-col>
......@@ -40,7 +60,13 @@
<el-card shadow="hover" class="statistics-card">
<div class="card-content">
<div class="card-label">待出账金额</div>
<div class="card-value">{{ statisticsData.pendingOutAmount ? formatCurrency(statisticsData.pendingOutAmount) : 0 }}</div>
<div class="card-value">
{{
statisticsData.pendingOutAmount
? formatCurrency(statisticsData.pendingOutAmount)
: 0
}}
</div>
</div>
</el-card>
</el-col>
......@@ -48,7 +74,13 @@
<el-card shadow="hover" class="statistics-card">
<div class="card-content">
<div class="card-label">可出账金额</div>
<div class="card-value">{{ statisticsData.availableOutAmount ? formatCurrency(statisticsData.availableOutAmount) : 0 }}</div>
<div class="card-value">
{{
statisticsData.availableOutAmount
? formatCurrency(statisticsData.availableOutAmount)
: 0
}}
</div>
</div>
</el-card>
</el-col>
......@@ -62,8 +94,15 @@
</el-col> -->
</el-row>
</div>
<el-table :data="tableData" @selection-change="handleSelectionChange" height="400" border highlight-current-row
style="width: 100%" v-loading="loading">
<el-table
:data="tableData"
@selection-change="handleSelectionChange"
height="400"
border
highlight-current-row
style="width: 100%"
v-loading="loading"
>
<el-table-column type="selection" width="40" />
<el-table-column prop="fortuneBizType" label="应付单类型" width="120" sortable>
<template #default="{ row }">
......@@ -72,21 +111,43 @@
</el-table-column>
<el-table-column prop="policyNo" label="保单号" width="120" sortable />
<el-table-column prop="insuranceCompany" label="保险公司" width="120" sortable />
<el-table-column prop="commissionPaidAmount" label="累积已入账金额" width="120" sortable />
<el-table-column prop="commissionPaidRatio" label="累积已入账比例" width="120" sortable :formatter="(row) => `${row.commissionPaidRatio ? row.commissionPaidRatio : 0 }%`" />
<el-table-column
prop="commissionPaidAmount"
label="累积已入账金额"
width="120"
sortable
/>
<el-table-column
prop="commissionPaidRatio"
label="累积已入账比例"
width="120"
sortable
:formatter="row => `${row.commissionPaidRatio ? row.commissionPaidRatio : 0}%`"
/>
<el-table-column prop="fortuneName" label="出账项目" width="130" sortable />
<el-table-column prop="fortunePeriod" label="出账期数" width="130" sortable />
<el-table-column prop="fortuneTotalPeriod" label="总期数" width="120" sortable />
<el-table-column prop="broker" label="转介人" width="130" sortable />
<el-table-column prop="team" label="所属团队" width="120" sortable />
<el-table-column prop="exchangeRate" label="结算汇率(估)" width="140" sortable />
<el-table-column prop="hkdAmount" label="应出账金额(HKD)" width="160" sortable/>
<el-table-column prop="hkdAmount" label="应出账金额(HKD)" width="160" sortable />
<el-table-column prop="currency" label="出账币种" width="130" sortable />
<el-table-column prop="fortunePaidAmount" label="已出账金额" width="160" sortable />
<el-table-column prop="fortuneUnpaidAmount" label="剩余出账金额" width="160" sortable />
<!-- <el-table-column prop="currentPaymentAmount" label="本期出账金额" width="120" sortable/> -->
<el-table-column prop="currentPaymentHkdAmount" label="本期出账金额(HKD)" width="160" sortable/>
<el-table-column prop="fortuneUnpaidRatio" label="剩余出账比例" width="120" sortable :formatter="(row) => `${row.fortuneUnpaidRatio }%`" />
<el-table-column
prop="currentPaymentHkdAmount"
label="本期出账金额(HKD)"
width="160"
sortable
/>
<el-table-column
prop="fortuneUnpaidRatio"
label="剩余出账比例"
width="120"
sortable
:formatter="row => `${row.fortuneUnpaidRatio}%`"
/>
<el-table-column prop="status" label="出账状态" width="160" sortable>
<template #default="{ row }">
{{ selectDictLabel(csf_fortune_status, row.status) }}
......@@ -106,9 +167,12 @@
</el-icon>
</template>
<el-menu @select="handleSelect($event, row)" popper-class="custom-menu">
<el-menu-item :index="item.value" v-for="item in dropdownItems" :key="item.value">{{
item.label
}}</el-menu-item>
<el-menu-item
:index="item.value"
v-for="item in dropdownItems"
:key="item.value"
>{{ item.label }}</el-menu-item
>
</el-menu>
</el-popover>
</template>
......@@ -116,26 +180,64 @@
</el-table>
<!-- 表格操作菜单 -->
<div class="tableOptionContainer">
<el-button type="primary" :icon="Select" :disabled="updatePayRollStatusDisable"
@click="downloadPolicyFortuneAccountapi">完成检核</el-button>
<el-button
type="primary"
:icon="Select"
:disabled="updatePayRollStatusDisable"
@click="downloadPolicyFortuneAccountapi"
>完成检核</el-button
>
</div>
</template>
</CommonPage>
<!-- 新增出账检核页面-->
<CommonDialog dialogTitle='新增出账检核' dialogWidth='80%' :openDialog='addCheckRecordFormDialogFlag' :showAction='true'
:showClose='true' @close='addCheckRecordFormDialogFlag = false' @confirm='addCheckRecordaddBatchapi'>
<SearchForm ref="addCheckRecordFormRef" :config="addCheckRecordConfig" v-model="addCheckRecordFormModel" />
<CommonDialog
dialogTitle="新增出账检核"
dialogWidth="80%"
:openDialog="addCheckRecordFormDialogFlag"
:showAction="true"
:showClose="true"
@close="addCheckRecordFormDialogFlag = false"
@confirm="addCheckRecordaddBatchapi"
>
<SearchForm
ref="addCheckRecordFormRef"
:config="addCheckRecordConfig"
v-model="addCheckRecordFormModel"
/>
</CommonDialog>
<!-- 导入出账检核页面 -->
<CommonDialog dialogTitle='新增出账检核' dialogWidth='80%' :openDialog='importCheckRecordFlag' :showAction='true'
:showClose='true' @close='importCheckRecordFlag = false'>
<FileUploadPreview :header-row="0" :required-fields="'amount,exchangeRate'" :use-chinese-header="true"
:transform-submit-data="transformToBackend" @submit="onSubmit" />
<CommonDialog
dialogTitle="新增出账检核"
dialogWidth="80%"
:openDialog="importCheckRecordFlag"
:showAction="true"
:showClose="true"
@close="importCheckRecordFlag = false"
>
<FileUploadPreview
:header-row="0"
:required-fields="'amount,exchangeRate'"
:use-chinese-header="true"
:transform-submit-data="transformToBackend"
@submit="onSubmit"
/>
</CommonDialog>
<!-- 设置本期出账金额 -->
<CommonDialog dialogTitle='设置本期出账金额' dialogWidth='80%' :openDialog='setPayoutAmountDialogFlag' :showAction='true'
:showClose='true' @close='setPayoutAmountDialogFlag = false' @confirm='updatePayoutAmountapi'>
<SearchForm ref="setPayoutAmountFormRef" :config="setPayoutAmountConfig" v-model="setPayoutAmountFormModel" />
<CommonDialog
dialogTitle="设置本期出账金额"
dialogWidth="80%"
:openDialog="setPayoutAmountDialogFlag"
:showAction="true"
:showClose="true"
@close="setPayoutAmountDialogFlag = false"
@confirm="updatePayoutAmountapi"
>
<SearchForm
ref="setPayoutAmountFormRef"
:config="setPayoutAmountConfig"
v-model="setPayoutAmountFormModel"
/>
</CommonDialog>
</div>
</template>
......@@ -149,13 +251,17 @@ import { ElMessage } from 'element-plus'
import { formatCurrency } from '@/utils/number'
import { Select } from '@element-plus/icons-vue'
// 接口
import { getPolicyFortuneList, addCheckRecordaddBatch, updatePayoutAmount, downloadPolicyFortuneAccount } from '@/api/financial/commission'
import {
getPolicyFortuneList,
addCheckRecordaddBatch,
updatePayoutAmount,
downloadPolicyFortuneAccount
} from '@/api/financial/commission'
import useUserStore from '@/store/modules/user'
const { proxy } = getCurrentInstance()
const { csf_fortune_status } = proxy.useDict('csf_fortune_status')
const userStore = useUserStore()
// 分页相关
const currentPage = ref(1)
......@@ -177,7 +283,8 @@ const searchConfig = ref([
label: '出账状态',
multiple: true,
dictType: 'csf_fortune_status'
}, {
},
{
type: 'select',
prop: 'insuranceCompanyBizIdList',
label: '保险公司',
......@@ -189,11 +296,12 @@ const searchConfig = ref([
multiple: true,
valueKey: 'insuranceCompanyBizId',
labelKey: 'fullName',
transform: (res) => {
transform: res => {
console.log(res)
return res?.data.records || []
}
}, {
},
{
type: 'select',
prop: 'productLaunchBizIdList',
label: '产品计划',
......@@ -201,17 +309,22 @@ const searchConfig = ref([
keywordField: 'productName',
requestParams: {
tenantBizId: userStore.projectInfo.tenantBizId || '',
projectBizId: userStore.projectInfo.projectBizId || '', fieldBizId: 'field_olk1qZe81qHHKXbw', fieldValueBizId: 'field_value_uOfJH5ucA2YwJpbn', pageNo: 1, pageSize: 20
projectBizId: userStore.projectInfo.projectBizId || '',
fieldBizId: 'field_olk1qZe81qHHKXbw',
fieldValueBizId: 'field_value_uOfJH5ucA2YwJpbn',
pageNo: 1,
pageSize: 20
},
placeholder: '输入产品计划名称搜索',
debounceWait: 500, // 自定义防抖时间
multiple: true,
valueKey: 'productLaunchBizId',
labelKey: 'productName',
transform: (res) => {
transform: res => {
return res?.data.records || []
}
}, {
},
{
type: 'daterange',
prop: 'payoutDate',
label: '出账日(估)',
......@@ -224,11 +337,11 @@ const searchConfig = ref([
label: '入账状态',
multiple: true,
dictType: 'csf_expected_commission_status'
},
}
])
// 表格操作菜单
const dropdownItems = [
{ label: '设置本期出账金额', value: 'setPayRoll' },
{ label: '设置本期出账金额', value: 'setPayRoll' }
// { label: '更新', value: 'editRecord' },
// { label: '查看记录', value: 'viewRecord' }
]
......@@ -238,7 +351,7 @@ const fortuneBizTypeOptions = [
{ value: 'U', label: '非关联保单应付单' }
]
// 应付单类型通过value转成label
const getFortuneBizTypeLabel = (value) => {
const getFortuneBizTypeLabel = value => {
const item = fortuneBizTypeOptions.find(item => item.value === value)
return item?.label || ''
}
......@@ -252,59 +365,63 @@ const addCheckRecordConfig = [
prop: 'fortuneBizType',
label: '应付单类型',
options: fortuneBizTypeOptions
}, {
},
{
type: 'select',
prop: 'status',
label: '出账状态',
dictType: 'csf_expected_fortune_status'
}, {
},
{
type: 'input',
prop: 'policyNo',
label: '关联保单号',
visible: (formData) => formData.fortuneBizType === 'R',
}, {
visible: formData => formData.fortuneBizType === 'R'
},
{
type: 'input',
prop: 'fortunePeriod',
label: '佣金期数',
inputType: 'decimal',
visible: (formData) => formData.fortuneBizType === 'R',
rules: [
{ pattern: /^\d+$/, message: '只能输入正整数', trigger: 'blur' }
]
}, {
visible: formData => formData.fortuneBizType === 'R',
rules: [{ pattern: /^\d+$/, message: '只能输入正整数', trigger: 'blur' }]
},
{
type: 'input',
prop: 'fortuneTotalPeriod',
label: '总期数',
inputType: 'decimal',
visible: (formData) => formData.fortuneBizType === 'R',
rules: [
{ pattern: /^\d+$/, message: '只能输入正整数', trigger: 'blur' }
]
}, {
visible: formData => formData.fortuneBizType === 'R',
rules: [{ pattern: /^\d+$/, message: '只能输入正整数', trigger: 'blur' }]
},
{
type: 'date',
prop: 'actualPayoutDate',
label: '出账日(实)',
placeholder: '请选择',
maxDate: 'today'
}, {
},
{
type: 'input',
prop: 'amount',
label: '出账金额',
inputType: 'decimal',
rules: [
{ pattern: /^\d+$/, message: '只能输入正整数', trigger: 'blur' }
]
}, {
inputType: 'decimalNumber',
decimalDigits: 4,
rules: [{ pattern: /^-?\d+(\.\d+)?$/, message: '请输入有效的数字', trigger: 'blur' }]
},
{
type: 'select',
prop: 'currency',
label: '出账币种',
dictType: 'bx_currency_type'
}, {
},
{
type: 'select',
prop: 'fortuneType',
label: '出账项目',
dictType: 'csf_fortune_type'
}, {
},
{
type: 'select',
prop: 'brokerBizId',
label: '转介人',
......@@ -316,16 +433,15 @@ const addCheckRecordConfig = [
valueKey: 'userSaleBizId',
labelKey: 'realName',
onChangeExtraFields: {
broker: 'realName',// 自动同步 raw.name 到 reconciliationCompany
broker: 'realName', // 自动同步 raw.name 到 reconciliationCompany
reconciliationCompanyCode: 'code'
},
transform: (res) => {
transform: res => {
return res?.data.records || []
}
}
]
// 设置本期出账金额
const setPayoutAmountFormModel = ref({})
const setPayoutAmountFormRef = ref(null)
......@@ -336,22 +452,20 @@ const setPayoutAmountConfig = [
prop: 'currentPaymentHkdAmount',
label: '本期出账金额(HKD)',
inputType: 'decimal',
rules: [
{ pattern: /^\d+$/, message: '只能输入正整数', trigger: 'blur' }
]
},
rules: [{ pattern: /^\d+$/, message: '只能输入正整数', trigger: 'blur' }]
},
// {
// type: 'select',
// prop: 'currency',
// label: '出账币种',
// dictType: 'bx_currency_type'
// },
// },
{
type: 'select',
prop: 'status',
label: '出账状态',
dictType: 'csf_expected_fortune_status'
},
}
// {
// type: 'input',
// prop: 'exchangeRate',
......@@ -360,9 +474,6 @@ const setPayoutAmountConfig = [
// }
]
// 统计信息
const statisticsData = ref({})
// 弹窗相关
......@@ -395,7 +506,7 @@ const operationBtnList = ref([
direction: 'left',
label: '新增出账',
click: handleAdd
},
},
{
key: 'export',
direction: 'right',
......@@ -440,11 +551,11 @@ const loadTableData = async (searchParams = {}) => {
}
loadTableData()
// 分页事件
const handleSizeChange = (val) => {
const handleSizeChange = val => {
pageSize.value = val
loadTableData()
}
const handleCurrentChange = (val) => {
const handleCurrentChange = val => {
currentPage.value = val
loadTableData()
}
......@@ -457,14 +568,11 @@ const handleSelect = (e, row) => {
if (e === 'setPayRoll') {
setPayoutAmountDialogFlag.value = true
}
}
const addCheckRecordaddBatchapi = async (data) => {
const addCheckRecordaddBatchapi = async data => {
const formData = addCheckRecordFormRef.value.getFormData()
console.log('新增出账检核记录:', formData)
const params = [
{ ...formData }
]
const params = [{ ...formData }]
try {
const res = await addCheckRecordaddBatch(params)
if (res.code === 200) {
......@@ -482,7 +590,7 @@ const addCheckRecordaddBatchapi = async (data) => {
}
// 设置本期出账金额
const updatePayoutAmountapi = async (data) => {
const updatePayoutAmountapi = async data => {
console.log('设置本期出账金额:', data)
const params = {
...setPayoutAmountFormRef.value.getFormData(),
......@@ -504,14 +612,14 @@ const updatePayoutAmountapi = async (data) => {
}
const updatePayRollStatusDisable = ref(true)
const multipleSelection = ref([])
const handleSelectionChange = (val) => {
const handleSelectionChange = val => {
multipleSelection.value = val
console.log('全选:', val)
// 完成检核按钮是否禁用
updatePayRollStatusDisable.value = val.length === 0
}
const downloadPolicyFortuneAccountapi = async (data) => {
const downloadPolicyFortuneAccountapi = async data => {
console.log('生成出账清单:', data)
try {
const res = await downloadPolicyFortuneAccount({
......@@ -530,7 +638,7 @@ import FileUploadPreview from '@/components/fileUploadPreview/fileUploadPreview.
const importCheckRecordFlag = ref(false)
// 如果后端接收的就是当前格式,可直接透传
const formatForBackend = (rows) => {
const formatForBackend = rows => {
return rows.map(row => ({
...row,
amount: Number(row.amount) || 0,
......@@ -538,15 +646,12 @@ const formatForBackend = (rows) => {
}))
}
const onSubmit = (data) => {
const onSubmit = data => {
console.log('提交给后端的数据:', data)
// 调用保存 API
}
onMounted(async () => {
})
onMounted(async () => {})
</script>
<style scoped>
......@@ -555,4 +660,4 @@ onMounted(async () => {
justify-content: flex-end;
margin-top: 10px;
}
</style>
\ No newline at end of file
</style>
......@@ -68,12 +68,13 @@
</el-checkbox-group>
</div>
</template>
<!-- -->
<el-input
v-if="child.domType === 'Input'"
:type="child.inputType"
v-model="form[child.key]"
:type="child.inputType"
:placeholder="child.placeholder"
maxlength="30"
:maxlength="child.maxlength"
:disabled="
child.key == 'age' ||
child.key == 'bmi' ||
......@@ -82,6 +83,7 @@
: editStatus
"
@blur="handleInputBlur(child)"
@input="val => handleInputChange(val, child)"
>
<template #append v-if="child.unit">
<span
......@@ -442,6 +444,7 @@ import CommonForm from '@/views/components/commonForm'
import CommonDialog from '@/components/commonDialog'
import CommonPage from '@/components/commonPage'
import CardOne from '@/components/formCard/cardOne'
import { numberFormat } from '@/utils/number'
import { watch } from 'vue'
import {
addCustomer,
......@@ -640,6 +643,11 @@ const handleAppendInput = child => {
customerList()
}
}
//处理数据
const handleInputChange = (val, child) => {
let newVal = numberFormat(val, child)
form.value[child.key] = newVal
}
const handleInputBlur = child => {
if (
(child.key == 'weight' || child.key == 'height') &&
......
......@@ -960,6 +960,13 @@ const handleSubmit = async type => {
return
}
}
console.log('====================================')
console.log(
'submitAppointmentObj.value.apiProductPlanInfoDto',
submitAppointmentObj.value.apiProductPlanInfoDto
)
console.log('====================================')
// return
// 获取投保人form
if (policyHolderInfoRef.value) {
submitAppointmentObj.value.apiPolicyholderInfoDto =
......
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