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.

1752 lines
53 KiB

<template>
<div ref="contractList" style="padding: 0 20px;">
<lx-header icon="md-apps" style="margin-bottom: 10px; border: 0px; margin-top: 15px" text="合同列表">
<div slot="content"></div>
<slot>
<div class="selects">
<div>
<span style="padding: 0 6px;word-break: keep-all;">关键字</span>
<span>
<Input v-model="select.keyword" clearable placeholder="关键字搜索" style="width: 200px"/>
</span>
</div>
<div>
<span style="padding: 0 6px;word-break: keep-all;">服务商/供应商</span>
<span>
<Input v-model="select.supply" clearable placeholder="请输入服务商/供应商" style="width: 200px"/>
</span>
</div>
<div>
<span style="padding: 0 6px;word-break: keep-all;">预算计划</span>
<span>
<Input v-model="select.plan_name" clearable placeholder="请选择预算计划" @on-focus="showPlanForSearch"
style="width: 200px" @on-clear="clearSelectForSearch"/>
</span>
</div>
<div>
<span style="padding: 0 6px;word-break: keep-all;">签订年份</span>
<span>
<DatePicker :value="select.year" placeholder="选择年份" placement="bottom" style="width: 90px;"
type="year"
@on-change="(e)=>select.year = e"></DatePicker>
</span>
</div>
<div>
<span style="padding: 0 6px;word-break: keep-all;">创建日期</span>
<span>
<DatePicker v-model="select.showDatePicker" clearable placeholder="请选择日期" placement="bottom-start"
style="width: 200px" type="daterange" @on-change="datePick"></DatePicker>
</span>
</div>
<div>
<span style="padding: 0 6px;word-break: keep-all;">
项目类型
</span>
<Select v-model="select.type" clearable placeholder="请选择项目类型" style="width:140px;">
<Option v-for="item in type" :key="item.value" :value="item.value">{{ item.label }}</Option>
</Select>
</div>
<div>
<span style="padding: 0 6px;word-break: keep-all;">
业务科室
</span>
<el-select v-model="select.department_id" clearable placeholder="业务科室选择" size="small"
style="width: 120px;">
<el-option v-for="item in departments" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
</div>
<div>
<span style="padding: 0 6px;word-break: keep-all;">
采购形式
</span>
<Select v-model="select.purchase_type_id" clearable placeholder="请选择采购形式" style="width:140px;">
<Option v-for="item in purchaseType" :key="item.id" :value="item.id">{{ item.value }}</Option>
</Select>
</div>
<div>
<span style="padding: 0 6px;word-break: keep-all;">
采购方式
</span>
<Select v-model="select.purchase_way_id" clearable placeholder="请选择采购方式" style="width:200px;">
<Option v-for="item in purchaseWay" :key="item.id" :value="item.id">{{ item.value }}</Option>
</Select>
</div>
<div>
<span style="padding: 0 6px;word-break: keep-all;">
预算金额
</span>
<InputNumber v-model="select.start_plan_price" :min="0" placeholder="最小金额" style="width: 100px;"/>
<span style="padding: 0 5px;">-</span>
<InputNumber v-model="select.end_plan_price" :min="0" placeholder="最大金额" style="width: 100px;"/>
</div>
<div>
<span style="padding: 0 6px;word-break: keep-all;">
合同状态
</span>
<Select v-model="select.status" clearable placeholder="请选择" style="width:100px;">
<Option v-for="item in [{label:'待签订',value:1},{label:'已签订',value:2}]" :key="item.value"
:value="item.value">{{ item.label }}
</Option>
</Select>
</div>
<div>
<span style="padding: 0 6px;word-break: keep-all;">
招标流程状态
</span>
<Select v-model="select.invite_status" clearable placeholder="请选择" style="width:100px;">
<Option v-for="item in options" :key="item.value" :value="item.value">{{ item.label }}
</Option>
</Select>
</div>
<div>
<span style="padding: 0 6px;word-break: keep-all;">
采购流程状态
</span>
<Select v-model="select.purchase_status" clearable placeholder="请选择" style="width:100px;">
<Option v-for="item in options" :key="item.value" :value="item.value">{{ item.label }}
</Option>
</Select>
</div>
<div>
<span style="padding: 0 6px;word-break: keep-all;">
合同会签状态
</span>
<Select v-model="select.join_status" clearable placeholder="请选择" style="width:100px;">
<Option v-for="item in options" :key="item.value" :value="item.value">{{ item.label }}
</Option>
</Select>
</div>
<div>
<span style="padding: 0 6px;word-break: keep-all;">
请示流程状态
</span>
<Select v-model="select.req_status" clearable placeholder="请选择" style="width:100px;">
<Option v-for="item in options" :key="item.value" :value="item.value">{{ item.label }}
</Option>
</Select>
</div>
<Button style="margin-left: 10px" type="primary" @click="isShowAdd = true">新增</Button>
<Button style="margin-left: 10px" type="primary" @click="getContracts">查询</Button>
<Button ghost style="margin-left: 10px" type="primary"
@click=" select = {showDatePicker:'',ageIndex:1,startDate:'',endDate:'',type:'',department:'',purchaseModality:'',purchaseMethods:'',priceMin:null,priceMax:null,status:''}">
重置
</Button>
<Button type="primary" @click="toExport()" style="margin-left: 10px">导出</Button>
<!-- <Button type="primary" style="margin-left: 10px">导出</Button>-->
</div>
</slot>
</lx-header>
<xy-table ref="xyTable" :cell-style="cellStyle" :list="list" :show-summary="true" :summary-method="summary"
:table-item="table" @cellClick="showPaymentPlan" @delete="(row)=>deleteContract(row.id)" @editor="">
<template v-slot:btns>
<el-table-column fixed="right" header-align="center" label="操作" width="200">
<template slot-scope="scope">
<div class="slot-btns">
<template v-if="scope.row.status === 2&&scope.row.is_end===0">
<block v-if="scope.row.is_assurance==1">
<!-- 如果是 履约文件-->
<block v-if="scope.row.assurance_status==1">
<!-- 那么必须财务审核通过-->
<Button class="slot-btns-item" size="small" type="primary"
@click="$refs['paymentRegistration'].getContract(scope.row),$refs['paymentRegistration'].isShowPaymentRegistration = true">
付款登记
</Button>
</block>
</block>
<block v-else>
<Button class="slot-btns-item" size="small" type="primary"
@click="$refs['paymentRegistration'].getContract(scope.row),$refs['paymentRegistration'].isShowPaymentRegistration = true">
付款登记
</Button>
</block>
</template>
<template v-if="scope.row.status === 1 && scope.row.join_status === 3">
<Button class="slot-btns-item" size="small" type="primary"
@click="$refs['contractSign'].isShow = true,$refs['contractSign'].contractId = scope.row.id">
签订合同
</Button>
</template>
<template
v-if="scope.row.invite_status === 1 && scope.row.purchase_status === 3 && scope.row.purchase_way.remark === 'true' && !scope.row.is_substitute">
<Button class="slot-btns-item" size="small" type="primary" @click="bidding(scope.row)">招标审查</Button>
</template>
<!-- <Button class="slot-btns-item" type="primary" size="small">附件管理</Button>-->
<template v-if="scope.row.req_status === 1 && scope.row.is_plan === 0 && !scope.row.is_substitute">
<Button class="slot-btns-item" size="small" type="primary" @click="askProcess(scope.row)">请示流程
</Button>
</template>
<template
v-if="(scope.row.join_status === 1 && ((scope.row.invite_status === 3)||(scope.row.purchase_way.remark === 'false' && scope.row.purchase_status === 3)) || ( scope.row.is_substitute && scope.row.join_status === 1) ) ">
<Button class="slot-btns-item" size="small" type="primary" @click="signProcess(scope.row)">合同会签
</Button>
</template>
<template
v-if="scope.row.purchase_status === 1 && ((scope.row.req_status === 3 && scope.row.is_plan === 0)||scope.row.is_plan === 1)&& !scope.row.is_substitute ">
<Button class="slot-btns-item" size="small" type="primary" @click="buyProcess(scope.row)">采购流程
</Button>
</template>
<Poptip trigger="hover" placement="bottom" transfer>
<Button ghost size="small" type="primary">更多</Button>
<div slot="content">
<template
v-if="!(scope.row.req_status != 1 || scope.row.join_status != 1 || scope.row.invite_status != 1 || scope.row.purchase_status != 1 || scope.row.status === 2)">
<Poptip :transfer="true" confirm placement="bottom" title="确认要删除吗"
@on-ok="()=>deleteContract(scope.row.id)">
<i-button class="slot-btns-item" ghost size="small" type="error">删除
</i-button>
</Poptip>
</template>
<Button class="slot-btns-item" size="small" type="primary"
@click="$refs['detailContract'].getDetail(scope.row.id),$refs['detailContract'].isShowDetail = true">
查看
</Button>
<template v-if="scope.row.status != 2||hasEdit">
<Button class="slot-btns-item" size="small" type="primary"
@click="$refs['editor'].isShowEditor = true,$refs['editor'].getDetail(scope.row.id)">编辑
</Button>
</template>
<template v-if="hasEdit&&scope.row.status === 2">
<Button class="slot-btns-item" size="small" type="primary"
@click="$refs['contractSign'].isShow = true,$refs['contractSign'].contractId = scope.row.id">
签订修改
</Button>
</template>
</div>
</Poptip>
</div>
</template>
</el-table-column>
</template>
</xy-table>
<div style="display: flex;justify-content: flex-end;">
<Page :total="total" show-elevator @on-change="pageChange" show-sizer @on-page-size-change="pageSizeChange"/>
</div>
<!-- 新增合同 -->
<xy-dialog ref="addContract" :form="form" :is-show.sync="isShowAdd" :rules="rules" title="新增合同" type="form"
@submit="submit">
<template v-slot:name>
<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 v-model="form.name" @change="checkName" placeholder="请填写项目名称" style="width: 300px;"/>
</div>
</div>
</template>
<template v-slot:is_simple>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;font-size: 11px;">*是否为简易流程(水电煤、报刊订阅、网络通讯、车辆使用等费用付款)</span>
</div>
<div class="xy-table-item-content">
<el-switch v-model="form.is_simple" active-text="是" inactive-text="否" :active-value="1" :inactive-value="0"/>
</div>
</div>
</template>
<template v-slot:supply v-if="form.is_simple">
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;font-size: 11px;">*</span>承包商/供货商
</div>
<div class="xy-table-item-content">
<el-input v-model="form.supply" placeholder="请填写承包商/供货商" style="width: 300px;"/>
</div>
</div>
</template>
<template v-slot:type v-if="!form.is_simple">
<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-select v-model="form.type" placeholder="请选择项目类型" style="width: 300px;">
<el-option v-for="item in type" :label="item.label" :value="item.value"></el-option>
</el-select>
</div>
</div>
</template>
<template v-slot:methods v-if="!form.is_simple">
<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-select v-model="form.methods" placeholder="请选择采购形式" style="width: 300px;">
<el-option v-for="item in purchaseType" :label="item.value" :value="item.id"></el-option>
</el-select>
</div>
</div>
</template>
<template v-slot:modality v-if="!form.is_simple">
<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-select v-model="form.modality" placeholder="请选择采购类型" style="width: 300px;">
<el-option v-for="item in purchaseWay" :label="item.value" :value="item.id"></el-option>
</el-select>
</div>
</div>
</template>
<template v-slot:price v-if="!form.is_simple">
<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 v-model="form.price" placeholder="请填写合同预算价" style="width: 300px;"/>
</div>
</div>
</template>
<template v-slot:fundingChannels>
<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-select v-model="form.fundingChannels" multiple placeholder="请选择资金渠道" style="width: 300px;">
<el-option v-for="item in moneyWay" :label="item.value" :value="item.id"></el-option>
</el-select>
</div>
</div>
</template>
<template v-slot:isBudget>
<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="form.isBudget"/>
</div>
</div>
</template>
<template v-slot:is_substitute>
<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="form.is_substitute" active-text="是" inactive-text="否" :active-value="1"
:inactive-value="0"/>
</div>
</div>
</template>
<template v-slot:plan>
<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">
<div class="contract-add-plan" style="width: 300px;" @click="showPlan">
<template v-if="form.plan.length > 0">
<template v-for="item in form.plan">
<Tag closable color="primary" @on-close="delPlan(item)">{{ item.label }}</Tag>
</template>
</template>
<template v-else>
<div class="contract-add-plan-no-plan">请选择关联计划</div>
</template>
</div>
</div>
</div>
</template>
</xy-dialog>
<!-- 搜索使用 预算计划 -->
<xy-dialog :is-show.sync="isShowPlanForSearch" title="预算计划" :width="720" @on-ok="planSelectForSearch">
<template v-slot:normalContent>
<Input v-model="planSearch.name" search enter-button="搜 索" placeholder="搜索预算计划.."
@on-search="searchBudgets"/>
<div style="margin: 10px 0;display: flex;justify-content: space-between;
align-items: center;">
<div>已选择:<span style="margin-right:10px">{{ select.plan_name }}</span></div>
<el-link type="success" @click="clearSelectForSearch">清空选择</el-link>
</div>
<xy-table :list="plans" @rowClick="selectPlanForSearch" :show-index="false" :table-item="planTableSearch"
:height="310" style="margin-top: 10px;" ref="singlePlanTable">
<template v-slot:btns>
</template>
</xy-table>
<div style="display: flex;justify-content: flex-end;">
<Page :total="planTotal" show-elevator @on-change="planPageChange"/>
</div>
<el-tag type="warning">点击行进行选择</el-tag>
</template>
<template v-slot:footerContent>
<Button type="primary" @click="confirmPlanForSearch">确定</Button>
</template>
</xy-dialog>
<!-- 新增表 预算计划 -->
<xy-dialog :is-show.sync="isShowPlan" :width="720" title="预算计划" @on-ok="planSelect">
<template v-slot:normalContent>
<div style="display: flex;">
<el-select placeholder="科室选择" clearable size="small" v-model="planSearch.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>
<Input v-model="planSearch.name" enter-button="搜 索" placeholder="搜索预算计划.." search
@on-search="searchBudgets"/>
</div>
<xy-table ref="planTable" :height="300" :list="plans" :show-index="false" :table-item="planTable"
style="margin-top: 10px;" @select="selectPlan">
<template v-slot:btns>
<el-table-column header-align="center" label="使用金额" fixed="right" width="140">
<template slot-scope="scope">
<Input :value="scope.row.useMoney" @input="planInput($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>
<template v-slot:footerContent>
<Button type="primary" @click="isShowPlan = false">确定</Button>
</template>
</xy-dialog>
<!-- 编辑-->
<editor ref="editor" :is-show-editor.sync="isShowEditor" :money-way="moneyWay" :purchase-type="purchaseType"
:purchase-way="purchaseWay" @success="getContracts"></editor>
<!-- 查看-->
<detail ref="detailContract"></detail>
<!--付款登记-->
<paymentRegistration ref="paymentRegistration"></paymentRegistration>
<!-- 合同签订-->
<contractSign ref="contractSign" @signSuccess="getContracts"></contractSign>
<!-- 查看付款计划-->
<contractPaymentRegistration ref="contractPaymentRegistration"></contractPaymentRegistration>
</div>
</template>
<script>
import {
getContract,
addContrant,
delContract,
checkContractName
} from "@/api/contract/contract"
import {
getparameter
} from "@/api/system/dictionary"
import {
listdeptNoAuth
} from "@/api/system/department";
import {
getBudget
} from "@/api/budget/budget"
import {
getOatoken
} from "@/api/oatoken"
import {
parseTime
} from "@/utils"
import {
Message
} from "element-ui";
import {
getInfo
} from '@/api/user.js'
import {
getToken
} from '@/utils/auth'
import editor from "./components/editorContract"
import detail from "./components/detailContract"
import paymentRegistration from "./components/paymentRegistration";
import contractSign from "@/views/contract/components/contractSign";
import contractPaymentRegistration from "@/views/contract/components/contractPaymentRegistration";
export default {
components: {
editor,
detail,
paymentRegistration,
contractSign,
contractPaymentRegistration
},
data() {
var planPass = (rule, value, callback) => {
if (this.form.isBudget) {
if (this.form.plan.length === 0) {
callback(new Error('必选'))
} else {
callback()
}
} else {
callback()
}
}
var supplyPass = (rule,value,callback) => {
if(this.form.is_simple){
if(value === ''){
callback(new Error('必填'))
}else{
callback()
}
}else{
callback()
}
}
var typePass = (rule,value,callback) => {
if(!this.form.is_simple){
if(value === ''){
callback(new Error('必填'))
}else{
callback()
}
}else{
callback()
}
}
var methodsPass = (rule,value,callback) => {
if(!this.form.is_simple){
if(value === ''){
callback(new Error('必填'))
}else{
callback()
}
}else{
callback()
}
}
var modalityPass = (rule,value,callback) => {
if(!this.form.is_simple){
if(value === ''){
callback(new Error('必填'))
}else{
callback()
}
}else{
callback()
}
}
var pricePass = (rule,value,callback) => {
if(!this.form.is_simple){
if(value === ''){
callback(new Error('必填'))
}else{
if(/^\d+(\.\d+)?$/.test(value)){
callback()
}else{
callback(new Error('必须为数字'))
}
}
}else{
callback()
}
}
return {
userList: ["liuxiangyu", "zhushulan", "admin", "jiangjiao"],
window: {
width: 0,
height: 0,
top: 0,
left: 0
},
hasEdit: false,
isShowPlanForSearch: false,
options: [{
value: "",
label: '全部'
}, {
value: 1,
label: '待申请'
}, {
value: 2,
label: '流转中'
}, {
value: 3,
label: '已办结'
}],
//搜索
select: {
keyword: '',
showDatePicker: '',
pageIndex: 1,
pageSize: 10,
startDate: "",
endDate: "",
type: "",
department_id: "",
purchaseModality: "",
purchaseMethods: "",
priceMin: null,
priceMax: null,
status: "",
year: "",
plan_id: "",
plan_name: "请选择预算计划",
start_plan_price: "",
end_plan_price: ""
},
type: [{
label: '服务',
value: 1
}, {
label: '货物',
value: 2
}, {
label: '工程',
value: 3
}],
purchaseType: [], //购买形式
purchaseWay: [], //购买方式
moneyWay: [], //资金渠道
departments: [], //部门科室
list: [], //数据
total: 0,
//表格
table: [{
label: "项目名称",
width: 380,
prop: 'name',
fixed: 'left',
align: 'left'
},
{
label: "采购形式",
width: 120,
prop: 'purchase_type.value'
},
{
label: "项目类型",
width: 120,
prop: 'type',
formatter: (cell, data, value) => {
switch (value) {
case 1:
return "服务"
break;
case 2:
return "货物"
break;
case 3:
return "工程"
break;
default:
return "未知"
}
}
},
{
label: "采购流程",
multiHd: [{
label: "请示流程",
width: 140,
prop: 'req_status',
formatter: (cell, data, value) => {
if (cell.is_substitute) {
return '无'
}
if (cell.is_plan === 1) {
return '无'
}
switch (value) {
case 1:
return "待申请"
break;
case 2:
return "流转中"
break;
case 3:
return "已办结"
break;
default:
return "异常"
break;
}
}
},
{
label: "采购业务审批流程",
width: 158,
prop: 'purchase_status',
formatter: (cell, data, value) => {
if (cell.is_substitute) {
return '无'
}
switch (value) {
case 1:
return "待申请"
break;
case 2:
return "流转中"
break;
case 3:
return "已办结"
break;
default:
return "异常"
break;
}
}
},
{
label: "招标审核流程",
width: 145,
prop: 'invite_status',
formatter: (cell, data, value) => {
if (cell.is_substitute) {
return '无'
}
if (cell.purchase_way.remark === 'false') {
return '无'
}
switch (value) {
case 1:
return "待申请"
break;
case 2:
return "流转中"
break;
case 3:
return "已办结"
break;
default:
return "异常"
break;
}
}
},
{
label: "合同会签流程",
width: 145,
prop: 'join_status',
formatter: (cell, data, value) => {
switch (value) {
case 1:
return "待申请"
break;
case 2:
return "流转中"
break;
case 3:
return "已办结"
break;
default:
return "异常"
break;
}
}
}
]
},
{
label: "采购方式",
width: 120,
prop: "purchase_way.value"
},
{
label: "资金来源",
width: 120,
customFn: (row) => {
{
return row.money_way_detail.map(item => {
return (< div> {
item.value
} < /div>)
})
}
}
},
{
label: "预算计划",
width: 320,
align: "left",
customFn: (row) => {
{
return row.plans.map(item => {
return (< div> [{
item.year
}] - {
item.name
} < /div>)
})
}
}
},
{
label: '已申请金额(元)',
prop: 'apply_money_total',
width: 140,
align: 'right',
formatter: (cell, data, value) => {
return Number(value).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, '$1,')
}
},
{
label: '已付金额(元)',
prop: 'fund_log_total',
width: 140,
align: 'right',
formatter: (cell, data, value) => {
return Number(value).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, '$1,')
}
},
{
label: '支付占比',
width: 140,
customFn: (row) => {
let per = ((((row.fund_log_total) / row.money) || 0) * 100)?.toFixed(2) || 0
return (<
div style={
{
'color': per > 110 ? 'red' : 'green'
}
}> {
per
} %
</div>
)
}
},
{
label: "合同预算价(元)",
width: 140,
prop: "plan_price",
align: 'right',
formatter: (v1, v2, value) => {
return Number(value).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, '$1,')
}
},
{
label: '合同签订价(元)',
width: 140,
prop: 'money',
align: 'right',
formatter: (cell, data, value) => {
return Number(value).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, '$1,')
}
},
{
label: "合同状态",
width: 120,
prop: "status",
formatter: (cell, data, value) => {
switch (value) {
case 1:
return "待签订"
break;
case 2:
return "已签订"
break;
default:
return "未知"
}
}
},
{
label: "结算状态",
width: 120,
prop: "is_end",
formatter: (cell, data, value) => {
return value === 0 ? "未结清" : "已结清";
}
},
{
label: '付款计划',
prop: 'sign_plan_count',
width: 120,
formatter: (cell, data, value) => {
if (value == 0) return '暂无'
return value + '期'
}
},
{
label: "供应商/服务商",
width: 220,
prop: 'supply',
align: "left"
},
{
label: "业务科室",
width: 140,
prop: 'department.name'
},
{
label: "经办人",
width: 140,
prop: 'admin.name'
},
{
label: "签订日期",
width: 160,
prop: 'date',
formatter: (cell, data, value) => {
if (value)
return parseTime(new Date(value), "{y}-{m}-{d}")
}
},
{
label: "创建日期",
width: 160,
prop: 'created_at',
formatter: (cell, data, value) => {
return parseTime(new Date(value), "{y}-{m}-{d}")
}
}
],
//总计
tableTotal: {
fundLogTotal: 0,
moneyTotal: 0,
planPriceTotal: 0
},
planTypes: [],
planTableSearch: [{
label: "分类",
prop: 'type',
formatter: (cell, data, value) => {
let res = this.moneyWay.filter(item => {
return item.id === value
})
return res[0]?.value || '未知'
}
},
{
label: "年份",
prop: 'year',
align: 'center'
},
{
label: "名称",
prop: 'name',
align: 'left'
},
{
label: "计划金额",
prop: 'money',
align: 'right',
width: 120,
customFn: (row) => {
let m1 = row.money;
let m2 = row.update_money;
return m2 == 0 ? m1 : m2;
}
}
],
planTable: [{
width: 36,
sortable: false,
type: 'selection',
fixed: "left"
},
{
label: "分类",
prop: 'type',
formatter: (cell, data, value) => {
let res = this.moneyWay.filter(item => {
return item.id === value
})
return res[0]?.value || '未知'
},
width: 100,
fixed: "left"
},
{
label: "科室",
prop: 'plan_department.name',
width: 100,
align: 'center'
},
{
label: "年份",
prop: 'year',
width: 80,
align: 'center'
},
{
label: "隶属",
prop: 'pid_info.name',
width: 180,
align: 'left'
},
{
label: "名称",
prop: 'name',
width: 320,
align: 'left'
},
{
label: "计划金额",
prop: 'money',
align: 'right',
width: 120,
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'
},
],
//新增
isShowAdd: false,
form: {
name: "",
is_simple:0,
supply: "",
type: "",
methods: "",
modality: "",
price: "",
fundingChannels: [],
isBudget: true,
plan: [],
is_substitute: 0,
},
plan: [],
rules: {
name: [{
required: true,
message: "必填"
}],
supply:[
{
validator:supplyPass,
trigger: 'change'
}
],
type:[
{
validator: typePass,
trigger: 'change'
}
],
methods:[
{
validator:methodsPass,
trigger: 'change'
}
],
modality:[
{
validator:modalityPass,
trigger: 'change'
}
],
price:[
{
validator:pricePass,
trigger: 'change'
}
],
fundingChannels: [{
required: true,
message: "必填"
}],
plan: [{
validator: planPass,
trigger: 'change'
}]
},
isShowPlan: false, //新增中预算计划
plans: [], //预算数据
planSearch: {
name: "",
plan_department_id: ""
},
planTotal: 0,
plansPageIndex: 1,
isShowEditor: false,
}
},
methods: {
toExport() {
this.select.is_export = 1;
this.getContracts(true);
},
clearSelectForSearch() {
this.select.plan_id = "";
this.select.plan_name = "请选择预算计划";
},
async getPlanTypes() {
const res = await getparameter({
number: 'money_way'
})
this.planTypes = res.detail
console.log(this.planTypes)
},
//预算计划金额输入
planInput(e, row) {
if (!/^[0-9]+.?[0-9]*$/.test(e) && e) {
Message({
type: 'warning',
message: '金额格式错误'
})
row.useMoney = 0
return
}
let money = Number(row.update_money) == 0 ? Number(row.money) : Number(row.update_money);
console.log(e, money, row.use_money_total)
console.log(e <= (money - Number(row.use_money_total)))
if (e <= (money - Number(row.use_money_total))) {
row.useMoney = e
this.plan.forEach(item => {
if (item.value.plan_id == row.id) {
item.value.use_money = e
}
})
return
}
Message({
type: 'warning',
message: '使用金额大于剩余预算'
})
row.useMoney = 0
},
//合计
summary(param) {
this.$nextTick(() => {
this.$refs['xyTable'].$children[0].doLayout()
})
const {
columns,
data
} = param
const sums = []
columns.map((column, index) => {
if (index === 0) {
sums[index] = '总计'
return
}
if (column.property === 'fund_log_total') {
sums[index] = this.tableTotal.fundLogTotal
return
}
if (column.property === 'plan_price') {
sums[index] = this.tableTotal.planPriceTotal
return
}
if (column.property === 'money') {
sums[index] = this.tableTotal.moneyTotal
return
}
// const values = data.map(item => Number(item[column.property]));
// if (!values.every(value => isNaN(value)) && (column.property === 'money' || column.property === 'plan_price'|| column.property === 'fund_log_total')) {
//
// sums[index] = sums[index].toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, '$1,')
// } else {
// sums[index] = '';
// }
})
return sums
},
cellStyle({
row,
column,
rowIndex,
columnIndex
}) {
if (column.property === 'req_status') {
if (row.is_plan === 1 || row.is_substitute) {
return {
'color': 'rgb(140,140,140)'
}
}
switch (row.req_status) {
case 1:
return {
'color': 'rgb(96,109,241)'
}
break;
case 2:
return {
'color': 'rgb(219,122,122)'
}
break;
case 3:
return {
'color': 'rgb(147,201,134)'
}
break;
default:
return {
'color': 'rgb(220,185,126)'
}
}
}
if (column.property === 'purchase_status') {
if (row.is_substitute) {
return {
'color': 'rgb(140,140,140)'
}
}
switch (row.purchase_status) {
case 1:
return {
'color': 'rgb(96,109,241)'
}
break;
case 2:
return {
'color': 'rgb(219,122,122)'
}
break;
case 3:
return {
'color': 'rgb(147,201,134)'
}
break;
default:
return {
'color': 'rgb(220,185,126)'
}
}
}
if (column.property === 'invite_status') {
if (row.purchase_way.remark === 'false' || row.is_substitute) {
return {
'color': 'rgb(140,140,140)'
}
}
switch (row.invite_status) {
case 1:
return {
'color': 'rgb(96,109,241)'
}
break;
case 2:
return {
'color': 'rgb(219,122,122)'
}
break;
case 3:
return {
'color': 'rgb(147,201,134)'
}
break;
default:
return {
'color': 'rgb(220,185,126)'
}
}
}
if (column.property === 'join_status') {
switch (row.join_status) {
case 1:
return {
'color': 'rgb(96,109,241)'
}
break;
case 2:
return {
'color': 'rgb(219,122,122)'
}
break;
case 3:
return {
'color': 'rgb(147,201,134)'
}
break;
default:
return {
'color': 'rgb(220,185,126)'
}
}
}
},
//y验证合同的名称是否存在重复
checkName(e) {
checkContractName({name: e}).then(res => {
console.log(res);
})
},
confirmPlanForSearch() {
this.isShowPlanForSearch = false;
this.getContracts();
},
//点击付款计划查看
showPaymentPlan(row, column, cell) {
if (column.property === 'sign_plan_count') {
this.$refs['contractPaymentRegistration'].getSignPlan(row.id)
row.status === 2 ? this.$refs['contractPaymentRegistration'].isSign = true : this.$refs[
'contractPaymentRegistration'].isSign = false
this.$refs['contractPaymentRegistration'].isShow = true
}
if (column.property === 'fund_log_total') {
this.$router.push(`/contract/paymentRegistrationList?contractId=${row.id}`)
}
},
//招标文件审查
async bidding(row) {
let baseInfo = {
"项目名称": row?.name,
"项目预算(元)": row?.plan_price
}
let res = await getOatoken()
let url =
`${process.env.VUE_APP_OUT_URL}/admin/flow/create/27?oatoken=${res.oatoken}&out_contract_id=${row.id}&contract_json=${JSON.stringify(baseInfo)}`
let bidding = window.open(url, 'bidding',
`top=${this.window.top},left=${this.window.left},width=${this.window.width},height=${this.window.height},location=0`
)
},
//采购流程
async buyProcess(row) {
let baseInfo = {
"项目名称": row?.name,
"采购形式": row?.purchase_type?.value,
"采购方式": row?.purchase_way?.value,
"项目类型": this.type.filter(item => {
return item.value === row.type
})[0]?.label,
"资金渠道": row?.money_way?.value,
"项目预算(元)": row?.plan_price
}
let res = await getOatoken()
let url =
`${process.env.VUE_APP_OUT_URL}/admin/flow/create/2?oatoken=${res.oatoken}&out_contract_id=${row.id}&contract_json=${JSON.stringify(baseInfo)}`
let buyProcess = window.open(url, 'buyProcess',
`top=${this.window.top},left=${this.window.left},width=${this.window.width},height=${this.window.height},location=0`
)
},
//会签流程
async signProcess(row) {
let baseInfo = {
"合同名称": row?.name,
"执行部门": row?.carry_department,
"合同金额(元)": row?.money,
//"承包商\\供应商":row.supply
}
let res = await getOatoken()
let url =
`${process.env.VUE_APP_OUT_URL}/admin/flow/create/3?oatoken=${res.oatoken}&out_contract_id=${row.id}&contract_json=${JSON.stringify(baseInfo)}`
let signProcess = window.open(url, 'signProcess',
`top=${this.window.top},left=${this.window.left},width=${this.window.width},height=${this.window.height},location=0`
)
},
//请示流程
async askProcess(row) {
let res = await getOatoken()
let url =
`${process.env.VUE_APP_OUT_URL}/admin/flow/create/17?oatoken=${res.oatoken}&out_contract_id=${row.id}`
let askProcess = window.open(url, 'askProcess',
`top=${this.window.top},left=${this.window.left},width=${this.window.width},height=${this.window.height},location=0`
)
},
//防抖
debounce(fn, delay = 500) {
let timer = null
return function _debounce() {
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
fn()
}, delay)
}
},
//翻页
pageChange(e) {
this.select.pageIndex = e
this.getContracts()
},
planPageChange(e) {
this.plansPageIndex = e
this.getBudgets()
},
//日期选择
datePick(e) {
this.select.start_created_at = e[0]
this.select.end_created_at = e[1]
},
//获取预算计划
async getBudgets() {
let res = await getBudget({
name: this.planSearch.name,
page_size: 10,
page: this.plansPageIndex,
plan_department_id: this.planSearch.plan_department_id,
top_pid: 1
})
this.plans = res.list.data
this.planTotal = res.list.total;
this.toggleSelection(this.plan.map(item => {
return item.value.plan_id
}), 1)
},
//获取资金渠道
async getMoneyWay() {
this.moneyWay = (await getparameter({
number: 'money_way'
})).detail
},
//获取购买方式
async getPurchaseWay() {
this.purchaseWay = (await getparameter({
number: 'purchase_way'
})).detail
}, //计划搜索
searchBudgets() {
this.plansPageIndex = 1;
this.getBudgets();
},
//获取科室
async getDepartment() {
this.departments = await listdeptNoAuth()
},
//获取购买形式列表
async getPurchaseType() {
this.purchaseType = (await getparameter({
number: 'purchase_type'
})).detail
},
pageSizeChange(e) {
this.select.pageSize = e;
this.select.pageIndex = 1;
this.getContracts();
},
//获取合同列表
async getContracts(is_export) {
const res = await getContract({
page_size: this.select.pageSize,
page: this.select.pageIndex,
is_auth: 1,
...this.select
})
let tokens = getToken();
if (is_export && this.select.is_export == 1) {
var url = "/api/admin/contract/index?is_auth=1&token=" + tokens
Object.keys(this.select).map((key, item) => {
url += "&" + key + "=" + this.select[key];
});
url = location.host + url;
console.log(url)
window.open("http://" + url, '_blank')
this.select.is_export = 0
return;
}
this.list = res.list.data
this.total = res.list.total
this.tableTotal.fundLogTotal = res.fund_log_total
this.tableTotal.moneyTotal = Number(res.money_total).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, '$1,')
this.tableTotal.planPriceTotal = Number(res.plan_price_total).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g,
'$1,')
},
//新建合同
//显示
async showPlan() {
this.isShowPlan = true
await this.getBudgets()
},
async showPlanForSearch() {
this.isShowPlanForSearch = true
await this.getBudgets();
},
//选择计划 搜索
selectPlanForSearch(sel) {
console.log(sel)
if (sel) {
this.select.plan_id = sel.id;
this.select.plan_name = sel.name;
} else {
this.select.plan_id = "";
this.select.plan_name = "";
}
},
//选择计划
selectPlan(sel, row) {
console.log(sel)
if (sel) {
let select = sel.map(item => {
return {
label: item.name,
value: {
plan_id: item.id,
use_money: item.useMoney,
new_money: item.money
}
}
})
//说明被删除了
if (sel.filter(plan => {
return plan.id == row.id
}).length == 0) {
this.delPlan({
value: {
plan_id: row.id
}
})
}
let _plan = JSON.parse(JSON.stringify(this.plan));
var _select = [];
select.map(item => {
if (_plan.filter(plan => {
return plan.value.plan_id == item.value.plan_id
}).length == 0) {
_select.push(item)
}
});
this.plan = [..._plan, ..._select]
} else {
this.plan = []
}
},
//确认计划选择
planSelect() {
if (this.plan.length === 0) {
Message({
type: 'warning',
message: '选择计划不能为空'
})
return
}
for (let item of this.plan) {
console.log(item)
if (!item.value.use_money) {
Message({
type: 'warning',
message: '金额不能为空'
})
return
}
}
this.form.plan = this.plan
this.isShowPlan = false
},
delPlan(val) {
this.form.plan.map((item, index) => {
if (item.value.plan_id === val.value.plan_id) {
this.form.plan.splice(index, 1)
}
})
this.plan.map((item, index) => {
if (item.value.plan_id === val.value.plan_id) {
this.plan.splice(index, 1)
}
})
},
//确认计划选择搜索
planSelectForSearch() {
if (this.select.plan_id == "") {
Message({
type: 'warning',
message: '选择计划不能为空'
})
return
}
this.isShowPlanForSearch = false
},
//默认选择计划
toggleSelection(plans, type) {
if (plans) {
this.plans.filter(plan => {
if (plans.includes(plan.id)) {
plan.useMoney = this.plan[plans.indexOf(plan.id)].value.use_money
return true
}
}).map(row => {
this.$refs.planTable.toggleRowSelection(row)
})
} else {
this.$refs.planTable.clearSelection()
}
},
//提交新建
submit() {
addContrant({
type: this.form.type,
is_plan: this.form.isBudget ? 1 : 0,
purchase_type_id: this.form.methods,
purchase_way_id: this.form.modality,
money_way_id: `${this.form.fundingChannels.toString()}`,
plan_price: this.form.price,
name: this.form.name,
contract_plan_links: this.form.plan.map(item => {
return item.value
}),
is_substitute: this.form.is_substitute,
is_simple:this.form.is_simple,
supply:this.form.supply
}).then(res => {
this.isShowAdd = false
Message({
type: 'success',
message: '操作成功'
})
this.$refs['addContract'].reset()
this.$refs['planTable'].clearSelection()
this.getContracts()
})
},
//删除合同
deleteContract(id) {
delContract({
id
}).then(res => {
Message({
type: 'success',
message: '操作成功'
})
this.getContracts()
})
},
},
mounted() {
this.window.width = screen.availWidth * 0.95
this.window.height = screen.availHeight * 0.95
this.window.top = (window.screen.height - 30 - this.window.height) / 2
this.window.left = (window.screen.width - 10 - this.window.width) / 2
let that = this;
getInfo().then(response => {
console.log(response)
this.user = response;
if (that.userList.indexOf(response.username) != -1) {
that.hasEdit = true;
}
}).catch(error => {
})
this.getPurchaseType()
this.getContracts()
this.getDepartment()
this.getPurchaseWay()
this.getMoneyWay()
//页面激活后刷新合同列表
window.onfocus = () => {
this.getContracts()
}
},
destroyed() {
window.onfocus = null
}
}
</script>
<style lang="scss" scoped>
.selects {
display: flex;
flex-wrap: wrap;
& > div {
margin-bottom: 6px;
}
}
.selectTop {
margin-top: 10px;
}
.contract-add-plan {
min-height: 30px;
border: 1px solid #dcdee2;
border-radius: 4px;
display: flex;
flex-wrap: wrap;
align-items: center;
align-content: center;
padding: 0 8px;
&-no-plan {
height: 30px;
line-height: 30px;
color: #CDD0D5;
}
}
.slot-btns {
display: flex;
flex-wrap: wrap;
align-content: center;
justify-content: flex-start;
&-item {
margin: 0 6px 4px 0;
}
}
.xy-table-item-label {
width: 200px;
}
.xy-table-item-price {
position: relative;
&::after {
position: absolute;
right: 0;
top: 0;
content: '(元)'
}
}
</style>