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
2b3989c6
Commit
2b3989c6
authored
May 14, 2026
by
yuzhenWang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
按需求修改
parent
c5b88c5f
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
497 additions
and
236 deletions
+497
-236
public/js/pdf.worker.min.mjs
+0
-0
src/views/financialCenter/financialBilling.vue
+27
-45
src/views/financialCenter/payables.vue
+268
-65
src/views/financialCenter/receivables.vue
+1
-2
src/views/sign/appointment/components/fileUpload.vue
+201
-124
No files found.
public/js/pdf.worker.min.mjs
0 → 100644
View file @
2b3989c6
This source diff could not be displayed because it is too large. You can
view the blob
instead.
src/views/financialCenter/financialBilling.vue
View file @
2b3989c6
...
...
@@ -273,7 +273,7 @@
</CommonDialog>
<!-- 设置出账年月弹窗 -->
<CommonDialog
dialogTitle=
"设置本期出账
金额
"
dialogTitle=
"设置本期出账
年月(实)
"
dialogWidth=
"80%"
:openDialog=
"settingBillYearMonthFlag"
:showAction=
"true"
...
...
@@ -452,7 +452,7 @@ const editTableRef = ref(null)
const
splitTableColumns
=
ref
([
{
prop
:
'splitRatio'
,
label
:
'出账比例'
,
label
:
'出账比例
(%)
'
,
editType
:
'input'
,
inputType
:
'decimal'
,
// integer / decimalNumber / decimal
decimalDigits
:
2
,
// 小数位数,默认2
...
...
@@ -542,38 +542,7 @@ const splitTableColumns = ref([
required
:
true
,
width
:
150
},
// {
// prop: 'amount',
// label: '原币种金额',
// editType: 'input',
// inputType: 'decimalNumber', // integer / decimalNumber / decimal
// decimalDigits: 2, // 小数位数,默认2
// required: true
// },
// {
// prop: 'originalAmount',
// label: '本次出账原币种金额',
// editType: 'input',
// inputType: 'decimalNumber', // integer / decimalNumber / decimal
// decimalDigits: 2, // 小数位数,默认2
// required: true
// },
// {
// prop: 'exchangeRate',
// label: '结算汇率',
// editType: 'input',
// inputType: 'decimal', // integer / decimalNumber / decimal
// decimalDigits: 2, // 小数位数,默认2
// required: true
// },
// {
// prop: 'hkdAmount',
// label: '港币出账金额',
// editType: 'input',
// inputType: 'decimalNumber', // integer / decimalNumber / decimal
// decimalDigits: 2, // 小数位数,默认2
// required: true
// },
{
prop
:
'payoutYearMonth'
,
label
:
'出账年月(估)'
,
...
...
@@ -710,7 +679,8 @@ const confirmRateExchange = async () => {
const
res
=
await
editExchangeRateApi
(
formData
)
ElMessage
.
success
(
'结算汇率修改成功'
)
rateExchangeFlag
.
value
=
false
loadTableData
()
const
params
=
searchFormRef
.
value
.
getFormData
()
loadTableData
(
params
)
}
catch
(
error
)
{
ElMessage
.
error
(
'结算汇率修改失败'
)
rateExchangeFlag
.
value
=
true
...
...
@@ -1006,7 +976,8 @@ const handleSpiltSubmit = async () => {
console
.
log
(
'分期出账结果'
,
res
)
installmentsBillFlag
.
value
=
false
ElMessage
.
success
(
'分期出账已保存'
)
loadTableData
()
const
searchParams
=
searchFormRef
.
value
.
getFormData
()
loadTableData
(
searchParams
)
}
catch
(
error
)
{
installmentsBillFlag
.
value
=
true
console
.
log
(
'分期出账错误'
,
error
)
...
...
@@ -1039,9 +1010,18 @@ const addSpiltRecord = () => {
id
:
generateId
(),
// 必须有 rowIdKey 对应的字段(默认 'id')
payoutCurrency
:
'HKD'
,
ruleCurrency
:
selectedRow
.
value
.
ruleCurrency
,
originalCurrency
:
selectedRow
.
value
.
originalCurrency
originalCurrency
:
selectedRow
.
value
.
originalCurrency
,
hkdToPayoutRate
:
'1'
}
if
(
selectedRow
.
value
.
originalCurrency
&&
selectedRow
.
value
.
originalCurrency
==
'HKD'
)
{
newRow
.
originalToHkdRate
=
'1'
}
// if (selectedRow.value.payoutCurrency && selectedRow.value.payoutCurrency == 'HKD') {
// newRow.hkdToPayoutRate = '1'
// }
console
.
log
(
'===================================='
)
console
.
log
(
'newRow'
,
newRow
)
console
.
log
(
'===================================='
)
// 插入到表格数据最前面
splitTableData
.
value
.
push
(
newRow
)
}
...
...
@@ -1380,11 +1360,13 @@ loadTableData()
// 分页事件
const
handleSizeChange
=
val
=>
{
pageSize
.
value
=
val
loadTableData
()
const
params
=
searchFormRef
.
value
.
getFormData
()
loadTableData
(
params
)
}
const
handleCurrentChange
=
val
=>
{
currentPage
.
value
=
val
loadTableData
()
const
params
=
searchFormRef
.
value
.
getFormData
()
loadTableData
(
params
)
}
// 表格数据
const
tableData
=
ref
([])
...
...
@@ -1407,15 +1389,13 @@ const handleSelect = (e, row) => {
ruleCurrency
:
row
.
ruleCurrency
,
originalCurrency
:
row
.
originalCurrency
,
payoutCurrency
:
row
.
payoutCurrency
,
hkdToPayoutRate
:
row
.
hkdToPayoutRate
?
row
.
hkdToPayoutRate
:
''
,
hkdToPayoutRate
:
''
,
exchangeRate
:
row
.
exchangeRate
?
row
.
exchangeRate
:
''
,
originalToHkdRate
:
row
.
originalToHkdRate
?
row
.
originalToHkdRate
:
''
,
originalToHkdRate
:
''
,
payoutAmount
:
row
.
payoutAmount
?
Number
(
row
.
payoutAmount
).
toFixed
(
2
)
:
''
,
ruleAmount
:
row
.
ruleAmount
?
Number
(
row
.
ruleAmount
).
toFixed
(
2
)
:
''
,
hkdAmount
:
row
.
hkdAmount
?
Number
(
row
.
hkdAmount
).
toFixed
(
2
)
:
''
}
rateExchangeFlag
.
value
=
true
}
}
...
...
@@ -1465,6 +1445,7 @@ const updatePayoutAmountapi = async data => {
const
updatePayRollStatusDisable
=
ref
(
true
)
const
multipleSelection
=
ref
([])
const
handleSelectionChange
=
val
=>
{
multipleSelection
.
value
=
val
console
.
log
(
'全选:'
,
val
)
// 完成检核按钮是否禁用
...
...
@@ -1481,7 +1462,8 @@ const submitSettingBillYearMonth = async () => {
if
(
res
.
code
===
200
)
{
settingBillYearMonthFlag
.
value
=
false
ElMessage
.
success
(
'完成检核,等待关账'
)
loadTableData
()
const
params
=
searchFormRef
.
value
.
getFormData
()
loadTableData
(
params
)
}
}
catch
(
error
)
{
console
.
error
(
'检核失败:'
,
error
)
...
...
src/views/financialCenter/payables.vue
View file @
2b3989c6
...
...
@@ -976,15 +976,135 @@ const updatePayRecordFormConfig = [
// label: '备注'
// }
]
// const addPayRecordFormConfig = [
// {
// type: 'select',
// prop: 'fortuneBizType',
// label: '应付单类型',
// options: [
// { value: 'R', label: '关联保单应付单' },
// { value: 'U', label: '非关联保单应付单' }
// ]
// },
// {
// type: 'input',
// prop: 'policyNo',
// label: '关联保单号',
// visible: formData => formData.fortuneBizType === 'R'
// },
// {
// type: 'input',
// prop: 'fortunePeriod',
// label: '佣金期数',
// inputType: 'decimal',
// 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' }]
// },
// {
// type: 'date',
// prop: 'payoutDate',
// label: '出账日(估)',
// placeholder: '请选择'
// },
// {
// type: 'date',
// prop: 'actualPayoutDate',
// label: '出账日(实)',
// placeholder: '请选择',
// maxDate: 'today'
// },
// {
// type: 'input',
// prop: 'hkdAmount',
// label: '出账金额',
// rules: [
// { required: true, message: '请输入', trigger: 'blur' },
// { pattern: /^-?\d+(\.\d{1,2})?$/, message: '小数(最多两位)', trigger: 'blur' }
// ]
// },
// {
// type: 'select',
// prop: 'currency',
// label: '出账币种',
// dictType: 'bx_currency_type',
// defaultValue: 'HKD'
// },
// {
// type: 'input',
// prop: 'defaultExchangeRate',
// label: '结算汇率(入账检核时的汇率)',
// rules: [
// { required: true, message: '请输入', trigger: 'blur' },
// { pattern: /^-?\d+(\.\d{1,6})?$/, message: '小数(最多6位)', trigger: 'blur' }
// ]
// },
// {
// type: 'select',
// prop: 'fortuneType',
// label: '出账项目',
// dictType: 'csf_fortune_type'
// },
// {
// type: 'select',
// prop: 'brokerBizId',
// label: '转介人',
// api: '/insurance/base/api/userSaleExpand/page',
// keywordField: 'realName',
// requestParams: { pageNo: 1, pageSize: 200 },
// placeholder: '输入转介人名称搜索',
// debounceWait: 500, // 自定义防抖时间
// valueKey: 'clientUserBizId',
// labelKey: 'realName',
// onChangeExtraFields: {
// broker: 'realName', // 自动同步 raw.name 到 reconciliationCompany
// reconciliationCompanyCode: 'code'
// },
// transform: res => {
// return res?.data.records || []
// }
// },
// {
// type: 'select',
// prop: 'status',
// label: '出账状态',
// dictType: 'csf_expected_fortune_status'
// },
// {
// type: 'input',
// prop: 'exchangeRate',
// label: '结算汇率',
// inputType: 'decimal',
// rules: [{ required: true, message: '只能输入正整数和小数', trigger: 'blur' }]
// // defaultValue: 1
// },
// {
// type: 'input',
// prop: 'remark',
// label: '备注'
// }
// ]
const
addPayRecordFormConfig
=
[
{
type
:
'select'
,
prop
:
'fortuneBizType'
,
label
:
'应付单类型'
,
options
:
[
{
value
:
'R'
,
label
:
'关联保单应付单'
},
{
value
:
'U'
,
label
:
'非关联保单应付单'
}
]
options
:
fortuneBizTypeOptions
,
rules
:
[{
required
:
true
,
message
:
'应付单类型必填'
,
trigger
:
'blur'
}]
},
{
type
:
'select'
,
prop
:
'status'
,
label
:
'出账状态'
,
dictType
:
'csf_expected_fortune_status'
,
rules
:
[{
required
:
true
,
message
:
'出账状态必填'
,
trigger
:
'blur'
}]
},
{
type
:
'input'
,
...
...
@@ -993,64 +1113,54 @@ const addPayRecordFormConfig = [
visible
:
formData
=>
formData
.
fortuneBizType
===
'R'
},
{
type
:
'input'
,
prop
:
'fortunePeriod'
,
label
:
'佣金期数'
,
inputType
:
'decimal'
,
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'
}]
},
{
type
:
'date'
,
type
:
'month'
,
prop
:
'payoutDate'
,
label
:
'出账日(估)'
,
placeholder
:
'请选择'
label
:
'出账月(估)'
,
placeholder
:
'请选择'
,
maxDate
:
'today'
,
rules
:
[{
required
:
true
,
message
:
'出账月(估)必填'
,
trigger
:
'blur'
}]
},
{
type
:
'
date
'
,
type
:
'
month
'
,
prop
:
'actualPayoutDate'
,
label
:
'出账
日(实)
'
,
label
:
'出账
月(实)
'
,
placeholder
:
'请选择'
,
maxDate
:
'today'
maxDate
:
'today'
,
rules
:
[{
required
:
true
,
message
:
'出账月(实)必填'
,
trigger
:
'blur'
}]
},
{
type
:
'input'
,
prop
:
'hkdAmount'
,
label
:
'出账金额'
,
rules
:
[
{
required
:
true
,
message
:
'请输入'
,
trigger
:
'blur'
},
{
pattern
:
/^-
?\d
+
(\.\d{1,2})?
$/
,
message
:
'小数(最多两位)'
,
trigger
:
'blur'
}
]
prop
:
'statusDesc'
,
label
:
'修改理由'
},
{
type
:
'input'
,
prop
:
'fortuneName'
,
label
:
'出账项目名称'
,
rules
:
[{
required
:
true
,
message
:
'出账项目名称必填'
,
trigger
:
'blur'
}]
},
{
type
:
'select'
,
prop
:
'
currency
'
,
label
:
'出账
币种
'
,
dictType
:
'
bx_currency
_type'
,
defaultValue
:
'HKD'
prop
:
'
fortuneType
'
,
label
:
'出账
项目类型
'
,
dictType
:
'
csf_fortune
_type'
,
rules
:
[{
required
:
true
,
message
:
'出账项目类型必填'
,
trigger
:
'blur'
}]
},
{
type
:
'input'
,
prop
:
'defaultExchangeRate'
,
label
:
'结算汇率(入账检核时的汇率)'
,
rules
:
[
{
required
:
true
,
message
:
'请输入'
,
trigger
:
'blur'
},
{
pattern
:
/^-
?\d
+
(\.\d{1,6})?
$/
,
message
:
'小数(最多6位)'
,
trigger
:
'blur'
}
]
prop
:
'fortunePeriod'
,
label
:
'佣金期数'
,
inputType
:
'decimal'
,
visible
:
formData
=>
formData
.
fortuneBizType
===
'R'
,
rules
:
[{
required
:
true
,
pattern
:
/^
\d
+$/
,
message
:
'只能输入正整数'
,
trigger
:
'blur'
}]
},
{
type
:
'select'
,
prop
:
'fortuneType'
,
label
:
'出账项目'
,
dictType
:
'csf_fortune_type'
type
:
'input'
,
prop
:
'fortuneTotalPeriod'
,
label
:
'总期数'
,
inputType
:
'decimal'
,
visible
:
formData
=>
formData
.
fortuneBizType
===
'R'
,
rules
:
[{
pattern
:
/^
\d
+$/
,
message
:
'只能输入正整数'
,
trigger
:
'blur'
}]
},
{
type
:
'select'
,
...
...
@@ -1066,32 +1176,125 @@ const addPayRecordFormConfig = [
onChangeExtraFields
:
{
broker
:
'realName'
,
// 自动同步 raw.name 到 reconciliationCompany
reconciliationCompanyCode
:
'code'
// team: 'deptName',
// teamBizId: 'deptBizId'
},
transform
:
res
=>
{
return
res
?.
data
.
records
||
[]
},
rules
:
[{
required
:
true
,
message
:
'转介人必填'
,
trigger
:
'blur'
}]
},
{
type
:
'select'
,
prop
:
'teamBizId'
,
label
:
'所属团队'
,
api
:
'/csf/api/team/page'
,
keywordField
:
'teamName'
,
requestParams
:
{
pageNo
:
1
,
pageSize
:
200
},
placeholder
:
'输入所属团队名称搜索'
,
debounceWait
:
500
,
// 自定义防抖时间
valueKey
:
'teamBizId'
,
labelKey
:
'teamName'
,
onChangeExtraFields
:
{
// broker: 'realName', // 自动同步 raw.name 到 reconciliationCompany
// reconciliationCompanyCode: 'code',
team
:
'teamName'
,
teamBizId
:
'teamBizId'
},
transform
:
res
=>
{
return
res
?.
data
.
records
||
[]
}
// rules: [{ required: true, message: '所属团队必填', trigger: 'blur' }]
},
// {
// type: 'input',
// prop: 'defaultExchangeRate',
// label: '结算汇率(入账检核时的汇率)',
// rules: [
// { required: true, message: '请输入', trigger: 'blur' },
// { pattern: /^-?\d+(\.\d{1,6})?$/, message: '小数(最多6位)', trigger: 'blur' }
// ]
// },
{
type
:
'select'
,
prop
:
'status'
,
label
:
'出账状态'
,
dictType
:
'csf_expected_fortune_status'
prop
:
'ruleCurrency'
,
label
:
'保单币种'
,
dictType
:
'bx_currency_type'
,
rules
:
[{
required
:
true
,
message
:
'保单币种必填'
,
trigger
:
'blur'
}]
},
{
type
:
'select'
,
prop
:
'originalCurrency'
,
label
:
'原币种'
,
dictType
:
'bx_currency_type'
,
rules
:
[{
required
:
true
,
message
:
'原币种必填'
,
trigger
:
'blur'
}]
},
{
type
:
'select'
,
prop
:
'payoutCurrency'
,
label
:
'发放币种'
,
dictType
:
'bx_currency_type'
,
rules
:
[{
required
:
true
,
message
:
'发放币种必填'
,
trigger
:
'blur'
}]
},
{
type
:
'input'
,
prop
:
'exchangeRate'
,
label
:
'结算汇率'
,
prop
:
'originalAmount'
,
label
:
'原币种金额'
,
inputType
:
'decimal'
,
rules
:
[{
required
:
true
,
message
:
'只能输入正整数和小数'
,
trigger
:
'blur'
}]
},
{
type
:
'input'
,
prop
:
'originalToHkdRate'
,
label
:
'汇率3(原币种->港币)'
,
inputType
:
'decimal'
,
rules
:
[{
required
:
true
,
message
:
'只能输入正整数和小数'
,
trigger
:
'blur'
}]
// defaultValue: 1
},
{
type
:
'input'
,
prop
:
'hkdAmount'
,
label
:
'港币金额'
,
inputType
:
'decimal'
,
rules
:
[{
required
:
true
,
message
:
'只能输入正整数和小数'
,
trigger
:
'blur'
}]
},
{
type
:
'input'
,
prop
:
'hkdToPayoutRate'
,
label
:
'汇率1(港币->发放币种)'
,
inputType
:
'decimal'
,
rules
:
[{
required
:
true
,
message
:
'只能输入正整数和小数'
,
trigger
:
'blur'
}]
// defaultValue: 1
},
{
type
:
'input'
,
prop
:
'payoutAmount'
,
label
:
'实际发放金额'
,
inputType
:
'decimal'
,
rules
:
[{
required
:
true
,
message
:
'只能输入正整数和小数'
,
trigger
:
'blur'
}]
},
{
type
:
'input'
,
prop
:
'defaultExchangeRate'
,
label
:
'汇率2(保单币种->港币)入账检核汇率'
,
inputType
:
'decimal'
,
rules
:
[{
required
:
true
,
message
:
'只能输入正整数和小数'
,
trigger
:
'blur'
}]
// defaultValue: 1
},
{
type
:
'input'
,
prop
:
'ruleAmount'
,
label
:
'保单币种金额'
,
inputType
:
'decimal'
,
rules
:
[{
required
:
true
,
message
:
'只能输入正整数和小数'
,
trigger
:
'blur'
}]
},
{
type
:
'input'
,
prop
:
'remark'
,
label
:
'备注'
}
]
//是否实收
const
typeOptions
=
[
{
value
:
1
,
label
:
'预计'
},
...
...
@@ -1121,7 +1324,7 @@ const handleInputChange = async (formType, prop, value, item) => {
commissionPeriod
:
fortunePeriod
})
if
(
res
.
code
==
200
)
{
addPayRecordFormModel
.
value
.
e
xchangeRate
=
res
.
data
addPayRecordFormModel
.
value
.
defaultE
xchangeRate
=
res
.
data
}
else
{
ElMessage
.
error
(
'查询结算汇率失败'
)
}
...
...
@@ -1141,9 +1344,9 @@ const handleInputChange = async (formType, prop, value, item) => {
await
nextTick
()
addPayRecordFormModel
.
value
.
payoutAmount
=
payoutAmount
}
const
exchangeRate
=
addPayRecordFormModel
.
value
.
e
xchangeRate
if
(
e
xchangeRate
)
{
const
ruleAmount
=
calculateAmount
(
hkdAmount
,
e
xchangeRate
,
2
,
'Divided'
)
const
defaultExchangeRate
=
addPayRecordFormModel
.
value
.
defaultE
xchangeRate
if
(
defaultE
xchangeRate
)
{
const
ruleAmount
=
calculateAmount
(
hkdAmount
,
defaultE
xchangeRate
,
2
,
'Divided'
)
await
nextTick
()
addPayRecordFormModel
.
value
.
ruleAmount
=
ruleAmount
}
...
...
@@ -1165,9 +1368,9 @@ const handleInputChange = async (formType, prop, value, item) => {
await
nextTick
()
addPayRecordFormModel
.
value
.
payoutAmount
=
payoutAmount
}
const
exchangeRate
=
addPayRecordFormModel
.
value
.
e
xchangeRate
if
(
e
xchangeRate
)
{
const
ruleAmount
=
calculateAmount
(
hkdAmount
,
e
xchangeRate
,
2
,
'Divided'
)
const
defaultExchangeRate
=
addPayRecordFormModel
.
value
.
defaultE
xchangeRate
if
(
defaultE
xchangeRate
)
{
const
ruleAmount
=
calculateAmount
(
hkdAmount
,
defaultE
xchangeRate
,
2
,
'Divided'
)
await
nextTick
()
addPayRecordFormModel
.
value
.
ruleAmount
=
ruleAmount
}
...
...
@@ -1190,18 +1393,18 @@ const handleInputChange = async (formType, prop, value, item) => {
}
//3.计算保单币种金额 港币金额*保单币种->港币汇率
if
(
prop
==
'hkdAmount'
&&
value
&&
addPayRecordFormModel
.
value
.
e
xchangeRate
)
{
if
(
prop
==
'hkdAmount'
&&
value
&&
addPayRecordFormModel
.
value
.
defaultE
xchangeRate
)
{
// 计算保单币种金额
const
exchangeRate
=
addPayRecordFormModel
.
value
.
e
xchangeRate
const
defaultExchangeRate
=
addPayRecordFormModel
.
value
.
defaultE
xchangeRate
const
hkdAmount
=
value
const
ruleAmount
=
calculateAmount
(
hkdAmount
,
e
xchangeRate
,
2
,
'Divided'
)
const
ruleAmount
=
calculateAmount
(
hkdAmount
,
defaultE
xchangeRate
,
2
,
'Divided'
)
await
nextTick
()
addPayRecordFormModel
.
value
.
ruleAmount
=
ruleAmount
}
else
if
(
prop
==
'
e
xchangeRate'
&&
value
&&
addPayRecordFormModel
.
value
.
hkdAmount
)
{
}
else
if
(
prop
==
'
defaultE
xchangeRate'
&&
value
&&
addPayRecordFormModel
.
value
.
hkdAmount
)
{
// 计算保单币种金额
const
e
xchangeRate
=
value
const
defaultE
xchangeRate
=
value
const
hkdAmount
=
addPayRecordFormModel
.
value
.
hkdAmount
const
ruleAmount
=
calculateAmount
(
hkdAmount
,
e
xchangeRate
,
2
,
'Divided'
)
const
ruleAmount
=
calculateAmount
(
hkdAmount
,
defaultE
xchangeRate
,
2
,
'Divided'
)
await
nextTick
()
addPayRecordFormModel
.
value
.
ruleAmount
=
ruleAmount
}
...
...
src/views/financialCenter/receivables.vue
View file @
2b3989c6
...
...
@@ -376,10 +376,9 @@ const addReceivablesFormConfig = [
visible
:
formData
=>
formData
.
commissionBizType
===
'R'
,
rules
:
[{
pattern
:
/^
\d
+$/
,
message
:
'只能输入正整数'
,
trigger
:
'blur'
}]
},
// 等待key
{
type
:
'month'
,
prop
:
'commissionDate
Month
'
,
prop
:
'commissionDate'
,
label
:
'入账月(估)'
,
placeholder
:
'请选择'
},
...
...
src/views/sign/appointment/components/fileUpload.vue
View file @
2b3989c6
...
...
@@ -181,7 +181,7 @@
<el-dialog
v-model=
"previewDialogVisible"
:title=
"previewFileName"
width=
"
8
0%"
width=
"
9
0%"
:close-on-click-modal=
"false"
destroy-on-close
@
close=
"closePreview"
...
...
@@ -191,19 +191,10 @@
<div
v-if=
"previewFileType === 'image'"
class=
"preview-image-wrapper"
>
<img
:src=
"previewUrl"
class=
"preview-image"
alt=
"预览图片"
/>
</div>
<!-- PDF 预览(pdf.js 插件) -->
<!-- PDF 预览区域(滚动多页) -->
<div
v-else-if=
"previewFileType === 'pdf'"
class=
"pdf-viewer"
>
<div
class=
"pdf-toolbar"
>
<el-button-group>
<el-button
size=
"small"
:disabled=
"pdfCurrentPage <= 1"
@
click=
"prevPage"
>
<el-icon><ArrowLeft
/></el-icon>
上一页
</el-button>
<el-button
size=
"small"
:disabled=
"pdfCurrentPage >= pdfTotalPages"
@
click=
"nextPage"
>
下一页
<el-icon><ArrowRight
/></el-icon>
</el-button>
</el-button-group>
<span
class=
"page-info"
>
第 {{ pdfCurrentPage }} / {{ pdfTotalPages }} 页
</span>
<!-- 只保留缩放按钮 -->
<el-button-group>
<el-button
size=
"small"
@
click=
"zoomOut"
>
<el-icon><ZoomOut
/></el-icon>
缩小
...
...
@@ -212,12 +203,16 @@
<el-icon><ZoomIn
/></el-icon>
放大
</el-button>
</el-button-group>
<span
class=
"page-info"
>
共 {{ pdfTotalPages }} 页
</span>
</div>
<div
class=
"pdf-canvas-wrapper"
>
<canvas
ref=
"pdfCanvasRef"
class=
"pdf-canvas"
></canvas>
<div
class=
"pdf-scroll-wrapper"
v-loading=
"pdfLoading"
element-loading-text=
"正在渲染页面..."
>
<div
ref=
"pdfScrollContainer"
class=
"pdf-scroll-container"
></div>
</div>
</div>
<!-- 不支持预览的文件类型 -->
<div
v-else-if=
"previewFileType === 'unsupported'"
class=
"preview-unsupported"
>
<el-icon
:size=
"48"
color=
"#909399"
><Document
/></el-icon>
...
...
@@ -235,7 +230,7 @@
</template>
<
script
setup
name=
"FileUpload"
>
import
{
ref
,
nextTick
}
from
'vue'
import
{
ref
,
nextTick
,
shallowRef
}
from
'vue'
import
{
ElMessage
}
from
'element-plus'
import
{
downloadFilesAsZip
}
from
'@/utils/zipDownload'
// 引入刚才封装的工具
import
CommonDialog
from
'@/components/commonDialog'
...
...
@@ -244,7 +239,7 @@ import { getToken } from '@/utils/auth'
import
{
addFile
,
getAppointmentFile
,
delFile
,
editAppointmentFile
}
from
'@/api/sign/appointment'
import
useDictStore
from
'@/store/modules/dict'
import
useUserStore
from
'@/store/modules/user'
import
{
ArrowLeft
,
ArrowRight
,
ZoomIn
,
ZoomOut
,
Document
}
from
'@element-plus/icons-vue'
import
{
ArrowLeft
,
ArrowRight
,
ZoomIn
,
ZoomOut
,
Document
,
Loading
}
from
'@element-plus/icons-vue'
const
userStore
=
useUserStore
()
import
{
uploadMaterialList
,
...
...
@@ -257,16 +252,14 @@ import {
}
from
'@/api/common'
import
*
as
PDFJS
from
'pdfjs-dist'
// 设置 worker 路径(重要!)
PDFJS
.
GlobalWorkerOptions
.
workerSrc
=
new
URL
(
'pdfjs-dist/build/pdf.worker.min.js'
,
import
.
meta
.
url
).
toString
()
PDFJS
.
GlobalWorkerOptions
.
workerSrc
=
'/js/pdf.worker.min.mjs'
const
props
=
defineProps
({
activeName
:
{
type
:
String
,
default
:
''
},
//tab名称
idsObj
:
{
type
:
Object
,
default
:
()
=>
({})
},
//父组件传递过来的id对象
pageSource
:
{
type
:
String
,
default
:
''
}
//页面来源
})
// 在定义其他响应式变量的附近添加
const
pdfLoading
=
ref
(
false
)
// PDF 加载状态
const
acceptUploadType
=
ref
(
'.pdf,.jpg,.jpeg,.png,.bmp,.gif,.svg'
)
const
uploadRef
=
ref
(
null
)
const
dictStore
=
useDictStore
()
//获取字典数据
...
...
@@ -281,128 +274,133 @@ const headers = ref({ Authorization: 'Bearer ' + getToken() })
const
uploadImgUrl
=
ref
(
import
.
meta
.
env
.
VITE_APP_BASE_API
+
'/oss/api/oss/upload'
)
// 上传的服务器地址
// PDF 预览相关
const
pdfCanvasRef
=
ref
(
null
)
// canvas 元素引用
const
pdfDoc
=
ref
(
null
)
// pdf 文档实例
const
pdfCurrentPage
=
ref
(
1
)
// 当前页
const
pdfTotalPages
=
ref
(
0
)
// 总页数
const
pdfScale
=
ref
(
1.2
)
// 缩放比例
// 修改 pdfDoc 的定义
const
pdfDoc
=
shallowRef
(
null
)
// pdf 文档实例
// 渲染指定页
const
renderPdfPage
=
async
pageNum
=>
{
if
(
!
pdfDoc
.
value
)
return
const
page
=
await
pdfDoc
.
value
.
getPage
(
pageNum
)
const
viewport
=
page
.
getViewport
({
scale
:
pdfScale
.
value
})
const
canvas
=
pdfCanvasRef
.
value
const
context
=
canvas
.
getContext
(
'2d'
)
canvas
.
height
=
viewport
.
height
canvas
.
width
=
viewport
.
width
const
renderContext
=
{
canvasContext
:
context
,
viewport
:
viewport
}
await
page
.
render
(
renderContext
).
promise
}
const
pdfScale
=
ref
(
1.2
)
// 缩放比例
// 新增标志:是否取消PDF加载
let
pdfLoadingCanceled
=
false
// ==================== 文件预览弹窗 ====================
const
previewDialogVisible
=
ref
(
false
)
const
previewUrl
=
ref
(
''
)
const
previewFileName
=
ref
(
''
)
const
previewFileType
=
ref
(
''
)
// 'image', 'pdf', 'unsupported'
const
pdfScrollContainer
=
ref
(
null
)
// 滚动容器的 ref
const
pdfTotalPages
=
ref
(
0
)
// 总页数(仅供显示)
const
isRendering
=
ref
(
false
)
// 防止重复渲染
// 加载并渲染 PDF
const
loadPdf
=
async
url
=>
{
pdfLoadingCanceled
=
false
pdfLoading
.
value
=
true
try
{
// 重置状态
pdfDoc
.
value
=
null
pdfCurrentPage
.
value
=
1
pdfTotalPages
.
value
=
0
if
(
pdfDoc
.
value
)
{
await
pdfDoc
.
value
.
destroy
().
catch
(()
=>
{})
pdfDoc
.
value
=
null
}
// 清空滚动容器
if
(
pdfScrollContainer
.
value
)
{
pdfScrollContainer
.
value
.
innerHTML
=
''
}
const
loadingTask
=
PDFJS
.
getDocument
(
url
)
pdfDoc
.
value
=
await
loadingTask
.
promise
if
(
pdfLoadingCanceled
)
{
if
(
pdfDoc
.
value
)
pdfDoc
.
value
.
destroy
()
pdfLoading
.
value
=
false
return
}
pdfTotalPages
.
value
=
pdfDoc
.
value
.
numPages
await
renderPdfPage
(
pdfCurrentPage
.
value
)
await
renderAllPages
(
pdfScale
.
value
)
// 渲染所有页面
pdfLoading
.
value
=
false
}
catch
(
err
)
{
console
.
error
(
'PDF 加载失败'
,
err
)
ElMessage
.
error
(
'PDF 文件加载失败,请检查文件链接'
)
previewDialogVisible
.
value
=
false
if
(
!
pdfLoadingCanceled
)
{
console
.
error
(
'PDF 加载失败'
,
err
)
ElMessage
.
error
(
'PDF 文件加载失败,请检查文件链接'
)
previewDialogVisible
.
value
=
false
}
pdfLoading
.
value
=
false
}
}
// 上一页
const
prevPage
=
()
=>
{
if
(
pdfCurrentPage
.
value
>
1
)
{
pdfCurrentPage
.
value
--
renderPdfPage
(
pdfCurrentPage
.
value
)
// 修改 renderPdfPage,增加有效性检查
const
renderPdfPage
=
async
pageNum
=>
{
if
(
!
pdfDoc
.
value
||
pdfLoadingCanceled
)
return
try
{
const
page
=
await
pdfDoc
.
value
.
getPage
(
pageNum
)
const
viewport
=
page
.
getViewport
({
scale
:
pdfScale
.
value
})
const
canvas
=
pdfCanvasRef
.
value
if
(
!
canvas
)
return
const
context
=
canvas
.
getContext
(
'2d'
)
canvas
.
height
=
viewport
.
height
canvas
.
width
=
viewport
.
width
const
renderContext
=
{
canvasContext
:
context
,
viewport
:
viewport
}
await
page
.
render
(
renderContext
).
promise
}
catch
(
err
)
{
if
(
!
pdfLoadingCanceled
)
{
console
.
error
(
'渲染PDF页失败'
,
err
)
}
}
}
const
renderAllPages
=
async
scale
=>
{
if
(
!
pdfDoc
.
value
||
pdfLoadingCanceled
||
isRendering
.
value
)
return
isRendering
.
value
=
true
pdfLoading
.
value
=
true
// 显示加载状态
// 下一页
const
nextPage
=
()
=>
{
if
(
pdfCurrentPage
.
value
<
pdfTotalPages
.
value
)
{
pdfCurrentPage
.
value
++
renderPdfPage
(
pdfCurrentPage
.
value
)
const
container
=
pdfScrollContainer
.
value
if
(
!
container
)
{
isRendering
.
value
=
false
return
}
}
// 清空之前的 canvas
container
.
innerHTML
=
''
// 放大/缩小
const
zoomIn
=
()
=>
{
pdfScale
.
value
=
Math
.
min
(
pdfScale
.
value
+
0.2
,
3.0
)
renderPdfPage
(
pdfCurrentPage
.
value
)
}
const
zoomOut
=
()
=>
{
pdfScale
.
value
=
Math
.
max
(
pdfScale
.
value
-
0.2
,
0.5
)
renderPdfPage
(
pdfCurrentPage
.
value
)
}
const
closePreview
=
()
=>
{
// 清理 PDF 资源
if
(
pdfDoc
.
value
)
{
pdfDoc
.
value
.
destroy
()
pdfDoc
.
value
=
null
try
{
const
promises
=
[]
for
(
let
pageNum
=
1
;
pageNum
<=
pdfTotalPages
.
value
;
pageNum
++
)
{
if
(
pdfLoadingCanceled
)
break
const
page
=
await
pdfDoc
.
value
.
getPage
(
pageNum
)
const
viewport
=
page
.
getViewport
({
scale
})
// 创建 canvas 元素
const
canvas
=
document
.
createElement
(
'canvas'
)
canvas
.
className
=
'pdf-page-canvas'
const
context
=
canvas
.
getContext
(
'2d'
)
canvas
.
height
=
viewport
.
height
canvas
.
width
=
viewport
.
width
// 添加一些底部间距,便于区分页面
canvas
.
style
.
marginBottom
=
'16px'
canvas
.
style
.
boxShadow
=
'0 2px 8px rgba(0,0,0,0.1)'
container
.
appendChild
(
canvas
)
// 渲染该页
const
renderTask
=
page
.
render
({
canvasContext
:
context
,
viewport
:
viewport
})
promises
.
push
(
renderTask
.
promise
)
}
await
Promise
.
all
(
promises
)
}
catch
(
err
)
{
if
(
!
pdfLoadingCanceled
)
{
console
.
error
(
'渲染多页 PDF 失败'
,
err
)
ElMessage
.
error
(
'渲染 PDF 页面失败'
)
}
}
finally
{
isRendering
.
value
=
false
pdfLoading
.
value
=
false
}
pdfTotalPages
.
value
=
0
pdfCurrentPage
.
value
=
1
pdfScale
.
value
=
1.0
previewUrl
.
value
=
''
}
// ==================== 文件预览弹窗 ====================
const
previewDialogVisible
=
ref
(
false
)
const
previewUrl
=
ref
(
''
)
const
previewFileName
=
ref
(
''
)
const
previewFileType
=
ref
(
''
)
// 'image', 'pdf', 'unsupported'
// 预览文件(页面内弹窗,不打开新窗口)
// function previewFile(file) {
// console.log('====================================')
// console.log('file', file)
// console.log('====================================')
// // const url = file.url || file.fileUrl
// let url = ''
// if (file.fileKey) {
// // url = `https://files.csf.hk/${file.fileKey}`
// url = `https://csf-hk.oss-cn-hongkong.aliyuncs.com/PC/test/pdf/2026/05/13/a482331b118142d782ac6ba7697eae15.pdf`
// } else {
// url = file.url
// }
// if (!url) {
// ElMessage.warning('文件地址不存在')
// return
// }
// const ext = (file.originalName || '').split('.').pop().toLowerCase()
// previewUrl.value = url
// previewFileName.value = file.originalName || '文件'
// if (['jpg', 'jpeg', 'png', 'webp', 'gif', 'bmp', 'svg'].includes(ext)) {
// previewFileType.value = 'image'
// previewDialogVisible.value = true
// } else if (ext === 'pdf') {
// previewFileType.value = 'pdf'
// previewDialogVisible.value = true
// } else {
// // 不支持预览的文件类型,弹窗显示提示
// previewFileType.value = 'unsupported'
// previewDialogVisible.value = true
// }
// console.log('====================================')
// console.log('previewUrl.value', previewUrl.value)
// console.log('previewFileName.value', previewFileName.value)
// console.log('previewFileType.value', previewFileType.value)
// console.log('====================================')
// }
// 修改 previewFile 中的 PDF 分支
function
previewFile
(
file
)
{
console
.
log
(
'===================================='
)
console
.
log
(
'file'
,
file
)
console
.
log
(
'===================================='
)
const
url
=
file
.
url
||
file
.
fileUrl
if
(
!
url
)
{
ElMessage
.
warning
(
'文件地址不存在'
)
...
...
@@ -418,7 +416,8 @@ function previewFile(file) {
}
else
if
(
ext
===
'pdf'
)
{
previewFileType
.
value
=
'pdf'
previewDialogVisible
.
value
=
true
// 确保 DOM 更新后再加载 PDF
// 先清理旧的资源
closePreview
()
nextTick
(()
=>
{
loadPdf
(
previewUrl
.
value
)
})
...
...
@@ -427,6 +426,29 @@ function previewFile(file) {
previewDialogVisible
.
value
=
true
}
}
const
closePreview
=
()
=>
{
pdfLoadingCanceled
=
true
// 取消任何进行中的渲染
pdfLoading
.
value
=
false
isRendering
.
value
=
false
if
(
pdfDoc
.
value
)
{
pdfDoc
.
value
.
destroy
().
catch
(()
=>
{})
pdfDoc
.
value
=
null
}
pdfTotalPages
.
value
=
0
pdfScale
.
value
=
1.2
if
(
pdfScrollContainer
.
value
)
{
pdfScrollContainer
.
value
.
innerHTML
=
''
}
}
const
zoomIn
=
()
=>
{
pdfScale
.
value
=
Math
.
min
(
pdfScale
.
value
+
0.2
,
3.0
)
renderAllPages
(
pdfScale
.
value
)
}
const
zoomOut
=
()
=>
{
pdfScale
.
value
=
Math
.
max
(
pdfScale
.
value
-
0.2
,
0.5
)
renderAllPages
(
pdfScale
.
value
)
}
// 图片查看相关状态
const
imageViewerVisible
=
ref
(
false
)
const
imageUrl
=
ref
(
''
)
...
...
@@ -867,6 +889,61 @@ defineExpose({
padding
:
8px
0
;
border-bottom
:
1px
solid
#e4e7ed
;
margin-bottom
:
12px
;
.page-info
{
font-size
:
14px
;
color
:
#606266
;
}
}
.pdf-scroll-wrapper
{
flex
:
1
;
overflow-y
:
auto
;
/* 垂直滚动 */
border
:
1px
solid
#ebeef5
;
border-radius
:
4px
;
background
:
#f9fafc
;
}
.pdf-scroll-container
{
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
/* 页面居中显示 */
padding
:
16px
;
}
.pdf-page-canvas
{
display
:
block
;
max-width
:
100%
;
/* 自适应宽度,防止溢出容器 */
height
:
auto
;
box-shadow
:
0
2px
8px
rgba
(
0
,
0
,
0
,
0.1
);
margin-bottom
:
16px
;
}
.pdf-loading
{
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
justify-content
:
center
;
min-height
:
300px
;
color
:
#409eff
;
gap
:
12px
;
.el-icon
{
font-size
:
32px
;
}
}
.pdf-viewer
{
display
:
flex
;
flex-direction
:
column
;
height
:
70vh
;
}
.pdf-toolbar
{
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
gap
:
16px
;
padding
:
8px
0
;
border-bottom
:
1px
solid
#e4e7ed
;
margin-bottom
:
12px
;
.page-info
{
font-size
:
14px
;
...
...
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