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.

669 lines
20 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 :is-show.sync="isShow" title="合同签订" type="form" :form="form" :rules="rules" @submit="sign" ok-text="">
<template v-slot:extraFormTop>
<div class="base-info" style="margin-bottom: 20px;">
<div class="base-info-title">合同信息</div>
<div class="base-info-item">
<div class="base-info-item-title">合同名称</div>
<div class="base-info-item-content">{{contract.name}}</div>
</div>
</div>
</template>
<template #is_contract>
<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 disabled v-model="form.is_contract" active-text="是" inactive-text="否" :active-value="1" :inactive-value="0" style="width: 300px;" />
</div>
</div>
</template>
<template v-slot:number>
<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 placeholder="请填写合同编号" v-model="form.number" style="width: 300px;" />
</div>
</div>
</template>
<template #content>
<div class="xy-table-item">
<div class="xy-table-item-label" style="width: 200px">
合同主要内容
</div>
<div class="xy-table-item-content">
<el-input v-model="form.content" style="width: 300px" type="textarea" :autosize="{ minRows: 2 }" placeholder="请输入合同主要内容"></el-input>
</div>
</div>
</template>
<template v-slot:supply>
<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 placeholder="请填写承包商\供应商" v-model="form.supply" style="width: 300px;" />
</div>
</div>
</template>
<template v-slot:carryDepartment>
<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 placeholder="请填写执行部门" v-model="form.carryDepartment" style="width: 300px;" />
</div>
</div>
</template>
<template v-slot:money>
<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-number :controls="false" :precision="2" placeholder="请填写合同金额" v-model="form.money" style="width: 300px;" />
</div>
</div>
</template>
<template v-slot:time>
<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-date-picker style="width: 300px;" value-format="yyyy-MM-dd" v-model="form.time" type="daterange"
range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期">
</el-date-picker>
</div>
</div>
</template>
<template v-slot:is_assurance>
<div class="xy-table-item">
<div class="xy-table-item-label" style="width: 200px">是否收取履约保函
</div>
<div class="xy-table-item-content">
<el-switch v-model="form.is_assurance" />
</div>
</div>
</template>
<template v-if="form.is_assurance" v-slot:assurance_money>
<div class="xy-table-item">
<div class="xy-table-item-label" style="width: 200px">保函金额
</div>
<div class="xy-table-item-content xy-table-item-price">
<el-input-number v-model="form.assurance_money" :controls="false" :precision="2" placeholder="请输入保函金额" style="width: 300px;"></el-input-number>
</div>
</div>
</template>
<template v-if="form.is_assurance" v-slot:assurance_expire>
<div class="xy-table-item">
<div class="xy-table-item-label" style="width: 200px">保函有效期
</div>
<div class="xy-table-item-content">
<el-date-picker value-format="yyyy-MM-dd" v-model="form.assurance_expire" placeholder="请输入保函有效期" style="width: 300px;"/>
</div>
</div>
</template>
<template v-slot:guaranteeMoney>
<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-number :precision="2" :controls="false" placeholder="请填写质保金" v-model="form.guaranteeMoney"
style="width: 300px;" />
</div>
</div>
</template>
<template v-slot:date>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;">*</span>
签订日期
</div>
<div class="xy-table-item-content">
<el-date-picker style="width: 300px;" value-format="yyyy-MM-dd" v-model="form.date" type="date">
</el-date-picker>
</div>
</div>
</template>
<template v-slot:guaranteeYear>
<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-year">
<el-input-number :controls="false" placeholder="请填写质保期" v-model="form.guaranteeYear"
style="width: 300px;" />
</div>
</div>
</template>
<template v-slot:extraFormBottom>
<div class="base-info add-plan" style="margin-top: 20px;margin-bottom: 20px">
<div class="base-info-title">付款计划</div>
<Button type="primary" style="margin-left: 50px;" @click="isShowAddPlan = true">新增计划</Button>
<p style="font-weight: 600;zoom: .9;color: red;margin-left: 10px;">如需分期付款,请分条填报付款计划</p>
</div>
<xy-table :list="signList" :table-item="signTable" :show-index="false" :height="160"
@delete="deleteContractSign"
@editor="(row)=>{$refs['detailContractSign'].planId = row.id;$refs['detailContractSign'].isShow = true}">
</xy-table>
<div class="base-info add-plan" style="margin-top: 20px;margin-bottom: 20px">
<div class="base-info-title">合同关联方</div>
<Button type="primary" style="margin-left: 50px;" @click="form.contract_links.push({contract_id:contract.id,type_id:'',name:'',remark:''})">新增</Button>
</div>
<xy-table :height="160" :list="form.contract_links instanceof Array ? form.contract_links : []" :table-item="linkTable">
<template v-slot:btns></template>
</xy-table>
</template>
</xy-dialog>
<!-- 新增计划-->
<xy-dialog :is-show.sync="isShowAddPlan" type="form" title="新增计划" :form="planForm" :rules="planRules" :width="48"
@submit="submit">
<template v-slot:date>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;">*</span>
<span>日期</span>
</div>
<div class="xy-table-item-content">
<el-datePicker style="width: 300px" v-model="planForm.date" type="date" placeholder="请选择日期"></el-datePicker>
</div>
</div>
</template>
<template v-slot:content>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;">*</span>
<span>内容</span>
</div>
<div class="xy-table-item-content">
<el-input style="width: 300px" type="textarea" v-model="planForm.content" placeholder="请输入内容" />
</div>
</div>
</template>
<template v-slot:money>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;">*</span>
<span>金额</span>
</div>
<div class="xy-table-item-content xy-table-item-price">
<el-input style="width: 300px" v-model="planForm.money" placeholder="请输入金额" />
</div>
</div>
</template>
<template v-slot:remark>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span>备注</span>
</div>
<div class="xy-table-item-content">
<el-input style="width: 300px" type="textarea" v-model="planForm.remark" placeholder="请输入备注" />
</div>
</div>
</template>
</xy-dialog>
<detailContractSign ref="detailContractSign" @editorSuccess="getContractSignList"></detailContractSign>
</div>
</template>
<script>
import {
addContractSign,
getContractSign,
delContractSign
} from "@/api/contractSign/contractSign";
import {
detailContract,
editorContract
} from "@/api/contract/contract";
import {
Message
} from "element-ui";
import {
parseTime,
moneyFormatter
} from "@/utils"
import { getOutDetail, httpCurl } from '@/api/out'
import { getparameter } from "@/api/system/dictionary"
import detailContractSign from "@/views/contract/components/detailContractSign";
import {
getOatoken
} from "@/api/oatoken";
import axios from "axios";
export default {
components: {
detailContractSign
},
data() {
return {
linTypes: [],
form: {
is_contract: 1,
number: '',
content: "",
supply: '',
carryDepartment: '',
money: '',
time: [],
guaranteeMoney: '',
guaranteeYear: '',
date: "",
is_assurance: false,
assurance_money:'',
assurance_expire:'',
contract_links:[]
},
rules: {
number: [{
required: true,
message: "必填"
}],
date: [{
required: true,
message: "必填"
}],
supply: [{
required: true,
message: "必填"
}],
carryDepartment: [{
required: true,
message: "必填"
}],
money: [{
required: true,
message: "必填"
},
{
pattern: /^\d+(\.\d+)?$/,
message: '必须为数字'
}
],
time: [{
required: true,
message: "必选"
}],
guaranteeMoney: [{
required: true,
message: "必填"
}],
guaranteeYear: [{
required: true,
message: "必填"
}]
},
isShow: false,
contractId: null,
contract: {},
signList: [],
signTable: [
{
prop: "date",
label: "计划日期",
width: 170,
formatter: (v1, v2, value) => {
return this.$moment(new Date(value)).format("YYYY-MM-DD")
}
},
{
prop: 'money',
label: '金额',
align: 'right',
width: 120,
sortable: false,
formatter: (v1, v2, value) => {
return moneyFormatter(value)
}
},
{
prop: 'content',
label: '内容',
minWidth: 180,
align: 'left',
sortable: false,
},
{
prop: 'remark',
label: '备注',
minWidth: 180,
align: 'left',
sortable: false,
},
{
prop: 'created_at',
label: '日期',
width: 170,
sortable: false,
formatter: (v1, v2, value) => {
return this.$moment(new Date(value)).format("YYYY-MM-DD HH:mm:ss")
}
}
],
isShowAddPlan: false,
planForm: {
date: '',
money: '',
content: '',
remark: ''
},
planRules: {
date: [{
required: true,
message: "必填"
}],
content: [{
required: true,
message: "必填"
}],
money: [{
required: true,
message: "必填"
},
{
pattern: /^\d+(\.\d+)?$/,
message: '必须为数字'
}
]
},
linkTable:[
{
prop: "",
width: 140,
label: "关联方类型",
customFn:row => {
return (
<el-select size="small" v-model={row.type_id}>
{
this.linTypes.map(i => {
return (
<el-option value={i.id} label={i.value}></el-option>
)
})
}
</el-select>
)
}
},
{
prop: "name",
label: "名称",
width: 140,
customFn:row => {
return (
<el-input size="small" v-model={row.name}></el-input>
)
}
},
{
prop: "remark",
label: "备注",
minWidth: 180,
customFn:row => {
return (
<el-input size="small" v-model={row.remark}></el-input>
)
}
},
{
label: "操作",
width: 80,
customFn:(row,scope) => {
return (
<Button type="primary"
size="small"
on={{
['click']:e => {
this.form.contract_links.splice(scope.$index,1)
}
}}>删除</Button>
)
}
}
]
}
},
methods: {
async getLinkTypes() {
const res = await getparameter({number:"linkType"})
this.linTypes = res.detail
},
//合同签订
sign() {
console.log(this.signList)
console.log(this.signList.length)
if (this.signList.length == 0) {
Message({
type: 'error',
message: '该项目未设置付款计划,请设置付款计划后保存'
})
return false;
}
editorContract({
id: this.contractId,
number: this.form.number,
content: this.form.content,
supply: this.form.supply,
carry_department: this.form.carryDepartment,
money: this.form.money,
status: 2,
guarantee_money: this.form.guaranteeMoney,
guarantee_year: this.form.guaranteeYear,
start_date: this.form.time[0],
end_date: this.form.time[1],
date: this.form.date,
is_assurance: this.form.is_assurance,
assurance_money:this.form.assurance_money,
assurance_expire:this.form.assurance_expire,
contract_links:this.form.contract_links,
}).then(res => {
this.isShow = false
Message({
type: 'success',
message: '操作成功'
})
this.$emit('signSuccess')
})
},
async getContractSignList() {
const res = await getContractSign({
contract_id: this.contractId
})
this.signList = res.data
},
async getContract() {
const res = await detailContract({
id: this.contractId
})
this.contract = res;
Object.assign(this.form, res);
if (res.start_date && res.end_date)
this.form.time = [res.start_date, res.end_date];
else
this.form.time = [];
this.form.carryDepartment = res.carry_department;
this.form.guaranteeMoney = res.guarantee_money;
this.form.guaranteeYear = res.guarantee_year;
this.form.is_assurance = res.is_assurance === 1
this.form.assurance_expire = res.assurance_expire
this.form.assurance_money = res.assurance_money
this.form.contract_links = res.contract_links || []
this.form.is_contract = res.is_contract
console.log(this.form)
},
deleteContractSign(row) {
delContractSign({
id: row.id
}).then(res => {
this.getContractSignList()
Message({
type: 'success',
message: '操作成功'
})
})
},
submit() {
console.log(this.planForm)
addContractSign({
contract_id: this.contract.id,
date: `${new Date(this.planForm.date).getFullYear()}-${new Date(this.planForm.date).getMonth()+1}-${new Date(this.planForm.date).getDate()}`,
content: this.planForm.content,
money: this.planForm.money,
remark: this.planForm.remark
}).then(res => {
this.isShowAddPlan = false
this.getContractSignList()
console.log(res)
Message({
type: 'success',
message: '操作成功'
})
})
},
async getOutContract() {
const res = await httpCurl({ tbname: 'hetong', out_contract_id: this.contract.id })
console.log(res)
if (res.flow.serial) this.form.number = "HT-"+res.flow?.serial
if (res.flow_detail.total) this.form.money = Number(res.flow_detail?.total)
if (res.flow_detail.yifang) this.form.supply = res.flow_detail?.yifang
if (res.flow.dept_name) this.form.carryDepartment = res.flow?.dept_name
if (res.flow_detail.contract_content) this.form.content = res.flow_detail.contract_content
},
//获取oa合同信息
// async getOaContractInfo() {
// try {
// let res = await getOatoken()
// let url =
// `${process.env.VUE_APP_OUT_URL}/admin/flow/view/${this.contract.join_last_flow_id}?oatoken=${res.oatoken}&get_raw=1`
// const oaInfo = await axios.get(url)
// this.form.money = Number(oaInfo.data.flow['合同金额(元)'])
// this.form.number = oaInfo.data.flow['合同编号']
// this.form.supply = oaInfo.data.flow['承包商\\供应商']
// this.form.carryDepartment = oaInfo.data.flow['执行部门']
// } catch {
//
// }
//
// }
},
watch: {
async isShow(val) {
if(val){
await this.getContractSignList()
await this.getContract()
//await this.getOaContractInfo()
await this.getOutContract()
}
}
},
created() {
this.getLinkTypes()
}
}
</script>
<style scoped lang="scss">
.base-info {
&-title {
font-weight: 600;
padding: 0 10px;
}
&-item {
display: flex;
margin-top: 8px;
&-title {
padding: 0 20px;
}
&-content {}
&-unit {
margin-left: 20px;
}
}
}
.add-plan {
display: flex;
align-items: center;
}
.xy-table-item-label {
width: 200px;
}
.xy-table-item-price {
position: relative;
&::after {
position: absolute;
right: 0;
top: 0;
content: ''
}
}
.xy-table-item-price-wan {
position: relative;
&::after {
position: absolute;
right: 0;
top: 0;
content: ''
}
::v-deep .el-input__clear {
position: relative;
right: 46px;
z-index: 2;
}
}
.xy-table-item-year {
position: relative;
&::after {
position: absolute;
right: 4%;
top: 0;
content: ''
}
}
::v-deep .el-input__inner {
text-align: left;
}
</style>