Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
yd-csf-front
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
yuzhenWang
yd-csf-front
Commits
a9cca2fa
Commit
a9cca2fa
authored
Dec 19, 2025
by
Sweet Zhang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
通用表单样式修改,查询页面动作区域按钮封装调整
parent
051a8a7b
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
1015 additions
and
119 deletions
+1015
-119
index.html
+11
-2
src/api/financial/commission.js
+34
-0
src/components/commonPage/index.vue
+329
-117
src/views/financialCenter/payables.vue
+0
-0
src/views/financialCenter/receivables.vue
+641
-0
No files found.
index.html
View file @
a9cca2fa
...
...
@@ -17,11 +17,20 @@
margin
:
0px
;
padding
:
0px
;
}
body
{
font-family
:
'Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif'
!important
;
font-size
:
14px
!important
;
letter-spacing
:
0.3px
;
color
:
#383838
!important
;
}
/* element-plus表单的label统一样式 */
.el-form-item__label
{
color
:
#383838
!important
;
}
.chromeframe
{
margin
:
0.2em
0
;
background
:
#ccc
;
color
:
#
000
;
color
:
#
383838
;
padding
:
0.2em
0
;
}
...
...
src/api/financial/commission.js
View file @
a9cca2fa
...
...
@@ -222,3 +222,37 @@ export function policyData(data) {
data
:
data
})
}
// 应付款管理列表
export
function
expectedFortuneList
(
data
)
{
return
request
({
url
:
'/csf/api/expectedFortune/list'
,
method
:
'post'
,
data
:
data
})
}
// 应收款管理列表
export
function
receivedFortuneList
(
data
)
{
return
request
({
url
:
'/csf/api/CommissionExpected/queryCommissionExpectedByPage'
,
method
:
'post'
,
data
:
data
})
}
// 统计应收数据总金额、总入账金额、待入账金额、已入账比例(已入账金额-总金额)、总保单数
export
function
commissionExpectedStatistics
(
data
)
{
return
request
({
url
:
'/csf/api/CommissionExpected/statistics'
,
method
:
'post'
,
data
:
data
})
}
// 统计计算统计数据 预计发佣金额 HKD、已出账金额 HKD、待出账金额 HKD、总保单数、总保费 HKD
export
function
expectedFortuneStatistics
(
data
)
{
return
request
({
url
:
'/csf/api/expectedFortune/statistics'
,
method
:
'post'
,
data
:
data
})
}
src/components/commonPage/index.vue
View file @
a9cca2fa
...
...
@@ -28,174 +28,360 @@
<!-- 按钮区域 -->
<el-col
:span=
"24"
class=
"operationBtn"
>
<div
class=
"operationLeft"
>
<template
v-for=
"left in leftOperationBtns"
:key=
"left.label"
>
<!-- 左侧按钮 -->
<template
v-for=
"btn in leftButtons"
:key=
"btn.key || btn.label"
>
<el-button
:type=
"left.type || 'primary'"
:icon=
"left.icon"
:size=
"left.size || 'default'"
@
click=
"left.click"
:disabled=
"left.disabled"
:loading=
"left.loading"
:type=
"btn.type || 'primary'"
:icon=
"btn.icon"
:size=
"btn.size || 'default'"
@
click=
"handleButtonClick(btn)"
:disabled=
"btn.disabled"
:loading=
"btn.loading"
:class=
"btn.customClass"
>
{{
left
.
label
}}
{{
btn
.
label
}}
</el-button>
</
template
>
<!-- 左侧插槽 -->
<slot
name=
"leftButtons"
></slot>
</div>
<div
class=
"operationRight"
>
<
template
v-for=
"right in rightOperationBtns"
:key=
"right.label"
>
<!-- 右侧按钮 -->
<
template
v-for=
"btn in rightButtons"
:key=
"btn.key || btn.label"
>
<el-button
:type=
"right.type || 'primary'"
:icon=
"right.icon"
:size=
"right.size || 'default'"
@
click=
"right.click"
:disabled=
"right.disabled"
:loading=
"right.loading"
:type=
"btn.type || 'primary'"
:icon=
"btn.icon"
:size=
"btn.size || 'default'"
@
click=
"handleButtonClick(btn)"
:disabled=
"btn.disabled"
:loading=
"btn.loading"
:class=
"btn.customClass"
>
{{
right
.
label
}}
{{
btn
.
label
}}
</el-button>
</
template
>
<!-- 右侧插槽 -->
<slot
name=
"rightButtons"
></slot>
</div>
</el-col>
<!-- 表格插槽 -->
<slot
name=
"table"
></slot>
<el-col
:span=
"24"
>
<slot
name=
"table"
></slot>
</el-col>
<!-- 分页区域 -->
<el-col
:span=
"24"
v-if=
"showPagination"
>
<div
class=
"pagination-container"
>
<el-pagination
v-model:current-page=
"currentPage"
v-model:page-size=
"pageSize"
:page-sizes=
"pageSizes"
:layout=
"paginationLayout"
:total=
"total"
@
size-change=
"handleSizeChange"
@
current-change=
"handleCurrentChange"
/>
</div>
</el-col>
</el-row>
</el-card>
</div>
</template>
<
script
setup
>
<
script
setup
lang=
"ts"
>
import
{
ref
,
computed
,
watch
,
nextTick
,
onMounted
,
defineExpose
}
from
'vue'
import
{
Bottom
,
Top
}
from
'@element-plus/icons-vue'
const
props
=
defineProps
({
// 按钮类型定义
export
interface
OperationButton
{
// 按钮唯一标识(用于匹配默认按钮配置)
key
?:
string
// 显示文本(如果提供了key,会自动使用默认文本)
label
?:
string
// 按钮类型
type
?:
'primary'
|
'success'
|
'warning'
|
'danger'
|
'info'
|
'text'
// 图标名称
icon
?:
string
// 按钮尺寸
size
?:
'large'
|
'default'
|
'small'
// 显示位置
direction
?:
'left'
|
'right'
// 是否禁用
disabled
?:
boolean
// 加载状态
loading
?:
boolean
// 是否显示(默认显示)
visible
?:
boolean
// 点击事件回调函数
click
?:
()
=>
void
|
Promise
<
void
>
// 权限标识
permission
?:
string
// 自定义样式类
customClass
?:
string
}
// 组件 Props
interface
Props
{
// 操作按钮列表
operationBtnList
:
{
type
:
Array
,
default
:
()
=>
[]
},
operationBtnList
?:
OperationButton
[]
// 是否显示查询表单
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'
},
showSearchForm
?:
boolean
// 是否显示分页
showPagination
?:
boolean
// 总条数
total
?:
number
// 当前页码
currentPage
?:
number
// 每页显示条数
pageSize
?:
number
// 每页条数选项
pageSizes
?:
number
[]
// 分页布局
paginationLayout
?:
string
// 默认显示的查询条件数量
defaultVisibleConditions
:
{
type
:
Number
,
default
:
6
}
defaultVisibleConditions
?:
number
// 是否显示默认按钮
showDefaultButtons
?:
boolean
// 需要显示的默认按钮
visibleDefaultButtons
?:
(
'add'
|
'import'
|
'export'
|
'reset'
|
'query'
)[]
}
const
props
=
withDefaults
(
defineProps
<
Props
>
(),
{
operationBtnList
:
()
=>
[],
showSearchForm
:
true
,
showPagination
:
false
,
total
:
0
,
currentPage
:
1
,
pageSize
:
10
,
pageSizes
:
()
=>
[
10
,
20
,
50
,
100
],
paginationLayout
:
'total, sizes, prev, pager, next, jumper'
,
defaultVisibleConditions
:
8
,
showDefaultButtons
:
true
,
visibleDefaultButtons
:
()
=>
[
'add'
,
'import'
,
'export'
,
'reset'
,
'query'
]
})
const
emit
=
defineEmits
([
'size-change'
,
'current-change'
,
'btn-click'
,
'search-toggle'
])
const
emit
=
defineEmits
<
{
// 分页事件
'size-change'
:
[
size
:
number
]
'current-change'
:
[
page
:
number
]
// 按钮点击事件
'btn-click'
:
[
btn
:
OperationButton
]
// 搜索展开/收起
'search-toggle'
:
[
expanded
:
boolean
]
// 默认按钮事件(为方便使用保留)
'add'
:
[]
'import'
:
[]
'export'
:
[]
'reset'
:
[]
'query'
:
[]
}
>
()
// 响应式数据
const
isExpanded
=
ref
(
false
)
const
hasMoreCondition
=
ref
(
false
)
const
searchFormRef
=
ref
(
null
)
const
searchFormRef
=
ref
<
HTMLElement
|
null
>
(
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
defaultButtonConfigs
=
{
add
:
{
key
:
'add'
,
label
:
'新增'
,
icon
:
'Plus'
,
type
:
'primary'
as
const
,
direction
:
'left'
as
const
,
size
:
'default'
as
const
},
import
:
{
key
:
'import'
,
label
:
'导入'
,
icon
:
'Upload'
,
type
:
'primary'
as
const
,
direction
:
'left'
as
const
,
size
:
'default'
as
const
},
export
:
{
key
:
'export'
,
label
:
'导出'
,
icon
:
'Download'
,
type
:
'success'
as
const
,
direction
:
'right'
as
const
,
size
:
'default'
as
const
},
reset
:
{
key
:
'reset'
,
label
:
'重置'
,
icon
:
'Refresh'
,
type
:
'info'
as
const
,
direction
:
'right'
as
const
,
size
:
'default'
as
const
},
query
:
{
key
:
'query'
,
label
:
'查询'
,
icon
:
'Search'
,
type
:
'primary'
as
const
,
direction
:
'right'
as
const
,
size
:
'default'
as
const
}
}
// 计算最终按钮配置
const
computedButtons
=
computed
(()
=>
{
const
result
:
OperationButton
[]
=
[]
// 1. 添加默认按钮(如果开启)
if
(
props
.
showDefaultButtons
)
{
props
.
visibleDefaultButtons
.
forEach
(
key
=>
{
if
(
defaultButtonConfigs
[
key
])
{
const
defaultBtn
=
{
...
defaultButtonConfigs
[
key
]
}
// 查找是否有自定义配置覆盖
const
customConfig
=
props
.
operationBtnList
.
find
(
btn
=>
btn
.
key
===
key
)
if
(
customConfig
)
{
// 合并配置:自定义配置覆盖默认配置
Object
.
assign
(
defaultBtn
,
customConfig
)
}
result
.
push
(
defaultBtn
)
}
})
}
// 2. 添加没有匹配到默认按钮的自定义按钮
props
.
operationBtnList
.
forEach
(
customBtn
=>
{
// 如果这个按钮已经有默认配置了,就跳过(已经在上面处理了)
const
isDefaultBtn
=
customBtn
.
key
&&
props
.
visibleDefaultButtons
.
includes
(
customBtn
.
key
as
any
)
const
alreadyAdded
=
result
.
some
(
btn
=>
btn
.
key
===
customBtn
.
key
)
if
(
!
isDefaultBtn
&&
!
alreadyAdded
)
{
result
.
push
(
customBtn
)
}
})
return
result
})
// 计算左侧按钮
const
leftButtons
=
computed
(()
=>
{
return
computedButtons
.
value
.
filter
(
btn
=>
(
btn
.
direction
===
'left'
||
(
!
btn
.
direction
&&
props
.
showDefaultButtons
))
&&
(
btn
.
visible
!==
false
)
)
})
const
rightOperationBtns
=
computed
(()
=>
{
return
props
.
operationBtnList
.
filter
(
btn
=>
btn
.
direction
===
'right'
)
// 计算右侧按钮
const
rightButtons
=
computed
(()
=>
{
return
computedButtons
.
value
.
filter
(
btn
=>
btn
.
direction
===
'right'
&&
(
btn
.
visible
!==
false
)
)
})
// 方法
const
toggleExpand
=
()
=>
{
isExpanded
.
value
=
!
isExpanded
.
value
emit
(
'search-toggle'
,
isExpanded
.
value
)
checkConditions
()
}
const
checkConditions
=
()
=>
{
if
(
!
searchFormRef
.
value
)
return
if
(
!
searchFormRef
.
value
||
!
props
.
showSearchForm
)
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
const
formItems
=
Array
.
from
(
searchFormRef
.
value
!
.
querySelectorAll
(
'.el-form-item, .el-button-group'
)
)
hasMoreCondition
.
value
=
formItems
.
length
>
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
++
if
(
index
>=
props
.
defaultVisibleConditions
)
{
(
item
as
HTMLElement
).
style
.
display
=
'none'
}
else
{
item
.
style
.
display
=
'none'
hiddenCount
++
}
})
// 处理按钮项
formButtons
.
forEach
((
button
,
index
)
=>
{
if
(
visibleCount
<
props
.
defaultVisibleConditions
)
{
button
.
style
.
display
=
''
visibleCount
++
}
else
{
button
.
style
.
display
=
'none'
hiddenCount
++
(
item
as
HTMLElement
).
style
.
display
=
''
}
})
}
else
{
// 显示所有条件
formItems
.
forEach
(
item
=>
(
item
.
style
.
display
=
''
))
formButtons
.
forEach
(
button
=>
(
button
.
style
.
display
=
''
)
)
formItems
.
forEach
(
item
=>
{
(
item
as
HTMLElement
).
style
.
display
=
''
}
)
}
})
}
const
handleBtnClick
=
btn
=>
{
// 处理按钮点击
const
handleButtonClick
=
async
(
btn
:
OperationButton
)
=>
{
// 触发通用按钮点击事件
emit
(
'btn-click'
,
btn
)
// 触发默认按钮的特定事件(保持向后兼容)
if
(
btn
.
key
)
{
switch
(
btn
.
key
)
{
case
'add'
:
emit
(
'add'
)
break
case
'import'
:
emit
(
'import'
)
break
case
'export'
:
emit
(
'export'
)
break
case
'reset'
:
emit
(
'reset'
)
break
case
'query'
:
emit
(
'query'
)
break
}
}
// 执行父组件传入的click函数
if
(
btn
.
click
&&
typeof
btn
.
click
===
'function'
)
{
btn
.
click
()
try
{
const
result
=
btn
.
click
()
// 如果是Promise,等待执行完成
if
(
result
instanceof
Promise
)
{
await
result
}
}
catch
(
error
)
{
console
.
error
(
'按钮点击事件执行失败:'
,
error
)
}
}
}
// 分页事件处理
const
handleSizeChange
=
(
size
:
number
)
=>
{
pageSize
.
value
=
size
emit
(
'size-change'
,
size
)
}
const
handleCurrentChange
=
(
page
:
number
)
=>
{
currentPage
.
value
=
page
emit
(
'current-change'
,
page
)
}
// 更新按钮状态的方法
const
updateButtonState
=
(
key
:
string
,
updates
:
Partial
<
OperationButton
>
)
=>
{
// 这个方法可以在父组件中调用
console
.
log
(
`更新按钮
${
key
}
状态:`
,
updates
)
}
// 暴露给父组件的方法
defineExpose
({
checkConditions
,
toggleExpand
toggleExpand
,
updateButtonState
,
refresh
:
()
=>
{
checkConditions
()
}
})
// 监听器
watch
(
isExpanded
,
()
=>
{
checkConditions
()
})
watch
(
isExpanded
,
checkConditions
)
watch
(
()
=>
props
.
currentPage
,
...
...
@@ -211,15 +397,27 @@ watch(
}
)
watch
(
()
=>
props
.
operationBtnList
,
()
=>
{
nextTick
(()
=>
{
checkConditions
()
})
},
{
deep
:
true
}
)
// 生命周期
onMounted
(()
=>
{
if
(
props
.
showSearchForm
)
{
checkConditions
()
setTimeout
(()
=>
{
checkConditions
()
},
100
)
}
})
</
script
>
<
style
scoped
>
<
style
lang=
"scss"
scoped
>
.commonPage-container
{
width
:
100%
;
box-sizing
:
border-box
;
...
...
@@ -228,6 +426,7 @@ onMounted(() => {
.cardStyle
{
margin-bottom
:
10px
;
border
:
none
!important
;
box-shadow
:
0
1px
3px
rgba
(
0
,
0
,
0
,
0.1
);
}
.moreBtn
{
...
...
@@ -235,25 +434,29 @@ onMounted(() => {
align-items
:
center
;
justify-content
:
center
;
margin-top
:
10px
;
padding-top
:
10px
;
border-top
:
1px
solid
var
(
--el-border-color-lighter
);
}
.operationBtn
{
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
margin-bottom
:
10px
;
margin-bottom
:
16px
;
flex-wrap
:
wrap
;
gap
:
12px
;
}
.operationLeft
,
.operationRight
{
display
:
flex
;
gap
:
10
px
;
gap
:
8
px
;
flex-wrap
:
wrap
;
}
.pagination-container
{
display
:
flex
;
justify-content
:
center
;
justify-content
:
flex-end
;
margin-top
:
20px
;
padding-top
:
20px
;
border-top
:
1px
solid
var
(
--el-border-color-lighter
);
...
...
@@ -262,27 +465,35 @@ onMounted(() => {
/* 搜索表单容器样式 */
.search-form-container
{
width
:
100%
;
transition
:
all
0.3s
ease
;
&.expanded
{
.el-form-item
{
display
:
flex
!important
;
}
}
}
/* 响应式调整 */
@media
(
max-width
:
768px
)
{
.operationBtn
{
flex-direction
:
column
;
gap
:
10px
;
align-items
:
stretch
;
gap
:
12px
;
}
.operationLeft
,
.operationRight
{
width
:
100%
;
justify-content
:
center
;
}
.
search-form-container
{
flex-direction
:
column
;
.
cardStyle
{
margin-bottom
:
8px
;
}
.
search-form-container
:deep
(
.el-form-item
)
{
width
:
100%
!important
;
.
pagination-container
{
justify-content
:
center
;
}
}
</
style
>
</
style
>
\ No newline at end of file
src/views/financialCenter/payables.vue
0 → 100644
View file @
a9cca2fa
src/views/financialCenter/receivables.vue
0 → 100644
View file @
a9cca2fa
<
template
>
<CommonPage
:operationBtnList=
"operationBtnList"
:visibleDefaultButtons=
"visibleDefaultButtons"
:showSearchForm=
"true"
:show-pagination=
"true"
>
<!-- 搜索区域 -->
<template
#
searchForm
>
<el-form
:model=
"searchFormData"
ref=
"searchFormRef"
label-width=
"120px"
label-position=
"top"
class=
"search-form"
>
<el-row
:gutter=
"20"
>
<el-col
:xs=
"24"
:sm=
"12"
:md=
"8"
:lg=
"6"
:xl=
"6"
v-for=
"item in searchFormItems"
:key=
"item.value"
>
<el-form-item
:label=
"item.label"
:prop=
"item.value"
:rules=
"item.rules"
>
<template
v-if=
"item.type === 'input'"
>
<el-input
v-model=
"searchFormData[item.value]"
:placeholder=
"item.placeholder"
size=
"large"
clearable
/>
</
template
>
<
template
v-else-if=
"item.type === 'select'"
>
<el-select
v-model=
"searchFormData[item.value]"
:placeholder=
"item.placeholder"
size=
"large"
clearable
>
<el-option
v-for=
"option in item.options"
:key=
"option.value"
:label=
"option.label"
:value=
"option.value"
/>
</el-select>
</
template
>
<
template
v-else-if=
"item.type === 'daterange'"
>
<el-date-picker
v-model=
"searchFormData[item.value]"
type=
"daterange"
range-separator=
"至"
start-placeholder=
"开始日期"
end-placeholder=
"结束日期"
size=
"large"
clearable
style=
"width: 100%"
/>
</
template
>
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<!-- 列表区域 -->
<
template
#
table
>
<!-- 统计信息卡片 -->
<div
class=
"statistics-cards"
v-if=
"statisticsData.totalPolicyCount > 0"
>
<el-row
:gutter=
"20"
>
<el-col
:xs=
"24"
:sm=
"12"
:md=
"6"
:lg=
"6"
>
<el-card
shadow=
"hover"
class=
"statistics-card"
>
<div
class=
"card-content"
>
<div
class=
"card-label"
>
应收款总金额
</div>
<div
class=
"card-value"
>
{{
formatCurrency
(
statisticsData
.
totalAmount
)
}}
</div>
</div>
</el-card>
</el-col>
<el-col
:xs=
"24"
:sm=
"12"
:md=
"6"
:lg=
"6"
>
<el-card
shadow=
"hover"
class=
"statistics-card"
>
<div
class=
"card-content"
>
<div
class=
"card-label"
>
已入账金额
</div>
<div
class=
"card-value"
>
{{
formatCurrency
(
statisticsData
.
totalPaidAmount
)
}}
</div>
</div>
</el-card>
</el-col>
<el-col
:xs=
"24"
:sm=
"12"
:md=
"6"
:lg=
"6"
>
<el-card
shadow=
"hover"
class=
"statistics-card"
>
<div
class=
"card-content"
>
<div
class=
"card-label"
>
待入账金额
</div>
<div
class=
"card-value"
>
{{
formatCurrency
(
statisticsData
.
pendingAmount
)
}}
</div>
</div>
</el-card>
</el-col>
<el-col
:xs=
"24"
:sm=
"12"
:md=
"6"
:lg=
"6"
>
<el-card
shadow=
"hover"
class=
"statistics-card"
>
<div
class=
"card-content"
>
<div
class=
"card-label"
>
总保单数
</div>
<div
class=
"card-value"
>
{{
statisticsData
.
totalPolicyCount
}}
</div>
</div>
</el-card>
</el-col>
</el-row>
</div>
<!-- 应收款管理列表 -->
<el-table
:data=
"tableData"
height=
"350"
border
highlight-current-row
style=
"width: 100%"
v-loading=
"loading"
>
<el-table-column
prop=
"commissionBizType"
label=
"应收款类型"
width=
"120"
fixed=
"left"
/>
<el-table-column
prop=
"receivableNo"
label=
"应收款编号"
width=
"120"
/>
<el-table-column
prop=
"policyNo"
label=
"保单号"
width=
"120"
/>
<el-table-column
prop=
"reconciliationCompany"
label=
"对账公司"
width=
"120"
/>
<el-table-column
prop=
"status"
label=
"入账状态"
width=
"100"
>
<template
#
default=
"
{ row }">
<el-tag
:type=
"row.status === '1' ? 'success' : 'warning'"
>
{{
row
.
status
===
'1'
?
'已入账'
:
'待入账'
}}
</el-tag>
</
template
>
</el-table-column>
<el-table-column
prop=
"commissionPeriod"
label=
"入账期数"
width=
"100"
/>
<el-table-column
prop=
"totalPeriod"
label=
"入账总期数"
width=
"100"
/>
<el-table-column
prop=
"commissionType"
label=
"入账项目"
width=
"100"
/>
<el-table-column
prop=
"commissionDate"
label=
"入账日(估)"
width=
"120"
/>
<el-table-column
prop=
"commissionRatio"
label=
"入账比例(估)"
width=
"120"
>
<
template
#
default=
"{ row }"
>
{{
(
row
.
commissionRatio
||
0
)
+
'%'
}}
</
template
>
</el-table-column>
<el-table-column
prop=
"expectedAmount"
label=
"入账金额(估)"
width=
"120"
>
<
template
#
default=
"{ row }"
>
{{
formatCurrency
(
row
.
expectedAmount
)
}}
</
template
>
</el-table-column>
<el-table-column
prop=
"paidRatio"
label=
"已入账比例"
width=
"120"
>
<
template
#
default=
"{ row }"
>
{{
(
row
.
paidRatio
||
0
)
+
'%'
}}
</
template
>
</el-table-column>
<el-table-column
prop=
"paidAmount"
label=
"已入账金额"
width=
"120"
>
<
template
#
default=
"{ row }"
>
{{
formatCurrency
(
row
.
paidAmount
)
}}
</
template
>
</el-table-column>
<el-table-column
prop=
"pendingRatio"
label=
"待入账比例"
width=
"120"
>
<
template
#
default=
"{ row }"
>
{{
(
row
.
pendingRatio
||
0
)
+
'%'
}}
</
template
>
</el-table-column>
<el-table-column
prop=
"pendingAmount"
label=
"待入账金额(估)"
width=
"120"
>
<
template
#
default=
"{ row }"
>
{{
formatCurrency
(
row
.
pendingAmount
)
}}
</
template
>
</el-table-column>
<el-table-column
prop=
"defaultExchangeRate"
label=
"结算汇率(估)"
width=
"120"
/>
<el-table-column
prop=
"insurerBizId"
label=
"保险公司"
width=
"120"
/>
<el-table-column
prop=
"productLaunchBizId"
label=
"产品计划"
width=
"120"
/>
<el-table-column
prop=
"premium"
label=
"期交保费"
width=
"120"
>
<
template
#
default=
"{ row }"
>
{{
formatCurrency
(
row
.
premium
)
}}
</
template
>
</el-table-column>
<el-table-column
prop=
"remark"
label=
"备注"
width=
"150"
/>
<el-table-column
fixed=
"right"
label=
"操作"
width=
"150"
>
<
template
#
default=
"{ row }"
>
<el-button
link
type=
"primary"
size=
"small"
@
click=
"handleViewDetail(row)"
>
查看
</el-button>
<el-button
link
type=
"danger"
size=
"small"
@
click=
"handleDelete(row)"
>
删除
</el-button>
</
template
>
</el-table-column>
</el-table>
</template>
</CommonPage>
</template>
<
script
setup
lang=
"ts"
>
import
{
ref
,
reactive
,
onMounted
,
watch
}
from
'vue'
import
CommonPage
from
'@/components/commonPage'
import
type
{
OperationButton
}
from
'@/components/commonPage'
import
{
ElMessage
,
ElMessageBox
}
from
'element-plus'
// 分页相关
const
currentPage
=
ref
(
1
)
const
pageSize
=
ref
(
10
)
const
pageTotal
=
ref
(
0
)
const
loading
=
ref
(
false
)
// 搜索表单数据
const
searchFormData
=
reactive
({
policyNo
:
''
,
incomeDateRange
:
[]
as
string
[],
incomeStatus
:
''
,
incomeTerm
:
''
,
incomeItem
:
''
,
outTeam
:
''
,
insurer
:
''
,
productPlan
:
''
,
paymentType
:
''
,
intermediary
:
''
,
signer
:
''
})
// 搜索表单项配置
const
searchFormItems
=
ref
([
{
label
:
'保单号'
,
value
:
'policyNo'
,
type
:
'input'
,
placeholder
:
'请输入保单号'
},
{
label
:
'入账日(估)'
,
value
:
'incomeDateRange'
,
type
:
'daterange'
,
placeholder
:
'请选择入账日(估)'
},
{
label
:
'入账状态'
,
value
:
'incomeStatus'
,
type
:
'select'
,
placeholder
:
'请选择入账状态'
,
options
:
[
{
label
:
'全部'
,
value
:
''
},
{
label
:
'已入账'
,
value
:
'1'
},
{
label
:
'待入账'
,
value
:
'0'
}
]
},
{
label
:
'入账期数'
,
value
:
'incomeTerm'
,
type
:
'input'
,
placeholder
:
'请输入入账期数'
},
{
label
:
'入账项目'
,
value
:
'incomeItem'
,
type
:
'select'
,
placeholder
:
'请选择入账项目'
,
options
:
[
{
label
:
'全部'
,
value
:
''
},
{
label
:
'佣金'
,
value
:
'1'
},
{
label
:
'服务费'
,
value
:
'2'
}
]
},
{
label
:
'出单团队'
,
value
:
'outTeam'
,
type
:
'select'
,
placeholder
:
'请选择出单团队'
,
options
:
[
{
label
:
'全部'
,
value
:
''
},
{
label
:
'团队A'
,
value
:
'1'
},
{
label
:
'团队B'
,
value
:
'2'
}
]
},
{
label
:
'保险公司'
,
value
:
'insurer'
,
type
:
'select'
,
placeholder
:
'请选择保险公司'
,
options
:
[
{
label
:
'全部'
,
value
:
''
},
{
label
:
'保险公司A'
,
value
:
'1'
},
{
label
:
'保险公司B'
,
value
:
'2'
}
]
},
{
label
:
'产品计划'
,
value
:
'productPlan'
,
type
:
'select'
,
placeholder
:
'请选择产品计划'
,
options
:
[
{
label
:
'全部'
,
value
:
''
},
{
label
:
'计划A'
,
value
:
'1'
},
{
label
:
'计划B'
,
value
:
'2'
}
]
},
{
label
:
'应收款类型'
,
value
:
'paymentType'
,
type
:
'select'
,
placeholder
:
'请选择应收款类型'
,
options
:
[
{
label
:
'全部'
,
value
:
''
},
{
label
:
'关联保单应收单'
,
value
:
'1'
},
{
label
:
'非关联保单应收单'
,
value
:
'2'
}
]
},
{
label
:
'转介人'
,
value
:
'intermediary'
,
type
:
'select'
,
placeholder
:
'请选择转介人'
,
options
:
[
{
label
:
'全部'
,
value
:
''
},
{
label
:
'转介人A'
,
value
:
'1'
},
{
label
:
'转介人B'
,
value
:
'2'
}
]
},
{
label
:
'签单员'
,
value
:
'signer'
,
type
:
'select'
,
placeholder
:
'请选择签单员'
,
options
:
[
{
label
:
'全部'
,
value
:
''
},
{
label
:
'签单员A'
,
value
:
'1'
},
{
label
:
'签单员B'
,
value
:
'2'
}
]
}
])
// 表格数据
const
tableData
=
ref
<
any
[]
>
([
// 示例数据
{
id
:
1
,
commissionBizType
:
'佣金'
,
receivableNo
:
'YSK001'
,
policyNo
:
'POL001'
,
reconciliationCompany
:
'对账公司A'
,
status
:
'1'
,
commissionPeriod
:
1
,
totalPeriod
:
12
,
commissionType
:
'首期佣金'
,
commissionDate
:
'2024-01-15'
,
commissionRatio
:
8.5
,
expectedAmount
:
8500
,
paidRatio
:
100
,
paidAmount
:
8500
,
pendingRatio
:
0
,
pendingAmount
:
0
,
defaultExchangeRate
:
1.0
,
insurerBizId
:
'保险公司A'
,
productLaunchBizId
:
'计划A'
,
premium
:
100000
,
remark
:
'备注信息'
},
{
id
:
2
,
commissionBizType
:
'服务费'
,
receivableNo
:
'YSK002'
,
policyNo
:
'POL002'
,
reconciliationCompany
:
'对账公司B'
,
status
:
'0'
,
commissionPeriod
:
2
,
totalPeriod
:
12
,
commissionType
:
'服务费'
,
commissionDate
:
'2024-02-15'
,
commissionRatio
:
5.0
,
expectedAmount
:
5000
,
paidRatio
:
50
,
paidAmount
:
2500
,
pendingRatio
:
50
,
pendingAmount
:
2500
,
defaultExchangeRate
:
1.0
,
insurerBizId
:
'保险公司B'
,
productLaunchBizId
:
'计划B'
,
premium
:
50000
,
remark
:
''
}
])
// 统计信息
const
statisticsData
=
ref
({
totalAmount
:
13500
,
totalPaidAmount
:
11000
,
pendingAmount
:
2500
,
paidRatio
:
81.48
,
// (11000/13500*100)
totalPolicyCount
:
2
})
// 货币格式化
const
formatCurrency
=
(
value
:
number
)
=>
{
if
(
value
===
undefined
||
value
===
null
)
return
'¥0.00'
return
'¥'
+
value
.
toFixed
(
2
).
replace
(
/
\d(?=(\d{3})
+
\.)
/g
,
'$&,'
)
}
// 按钮事件处理
const
handleAdd
=
()
=>
{
ElMessage
.
info
(
'点击新增按钮'
)
// 这里可以打开新增弹窗
// proxy.$refs.addForm.resetFields()
}
const
handleImport
=
()
=>
{
ElMessage
.
info
(
'点击导入按钮'
)
// 这里可以打开导入弹窗
// proxy.$refs.importForm.resetFields()
}
const
handleExport
=
()
=>
{
ElMessage
.
info
(
'点击导出按钮'
)
// 这里可以执行导出逻辑
// proxy.$refs.exportForm.resetFields()
}
const
handleReset
=
()
=>
{
// 重置搜索表单
Object
.
keys
(
searchFormData
).
forEach
(
key
=>
{
if
(
Array
.
isArray
(
searchFormData
[
key
]))
{
searchFormData
[
key
]
=
[]
}
else
{
searchFormData
[
key
]
=
''
}
})
ElMessage
.
success
(
'搜索条件已重置'
)
// 重新加载数据
loadTableData
()
}
const
handleQuery
=
async
()
=>
{
// 表单验证
// const valid = await proxy.$refs.searchFormRef.validate()
// if (!valid) return
ElMessage
.
info
(
'执行查询操作'
)
loadTableData
()
}
// 控制要显示的默认按钮
const
visibleDefaultButtons
=
ref
([
'add'
,
'import'
,
'export'
])
// 只显示新增和查询两个默认按钮
// 按钮配置
const
operationBtnList
=
ref
<
OperationButton
[]
>
([
{
key
:
'add'
,
direction
:
'left'
,
click
:
handleAdd
},
{
key
:
'import'
,
direction
:
'left'
,
click
:
handleImport
},
{
key
:
'export'
,
direction
:
'right'
,
click
:
handleExport
},
{
key
:
'reset'
,
direction
:
'right'
,
click
:
handleReset
},
{
key
:
'query'
,
direction
:
'right'
,
click
:
handleQuery
}
])
// 表格操作
const
handleViewDetail
=
(
row
:
any
)
=>
{
ElMessage
.
info
(
`查看应收款详情:
${
row
.
receivableNo
}
`
)
// 这里可以打开详情弹窗或跳转到详情页
}
const
handleDelete
=
async
(
row
:
any
)
=>
{
try
{
await
ElMessageBox
.
confirm
(
`确定要删除应收款 "
${
row
.
receivableNo
}
" 吗?`
,
'提示'
,
{
confirmButtonText
:
'确定'
,
cancelButtonText
:
'取消'
,
type
:
'warning'
}
)
// 执行删除操作
tableData
.
value
=
tableData
.
value
.
filter
(
item
=>
item
.
id
!==
row
.
id
)
ElMessage
.
success
(
'删除成功'
)
// 重新计算统计信息
calculateStatistics
()
}
catch
{
// 用户取消了操作
}
}
// 分页事件
const
handleSizeChange
=
(
val
:
number
)
=>
{
pageSize
.
value
=
val
loadTableData
()
}
const
handleCurrentChange
=
(
val
:
number
)
=>
{
currentPage
.
value
=
val
loadTableData
()
}
// 加载表格数据
const
loadTableData
=
async
()
=>
{
loading
.
value
=
true
try
{
// 模拟API调用
await
new
Promise
(
resolve
=>
setTimeout
(
resolve
,
500
))
// 这里应该调用真实的API接口
// const params = {
// ...searchFormData,
// currentPage: currentPage.value,
// pageSize: pageSize.value
// }
// const response = await api.getReceivablesList(params)
// tableData.value = response.data.list
// pageTotal.value = response.data.total
// 计算统计信息
calculateStatistics
()
}
catch
(
error
)
{
console
.
error
(
'加载数据失败:'
,
error
)
ElMessage
.
error
(
'加载数据失败'
)
}
finally
{
loading
.
value
=
false
}
}
// 计算统计信息
const
calculateStatistics
=
()
=>
{
const
data
=
tableData
.
value
const
totalAmount
=
data
.
reduce
((
sum
,
item
)
=>
sum
+
(
item
.
expectedAmount
||
0
),
0
)
const
totalPaidAmount
=
data
.
reduce
((
sum
,
item
)
=>
sum
+
(
item
.
paidAmount
||
0
),
0
)
const
pendingAmount
=
totalAmount
-
totalPaidAmount
const
paidRatio
=
totalAmount
>
0
?
(
totalPaidAmount
/
totalAmount
*
100
)
:
0
statisticsData
.
value
=
{
totalAmount
,
totalPaidAmount
,
pendingAmount
,
paidRatio
:
Number
(
paidRatio
.
toFixed
(
2
)),
totalPolicyCount
:
data
.
length
}
}
// 监听搜索条件变化(可选:自动查询)
watch
(
()
=>
searchFormData
,
()
=>
{
// 如果需要自动查询,可以在这里调用
// debounce(() => loadTableData(), 500)
},
{
deep
:
true
}
)
// 初始化加载数据
onMounted
(()
=>
{
loadTableData
()
calculateStatistics
()
})
</
script
>
<
style
scoped
lang=
"scss"
>
.search-form
{
padding
:
10px
0
;
:deep(.el-form-item)
{
margin-bottom
:
20px
;
.el-form-item__label
{
font-weight
:
500
;
}
}
}
.pagination-wrapper
{
display
:
flex
;
justify-content
:
flex-end
;
margin-top
:
20px
;
padding
:
15px
0
;
border-top
:
1px
solid
var
(
--el-border-color-lighter
);
}
.statistics-cards
{
margin-top
:
20px
;
}
.statistics-card
{
height
:
120px
;
margin-bottom
:
20px
;
.card-content
{
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
justify-content
:
center
;
height
:
100%
;
.card-label
{
font-size
:
14px
;
color
:
var
(
--el-text-color-secondary
);
margin-bottom
:
8px
;
}
.card-value
{
font-size
:
24px
;
font-weight
:
600
;
color
:
var
(
--el-color-primary
);
}
}
}
//
响应式调整
@media
(
max-width
:
768px
)
{
.search-form
{
:deep(.el-col)
{
margin-bottom
:
10px
;
}
}
.statistics-cards
{
.el-col
{
margin-bottom
:
15px
;
}
}
}
</
style
>
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment