Files
income_payments_client/src/views/packManagement/PackProjectMaintenance.vue
T

601 lines
20 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div>
<page-header-title :is-level-one="false" :img-for-icon="IconImg"
:level-two-title="$route.query.packCompanyName"></page-header-title>
<a-card :bordered="false">
<!-- 企业信息-->
<div class="part-title">
<div class="part-title-text">企业信息</div>
</div>
<div class="company-detail">
<div class="company-detail-item company-detail-item-small"
v-for="(item, index) in companyDataField"
:key="index">
<div class="company-detail-item-title">{{ item.title }}</div>
<div class="company-detail-item-content">{{ companyDataById[item.dataIndex] }}</div>
</div>
<div class="company-detail-item">
<div class="company-detail-item-title">打包费用说明</div>
<div class="company-detail-item-content">{{ companyDataById.packChargeRemark }}</div>
</div>
<div class="company-detail-item">
<div class="company-detail-item-title">备注</div>
<div class="company-detail-item-content">{{ companyDataById.remark }}</div>
</div>
</div>
<!-- /企业信息-->
<a-divider></a-divider>
<!-- 项目信息-->
<div class="part-title">
<div class="part-title-text">项目信息</div>
</div>
<!-- 查询区域-start -->
<div class="table-page-search-wrapper">
<a-form layout="inline" @keyup.enter.native="searchQuery">
<a-row>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="项目名称" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input placeholder="请输入项目名称" v-model="queryParam.projectName" :maxLength='50'></a-input>
</a-form-item>
</a-col>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="来款年份" :labelCol="labelCol" :wrapperCol="wrapperCol">
<j-year-date style="width:100%" placeholder="请选择来款年份" v-model="queryParam.paymentDate"></j-year-date>
</a-form-item>
</a-col>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="运行年份" :labelCol="labelCol" :wrapperCol="wrapperCol">
<j-year-date style="width:100%" placeholder="请选择运行年份" v-model="queryParam.year"></j-year-date>
</a-form-item>
</a-col>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<span class="table-page-search-submitButtons">
<a-button type="primary" icon="search" @click="searchQuery" v-has="'packProject:search'">查询</a-button>
<a-button icon="reload" @click="searchReset" class="reset-button">重置</a-button>
</span>
</a-col>
</a-row>
</a-form>
</div>
<!-- /查询区域-->
<!-- 操作按钮区域-->
<div class="table-operator">
<a-button type="primary" icon="plus" @click="handlePack" v-has="'packProject:pack'">打包</a-button>
<a-button type="danger" icon="close-circle" @click="batchCancelPack" v-has="'packProject:batchCancelPack'">
批量取消打包
</a-button>
<a-button type="primary" icon="pay-circle" @click="batchIncomePayment" v-has="'packProject:batchIncomePayment'">
批量来款
</a-button>
<a-button type="primary" icon="file-text" @click="batchInvoicing" v-has="'packProject:batchInvoicing'">批量开票
</a-button>
<a-button type="primary" icon="export" @click="handleExportXls('打包项目列表')" v-has="'packProject:export'">导出
</a-button>
</div>
<!-- 操作按钮区域-end-->
<!-- table表格区域-->
<div>
<a-table
ref="table"
size="middle"
bordered
rowKey="id"
:columns="columns"
:scroll="{x: 1000}"
:dataSource="dataSource"
:pagination="false"
:loading="loading"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
@change="handleTableChange"
class="j-table-force-nowrap">
<!-- 项目名称-->
<template slot="projectName" slot-scope="text, record">
<j-ellipsis :value="text" :length="18" class="primary-color" @click="openDetailModal(record)"></j-ellipsis>
</template>
<template slot="text" slot-scope="text">
<j-ellipsis :value="text" :length="18"></j-ellipsis>
</template>
<!-- 打包需要发票到账开票邮寄状态-->
<template slot="status" slot-scope="text,record">
<status-slot :statu-obj="record" :status-no="text" :status-type="true"></status-slot>
</template>
<!-- 开票-->
<template slot="status-bill" slot-scope="text,record">
<status-slot :statu-obj="record" :status-no="text" :status-type="true" status-key="bill"></status-slot>
</template>
<!-- 邮寄-->
<template slot="status-mail" slot-scope="text,record">
<status-slot :statu-obj="record" :status-no="text" :status-type="true" status-key="mail"></status-slot>
</template>
<template slot="status-pack" slot-scope="text,record">
<status-slot :statu-obj="record" :status-no="text"></status-slot>
</template>
<span slot="action" class="action-span-cell" slot-scope="text, record">
<a @click="incomePayment(record)" :disabled="Number(record.receivableAmount) === 0"
v-has="'packProject:incomePayment'">来款</a>
<a @click="cancelPack(record.id)" v-has="'packProject:cancelPack'">取消打包</a>
<a @click="invoicing(record)" :disabled="record.needInvoice === 0 || Number(record.receivableAmount) === 0"
v-has="'packProject:invoicing'">开票</a>
</span>
</a-table>
</div>
<!-- /项目信息-->
</a-card>
<!-- 打包-->
<pack-project-select-project-module
:visible.sync="selectPackProjectVisible"
:pack-id="companyDataById.id"
@ok="modalFormOk"></pack-project-select-project-module>
<!-- 批量来款-->
<batch-income-payment-module
ref="batchIncomePaymentModal"
:table-data="selectedProject"
:visible.sync="incomeVisible"
@ok="modalFormOk"></batch-income-payment-module>
<!-- 批量开票-->
<batch-invoicing-module
ref="batchInvoicingModal"
:selected-data="selectedProject"
:visible.sync="batchInvoicingVisible"
:pack-contact-id="companyDataById.packContactId"
@ok="modalFormOk"></batch-invoicing-module>
<!-- 来款阶段-->
<arrive-stage-module
ref="arriveStage"
:project-type="selectProjectType"
:project-id="selectProjectId"
:visible.sync="arriveStageVisible"
@ok="modalFormOk"></arrive-stage-module>
<!-- 开票阶段-->
<invoicing-stage-module
ref="invoicingStage"
:visible.sync="invoicingStageVisible"
:mail-contacts-id="companyDataById.packContactId"
:project-id="selectProjectId"
:project-type="selectProjectType"
:project-name="selectProjectName"
@ok="modalFormOk"></invoicing-stage-module>
<!-- 项目详情-->
<project-detail-modal ref="projectDetail"></project-detail-modal>
</div>
</template>
<script>
import IconImg from '@/assets/imgs/icon/icon_pack_project_maintenance.png'
import PageHeaderTitle from '../../components/layouts/PageHeaderTitle'
import { JeroListMixin } from '../../mixins/JeroListMixin'
import JYearDate from '../../components/jero/JYearDate'
import StatusSlot from '../../components/tools/StatusSlot'
import PackProjectSelectProjectModule from './modules/PackProjectSelectProjectModule'
import BatchIncomePaymentModule from './modules/BatchIncomePaymentModule'
import BatchInvoicingModule from './modules/BatchInvoicingModule'
import ArriveStageModule from '../financialManagement/arriveAndInvoicing/modules/ArriveStageModule'
import InvoicingStageModule from '../financialManagement/arriveAndInvoicing/modules/InvoicingStageModule'
import { getPackCompanyById, batchRemovePackProject, removePackProject } from '../../api/incomePaymentsApi'
import ProjectDetailModal from '../../components/ProjectDetailModal'
export default {
name: 'PackProjectMaintenance',
components: {
PageHeaderTitle,
JYearDate,
StatusSlot,
PackProjectSelectProjectModule,
BatchIncomePaymentModule,
BatchInvoicingModule,
ArriveStageModule,
InvoicingStageModule,
ProjectDetailModal
},
mixins: [JeroListMixin],
data() {
return {
IconImg,
// 企业信息名称字段对应
companyDataField: [
{
title: '企业名称',
dataIndex: 'companyTemporaryName'
}, {
title: '企业联系人',
dataIndex: 'companyContactTemporaryName'
}, {
title: '手机号',
dataIndex: 'phone'
}, {
title: '邮箱',
dataIndex: 'email'
}, {
title: '打包费用总计',
dataIndex: 'packChargeTotal'
}, {
title: '实际到账费用',
dataIndex: 'receiptExpense'
}, {
title: '已开票金额',
dataIndex: 'invoiceAmount'
}, {
title: '已来款未开票金额',
dataIndex: 'uninvoicedAmount'
}, {
title: '打包年份',
dataIndex: 'packYear'
}
],
// 通过id获取的企业信息
companyDataById: {},
labelCol: {
xs: { span: 24 },
sm: { span: 5 }
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 10 }
},
columns: [
{
title: '序号',
dataIndex: '',
key: 'rowIndex',
width: 60,
align: 'center',
customRender: function (t, r, index) {
return parseInt(index) + 1
}
}, {
title: '打包项目名称',
align: 'center',
width: 280,
dataIndex: 'chargeProject',
scopedSlots: { customRender: 'projectName' }
}, {
title: '项目负责人',
align: 'center',
width: 140,
dataIndex: 'principalName',
scopedSlots: { customRender: 'text' }
}, {
title: '应收金额',
align: 'center',
width: 120,
dataIndex: 'receivableAmount'
}, {
title: '实收金额',
align: 'center',
width: 120,
dataIndex: 'paidAmount'
}, {
title: '打包',
align: 'center',
width: 80,
dataIndex: 'pack',
scopedSlots: { customRender: 'status-pack' }
}, {
title: '需要发票',
align: 'center',
width: 80,
dataIndex: 'needInvoice',
scopedSlots: { customRender: 'status-pack' }
}, {
title: '到账',
align: 'center',
width: 80,
dataIndex: 'inAccount',
scopedSlots: { customRender: 'status' }
}, {
title: '开票',
align: 'center',
width: 80,
dataIndex: 'makeInvoice',
scopedSlots: { customRender: 'status-bill' }
}, {
title: '邮寄',
align: 'center',
width: 80,
dataIndex: 'mail',
scopedSlots: { customRender: 'status-mail' }
}, {
title: '企业联系人',
align: 'center',
width: 280,
dataIndex: 'contactsTemporaryName',
scopedSlots: { customRender: 'text' }
}, {
title: '联系人电话',
align: 'center',
width: 160,
dataIndex: 'phone',
scopedSlots: { customRender: 'text' }
}, {
title: '联系人邮箱',
align: 'center',
width: 200,
dataIndex: 'email',
scopedSlots: { customRender: 'text' }
}, {
title: '操作',
dataIndex: 'action',
align: 'center',
fixed: 'right',
width: 180,
scopedSlots: { customRender: 'action' }
}
],
disableMixinCreated: true,
selectPackProjectVisible: false,
selectedProject: [], // 选中的项目
batchInvoicingVisible: false, // 批量开票对话框开启状态
incomeVisible: false, // 批量来款对话框开启状态
arriveStageVisible: false, // 来款阶段对话框开启状态
invoicingStageVisible: false, // 开票阶段对话框开启状态
selectProjectId: null, // 选中项目id
selectProjectType: null, // 选中项目类型
selectProjectName: null, // 选中项目名称
selectProjectChargeCompanyName: null, // 选中项目来款企业
url: {
list: '/pack/payPackCompanyProject/listAll',
exportXlsUrl: '/pack/payPackCompanyProject/exportXls'
}
}
},
created() {
this.loadCompanyDetail().then(() => {
this.filters.packId = this.companyDataById.id
this.loadData()
})
},
methods: {
/**
* 获取企业信息
*/
loadCompanyDetail() {
let param = {
id: this.$route.query.packCompanyId
}
return new Promise(resolve => {
getPackCompanyById(param).then(res => {
if (res.success) {
this.companyDataById = res.result
resolve()
} else {
this.$message.warn(res.message)
}
})
})
},
/**
* 添加打包项目
*/
handlePack() {
this.selectPackProjectVisible = true
},
/**
* 批量取消打包
*/
batchCancelPack() {
if (this.selectedRowKeys.length === 0) {
this.$message.warn('请至少选中一个项目')
return
}
let that = this
this.$confirm({
title: '确认取消打包',
content: '确定要取消选中项目的打包状态吗?',
onOk: function () {
let param = {
packId: that.companyDataById.id,
packProjectIds: that.selectedRowKeys.join(',')
}
batchRemovePackProject(param).then(res => {
if (res.success) {
that.$message.success(res.message)
// 判断当前删除的数据是否是最后一页的全部数据,如果是的话页码减一
if (that.ipagination.current > 1 && (that.ipagination.current === Math.ceil(that.ipagination.total / that.ipagination.pageSize)) &&
that.selectedRowKeys.length === that.dataSource.length
) {
that.ipagination.current -= 1
}
that.loadData()
that.onClearSelected()
} else {
that.$message.warn(res.message)
}
})
}
})
},
/**
* 批量来款
*/
batchIncomePayment() {
this.selectedProject = []
if (this.selectedRowKeys.length === 0) {
this.$message.warn('请选择至少一个项目')
return
}
this.getProjectListBySelectedKeys(this.selectedRowKeys, 'incomePayment').then(res => {
this.selectedProject = res
this.incomeVisible = true
}).catch(message => {
this.$message.warn(message)
}).finally(() => {
this.onClearSelected()
})
},
/**
* 批量开票
*/
batchInvoicing() {
this.selectedProject = []
if (this.selectedRowKeys.length === 0) {
this.$message.warn('请选择至少一个项目')
return
}
this.getProjectListBySelectedKeys(this.selectedRowKeys, 'invoic').then(res => {
this.selectedProject = res
this.batchInvoicingVisible = true
}).catch((message) => {
this.$message.warn(message)
}).finally(() => {
this.onClearSelected()
})
},
/**
* 取消打包
* @param id
*/
cancelPack(id) {
let that = this
this.$confirm({
title: '确认取消打包',
content: '确定要取消该项目的打包状态吗?',
onOk: function () {
let param = {
id: id,
packId: that.companyDataById.id
}
removePackProject(param).then(res => {
if (res.success) {
that.$message.success(res.message)
// 判断当前删除的数据是否是最后一页的最后一条数据,如果是的话页码减一
if (that.ipagination.current > 1 && ((that.ipagination.current - 1) * that.ipagination.pageSize) + 1 === that.ipagination.total) {
that.ipagination.current -= 1
}
that.loadData()
that.onClearSelected()
} else {
that.$message.warn(res.message)
}
})
}
})
},
/**
* 来款
* @param record
*/
incomePayment(record) {
this.selectProjectId = record.id
this.arriveStageVisible = true
this.selectProjectType = record.projectType
},
/**
* 开票
* @param record
*/
invoicing(record) {
if (record.projectType === 5 && record.inAccount !== 1) {
this.$message.warn('标协会员项目必须先到账才可开票。')
return
}
this.selectProjectName = record.chargeProject
this.selectProjectId = record.id
this.selectProjectType = record.projectType
this.selectProjectChargeCompanyName = this.companyDataById.companyTemporaryName
this.invoicingStageVisible = true
},
/**
* 通过选中项目id获取数据,并进行相应提示
* @param selectedKeys
* @param operateType
* @returns {Promise<unknown>}
*/
getProjectListBySelectedKeys(selectedKeys, operateType) {
return new Promise((resolve, reject) => {
let arr = []
arr = this.dataSource.filter(tt => selectedKeys.indexOf(tt.id) > -1)
// 开票
if (operateType === 'invoic') {
// 是否存在不需要发票的项目
if (arr.some(item => item.needInvoice === 0 || Number(item.receivableAmount) === 0)) {
reject('存在不需要发票的项目!')
}
if (arr.some(item => item.makeInvoice === 1)) {
reject('存在已完成开票的项目!')
}
// 是否选中了标协会员项目,标协会员项目只能到账一次、开票一次,前端进行是否完全到账的限制
if (arr.some(item => item.projectType === 5)) {
// 标协会员项目是否完全到账
if (arr.some(item => item.inAccount !== 1)) {
reject('标协会员项目必须先到账才可开票。')
}
}
}
// 来款
if (operateType === 'incomePayment') {
// 是否存在应收金额为0的项目
if (arr.some(item => Number(item.receivableAmount) === 0)) {
reject('存在应收金额为0的项目!')
}
if (arr.some(item => item.inAccount === 1)) {
reject('不可选择已付全款的项目!')
}
}
resolve(arr)
})
}
}
}
</script>
<style scoped lang="less">
@import '~@assets/less/common.less';
.company-detail {
display: flex;
flex-wrap: wrap;
padding-bottom: 20px;
&-item-small {
width: 33.3% !important;
}
&-item {
display: flex;
padding: 5px 5px;
width: 100%;
font-size: 14px;
&-title {
flex-shrink: 0;
color: #999999;
}
&-content {
word-break: break-all;
color: #2F3133;
}
&-filename {
cursor: pointer;
color: #069f99;
}
}
}
.ant-divider-horizontal {
height: 1px;
background-color: #F2F2F2;
margin: 15px 0px;
}
</style>