Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
B
bims
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
孙海亮
bims
Commits
ecd603e2
Commit
ecd603e2
authored
1 year ago
by
yanglilong
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'yll-fix' into 'master'
fix(custom): 修改回款管理账单列表虚拟滚动 See merge request
!87
parents
4b18951c
092fad97
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
1962 additions
and
1132 deletions
+1962
-1132
collectionDetail.vue
src/views/verification/collectionDetail.vue
+1288
-1102
Index.vue
src/views/verification/components/a-virtual-table/Index.vue
+617
-0
README.MD
src/views/verification/components/a-virtual-table/README.MD
+26
-0
vue.config.js
vue.config.js
+31
-30
No files found.
src/views/verification/collectionDetail.vue
View file @
ecd603e2
...
...
@@ -18,7 +18,11 @@
@
change=
"changePayor"
:filterOption=
"filterCode"
>
<a-select-option
v-for=
"item in companyOptions"
:key=
"item.payorCode"
:value=
"item.payorCode"
>
<a-select-option
v-for=
"item in companyOptions"
:key=
"item.payorCode"
:value=
"item.payorCode"
>
{{
item
.
longName
}}
</a-select-option>
</a-select>
...
...
@@ -37,7 +41,10 @@
</a-form-model-item>
</a-col>
<a-col
:lg=
"6"
:sm=
"12"
>
<a-form-model-item
label=
"回款金额(人民币)"
prop=
"backAmountCny"
>
<a-form-model-item
label=
"回款金额(人民币)"
prop=
"backAmountCny"
>
<a-input
class=
"fixed_width"
type=
"number"
...
...
@@ -50,7 +57,11 @@
</a-col>
<a-col
:lg=
"5"
:sm=
"12"
>
<a-form-model-item
label=
"可核销余额"
>
<a-input
class=
"fixed_width"
v-model=
"residueBackAmount"
disabled
/>
<a-input
class=
"fixed_width"
v-model=
"residueBackAmount"
disabled
/>
</a-form-model-item>
</a-col>
<a-col
:lg=
"7"
:sm=
"12"
>
...
...
@@ -67,17 +78,32 @@
</a-col>
<a-col
:lg=
"5"
:sm=
"12"
>
<a-form-model-item
label=
"汇率差"
>
<a-input
v-model=
"form.backExchangeRate"
placeholder=
"请输入金额"
allow-clear
:disabled=
"!isEdit"
/>
<a-input
v-model=
"form.backExchangeRate"
placeholder=
"请输入金额"
allow-clear
:disabled=
"!isEdit"
/>
</a-form-model-item>
</a-col>
<a-col
:lg=
"6"
:sm=
"12"
>
<a-form-model-item
label=
"EOB编号"
>
<a-input
v-model=
"form.eobNos"
placeholder=
"请输入EOB编号"
allow-clear
:disabled=
"!isEdit"
/>
<a-input
v-model=
"form.eobNos"
placeholder=
"请输入EOB编号"
allow-clear
:disabled=
"!isEdit"
/>
</a-form-model-item>
</a-col>
<a-col
:lg=
"5"
:sm=
"12"
>
<a-form-model-item
label=
"EOB备注"
>
<a-input
v-model=
"form.eobRemark"
placeholder=
"请输入EOB备注"
allow-clear
:disabled=
"!isEdit"
/>
<a-input
v-model=
"form.eobRemark"
placeholder=
"请输入EOB备注"
allow-clear
:disabled=
"!isEdit"
/>
</a-form-model-item>
</a-col>
<a-col
:lg=
"5"
:sm=
"12"
>
...
...
@@ -92,7 +118,9 @@
:beforeUpload=
"() => beforeUpload()"
:remove=
"(file) => removeFile(file)"
>
<a-button
type=
"primary"
>
<Icon
name=
"ssiupload"
:size=
"18"
/>
上传文件
</a-button>
<a-button
type=
"primary"
>
<Icon
name=
"ssiupload"
:size=
"18"
/>
上传文件
</a-button>
</a-upload>
</a-form-model-item>
</a-col>
...
...
@@ -110,14 +138,21 @@
@
change=
"changePayor"
:filterOption=
"filterCode"
>
<a-select-option
v-for=
"item in companyOptions"
:key=
"item.payorCode"
:value=
"item.payorCode"
>
<a-select-option
v-for=
"item in companyOptions"
:key=
"item.payorCode"
:value=
"item.payorCode"
>
{{
item
.
longName
}}
</a-select-option>
</a-select>
</a-form-model-item>
</a-col>
<a-col
:lg=
"6"
:sm=
"12"
>
<a-form-model-item
label=
"回款金额(人民币)"
prop=
"backAmountCny"
>
<a-form-model-item
label=
"回款金额(人民币)"
prop=
"backAmountCny"
>
<a-input
class=
"fixed_width"
type=
"number"
...
...
@@ -131,13 +166,23 @@
<a-col
:lg=
"6"
:sm=
"12"
>
<a-form-model-item
label=
"本次账单回款金额合计"
>
<!--
<div
class=
"blue-text"
>
{{
ciReceiptTotalVo
.
backAmountTotal
||
0
}}
</div>
-->
<div
class=
"blue-text"
>
{{
accuracy
.
subtract
(
form
.
backAmountCny
,
residueBackAmount
)
||
0
}}
</div>
<div
class=
"blue-text"
>
{{
accuracy
.
subtract
(
form
.
backAmountCny
,
residueBackAmount
)
||
0
}}
</div>
</a-form-model-item>
</a-col>
<a-col
:lg=
"6"
:sm=
"12"
>
<a-form-model-item
label=
"可核销余额"
>
<a-input
class=
"fixed_width"
v-model=
"residueBackAmount"
disabled
/>
<a-input
class=
"fixed_width"
v-model=
"residueBackAmount"
disabled
/>
</a-form-model-item>
</a-col>
</
template
>
...
...
@@ -146,12 +191,27 @@
<
template
v-if=
"activeKey === '1'"
>
<div
class=
"bill-content"
>
<div
class=
"checked-count"
>
<a-button
type=
"primary"
size=
"small"
@
click=
"selectAllList"
>
全选
</a-button>
已勾选账单:
<span
class=
"blue-text"
>
{{
selectedRowKeys
.
length
||
0
}}
</span>
条
<span
v-if=
"selectedRows.filter(v=> v.status == 2).length != 0"
>
,其中:无效
<span
style=
"color: red;"
>
{{
selectedRows
.
filter
(
v
=>
v
.
status
==
2
).
length
||
0
}}
</span>
条
</span>
<a-button
type=
"primary"
size=
"small"
@
click=
"selectAllList"
>
全选
</a-button
>
已勾选账单:
<span
class=
"blue-text"
>
{{
selectedRowKeys
.
length
||
0
}}
</span>
条
<span
v-if=
"selectedRows.filter((v) => v.status == 2).length != 0"
>
,其中:无效
<span
style=
"color: red"
>
{{
selectedRows
.
filter
((
v
)
=>
v
.
status
==
2
).
length
||
0
}}
</span>
条
</span
>
</div>
<a-tabs
type=
"card"
v-model=
"activeKey1"
>
<a-tab-pane
v-for=
"pane in panes1"
:key=
"pane.key"
:tab=
"pane.title"
>
<a-tab-pane
v-for=
"pane in panes1"
:key=
"pane.key"
:tab=
"pane.title"
>
<div>
<a-row
type=
"flex"
align=
"middle"
class=
"search-form"
>
<a-form-model
...
...
@@ -193,9 +253,21 @@
</a-form-model-item>
</a-col>
<a-col
:lg=
"4"
:sm=
"12"
>
<a-form-model-item
label=
"状态"
:labelCol=
"
{ span: 7 }" :wrapperCol="{ span: 14 }">
<a-select
v-model=
"searchForm.rStatus"
placeholder=
"请选择状态"
allowClear
>
<a-select-option
v-for=
"item in statusOptions"
:key=
"item.code"
:value=
"item.code"
>
<a-form-model-item
label=
"状态"
:labelCol=
"
{ span: 7 }"
:wrapperCol="{ span: 14 }"
>
<a-select
v-model=
"searchForm.rStatus"
placeholder=
"请选择状态"
allowClear
>
<a-select-option
v-for=
"item in statusOptions"
:key=
"item.code"
:value=
"item.code"
>
{{
item
.
name
}}
</a-select-option>
</a-select>
...
...
@@ -217,7 +289,9 @@
<Icon
name=
"ssisearch_active"
:size=
"14"
/>
查询
</a-button>
</div>
<div
v-if=
"activeKey1 === '0' && selectedRows.length > 0"
>
<div
v-if=
"activeKey1 === '0' && selectedRows.length > 0"
>
<a-button
type=
"primary"
@
click=
"exportExcel"
>
<Icon
name=
"ssidaochu"
:size=
"14"
/>
导出
</a-button>
...
...
@@ -231,21 +305,31 @@
<template
v-if=
"activeKey1 === '0'"
>
<template
v-if=
"selectedRows.length > 0"
>
<div
class=
"all-list_box"
>
<a
-table
<a-virtual
-table
class=
"table-content"
:rowClassName=
"rowClassName"
:columns=
"selectedColumns"
:data-source=
"selectedRows"
:rowKey=
"'id'"
:scroll=
"
{ x: '100%', y: tableHeight }"
:itemSize=
"46"
keyProp=
"id"
row-key=
"id"
:pagination=
"false"
bordered
:scroll=
"
{ x: 1300, y: tableHeight }"
>
<template
slot=
"status"
slot-scope=
"text"
>
<span
:style=
"
{ color: text == 2 ? 'red' : '' }">
{{
<!-- 账单状态 -->
<template
slot=
"status"
slot-scope=
"
{ text }">
<span
:style=
"
{
color: text == 2 ? 'red' : ''
}"
>
{{
text
==
1
?
'
有效
'
:
text
==
2
?
'
无效
'
:
''
}}
</span>
}}
</span
>
</
template
>
<
template
slot=
"patientName"
slot-scope=
"text"
>
<!-- 客户姓名 -->
<
template
slot=
"patientName"
slot-scope=
"{ text }"
>
<a-tooltip
placement=
"top"
>
<template
slot=
"title"
>
<span>
{{
text
}}
</span>
...
...
@@ -253,13 +337,13 @@
<span
class=
"ellipsis_"
>
{{ text }}
</span>
</a-tooltip>
</template>
<
template
slot=
"operation"
slot-scope=
"text, record, index"
>
<a-button
type=
"link"
class=
"danger"
@
click.stop=
"delRecord(record, index)"
>
删除
</a-button>
</
template
>
</a-table>
</a-virtual-table>
<!-- s -->
</div>
</template>
<div
class=
"all-list_box no-data"
v-else
><a-empty
:image=
"simpleImage"
/></div>
<div
class=
"all-list_box no-data"
v-else
>
<a-empty
:image=
"simpleImage"
/>
</div>
</template>
<
template
v-else
>
<!-- table -->
...
...
@@ -292,7 +376,11 @@
</a-tooltip>
</template>
</a-table>
<BurtPagination
class=
"pagination"
:pagination=
"pagination"
@
pageChange=
"pageChange"
/>
<BurtPagination
class=
"pagination"
:pagination=
"pagination"
@
pageChange=
"pageChange"
/>
</div>
</template>
</template>
...
...
@@ -314,25 +402,27 @@
</template>
<
script
>
import
{
Empty
}
from
'
ant-design-vue
'
;
import
Goback
from
'
@/components/Customers/goback
'
;
import
BurtPagination
from
'
@/components/Customers/pagation
'
;
import
{
eobStatusOptions
}
from
'
@/assets/js/utilsdictOptions.js
'
;
import
{
exportFile
,
accuracy
}
from
'
@/utils/index
'
;
import
moment
from
'
moment
'
;
import
mixins
from
'
@/mixins
'
;
import
{
Empty
}
from
'
ant-design-vue
'
import
Goback
from
'
@/components/Customers/goback
'
import
BurtPagination
from
'
@/components/Customers/pagation
'
import
{
eobStatusOptions
}
from
'
@/assets/js/utilsdictOptions.js
'
import
{
exportFile
,
accuracy
}
from
'
@/utils/index
'
import
moment
from
'
moment
'
import
mixins
from
'
@/mixins
'
const
panes
=
[
{
title
:
'
基础信息
'
,
key
:
'
0
'
,
show
:
true
,
content
:
'
PaymentClaims
'
},
{
title
:
'
账单列表
'
,
key
:
'
1
'
,
show
:
false
,
content
:
'
Insurance
'
}
];
]
import
AVirtualTable
from
'
./components/a-virtual-table/Index.vue
'
export
default
{
data
()
{
return
{
accuracy
,
crollHeight
:
0
,
isEdit
:
false
,
eobStatusOptions
,
dialogShow
:
false
,
ciReceiptTotalVo
:
{},
ciReceiptTotalVo
:
{},
form
:
{
payorCode
:
undefined
,
backDate
:
null
,
...
...
@@ -355,9 +445,19 @@ export default {
selectedRows
:
[],
// Check here to configure the default column
backMoneyNo
:
''
,
rules
:
{
payorCode
:
[{
required
:
true
,
message
:
'
请选择保险公司
'
,
trigger
:
'
change
'
}],
backDate
:
[{
required
:
true
,
message
:
'
请选择回款日期
'
,
trigger
:
'
change
'
}],
backAmountCny
:
[{
required
:
true
,
message
:
'
请输入回款金额(人民币)
'
,
trigger
:
[
'
change
'
,
'
blur
'
]
}]
payorCode
:
[
{
required
:
true
,
message
:
'
请选择保险公司
'
,
trigger
:
'
change
'
}
],
backDate
:
[
{
required
:
true
,
message
:
'
请选择回款日期
'
,
trigger
:
'
change
'
}
],
backAmountCny
:
[
{
required
:
true
,
message
:
'
请输入回款金额(人民币)
'
,
trigger
:
[
'
change
'
,
'
blur
'
]
}
]
},
searchForm
:
{
...
...
@@ -381,22 +481,29 @@ export default {
code
:
1
}
],
tableHeight
:
200
,
// 已关联账单表格高度
tableHeight1
:
200
// 全部账单表格高度
};
}
},
mixins
:
[
mixins
],
components
:
{
Goback
,
BurtPagination
BurtPagination
,
AVirtualTable
},
computed
:
{
panes1
()
{
const
panes
=
[{
title
:
'
已关联账单
'
,
key
:
'
0
'
,
show
:
true
,
content
:
'
Associated
'
}];
const
panes
=
[
{
title
:
'
已关联账单
'
,
key
:
'
0
'
,
show
:
true
,
content
:
'
Associated
'
}
]
if
(
this
.
isEdit
)
{
panes
.
push
({
title
:
'
全部账单
'
,
key
:
'
1
'
,
show
:
false
,
content
:
'
Insurance
'
});
panes
.
push
({
title
:
'
全部账单
'
,
key
:
'
1
'
,
show
:
false
,
content
:
'
Insurance
'
})
}
return
panes
;
return
panes
},
columns
()
{
const
base
=
[
...
...
@@ -424,7 +531,12 @@ export default {
scopedSlots
:
{
customRender
:
'
patientName
'
}
},
{
title
:
'
病历号
'
,
dataIndex
:
'
mrnNo
'
,
ellipsis
:
true
,
width
:
195
},
{
title
:
'
保险公司
'
,
dataIndex
:
'
payorName
'
,
ellipsis
:
true
,
width
:
195
},
{
title
:
'
保险公司
'
,
dataIndex
:
'
payorName
'
,
ellipsis
:
true
,
width
:
195
},
{
title
:
'
账单编号
'
,
dataIndex
:
'
receiptNo
'
,
...
...
@@ -455,7 +567,7 @@ export default {
ellipsis
:
true
,
width
:
150
,
customRender
:
(
val
)
=>
{
return
<
span
style
=
"
color: red;
"
>
{
val
}
<
/span>;
return
<
span
style
=
"
color: red;
"
>
{
val
}
<
/span>
}
},
{
...
...
@@ -464,7 +576,7 @@ export default {
ellipsis
:
true
,
width
:
200
,
customRender
:
(
val
)
=>
{
return
<
span
style
=
"
color: red;
"
>
{
val
}
<
/span>;
return
<
span
style
=
"
color: red;
"
>
{
val
}
<
/span>
}
},
{
...
...
@@ -473,12 +585,31 @@ export default {
ellipsis
:
true
,
width
:
120
}
];
return
base
;
]
return
base
},
selectedColumns
()
{
const
base
=
JSON
.
parse
(
JSON
.
stringify
(
this
.
columns
));
const
changeAmount
=
this
.
changeAmount
;
const
base
=
JSON
.
parse
(
JSON
.
stringify
(
this
.
columns
))
const
changeAmount
=
this
.
changeAmount
const
delRecord
=
this
.
delRecord
// base[1] = {
// title: '账单状态',
// dataIndex: 'status',
// ellipsis: true,
// width: 100,
// fixed: 'left',
// customRender: (val, row) => {
// return (
//
<
span
// style={{
// color: row.staus == 2 ? 'red' : ''
// }}
// >
// {row.staus == 1 ? '有效' : row.staus == 2 ? '无效' : ''}
//
<
/span>
// )
// }
// }
base
[
7
]
=
{
title
:
'
回款金额
'
,
dataIndex
:
'
backAmount
'
,
...
...
@@ -490,14 +621,16 @@ export default {
v
-
model
=
{
row
.
backAmount
}
allow
-
clear
disabled
=
{
!
this
.
isEdit
}
style
=
{{
color
:
row
.
backAmount
==
row
.
currentReceiptAmount
?
''
:
'
red
'
}}
style
=
{{
color
:
row
.
backAmount
==
row
.
currentReceiptAmount
?
''
:
'
red
'
}}
onBlur
=
{()
=>
{
changeAmount
(
row
,
'
backAmount
'
);
changeAmount
(
row
,
'
backAmount
'
)
}}
/>
);
)
}
}
};
base
[
10
].
customRender
=
(
val
,
row
)
=>
{
return
(
<
div
>
...
...
@@ -514,7 +647,12 @@ export default {
<
/template>
<
a
-
tooltip
>
<
template
slot
=
"
title
"
>
{
row
.
remark
}
<
/template>
<
a
-
input
class
=
"
red_inp
"
v
-
model
=
{
row
.
remark
}
allow
-
clear
disabled
=
{
!
this
.
isEdit
}
/>
<
a
-
input
class
=
"
red_inp
"
v
-
model
=
{
row
.
remark
}
allow
-
clear
disabled
=
{
!
this
.
isEdit
}
/>
<
/a-tooltip>
<
/a-popover>
)
:
(
...
...
@@ -524,8 +662,8 @@ export default {
<
/a-tooltip>
)}
<
/div>
);
};
)
}
base
[
8
]
=
{
title
:
'
未清余额
'
,
dataIndex
:
'
residueBackAmount
'
,
...
...
@@ -533,10 +671,12 @@ export default {
width
:
150
,
customRender
:
(
val
,
row
)
=>
{
const
residueBackAmount
=
Number
(
row
.
currentReceiptAmount
||
0
)
-
Number
(
row
.
backAmount
||
0
)
-
Number
(
row
.
arrearsAmount
||
0
);
return
Number
(
residueBackAmount
.
toFixed
(
2
));
Number
(
row
.
currentReceiptAmount
||
0
)
-
Number
(
row
.
backAmount
||
0
)
-
Number
(
row
.
arrearsAmount
||
0
)
return
Number
(
residueBackAmount
.
toFixed
(
2
))
}
}
};
base
[
9
]
=
{
title
:
'
个人欠费
'
,
dataIndex
:
'
arrearsAmount
'
,
...
...
@@ -550,42 +690,55 @@ export default {
allow
-
clear
disabled
=
{
!
this
.
isEdit
}
onBlur
=
{()
=>
{
changeAmount
(
row
,
'
arrearsAmount
'
);
changeAmount
(
row
,
'
arrearsAmount
'
)
}}
/>
);
)
}
}
};
base
.
splice
(
7
,
0
,
{
title
:
'
余末金额
'
,
dataIndex
:
'
currentReceiptAmount
'
,
ellipsis
:
true
,
width
:
150
});
})
base
.
push
({
title
:
'
回款日期
'
,
dataIndex
:
'
backDate
'
,
ellipsis
:
true
,
width
:
150
});
})
if
(
this
.
isEdit
)
{
base
.
push
({
title
:
'
操作
'
,
dataIndex
:
'
operation
'
,
fixed
:
'
right
'
,
width
:
100
,
scopedSlots
:
{
customRender
:
'
operation
'
}
});
scopedSlots
:
{
customRender
:
'
operation
'
},
customRender
:
(
val
,
row
,
index
)
=>
{
return
(
<
a
-
button
type
=
"
link
"
class
=
"
danger
"
onClick
=
{()
=>
{
delRecord
(
row
,
index
)
}}
>
删除
<
/a-button>
)
}
})
}
return
base
;
return
base
},
// 可核销余额
residueBackAmount
()
{
let
totalMoney
=
Number
(
this
.
form
.
backAmountCny
||
0
);
let
totalMoney
=
Number
(
this
.
form
.
backAmountCny
||
0
)
this
.
selectedRows
.
forEach
((
item
)
=>
{
totalMoney
-=
Number
(
item
.
backAmount
);
});
return
Number
(
totalMoney
.
toFixed
(
2
));
totalMoney
-=
Number
(
item
.
backAmount
)
})
return
Number
(
totalMoney
.
toFixed
(
2
))
}
},
watch
:
{
...
...
@@ -594,19 +747,23 @@ export default {
billDate
:
[],
mrnNo
:
''
,
// 病历号
patientName
:
''
// 客户名字
};
}
}
},
created
()
{
this
.
simpleImage
=
Empty
.
PRESENTED_IMAGE_SIMPLE
;
const
{
backMoneyNo
,
isEdit
}
=
this
.
$route
.
query
;
this
.
backMoneyNo
=
backMoneyNo
;
this
.
isEdit
=
isEdit
;
this
.
_getCompanyOptions
();
this
.
simpleImage
=
Empty
.
PRESENTED_IMAGE_SIMPLE
const
{
backMoneyNo
,
isEdit
}
=
this
.
$route
.
query
this
.
backMoneyNo
=
backMoneyNo
this
.
isEdit
=
isEdit
this
.
_getCompanyOptions
()
if
(
backMoneyNo
)
{
const
backMoneyDataDetail
=
JSON
.
parse
(
localStorage
.
getItem
(
'
backMoneyDataDetail
'
)
||
'
{}
'
);
this
.
form
=
backMoneyDataDetail
;
this
.
form
.
backDate
=
this
.
form
.
backDate
?
moment
(
this
.
form
.
backDate
).
format
(
'
YYYY-MM-DD 00:00:00
'
)
:
null
;
const
backMoneyDataDetail
=
JSON
.
parse
(
localStorage
.
getItem
(
'
backMoneyDataDetail
'
)
||
'
{}
'
)
this
.
form
=
backMoneyDataDetail
this
.
form
.
backDate
=
this
.
form
.
backDate
?
moment
(
this
.
form
.
backDate
).
format
(
'
YYYY-MM-DD 00:00:00
'
)
:
null
// 如果有上传附件则显示列表
if
(
backMoneyDataDetail
.
fileList
)
{
...
...
@@ -616,122 +773,136 @@ export default {
name
:
d
.
fileName
,
status
:
'
done
'
,
url
:
d
.
fileUrl
};
return
file
;
});
}
this
.
getData
();
return
file
})
}
this
.
getData
()
}
},
mounted
()
{
this
.
calcTableHeight
();
this
.
_getNewEOBList
();
this
.
calcTableHeight
()
this
.
_getNewEOBList
()
},
methods
:
{
moment
,
// 获取未清余额合计
getBackMoneyReportCount
(
params
)
{
this
.
$apis
.
queryBackReceiptCount
({
this
.
$apis
.
queryBackReceiptCount
({
...
params
,
...
this
.
pagination
}).
then
((
res
)
=>
{
})
.
then
((
res
)
=>
{
if
(
res
.
returnCode
==
'
0000
'
)
{
console
.
log
(
res
.
content
)
this
.
ciReceiptTotalVo
=
res
.
content
}
});
})
},
// 计算表格最大高度
calcTableHeight
()
{
const
dom
=
this
.
$refs
.
burt
;
const
containterH
=
dom
.
clientHeight
;
const
gobackH
=
document
.
querySelector
(
'
.back-container
'
).
clientHeight
;
const
style
=
window
.
getComputedStyle
(
dom
,
null
);
const
paddingT
=
parseFloat
(
style
.
getPropertyValue
(
'
padding-top
'
));
const
paddingB
=
parseFloat
(
style
.
getPropertyValue
(
'
padding-bottom
'
));
const
paddingSum
=
paddingT
+
paddingB
;
this
.
tableHeight
=
containterH
-
300
-
gobackH
-
paddingSum
;
this
.
tableHeight1
=
containterH
-
340
-
gobackH
-
paddingSum
;
const
dom
=
this
.
$refs
.
burt
const
containterH
=
dom
.
clientHeight
const
gobackH
=
document
.
querySelector
(
'
.back-container
'
).
clientHeight
const
style
=
window
.
getComputedStyle
(
dom
,
null
)
const
paddingT
=
parseFloat
(
style
.
getPropertyValue
(
'
padding-top
'
))
const
paddingB
=
parseFloat
(
style
.
getPropertyValue
(
'
padding-bottom
'
))
const
paddingSum
=
paddingT
+
paddingB
this
.
tableHeight
=
containterH
-
300
-
gobackH
-
paddingSum
this
.
tableHeight1
=
containterH
-
340
-
gobackH
-
paddingSum
// 设置每页展示条数
const
pageSize
=
Math
.
floor
((
this
.
tableHeight1
-
10
)
/
32
);
this
.
$set
(
this
.
pagination
,
'
pageSize
'
,
pageSize
);
const
pageSize
=
Math
.
floor
((
this
.
tableHeight1
-
10
)
/
32
)
this
.
$set
(
this
.
pagination
,
'
pageSize
'
,
pageSize
)
},
// 已关联账单表格行类名
rowClassName
(
record
)
{
return
record
.
hidden
?
'
hide_
'
:
''
;
return
record
.
hidden
?
'
hide_
'
:
''
},
// 账单查询
searchData
()
{
if
(
this
.
activeKey1
===
'
1
'
)
{
this
.
_getNewEOBList
();
this
.
_getNewEOBList
()
}
else
{
this
.
getData
();
this
.
getData
()
}
},
// 选择框筛选
filterCode
(
input
,
option
)
{
return
option
.
componentOptions
.
children
[
0
].
text
.
toLowerCase
().
indexOf
(
input
.
toLowerCase
())
>=
0
;
return
(
option
.
componentOptions
.
children
[
0
].
text
.
toLowerCase
()
.
indexOf
(
input
.
toLowerCase
())
>=
0
)
},
paneChange
()
{
this
.
$refs
.
ruleForm
[
0
].
clearValidate
();
this
.
$refs
.
ruleForm
[
0
].
clearValidate
()
this
.
panes
.
forEach
((
item
)
=>
{
item
.
show
=
false
;
});
this
.
panes
[
Number
(
this
.
activeKey
)].
show
=
true
;
item
.
show
=
false
})
this
.
panes
[
Number
(
this
.
activeKey
)].
show
=
true
},
changeAmount
(
row
)
{
let
totalMoney
=
Number
(
this
.
form
.
backAmountCny
||
0
);
let
totalMoney
=
Number
(
this
.
form
.
backAmountCny
||
0
)
this
.
selectedRows
.
forEach
((
item
)
=>
{
totalMoney
-=
Number
(
item
.
backAmount
);
});
totalMoney
-=
Number
(
item
.
backAmount
)
})
if
(
totalMoney
<
0
)
{
this
.
$message
.
error
(
'
可核销余额不足
'
);
this
.
$message
.
error
(
'
可核销余额不足
'
)
}
if
(
Number
(
row
.
actualAmount
||
0
)
-
Number
(
row
.
backAmount
||
0
)
<
0
)
{
this
.
$message
.
warning
(
'
录入账单回款金额大于账单金额
'
);
this
.
$message
.
warning
(
'
录入账单回款金额大于账单金额
'
)
}
},
onSelectChange
(
selectedRow
,
selected
)
{
selectedRow
[
'
backAmount
'
]
=
this
.
residueBackAmount
>
selectedRow
.
currentReceiptAmount
?
selectedRow
.
currentReceiptAmount
:
this
.
residueBackAmount
;
:
this
.
residueBackAmount
if
(
selected
)
{
this
.
selectedRowKeys
.
push
(
selectedRow
.
id
);
this
.
selectedRows
.
push
(
selectedRow
);
this
.
selectedRowKeys
.
push
(
selectedRow
.
id
)
this
.
selectedRows
.
push
(
selectedRow
)
}
else
{
const
index
=
this
.
selectedRowKeys
.
findIndex
((
item
)
=>
item
===
selectedRow
.
id
);
this
.
selectedRowKeys
.
splice
(
index
,
1
);
this
.
selectedRows
.
splice
(
index
,
1
);
this
.
_confirmDelReceipt
([
selectedRow
]);
const
index
=
this
.
selectedRowKeys
.
findIndex
(
(
item
)
=>
item
===
selectedRow
.
id
)
this
.
selectedRowKeys
.
splice
(
index
,
1
)
this
.
selectedRows
.
splice
(
index
,
1
)
this
.
_confirmDelReceipt
([
selectedRow
])
}
this
.
addNewEvt
(
0
);
this
.
addNewEvt
(
0
)
},
onSelectAll
(
selected
,
selectedRows
,
changeRows
)
{
if
(
selected
)
{
this
.
selectedRowKeys
=
this
.
selectedRowKeys
.
concat
(
changeRows
.
map
((
item
)
=>
item
.
id
));
this
.
selectedRowKeys
=
this
.
selectedRowKeys
.
concat
(
changeRows
.
map
((
item
)
=>
item
.
id
)
)
changeRows
.
forEach
((
item
)
=>
{
const
obj
=
{
...
item
,
backAmount
:
this
.
residueBackAmount
>
item
.
currentReceiptAmount
?
item
.
currentReceiptAmount
:
this
.
residueBackAmount
};
this
.
selectedRows
.
push
(
obj
);
});
this
.
residueBackAmount
>
item
.
currentReceiptAmount
?
item
.
currentReceiptAmount
:
this
.
residueBackAmount
}
this
.
selectedRows
.
push
(
obj
)
})
// this.selectedRows = this.selectedRows.concat(chgRows);
}
else
{
changeRows
.
forEach
((
item
)
=>
{
const
findIndex
=
this
.
selectedRowKeys
.
findIndex
((
rowId
)
=>
rowId
===
item
.
id
);
this
.
selectedRowKeys
.
splice
(
findIndex
,
1
);
this
.
selectedRows
.
splice
(
findIndex
,
1
);
});
this
.
_confirmDelReceipt
(
changeRows
);
const
findIndex
=
this
.
selectedRowKeys
.
findIndex
(
(
rowId
)
=>
rowId
===
item
.
id
)
this
.
selectedRowKeys
.
splice
(
findIndex
,
1
)
this
.
selectedRows
.
splice
(
findIndex
,
1
)
})
this
.
_confirmDelReceipt
(
changeRows
)
}
this
.
addNewEvt
(
0
);
this
.
addNewEvt
(
0
)
},
// 全选
selectAllList
()
{
let
billDate
=
this
.
searchForm
.
billDate
||
[];
let
billDate
=
this
.
searchForm
.
billDate
||
[]
this
.
$apis
.
queryReceiptInfoList
({
pageNum
:
1
,
...
...
@@ -744,43 +915,45 @@ export default {
})
.
then
((
res
)
=>
{
if
(
res
.
returnCode
==
'
0000
'
)
{
let
content
=
res
.
content
||
{};
let
content
=
res
.
content
||
{}
const
dataList
=
content
.
list
.
map
((
item
)
=>
{
item
.
arrearsAmountShow
=
item
.
arrearsAmount
;
item
.
arrearsAmount
=
''
;
return
item
;
})
||
[];
item
.
arrearsAmountShow
=
item
.
arrearsAmount
item
.
arrearsAmount
=
''
return
item
})
||
[]
//
this
.
selectedRowKeys
=
dataList
.
map
(
item
=>
item
.
id
)
this
.
selectedRowKeys
=
dataList
.
map
((
item
)
=>
item
.
id
)
this
.
selectedRows
=
dataList
this
.
addNewEvt
(
0
);
this
.
addNewEvt
(
0
)
}
else
{
this
.
$message
.
error
(
res
.
returnMsg
);
this
.
$message
.
error
(
res
.
returnMsg
)
}
});
})
},
delRecord
(
record
,
index
)
{
this
.
selectedRowKeys
.
splice
(
index
,
1
);
this
.
selectedRows
.
splice
(
index
,
1
);
this
.
selectedRowKeys
.
splice
(
index
,
1
)
this
.
selectedRows
.
splice
(
index
,
1
)
if
(
record
.
relationed
)
{
// 已经关联的调用接口删除
this
.
_confirmDelReceipt
([
record
]);
this
.
_confirmDelReceipt
([
record
])
}
},
_confirmDelReceipt
(
records
)
{
if
(
!
this
.
backMoneyNo
)
return
;
if
(
!
this
.
backMoneyNo
)
return
const
receiptVoList
=
records
.
filter
((
item
)
=>
{
const
findIndex
=
this
.
relatedList
.
findIndex
((
rowId
)
=>
rowId
===
item
.
id
);
return
findIndex
>
-
1
;
const
findIndex
=
this
.
relatedList
.
findIndex
(
(
rowId
)
=>
rowId
===
item
.
id
)
return
findIndex
>
-
1
})
.
map
((
item
)
=>
{
return
{
id
:
item
.
id
};
});
if
(
receiptVoList
.
length
===
0
)
return
;
}
})
if
(
receiptVoList
.
length
===
0
)
return
this
.
$apis
.
deleteReceiptRecord
({
backMoneyNo
:
this
.
backMoneyNo
,
...
...
@@ -788,51 +961,54 @@ export default {
})
.
then
((
res
)
=>
{
if
(
res
.
returnCode
==
'
0000
'
)
{
this
.
_getNewEOBList
();
this
.
_getNewEOBList
()
}
else
{
this
.
$message
.
error
(
res
.
returnMsg
);
this
.
$message
.
error
(
res
.
returnMsg
)
}
});
})
},
// 修改保险公司
changePayor
()
{
if
(
this
.
selectedRowKeys
.
length
>
0
&&
(
this
.
form
.
id
||
this
.
savedStatus
))
{
if
(
this
.
selectedRowKeys
.
length
>
0
&&
(
this
.
form
.
id
||
this
.
savedStatus
)
)
{
this
.
$modal
.
confirm
({
title
:
'
提示
'
,
content
:
'
是否解除已关联账单
'
,
okText
:
'
确认
'
,
cancelText
:
'
取消
'
,
onOk
:
()
=>
{
this
.
selectedRowKeys
=
[];
this
.
selectedRows
=
[];
this
.
selectedRowKeys
=
[]
this
.
selectedRows
=
[]
},
onCancel
:
()
=>
{}
});
})
}
this
.
_getNewEOBList
();
this
.
_getNewEOBList
()
},
pageChange
(
pager
)
{
this
.
pagination
=
{
...
this
.
pagination
,
...
pager
};
this
.
_getNewEOBList
();
}
this
.
_getNewEOBList
()
},
// 获取保险公司下拉选项
_getCompanyOptions
()
{
this
.
$apis
.
getCompanyOptions
().
then
((
res
)
=>
{
this
.
companyOptions
=
res
.
content
||
[];
});
this
.
companyOptions
=
res
.
content
||
[]
})
},
// 获取已关联的账单
getData
()
{
if
(
!
this
.
backMoneyNo
)
{
if
(
this
.
activeKey1
===
'
0
'
)
{
this
.
$message
.
error
(
'
暂未关联账单,请在全部账单中添加账单
'
);
this
.
$message
.
error
(
'
暂未关联账单,请在全部账单中添加账单
'
)
}
return
;
return
}
let
billDate
=
this
.
searchForm
.
billDate
||
[];
let
billDate
=
this
.
searchForm
.
billDate
||
[]
this
.
$apis
.
queryBackReceiptList
({
pageNum
:
1
,
...
...
@@ -849,26 +1025,30 @@ export default {
pageSize
:
999
,
backMoneyNo
:
this
.
backMoneyNo
,
...
this
.
searchForm
,
receiptEndDate
:
billDate
[
1
]
?
billDate
[
1
]
+
'
23:59:59
'
:
undefined
,
receiptStartDate
:
billDate
[
0
]
?
billDate
[
0
]
+
'
00:00:00
'
:
undefined
receiptEndDate
:
billDate
[
1
]
?
billDate
[
1
]
+
'
23:59:59
'
:
undefined
,
receiptStartDate
:
billDate
[
0
]
?
billDate
[
0
]
+
'
00:00:00
'
:
undefined
})
const
list
=
res
.
content
.
list
||
[];
let
ids
=
[];
const
list
=
res
.
content
.
list
||
[]
let
ids
=
[]
this
.
selectedRows
=
list
.
map
((
item
)
=>
{
item
.
relationed
=
true
;
ids
.
push
(
item
.
id
);
return
item
;
});
this
.
selectedRowKeys
=
this
.
$lodash
.
cloneDeep
(
ids
);
this
.
relatedList
=
this
.
$lodash
.
cloneDeep
(
ids
);
item
.
relationed
=
true
ids
.
push
(
item
.
id
)
return
item
})
this
.
selectedRowKeys
=
this
.
$lodash
.
cloneDeep
(
ids
)
this
.
relatedList
=
this
.
$lodash
.
cloneDeep
(
ids
)
}
else
{
this
.
$message
.
error
(
res
.
returnMsg
);
this
.
$message
.
error
(
res
.
returnMsg
)
}
});
})
},
// 获取所有账单
_getNewEOBList
()
{
let
billDate
=
this
.
searchForm
.
billDate
||
[];
let
billDate
=
this
.
searchForm
.
billDate
||
[]
this
.
$apis
.
queryReceiptInfoList
({
pageNum
:
this
.
pagination
.
pageNum
,
...
...
@@ -887,35 +1067,39 @@ export default {
backMoneyNo
:
this
.
backMoneyNo
,
payorCode
:
this
.
form
.
payorCode
,
...
this
.
searchForm
,
receiptEndDate
:
billDate
[
1
]
?
billDate
[
1
]
+
'
23:59:59
'
:
undefined
,
receiptStartDate
:
billDate
[
0
]
?
billDate
[
0
]
+
'
00:00:00
'
:
undefined
receiptEndDate
:
billDate
[
1
]
?
billDate
[
1
]
+
'
23:59:59
'
:
undefined
,
receiptStartDate
:
billDate
[
0
]
?
billDate
[
0
]
+
'
00:00:00
'
:
undefined
})
let
content
=
res
.
content
||
{};
this
.
pagination
.
total
=
content
.
total
||
0
;
let
content
=
res
.
content
||
{}
this
.
pagination
.
total
=
content
.
total
||
0
this
.
dataList
=
content
.
list
.
map
((
item
)
=>
{
item
.
arrearsAmountShow
=
item
.
arrearsAmount
;
item
.
arrearsAmount
=
''
;
return
item
;
})
||
[];
item
.
arrearsAmountShow
=
item
.
arrearsAmount
item
.
arrearsAmount
=
''
return
item
})
||
[]
}
else
{
this
.
$message
.
error
(
res
.
returnMsg
);
this
.
$message
.
error
(
res
.
returnMsg
)
}
});
})
},
//新建/保存回款
addNewEvt
(
backStatus
)
{
if
(
!
this
.
form
.
payorCode
)
{
this
.
$message
.
warning
(
'
请选择保险公司
'
);
return
;
this
.
$message
.
warning
(
'
请选择保险公司
'
)
return
}
if
(
!
this
.
form
.
backDate
)
{
this
.
$message
.
warning
(
'
请选择回款日期
'
);
return
;
this
.
$message
.
warning
(
'
请选择回款日期
'
)
return
}
if
(
!
this
.
form
.
backAmountCny
&&
this
.
form
.
backAmountCny
!==
0
)
{
this
.
$message
.
warning
(
'
请输入回款金额(人民币)
'
);
return
;
this
.
$message
.
warning
(
'
请输入回款金额(人民币)
'
)
return
}
let
receiptVoList
=
this
.
selectedRows
.
map
((
item
)
=>
{
return
{
...
...
@@ -923,105 +1107,107 @@ export default {
backAmount
:
item
.
backAmount
,
arrearsAmount
:
item
.
arrearsAmount
,
remark
:
item
.
remark
};
});
}
})
const
flag
=
receiptVoList
.
some
((
item
)
=>
{
const
exist
=
!
item
.
backAmount
&&
item
.
backAmount
!==
0
;
return
exist
;
});
const
exist
=
!
item
.
backAmount
&&
item
.
backAmount
!==
0
return
exist
})
if
(
flag
)
{
this
.
$message
.
warning
(
'
存在关联账单未输入回款金额
'
);
return
;
this
.
$message
.
warning
(
'
存在关联账单未输入回款金额
'
)
return
}
const
formData
=
{
...
this
.
form
,
receiptVoList
,
backDate
:
this
.
form
.
backDate
?
moment
(
this
.
form
.
backDate
).
format
(
'
YYYY-MM-DD HH:mm:ss
'
)
:
''
,
backDate
:
this
.
form
.
backDate
?
moment
(
this
.
form
.
backDate
).
format
(
'
YYYY-MM-DD HH:mm:ss
'
)
:
''
,
backMoneyNo
:
this
.
backMoneyNo
,
//回款编号
backStatus
// 0暂存 1结案
};
}
// 上传附件格式转换
formData
.
fileList
=
this
.
fileList
.
map
((
d
)
=>
{
const
file
=
{
fileName
:
d
.
name
,
fileUrl
:
d
.
url
};
return
file
;
});
}
return
file
})
this
.
$apis
.
saveBackMoney
(
formData
).
then
((
res
)
=>
{
const
msg
=
backStatus
===
1
?
'
结案
'
:
'
暂存
'
;
const
msg
=
backStatus
===
1
?
'
结案
'
:
'
暂存
'
if
(
res
.
returnCode
==
'
0000
'
)
{
this
.
backMoneyNo
=
res
.
content
;
this
.
savedStatus
=
true
;
this
.
$message
.
success
(
`
${
msg
}
成功`
);
this
.
selectedRowKeys
=
[];
this
.
getData
();
this
.
_getNewEOBList
();
this
.
backMoneyNo
=
res
.
content
this
.
savedStatus
=
true
this
.
$message
.
success
(
`
${
msg
}
成功`
)
this
.
selectedRowKeys
=
[]
this
.
getData
()
this
.
_getNewEOBList
()
// this.$router.go(-1);
}
else
{
this
.
$message
.
error
(
res
.
returnMsg
);
this
.
$message
.
error
(
res
.
returnMsg
)
}
});
})
},
/* ======== 上传区域 ======== */
// 上传之前
beforeUpload
()
{
const
len
=
this
.
fileList
.
length
;
const
len
=
this
.
fileList
.
length
if
(
len
>=
5
)
{
this
.
$message
.
warning
(
'
不能超过5个文件
'
);
return
false
;
this
.
$message
.
warning
(
'
不能超过5个文件
'
)
return
false
}
return
true
;
return
true
},
// 删除文件
removeFile
(
file
)
{
let
index
;
let
index
this
.
fileList
.
forEach
((
item
,
i
)
=>
{
if
(
item
.
uid
==
file
.
uid
)
{
index
=
i
;
index
=
i
}
});
this
.
fileList
.
splice
(
index
,
1
);
return
true
;
})
this
.
fileList
.
splice
(
index
,
1
)
return
true
},
// 上传文件
uploadFile
(
fileData
)
{
let
formData
=
new
FormData
();
formData
.
append
(
'
file
'
,
fileData
.
file
);
let
formData
=
new
FormData
()
formData
.
append
(
'
file
'
,
fileData
.
file
)
this
.
$apis
.
uploadImg
(
formData
).
then
((
res
)
=>
{
fileData
.
onSuccess
();
fileData
.
onSuccess
()
let
tmp
=
{
uid
:
Math
.
random
()
*
10000
,
name
:
res
.
original
,
status
:
'
done
'
,
url
:
res
.
url
};
this
.
fileList
.
push
(
tmp
);
}
this
.
fileList
.
push
(
tmp
)
this
.
$forceUpdate
();
});
this
.
$forceUpdate
()
})
},
//导出报表
exportExcel
()
{
let
filter
=
{
backMoneyNo
:
this
.
backMoneyNo
,
payorCode
:
this
.
form
.
payorCode
};
}
this
.
$apis
.
exportBackReceiptList
(
filter
).
then
((
res
)
=>
{
exportFile
(
res
,
'
已关联账单.xls
'
);
});
exportFile
(
res
,
'
已关联账单.xls
'
)
})
},
// 保险公司支持输入搜索
filterOption
(
input
,
option
)
{
return
option
.
componentOptions
.
children
[
0
].
text
.
indexOf
(
input
)
>=
0
;
return
option
.
componentOptions
.
children
[
0
].
text
.
indexOf
(
input
)
>=
0
}
}
}
;
}
</
script
>
<
style
lang=
"less"
scoped
>
...
...
@@ -1141,7 +1327,7 @@ export default {
height: calc(100vh - 400px);
}
}
.checked-count{
.checked-count
{
position: absolute;
top: 14px;
left: 210px;
...
...
This diff is collapsed.
Click to expand it.
src/views/verification/components/a-virtual-table/Index.vue
0 → 100644
View file @
ecd603e2
<
template
>
<!-- 表格虚拟滚动 -->
<div>
<a-table
v-bind=
"$attrs"
v-on=
"$listeners"
:pagination=
"false"
:columns=
"tableColumns"
:data-source=
"renderData"
>
<template
v-for=
"slot in Object.keys($scopedSlots)"
:slot=
"slot"
slot-scope=
"text, record, index"
>
<slot
:name=
"slot"
v-bind=
"
{ text, record, index }">
</slot>
</
template
>
</a-table>
<div
class=
"ant-table-append"
ref=
"append"
v-show=
"!isHideAppend"
>
<slot
name=
"append"
></slot>
</div>
</div>
</template>
<
script
>
import
{
throttle
}
from
'
lodash
'
// 判断是否是滚动容器
function
isScroller
(
el
)
{
const
style
=
window
.
getComputedStyle
(
el
,
null
)
const
scrollValues
=
[
'
auto
'
,
'
scroll
'
]
return
(
scrollValues
.
includes
(
style
.
overflow
)
||
scrollValues
.
includes
(
style
[
'
overflow-y
'
])
)
}
// 获取父层滚动容器
function
getParentScroller
(
el
)
{
let
parent
=
el
while
(
parent
)
{
if
([
window
,
document
,
document
.
documentElement
].
includes
(
parent
))
{
return
window
}
if
(
isScroller
(
parent
))
{
return
parent
}
parent
=
parent
.
parentNode
}
return
parent
||
window
}
// 获取容器滚动位置
function
getScrollTop
(
el
)
{
return
el
===
window
?
window
.
pageYOffset
:
el
.
scrollTop
}
// 获取容器高度
function
getOffsetHeight
(
el
)
{
return
el
===
window
?
window
.
innerHeight
:
el
.
offsetHeight
}
// 滚动到某个位置
function
scrollToY
(
el
,
y
)
{
if
(
el
===
window
)
{
window
.
scroll
(
0
,
y
)
}
else
{
el
.
scrollTop
=
y
}
}
// 表格body class名称
const
TableBodyClassNames
=
[
'
.ant-table-scroll .ant-table-body
'
,
'
.ant-table-fixed-left .ant-table-body-inner
'
,
'
.ant-table-fixed-right .ant-table-body-inner
'
]
let
checkOrder
=
0
// 多选:记录多选选项改变的顺序
export
default
{
inheritAttrs
:
false
,
name
:
'
a-virtual-table
'
,
props
:
{
dataSource
:
{
type
:
Array
,
default
:
()
=>
[]
},
columns
:
{
type
:
Array
,
default
:
()
=>
[]
},
// key值,data数据中的唯一id
keyProp
:
{
type
:
String
,
default
:
'
id
'
},
// 每一行的预估高度
itemSize
:
{
type
:
Number
,
default
:
60
},
// 指定滚动容器
scrollBox
:
{
type
:
String
},
// 顶部和底部缓冲区域,值越大显示表格的行数越多
buffer
:
{
type
:
Number
,
default
:
100
},
// 滚动事件的节流时间
throttleTime
:
{
type
:
Number
,
default
:
10
},
// 是否获取表格行动态高度
dynamic
:
{
type
:
Boolean
,
default
:
true
},
// 是否开启虚拟滚动
virtualized
:
{
type
:
Boolean
,
default
:
true
},
// 是否是树形结构
isTree
:
{
type
:
Boolean
,
default
:
false
}
},
data
()
{
return
{
start
:
0
,
end
:
undefined
,
sizes
:
{},
// 尺寸映射(依赖响应式)
renderData
:
[],
// 兼容多选
isCheckedAll
:
false
,
// 全选
isCheckedImn
:
false
,
// 控制半选样式
isHideAppend
:
false
}
},
computed
:
{
tableColumns
()
{
return
this
.
columns
.
map
((
column
)
=>
{
// 兼容多选
if
(
column
.
type
===
'
selection
'
)
{
return
{
title
:
()
=>
{
return
(
<
a
-
checkbox
checked
=
{
this
.
isCheckedAll
}
indeterminate
=
{
this
.
isCheckedImn
}
onchange
=
{()
=>
this
.
onCheckAllRows
(
!
this
.
isCheckedAll
)}
><
/a-checkbox
>
)
},
customRender
:
(
text
,
row
)
=>
{
return
(
<
a
-
checkbox
checked
=
{
row
.
$v_checked
}
onchange
=
{()
=>
this
.
onCheckRow
(
row
,
!
row
.
$v_checked
)}
><
/a-checkbox
>
)
},
width
:
60
,
...
column
}
}
else
if
(
column
.
index
)
{
// 兼容索引
return
{
customRender
:
(
text
,
row
,
index
)
=>
{
const
curIndex
=
this
.
start
+
index
return
typeof
column
.
index
===
'
function
'
?
column
.
index
(
curIndex
)
:
curIndex
+
1
},
...
column
}
}
else
if
(
column
.
customRender
&&
typeof
column
.
customRender
===
'
function
'
)
{
// 如果定义了 customRender 函数,使用一个新的 customRender 方法包装它
const
originalCustomRender
=
column
.
customRender
column
.
customRender
=
(
text
,
record
,
index
)
=>
{
// 调用原始的 customRender 函数,并传入必要的参数
return
originalCustomRender
(
text
,
record
,
index
)
}
}
return
column
})
},
// 计算出每个item(的key值)到滚动容器顶部的距离
offsetMap
({
keyProp
,
itemSize
,
sizes
,
dataSource
})
{
if
(
!
this
.
dynamic
)
return
{}
const
res
=
{}
let
total
=
0
for
(
let
i
=
0
;
i
<
dataSource
.
length
;
i
++
)
{
const
key
=
dataSource
[
i
][
keyProp
]
res
[
key
]
=
total
const
curSize
=
sizes
[
key
]
const
size
=
typeof
curSize
===
'
number
'
?
curSize
:
itemSize
total
+=
size
}
return
res
}
},
methods
:
{
// 初始化数据
initData
()
{
// 是否是表格内部滚动
this
.
isInnerScroll
=
false
this
.
scroller
=
this
.
getScroller
()
this
.
setToTop
()
// 首次需要执行2次handleScroll:因为第一次计算renderData时表格高度未确认导致计算不准确;第二次执行时,表格高度确认后,计算renderData是准确的
this
.
handleScroll
()
this
.
$nextTick
(()
=>
{
this
.
handleScroll
()
})
// 监听事件
this
.
onScroll
=
throttle
(
this
.
handleScroll
,
this
.
throttleTime
)
this
.
scroller
.
addEventListener
(
'
scroll
'
,
this
.
onScroll
)
window
.
addEventListener
(
'
resize
'
,
this
.
onScroll
)
},
// 设置表格到滚动容器的距离
setToTop
()
{
if
(
this
.
isInnerScroll
)
{
this
.
toTop
=
0
}
else
{
this
.
toTop
=
this
.
$el
.
getBoundingClientRect
().
top
-
(
this
.
scroller
===
window
?
0
:
this
.
scroller
.
getBoundingClientRect
().
top
)
+
getScrollTop
(
this
.
scroller
)
}
},
// 获取滚动元素
getScroller
()
{
let
el
if
(
this
.
scrollBox
)
{
if
(
this
.
scrollBox
===
'
window
'
||
this
.
scrollBox
===
window
)
return
window
el
=
document
.
querySelector
(
this
.
scrollBox
)
if
(
!
el
)
throw
new
Error
(
` scrollBox prop: '
${
this
.
scrollBox
}
' is not a valid selector`
)
if
(
!
isScroller
(
el
))
console
.
warn
(
`Warning! scrollBox prop: '
${
this
.
scrollBox
}
' is not a scroll element`
)
return
el
}
// 如果表格是固定高度,则获取表格内的滚动节点,否则获取父层滚动节点
if
(
this
.
$attrs
.
scroll
&&
this
.
$attrs
.
scroll
.
y
)
{
this
.
isInnerScroll
=
true
return
this
.
$el
.
querySelector
(
'
.ant-table-body
'
)
}
else
{
return
getParentScroller
(
this
.
$el
)
}
},
// 处理滚动事件
handleScroll
()
{
if
(
!
this
.
virtualized
)
return
// 更新当前尺寸(高度)
this
.
updateSizes
()
// 计算renderData
this
.
calcRenderData
()
// 计算位置
this
.
calcPosition
()
},
// 更新尺寸(高度)
updateSizes
()
{
if
(
!
this
.
dynamic
)
return
let
rows
=
[]
if
(
this
.
isTree
)
{
// 处理树形表格,筛选出一级树形结构
rows
=
this
.
$el
.
querySelectorAll
(
'
.ant-table-body .ant-table-row-level-0
'
)
}
else
{
rows
=
this
.
$el
.
querySelectorAll
(
'
.ant-table-body .ant-table-tbody .ant-table-row
'
)
}
Array
.
from
(
rows
).
forEach
((
row
,
index
)
=>
{
const
item
=
this
.
renderData
[
index
]
if
(
!
item
)
return
// 计算表格行的高度
let
offsetHeight
=
row
.
offsetHeight
// 表格行如果有扩展行,需要加上扩展内容的高度
const
nextEl
=
row
.
nextSibling
if
(
nextEl
&&
nextEl
.
classList
&&
nextEl
.
classList
.
contains
(
'
ant-table-expanded-row
'
)
)
{
offsetHeight
+=
row
.
nextSibling
.
offsetHeight
}
// 表格行如果有子孙节点,需要加上子孙节点的高度
if
(
this
.
isTree
)
{
let
next
=
row
.
nextSibling
while
(
next
&&
next
.
tagName
===
'
TR
'
&&
!
next
.
classList
.
contains
(
'
ant-table-row-level-0
'
)
)
{
offsetHeight
+=
next
.
offsetHeight
next
=
next
.
nextSibling
}
}
const
key
=
item
[
this
.
keyProp
]
if
(
this
.
sizes
[
key
]
!==
offsetHeight
)
{
this
.
$set
(
this
.
sizes
,
key
,
offsetHeight
)
row
.
_offsetHeight
=
offsetHeight
}
})
},
// 计算只在视图上渲染的数据
calcRenderData
()
{
const
{
scroller
,
buffer
,
dataSource
:
data
}
=
this
// 计算可视范围顶部、底部
const
top
=
getScrollTop
(
scroller
)
-
buffer
-
this
.
toTop
const
scrollerHeight
=
this
.
isInnerScroll
?
this
.
$attrs
.
scroll
.
y
:
getOffsetHeight
(
scroller
)
const
bottom
=
getScrollTop
(
scroller
)
+
scrollerHeight
+
buffer
-
this
.
toTop
let
start
let
end
if
(
!
this
.
dynamic
)
{
start
=
top
<=
0
?
0
:
Math
.
floor
(
top
/
this
.
itemSize
)
end
=
bottom
<=
0
?
0
:
Math
.
ceil
(
bottom
/
this
.
itemSize
)
}
else
{
// 二分法计算可视范围内的开始的第一个内容
let
l
=
0
let
r
=
data
.
length
-
1
let
mid
=
0
while
(
l
<=
r
)
{
mid
=
Math
.
floor
((
l
+
r
)
/
2
)
const
midVal
=
this
.
getItemOffsetTop
(
mid
)
if
(
midVal
<
top
)
{
const
midNextVal
=
this
.
getItemOffsetTop
(
mid
+
1
)
if
(
midNextVal
>
top
)
break
l
=
mid
+
1
}
else
{
r
=
mid
-
1
}
}
// 计算渲染内容的开始、结束索引
start
=
mid
end
=
data
.
length
-
1
for
(
let
i
=
start
+
1
;
i
<
data
.
length
;
i
++
)
{
const
offsetTop
=
this
.
getItemOffsetTop
(
i
)
if
(
offsetTop
>=
bottom
)
{
end
=
i
break
}
}
}
// 开始索引始终保持偶数,如果为奇数,则加1使其保持偶数【确保表格行的偶数数一致,不会导致斑马纹乱序显示】
if
(
start
%
2
)
{
start
=
start
-
1
}
this
.
top
=
top
this
.
bottom
=
bottom
this
.
start
=
start
this
.
end
=
end
this
.
renderData
=
data
.
slice
(
start
,
end
+
1
)
this
.
$emit
(
'
change
'
,
this
.
renderData
,
this
.
start
,
this
.
end
)
},
// 计算位置
calcPosition
()
{
const
last
=
this
.
dataSource
.
length
-
1
// 计算内容总高度
const
wrapHeight
=
this
.
getItemOffsetTop
(
last
)
+
this
.
getItemSize
(
last
)
// 计算当前滚动位置需要撑起的高度
const
offsetTop
=
this
.
getItemOffsetTop
(
this
.
start
)
// 设置dom位置
TableBodyClassNames
.
forEach
((
className
)
=>
{
const
el
=
this
.
$el
.
querySelector
(
className
)
if
(
!
el
)
return
// 创建wrapEl、innerEl
if
(
!
el
.
wrapEl
)
{
const
wrapEl
=
document
.
createElement
(
'
div
'
)
const
innerEl
=
document
.
createElement
(
'
div
'
)
// 此处设置display为'inline-block',是让div宽度等于表格的宽度,修复x轴滚动时右边固定列没有阴影的bug
wrapEl
.
style
.
display
=
'
inline-block
'
innerEl
.
style
.
display
=
'
inline-block
'
wrapEl
.
appendChild
(
innerEl
)
innerEl
.
appendChild
(
el
.
children
[
0
])
el
.
insertBefore
(
wrapEl
,
el
.
firstChild
)
el
.
wrapEl
=
wrapEl
el
.
innerEl
=
innerEl
}
if
(
el
.
wrapEl
)
{
// 设置高度
el
.
wrapEl
.
style
.
height
=
wrapHeight
+
'
px
'
// 设置transform撑起高度
el
.
innerEl
.
style
.
transform
=
`translateY(
${
offsetTop
}
px)`
// 设置paddingTop撑起高度
// el.innerEl.style.paddingTop = `${offsetTop}px`
}
})
},
// 获取某条数据offsetTop
getItemOffsetTop
(
index
)
{
if
(
!
this
.
dynamic
)
{
return
this
.
itemSize
*
index
}
const
item
=
this
.
dataSource
[
index
]
if
(
item
)
{
return
this
.
offsetMap
[
item
[
this
.
keyProp
]]
||
0
}
return
0
},
// 获取某条数据的尺寸
getItemSize
(
index
)
{
if
(
index
<=
-
1
)
return
0
const
item
=
this
.
dataSource
[
index
]
if
(
item
)
{
const
key
=
item
[
this
.
keyProp
]
return
this
.
sizes
[
key
]
||
this
.
itemSize
}
return
this
.
itemSize
},
// 【外部调用】更新
update
()
{
this
.
setToTop
()
this
.
handleScroll
()
},
// 【外部调用】滚动到第几行
// (不太精确:滚动到第n行时,如果周围的表格行计算出真实高度后会更新高度,导致内容坍塌或撑起)
scrollTo
(
index
,
stop
=
false
)
{
const
item
=
this
.
dataSource
[
index
]
if
(
item
&&
this
.
scroller
)
{
this
.
updateSizes
()
this
.
calcRenderData
()
this
.
$nextTick
(()
=>
{
const
offsetTop
=
this
.
getItemOffsetTop
(
index
)
scrollToY
(
this
.
scroller
,
offsetTop
)
// 调用两次scrollTo,第一次滚动时,如果表格行初次渲染高度发生变化时,会导致滚动位置有偏差,此时需要第二次执行滚动,确保滚动位置无误
if
(
!
stop
)
{
setTimeout
(()
=>
{
this
.
scrollTo
(
index
,
true
)
},
50
)
}
})
}
},
// 渲染全部数据
renderAllData
()
{
this
.
renderData
=
this
.
dataSource
this
.
$emit
(
'
change
'
,
this
.
dataSource
,
0
,
this
.
dataSource
.
length
-
1
)
this
.
$nextTick
(()
=>
{
// 清除撑起的高度和位置
TableBodyClassNames
.
forEach
((
className
)
=>
{
const
el
=
this
.
$el
.
querySelector
(
className
)
if
(
!
el
)
return
if
(
el
.
wrapEl
)
{
// 设置高度
el
.
wrapEl
.
style
.
height
=
'
auto
'
// 设置transform撑起高度
el
.
innerEl
.
style
.
transform
=
`translateY(
${
0
}
px)`
}
})
})
},
// 执行update方法更新虚拟滚动,且每次nextTick只能执行一次【在数据大于100条开启虚拟滚动时,由于监听了data、virtualized会连续触发两次update方法:第一次update时,(updateSize)计算尺寸里的渲染数据(renderData)与表格行的dom是一一对应,之后会改变渲染数据(renderData)的值;而第二次执行update时,renderData改变了,而表格行dom未改变,导致renderData与dom不一一对应,从而位置计算错误,最终渲染的数据对应不上。因此使用每次nextTick只能执行一次来避免bug发生】
doUpdate
()
{
if
(
this
.
hasDoUpdate
)
return
// nextTick内已经执行过一次就不执行
if
(
!
this
.
scroller
)
return
// scroller不存在说明未初始化完成,不执行
// 启动虚拟滚动的瞬间,需要暂时隐藏el-table__append-wrapper里的内容,不然会导致滚动位置一直到append的内容处
this
.
isHideAppend
=
true
this
.
update
()
this
.
hasDoUpdate
=
true
this
.
$nextTick
(()
=>
{
this
.
hasDoUpdate
=
false
this
.
isHideAppend
=
false
})
},
// 兼容多选:选择表格所有行
onCheckAllRows
(
val
)
{
val
=
this
.
isCheckedImn
?
true
:
val
this
.
dataSource
.
forEach
((
row
)
=>
{
if
(
row
.
$v_checked
===
val
)
return
this
.
$set
(
row
,
'
$v_checked
'
,
val
)
this
.
$set
(
row
,
'
$v_checkedOrder
'
,
val
?
checkOrder
++
:
undefined
)
})
this
.
isCheckedAll
=
val
this
.
isCheckedImn
=
false
this
.
emitSelectionChange
()
// 取消全选,则重置checkOrder
if
(
val
===
false
)
checkOrder
=
0
},
// 兼容多选:选择表格某行
onCheckRow
(
row
,
val
)
{
if
(
row
.
$v_checked
===
val
)
return
this
.
$set
(
row
,
'
$v_checked
'
,
val
)
this
.
$set
(
row
,
'
$v_checkedOrder
'
,
val
?
checkOrder
++
:
undefined
)
const
checkedLen
=
this
.
dataSource
.
filter
(
(
row
)
=>
row
.
$v_checked
===
true
).
length
if
(
checkedLen
===
0
)
{
this
.
isCheckedAll
=
false
this
.
isCheckedImn
=
false
}
else
if
(
checkedLen
===
this
.
dataSource
.
length
)
{
this
.
isCheckedAll
=
true
this
.
isCheckedImn
=
false
}
else
{
this
.
isCheckedAll
=
false
this
.
isCheckedImn
=
true
}
this
.
emitSelectionChange
()
},
// 多选:兼容表格selection-change事件
emitSelectionChange
()
{
const
selection
=
this
.
dataSource
.
filter
((
row
)
=>
row
.
$v_checked
)
.
sort
((
a
,
b
)
=>
a
.
$v_checkedOrder
-
b
.
$v_checkedOrder
)
this
.
$emit
(
'
selection-change
'
,
selection
)
},
// 多选:兼容表格toggleRowSelection方法
toggleRowSelection
(
row
,
selected
)
{
const
val
=
typeof
selected
===
'
boolean
'
?
selected
:
!
row
.
$v_checked
this
.
onCheckRow
(
row
,
val
)
},
// 多选:兼容表格clearSelection方法
clearSelection
()
{
this
.
isCheckedImn
=
false
this
.
onCheckAllRows
(
false
)
}
},
watch
:
{
dataSource
()
{
if
(
!
this
.
virtualized
)
{
this
.
renderAllData
()
}
else
{
this
.
doUpdate
()
}
},
virtualized
:
{
immediate
:
true
,
handler
(
val
)
{
if
(
!
val
)
{
this
.
renderAllData
()
}
else
{
this
.
doUpdate
()
}
}
}
},
created
()
{
this
.
$nextTick
(()
=>
{
this
.
initData
()
})
},
mounted
()
{
const
appendEl
=
this
.
$refs
.
append
this
.
$el
.
querySelector
(
'
.ant-table-body
'
).
appendChild
(
appendEl
)
},
beforeDestroy
()
{
if
(
this
.
scroller
)
{
this
.
scroller
.
removeEventListener
(
'
scroll
'
,
this
.
onScroll
)
window
.
removeEventListener
(
'
resize
'
,
this
.
onScroll
)
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
></
style
>
This diff is collapsed.
Click to expand it.
src/views/verification/components/a-virtual-table/README.MD
0 → 100644
View file @
ecd603e2
### 表格虚拟滚动
#### api文档
1.
属性说明
参数 说明 类型 可选值 默认值
dataSource 总数据 Array 必填
keyProp key值,data数据中的唯一id【⚠️若keyProp未设置或keyProp值不唯一,可能导致表格空数据或者滚动时渲染的数据断层、不连贯】 string — id
itemSize 每一行的预估高度 number — 60
scrollBox 指定滚动容器;在指定滚动容器时,如果表格设置了height高度,则滚动容器为表格内的滚动容器;如果表格为设置height高度,则自动获取父层以外的滚动容器,直至window容器为止 string — -
buffer 顶部和底部缓冲区域,值越大显示表格的行数越多 Number — 200
throttleTime 滚动事件的节流时间 number — 10
dynamic 动态获取表格行高度,默认开启。设置为false时,则以itemSize为表格行的真实高度,能大大减少虚拟滚动计算量,减少滚动白屏;如果itemSize与表格行的真实高度不一致,可能导致滚动时表格数据错乱 boolean — true
virtualized 是否开启虚拟滚动 boolean — true
*
支持
<a-table>
组件的props属性,更多请看
<a-table>
api - — -
2.
方法说明
方法名 说明 参数
scrollTo 滚动到第几行【不太精确:因为滚动到第n行时,如果周围的表格行计算出真实高度后会更新高度,导致当前行坍塌或撑起】 index
update 更新 -
clearSelection 用于多选
<virtual-column
type=
"selection"
>
,清空用户的选择 -
toggleRowSelection 用于多选
<virtual-column
type=
"selection"
>
, 切换某一行的选中状态,如果使用了第二个参数,则是设置这一行选中与否(selected 为 true 则选中) row, selected
3.
事件说明
事件名称 说明 参数
change 计算完成真实显示的表格行数 (renderData, start, end):renderData 真实渲染的数据,start和end指的是渲染的数据在总数据的开始到结束的区间范围
selection-change 虚拟表格多选选项发生更改时触发事件 selectedRows
This diff is collapsed.
Click to expand it.
vue.config.js
View file @
ecd603e2
const
path
=
require
(
"
path
"
);
const
LodashModuleReplacementPlugin
=
require
(
"
lodash-webpack-plugin
"
);
const
CompressionPlugin
=
require
(
"
compression-webpack-plugin
"
);
// 代码压缩
const
defaultSettings
=
require
(
"
./src/settings.js
"
);
const
path
=
require
(
'
path
'
)
const
LodashModuleReplacementPlugin
=
require
(
'
lodash-webpack-plugin
'
)
const
CompressionPlugin
=
require
(
'
compression-webpack-plugin
'
)
// 代码压缩
const
defaultSettings
=
require
(
'
./src/settings.js
'
)
module
.
exports
=
{
publicPath
:
"
/bims
"
,
publicPath
:
'
/bims
'
,
productionSourceMap
:
false
,
pluginOptions
:
{
"
style-resources-loader
"
:
{
preProcessor
:
"
less
"
,
patterns
:
[
path
.
resolve
(
__dirname
,
"
src/assets/style/common.less
"
)],
}
,
'
style-resources-loader
'
:
{
preProcessor
:
'
less
'
,
patterns
:
[
path
.
resolve
(
__dirname
,
'
src/assets/style/common.less
'
)]
}
},
css
:
{
loaderOptions
:
{
less
:
{
javascriptEnabled
:
true
,
}
,
javascriptEnabled
:
true
}
}
},
chainWebpack
:
(
config
)
=>
{
if
(
process
.
env
.
NODE_ENV
===
"
production
"
)
{
if
(
process
.
env
.
NODE_ENV
===
'
production
'
)
{
// lodash 按需加载
config
.
plugin
(
"
loadshReplace
"
).
use
(
new
LodashModuleReplacementPlugin
());
config
.
plugin
(
'
loadshReplace
'
).
use
(
new
LodashModuleReplacementPlugin
())
}
},
configureWebpack
:
(
config
)
=>
{
config
.
name
=
defaultSettings
.
title
;
const
plugins
=
[]
;
if
(
process
.
env
.
NODE_ENV
===
"
production
"
)
{
config
.
name
=
defaultSettings
.
title
const
plugins
=
[]
if
(
process
.
env
.
NODE_ENV
===
'
production
'
)
{
plugins
.
push
(
new
CompressionPlugin
({
filename
:
"
[path][base].gz
"
,
algorithm
:
"
gzip
"
,
test
:
new
RegExp
(
"
.(
"
+
[
"
js
"
,
"
css
"
,
"
json
"
].
join
(
"
|
"
)
+
"
)$
"
),
filename
:
'
[path][base].gz
'
,
algorithm
:
'
gzip
'
,
test
:
new
RegExp
(
'
.(
'
+
[
'
js
'
,
'
css
'
,
'
json
'
].
join
(
'
|
'
)
+
'
)$
'
),
threshold
:
8192
,
include
:
/
\/
src/
,
exclude
:
/node_modules/
,
minRatio
:
0.8
,
deleteOriginalAssets
:
false
,
// 此处源文件保留吧,以防不测
deleteOriginalAssets
:
false
// 此处源文件保留吧,以防不测
})
)
;
)
}
config
.
plugins
=
[...
config
.
plugins
,
...
plugins
]
;
config
.
plugins
=
[...
config
.
plugins
,
...
plugins
]
},
devServer
:
{
...
...
@@ -51,14 +51,15 @@ module.exports = {
port
:
8888
,
hot
:
true
,
proxy
:
{
"
^/api_bims
"
:
{
target
:
"
http://47.99.75.3:8070
"
,
'
^/api_bims
'
:
{
target
:
'
http://47.99.75.3:8070
'
,
// 测试
// target: 'http://bims.medilink-global.com.cn/api_bims', // 生产
pathRewrite
:
{
"
^/api_bims
"
:
"
/
"
,
'
^/api_bims
'
:
'
/
'
},
changeOrigin
:
true
,
secure
:
false
,
}
,
}
,
}
,
}
;
secure
:
false
}
}
}
}
This diff is collapsed.
Click to expand it.
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