You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

835 lines
26 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div>
<!-- 付款登记审核-->
<xy-dialog title="付款审核" :is-show.sync="isShow" type="form" class="payment-registration"
:form="paymentRegistrationForm" :rules="paymentRegistrationRules" ref="paymentRegistration" @submit="editor">
<template v-slot:extraFormTop>
<div class="payment-registration-row">
<div class="payment-registration-row-title">受款单位</div>
<div class="payment-registration-row-content">{{contract ? contract.supply : ''}}</div>
</div>
<div class="payment-registration-row">
<div class="payment-registration-row-title">合同名称</div>
<div class="payment-registration-row-content">{{contract ? contract.name : ''}}</div>
</div>
<div class="payment-registration-row">
<div class="payment-registration-row-title">合同金额</div>
<div class="payment-registration-row-content">{{contract ? moneyFormat(contract.money) : 0}} </div>
</div>
<div style="display: flex">
<div class="payment-registration-row">
<div class="payment-registration-row-title">已申请金额</div>
<div class="payment-registration-row-content">{{totalApplyMoney()}} </div>
</div>
<div class="payment-registration-row">
<div class="payment-registration-row-title">已申请笔数</div>
<div class="payment-registration-row-content">{{payment.length}}</div>
</div>
</div>
<div style="display: flex">
<div class="payment-registration-row">
<div class="payment-registration-row-title">已付金额</div>
<div class="payment-registration-row-content">{{totalMoney()}} </div>
</div>
<div class="payment-registration-row">
<div class="payment-registration-row-title">支付占比</div>
<div class="payment-registration-row-content">{{percentPay()}}%</div>
</div>
<div class="payment-registration-row">
<div class="payment-registration-row-title">已付笔数</div>
<div class="payment-registration-row-content">{{actNumsTotal()}}</div>
<div class="payment-registration-row-content" style="color: #ff0000;padding-left: 16px;cursor: pointer;">
<Poptip :transfer="true">
<div>点击查看列表</div>
<template v-slot:content>
<template v-if="payment&&payment.length>0">
<xy-table :height="200" :list="payment" :table-item="payTable">
<template v-slot:btns>
<p></p>
</template>
</xy-table>
</template>
<template v-else>
<div style="text-align: center">暂无已付笔数</div>
</template>
</template>
</Poptip>
</div>
</div>
</div>
</template>
<template v-slot:remark>
<div class="xy-table-item">
<div class="xy-table-item-label">备注
</div>
<div class="xy-table-item-content">
{{paymentRegistrationForm.remark}}
</div>
</div>
</template>
<template v-slot:applyMoney>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;">*</span>申请付款金额
</div>
<div class="xy-table-item-content xy-table-item-price">
<el-input clearable placeholder="请填写付款金额" v-model="paymentRegistrationForm.applyMoney"
style="width: 300px;" />
</div>
</div>
</template>
<!-- <template v-slot:deductionMoney>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;">*</span>本期扣款金额
</div>
<div class="xy-table-item-content xy-table-item-price">
<el-input clearable placeholder="请填写扣款金额" v-model="paymentRegistrationForm.deductionMoney"
style="width: 300px;" />
</div>
</div>
</template> -->
<template v-slot:type>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;">*</span>款项类型
</div>
<div class="xy-table-item-content">
<!-- <el-input readonly clearable placeholder="选择款项类型或直接填写其他类型" v-model="paymentRegistrationForm.type" style="width: 300px;"/>-->
<el-select placeholder="选择款项类型或直接填写其他类型" v-model="paymentRegistrationForm.type" style="width: 300px;"
disabled filterable allow-create clearable>
<el-option v-for="item in paymentType" :key="item" :label="item" :value="item">
</el-option>
</el-select>
</div>
</div>
</template>
<template v-slot:isLast>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;">*</span>是否为最后一笔
</div>
<div class="xy-table-item-content">
<el-switch v-model="paymentRegistrationForm.isLast" />
</div>
</div>
</template>
<template v-slot:property>
<div class="xy-table-item">
<div class="xy-table-item-label" style="width: 200px">
<span style="color: red; font-weight: 600; padding-right: 4px"
>*</span
>是否为资产
</div>
<div class="xy-table-item-content">
<el-switch v-model="paymentRegistrationForm.property" :active-value="1" :inactive-value="0"/>
</div>
</div>
</template>
<template v-slot:property_type_id v-if="paymentRegistrationForm.property">
<div class="xy-table-item">
<div class="xy-table-item-label" style="width: 200px">
<span style="color: red; font-weight: 600; padding-right: 4px"
>*</span
>资产类型
</div>
<div class="xy-table-item-content">
<el-select v-model="paymentRegistrationForm.property_type_id" style="width: 150px">
<el-option v-for="item in flowIds" :key="item.id" :value="item.id" :label="item.name"></el-option>
</el-select>
</div>
</div>
</template>
<template v-slot:actMoney>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;">*</span>实际付款金额
</div>
<div class="xy-table-item-content xy-table-item-price">
<el-input placeholder="请填写实际付款金额" v-model="paymentRegistrationForm.actMoney" style="width: 300px;" />
</div>
</div>
</template>
<!-- <template v-slot:moneyWay>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;">*</span>资金列支渠道
</div>
<div class="xy-table-item-content">
<el-cascader
:show-all-levels="false"
:options="planTypes"
:props="{
emitPath: false,
multiple: true,
checkStrictly: false,
label: 'name',
value: 'id',
}"
:value="paymentRegistrationForm.moneyWay"
clearable
size="small"
style="width: 300px"
@change="moneyWayChange"
/> -->
<!-- <el-select multiple style="width: 300px;" v-model="paymentRegistrationForm.moneyWay" placeholder="请选择资金列支渠道"-->
<!-- @change="moneyWayChange">-->
<!-- <el-option v-for="item in planTypes" :value="item.id" :label="item.value"></el-option>-->
<!-- </el-select>-->
<!-- </div>
</div>
</template> -->
<template #files v-if="paymentRegistrationForm.type === '结算款'">
<div class="xy-table-item">
<div class="xy-table-item-label">
附件
</div>
<div class="xy-table-item-content">
<el-upload
style="width: 300px"
ref="upload"
multiple
accept=".rar,.zip,.doc,.docx,.pdf,.jpg,.png,.gif,.mp4,.xls,.xlsx"
action=""
:file-list="fileList"
:auto-upload="false"
:limit="10"></el-upload>
</div>
</div>
</template>
<template v-slot:extraFormBottom>
<div style="display: flex;align-items: center;">
<el-select
placeholder="科室选择"
clearable
size="small"
v-model="plansSelect.plan_department_id"
style="width: 160px"
>
<el-option
v-for="item in departments"
:label="item.name"
:value="item.id"
:key="item.id"
>
</el-option>
</el-select>
<el-date-picker style="width: 160px" size="small" v-model="plansSelect.year" value-format="yyyy" type="year" />
<el-cascader
:options="planTypes"
:props="{
checkStrictly: false,
label: 'name',
value: 'id',
}"
:value="plansSelect.type"
clearable
size="small"
style="width: 160px;margin-left: 6px;"
@change="(e) => (plansSelect.type = e[e.length - 1] || '')"
/>
<Input style="margin-left: 6px;" search enter-button="搜 索" placeholder="搜索预算计划.." v-model="plansSelect.name" @on-search="getBudgets" />
</div>
<div class="contract-add-plan" style="min-width: 300px;">
<template v-if="false">
<template v-for="item in paymentRegistrationForm.plan">
<Tag closable color="primary" @on-close="delPlan(item)">{{item.label}}</Tag>
</template>
</template>
</div>
<xy-table :list="plans" :show-index="false" :table-item="planTable" :height="310" style="margin-top: 10px;"
ref="planTable" @select="selectPlan">
<template v-slot:btns>
<el-table-column label="使用金额(元)" header-align="center" width="140" :fixed="$store.getters.device === 'mobile'?false:'right'">
<template slot-scope="scope">
<Input :value="scope.row.use_money" @input="inputMoney($event,scope.row)" />
</template>
</el-table-column>
</template>
</xy-table>
<div style="display: flex;justify-content: flex-end;">
<Page :total="planTotal" show-elevator @on-change="planPageChange" />
</div>
</template>
</xy-dialog>
</div>
</template>
<script>
import {
getparameter, getparameterTree
} from '@/api/system/dictionary'
import {
getFundLog,
detailFundLog,
editorFundLog
} from "@/api/paymentRegistration/fundLog"
import {
getBudget
} from "@/api/budget/budget";
import {
detailContract
} from "@/api/contract/contract";
import {
Message
} from "element-ui";
import {
parseTime,
moneyFormatter, deepCopy
} from "@/utils";
import {listdeptNoAuth} from "@/api/system/department";
export default {
data() {
return {
departments: [],
flowIds: [
{
flow_id: 14,
name: "供应品验收",
},
{
flow_id: 57,
name: "固定资产验收"
}
],
fileList: [],
planTotal: 0,
pageIndex: 1,
//付款登记
plans: [],
contract: {},
payment: [], //合同关联的付款登记
planTypes: [],
payTable: [{
label: '申请金额',
prop: 'apply_money',
sortable: false,
width: 160,
align: 'right'
},
{
label: '已付金额',
prop: 'act_money',
sortable: false,
width: 160,
align: 'right'
},
{
label: '时间',
prop: 'created_at',
sortable: false,
width: 120,
formatter: (t1, t2, value) => {
return parseTime(new Date(value), '{y}-{m}-{d}')
}
}
],
paymentType: ["进度款", "结算款", "质保金"],
isShow: false,
registrationId: "",
paymentRegistrationForm: {
applyMoney: "",
deductionMoney: "",
type: "",
//isLast:false,
property: 0,
property_type_id: "",
plan: [],
actMoney: '',
moneyWay: [], //资金列支渠道
files: []
},
paymentRegistrationRules: {
applyMoney: [{
required: true,
message: "必填"
},
{
pattern: /^\d+(\.\d+)?$/,
message: '必须为数字'
}
],
// deductionMoney: [{
// required: true,
// message: "必填"
// },
// {
// pattern: /^\d+(\.\d+)?$/,
// message: '必须为数字'
// }
// ],
type: [{
required: true,
message: "必选"
}],
actMoney: [{
required: true,
message: "必填"
},
{
pattern: /^\d+(\.\d+)?$/,
message: '必须为数字'
}
],
// moneyWay: [{
// required: true,
// message: "必填"
// }]
},
plansSelect: {
page: 1,
page_size: 10,
name: '',
year: ''
},
planTable: [{
sortable: false,
width: 44,
type: 'selection'
},
{
label: "年份",
prop: 'year',
align: 'center',
width: 96,
},
{
label: "分类",
width: 136,
prop: 'type_detail.value',
formatter: (row, column, value) => {
const findVal = (arr, id) => {
for (let i = 0;i < arr.length;i++) {
if (i.id === id) {
return arr[i].name
} else if (arr.children instanceof Array) {
findVal(arr.children, id)
}
}
}
return value ? value : findVal(this.planTypes, row.type_id)
}
},
{
label: "科室",
prop: 'plan_department.name',
width: 140,
align: 'center',
formatter: (row, column, value) => {
return value ? value : this.departments.find(i => i.id === row.department_id)?.name
}
},
// {
// label: "隶属",
// prop: 'pid_info.name',
// width: 180,
// align: 'left'
// },
{
label: "名称",
prop: 'name',
width: 280,
align: 'left'
},
{
label: "计划金额",
prop: 'money',
width: 136,
align: 'right',
customFn: (row) => {
let m1 = row.money;
let m2 = row.update_money;
return m2 == 0 ? m1 : m2;
}
},
{
label: "实付金额",
prop: "use_money_total",
width: 120,
align: "right",
formatter: (v1, v2, value) =>
value ? `${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ",") : "",
},
{
label: "已用金额",
prop: "has_money_total",
width: 120,
align: "right",
formatter: (v1, v2, value) =>
value ? `${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ",") : "",
},
],
}
},
methods: {
delPlan(val) {
this.paymentRegistrationForm.plan.map((item, index) => {
if (item.plan_id === val.plan_id) {
this.paymentRegistrationForm.plan.splice(index, 1)
}
})
},
//合计申请金额
totalApplyMoney() {
let total = 0.00
this.payment.map(item => {
total += Number(item.apply_money)
})
return total.toFixed(2)
},
//资金列支渠道选择后变化
moneyWayChange(e) {
this.paymentRegistrationForm.moneyWay = e;
let page = 1
let pageSize = this.plansSelect.page_size
let name = this.plansSelect.name
this.plansSelect = {
page: page,
page_size: pageSize,
name: name
}
if (this.paymentRegistrationForm.moneyWay) {
let _arr = [];
this.paymentRegistrationForm.moneyWay.forEach((item, index) => {
_arr.push(item);
});
this.plansSelect[`type`]=_arr +'';
}
// this.getBudgets()
},
inputMoney(e, row) {
row.use_money = e
this.paymentRegistrationForm.plan.forEach(item => {
if (item.plan_id == row.id) {
item.use_money = e
}
})
},
async getPlanTypes() {
const res = await getparameterTree({
id: 3
});
const dataHandler = (data) => {
data.forEach(i => {
if (i.hasOwnProperty('detail')) {
i.children = i.detail.map(j => {
j.name = j.value
return j;
})
} else {
dataHandler(i['children'])
}
})
return data;
}
this.planTypes = dataHandler(res?.children) || []
},
//翻页
pageChange(e) {
this.pageIndex = e
this.getBudgets()
},
//合计金额
totalMoney() {
let total = 0.00
this.payment.map(item => {
total += Number(item.act_money)
})
return moneyFormatter(total)
},
//已付笔数
actNumsTotal() {
let total = 0
this.payment.map(item => {
if (Number(item.act_money)) {
total++
}
})
return total
},
//支付占比
percentPay() {
let total = 0
this.payment.map(item => {
total += Number(item.act_money)
})
return ((total / this.contract?.money??0) * 100).toFixed(2) || 0
},
async getRegistration(id) {
this.registrationId = id
const res = await detailFundLog({
id
})
console.log(res)
this.fileList = res.files_detail?.map(i => {
return {
url: i?.url,
name: i?.original_name,
response: i
}
})
this.paymentRegistrationForm.type = res.type
this.paymentRegistrationForm.isLast = res.is_end === 1
this.paymentRegistrationForm.deductionMoney = res.discount_money
this.paymentRegistrationForm.applyMoney = res.apply_money
this.paymentRegistrationForm.remark = res.remark
for (var m of res.plan_link) {
m.label = m.plan ? m.plan.name : "无计划名称";
}
this.paymentRegistrationForm.plan = res.plan_link
this.paymentRegistrationForm.actMoney = res.apply_money
this.paymentRegistrationForm.moneyWay = res.money_way_id?.split(',').map(item => Number(item))
await this.getContract(res.contract)
this.getBudgets(this.paymentRegistrationForm.plan?.map(i => i.plan_id)?.toString())
await this.moneyWayChange()
},
//获取合同信息
async getContract(info) {
this.contract = info
const res = await getFundLog({
contract_id: this.contract.id,
show_type: 1
})
this.payment = res.data
this.toggleSelection(this.paymentRegistrationForm.plan.map(item => {
return item.plan_id
}))
},
//确认审核
editor() {
let total = 0
this.paymentRegistrationForm.plan.forEach(item => {
total += Number(item.use_money)
})
console.log(Number(this.paymentRegistrationForm.actMoney).toFixed(2), total.toFixed(2))
// if (Number(this.paymentRegistrationForm.actMoney).toFixed(2) !== total.toFixed(2)) {
// Message({
// type: 'warning',
// message: '实际付款金额与计划总金额不符'
// })
// return
// }
editorFundLog({
id: this.registrationId,
contract_id: this.contract.id,
act_money: this.paymentRegistrationForm.actMoney,
status: 1,
apply_money: this.paymentRegistrationForm.applyMoney,
// discount_money: this.paymentRegistrationForm.deductionMoney,
// money_way_id: this.paymentRegistrationForm.moneyWay.toString(),
contract_plan_act_links: this.paymentRegistrationForm.plan,
property: this.paymentRegistrationForm.property,
property_type_id: this.paymentRegistrationForm.property_type_id,
}).then(res => {
this.$emit('refresh')
this.isShow = false
Message({
type: 'success',
message: '操作成功'
})
})
},
//计划
//获取预算计划
async getBudgets(pid) {
console.log("this.paymentRegistrationForm.applyMoney",this.paymentRegistrationForm.applyMoney)
let res = await getBudget({
top_pid: 1,
...this.plansSelect,
pid
})
if (res.list.data) {
this.plans = res.list.data.map(i => ({
use_money: this.paymentRegistrationForm.applyMoney,
...i
})).reduce((accumulator, current) => {
const duplicate = accumulator.find(item => item.id === current.id);
if (!duplicate) {
return accumulator.concat([current]);
}
return accumulator;
}, []);
this.planTotal = res.list.total
this.toggleSelection(this.paymentRegistrationForm.plan.map(item => {
return item.plan_id
}))
}
},
planPageChange(e) {
this.plansSelect.page = e
this.getBudgets()
},
selectPlan(sel, row) {
if (sel) {
let select = sel.map(item => {
return {
contract_id: this.contract.id,
plan_id: item.id,
use_money: item.use_money,
new_money: item.money,
label: item.name
}
});
//说明被删除了
if (sel.filter(plan => {
return plan.id == row.id
}).length == 0) {
this.delPlan({
plan_id: row.id
})
}
let _plan = JSON.parse(JSON.stringify(this.paymentRegistrationForm.plan));
var _select = [];
select.map(item => {
if (_plan.filter(plan => {
return plan.plan_id == item.plan_id
}).length == 0) {
_select.push(item)
}
});
this.paymentRegistrationForm.plan = [..._plan, ..._select]
} else {
this.paymentRegistrationForm.plan = []
}
},
//默认选择计划
toggleSelection(plans) {
if (plans) {
this.plans.filter(plan => {
// if (plans.includes(plan.pid)) {
// plan.use_money = this.paymentRegistrationForm.plan[plans.indexOf(plan.pid)].use_money
// return true
// }
// else{
plan.use_money = this.paymentRegistrationForm.applyMoney
// }
}).forEach(row => {
this.$refs.planTable.toggleRowSelection(row)
})
} else {
this.$refs.planTable.clearSelection()
}
},
async getAssetsFlowIds () {
let copy = deepCopy(this.flowIds)
const res = await getparameter({
number: "asset_flow_ids"
})
try {
this.flowIds = res?.detail?.map(i => {
let data = JSON.parse(i.remark)
return {
id: i.id,
name: i.value,
...data
}
})
} catch (e) {
this.flowIds = copy
}
},
//获取科室
getDepartment() {
listdeptNoAuth().then((res) => {
this.departments = res.data;
});
},
},
computed: {
moneyFormat() {
return function(money) {
return moneyFormatter(money)
}
}
},
watch: {
isShow(newVal) {
if (!newVal) {
this.paymentRegistrationForm.actMoney = ''
this.paymentRegistrationForm.moneyWay = ''
this.paymentRegistrationForm.plan = []
this.$refs.planTable.clearSelection()
}
}
},
async mounted() {
this.getDepartment()
//await this.getBudgets()
await this.getPlanTypes()
await this.getAssetsFlowIds()
}
}
</script>
<style scoped lang="scss">
.payment-registration {
&-row {
display: flex;
padding: 6px 0;
&-title {
padding: 0 10px;
}
&-content {}
}
}
.xy-table-item-label {
width: 150px;
}
.xy-table-item-price {
position: relative;
&::after {
z-index: 1;
position: absolute;
right: 0;
top: 0;
content: ''
}
::v-deep .el-input__clear {
position: relative;
right: 30px;
z-index: 2;
}
}
</style>
<style>
.el-cascader-panel li[aria-haspopup] .el-checkbox{
display:none;
}
</style>