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.

799 lines
23 KiB

<template>
<div v-if="detail">
<!-- -->
<xy-dialog
:is-show.sync="isShowDetail"
type="normal"
title="详情"
class="contract-detail"
>
<template v-slot:default>
<div class="base-info">
<div class="base-info-title">项目基本信息</div>
<div class="base-info-item">
<div class="base-info-item-title">项目名称</div>
<div class="base-info-item-content">{{ detail.name }}</div>
</div>
<div class="base-info-item" v-if="detail.outcome_type === 1">
<div class="base-info-item-title">项目类型</div>
<div class="base-info-item-content">
{{ typeFormatter(detail.type) }}
</div>
</div>
<div style="display: flex; justify-content: space-between">
<div
class="base-info-item"
style="flex-basis: 50%"
v-if="detail.outcome_type === 1"
>
<div class="base-info-item-title">采购形式</div>
<div class="base-info-item-content" v-if="detail.purchase_way">
{{ detail.purchase_way.value }}
</div>
</div>
<div
class="base-info-item"
style="flex-basis: 50%"
v-if="detail.outcome_type === 1"
>
<div class="base-info-item-title">采购方式</div>
<div class="base-info-item-content" v-if="detail.purchase_type">
{{ detail.purchase_type.value }}
</div>
</div>
</div>
<div style="display: flex; justify-content: space-between">
<div
class="base-info-item"
style="flex-basis: 50%"
v-if="detail.outcome_type === 1"
>
<div class="base-info-item-title">签订时间</div>
<div class="base-info-item-content">{{ detail.date }}</div>
</div>
<div
class="base-info-item"
style="flex-basis: 50%"
v-if="detail.outcome_type === 1"
>
<div class="base-info-item-title">服务时间</div>
<div class="base-info-item-content">
{{ detail.start_date }}至{{ detail.end_date }}
</div>
</div>
</div>
<div class="base-info-item" v-if="detail.outcome_type === 1">
<div class="base-info-item-title">项目预算</div>
<div class="base-info-item-content">
{{ moneyFormat(detail.plan_price) }}
</div>
<div class="base-info-item-unit">(元)</div>
</div>
<div class="base-info-item" v-if="detail.outcome_type === 1">
<div class="base-info-item-title">资金渠道</div>
<div class="base-info-item-content">
{{ moneyWayFormatter(detail.money_way_detail) }}
</div>
</div>
<div class="base-info-item" v-if="detail.outcome_type !== 1">
<div class="base-info-item-title">备注</div>
<div class="base-info-item-content">
{{ detail.remark }}
</div>
</div>
<div class="base-info-item" v-if="detail.outcome_type !== 1">
<div class="base-info-item-title">附件</div>
<div class="base-info-item-content">
<div v-for="i in detail.files_detail">
<a @click="open(i)">{{ i.original_name }}</a>
</div>
</div>
</div>
</div>
<div class="link-budget-plan" v-if="detail.outcome_type === 1">
<div class="link-budget-plan-title">关联预算计划</div>
<xy-table
:height="260"
:table-item="linkBudgetPlanTable"
:show-index="false"
:list="detail.plans"
>
<template v-slot:btns>
<div></div>
</template>
</xy-table>
</div>
<div class="sign-info" style="margin-top: 20px">
<div class="sign-info-title">签订信息</div>
<div class="sign-info-item">
<div class="sign-info-item-title">合同金额</div>
<div class="sign-info-item-content">
{{ moneyFormat(detail.money) }}
</div>
<div class="sign-info-item-unit">(元)</div>
</div>
<div style="display: flex; justify-content: space-between">
<div
class="sign-info-item"
style="flex-basis: 50%"
v-if="detail.outcome_type === 1"
>
<div class="sign-info-item-title">承包商\供应商</div>
<div class="sign-info-item-content">{{ detail.supply }}</div>
</div>
<div class="sign-info-item" style="flex-basis: 50%">
<div class="sign-info-item-title">执行部门</div>
<div class="sign-info-item-content">
{{ detail.carry_department }}
</div>
</div>
</div>
</div>
<div class="out-sign-info" v-if="outContractDetail.flow_detail">
<div class="sign-info-title">合同会签信息</div>
<div class="sign-info-item">
<div class="sign-info-item-title">合同金额</div>
<div class="sign-info-item-content">
{{ moneyFormat(outContractDetail.flow_detail.total) }}
</div>
<div class="sign-info-item-unit">(元)</div>
</div>
<div style="display: flex; justify-content: space-between">
<div class="sign-info-item" style="flex-basis: 50%">
<div class="sign-info-item-title">甲方</div>
<div class="sign-info-item-content">
{{ outContractDetail.flow_detail.jiafang }}
</div>
</div>
<div class="sign-info-item" style="flex-basis: 50%">
<div class="sign-info-item-title">乙方</div>
<div class="sign-info-item-content">
{{ outContractDetail.flow_detail.yifang }}
</div>
</div>
</div>
</div>
<div class="out-sign-info" v-if="outCaigouDetail.flow_detail">
<div class="sign-info-title">采购信息</div>
<div class="sign-info-item">
<div class="sign-info-item-title">名称</div>
<div class="sign-info-item-content">
{{ outCaigouDetail.flow_detail.content_name }}
</div>
</div>
<div class="sign-info-item" style="flex-basis: 50%">
<div class="sign-info-item-title">规格</div>
<div class="sign-info-item-content">
{{ outCaigouDetail.flow_detail.content_guige }}
</div>
</div>
<div class="sign-info-item" style="flex-basis: 50%">
<div class="sign-info-item-title">类型</div>
<div class="sign-info-item-content">
{{ outCaigouDetail.flow_detail.type }}
</div>
</div>
<div class="sign-info-item" style="flex-basis: 50%">
<div class="sign-info-item-title">预算</div>
<div class="sign-info-item-content">
{{ moneyFormat(outCaigouDetail.flow_detail.yusuan) }}
</div>
</div>
</div>
<div class="out-sign-info" v-if="outPayDetail.flow_detail">
<div class="sign-info-title">付款信息</div>
<div class="sign-info-item">
<div class="sign-info-item-title">状态</div>
<div class="sign-info-item-content">
{{ statusFormat(outPayDetail.flow.current_step) }}
</div>
</div>
<div class="sign-info-item">
<div class="sign-info-item-title">总价</div>
<div class="sign-info-item-content">
{{ moneyFormat(outPayDetail.flow_detail.zongjia) }}
</div>
<div class="sign-info-item-unit">(元)</div>
</div>
<div style="display: flex; justify-content: space-between">
<div class="sign-info-item" style="flex-basis: 50%">
<div class="sign-info-item-title">已支付次数</div>
<div class="sign-info-item-content">
{{ outPayDetail.flow_detail.yizhifucishu }}
</div>
</div>
<div class="sign-info-item" style="flex-basis: 50%">
<div class="sign-info-item-title">已支付金额</div>
<div class="sign-info-item-content">
{{ outPayDetail.flow_detail.yizhifujine }}
</div>
<div class="sign-info-item-unit">(元)</div>
</div>
<div class="sign-info-item" style="flex-basis: 50%">
<div class="sign-info-item-title">总支付次数</div>
<div class="sign-info-item-content">
{{ outPayDetail.flow_detail.zhifucishu }}
</div>
</div>
</div>
</div>
<div class="pay-plan" v-if="detail.outcome_type !== 1">
<div class="pay-plan-title">关联审批单</div>
<xy-table
:height="240"
:table-item="[
{ label: '名称', prop: 'title', minWidth: 140, align: 'left' },
]"
:list="detail.oa"
:show-index="false"
>
<template v-slot:btns>
<div></div>
</template>
</xy-table>
</div>
<div class="pay-plan">
<div class="pay-plan-title">付款计划</div>
<xy-table
:height="240"
:list="signPlan"
:table-item="planTable"
:show-index="false"
:btn-width="130"
@delete="deletePayPlan"
@editor="
(row) => {
$refs['detailContractSign'].planId = row.id;
$refs['detailContractSign'].isShow = true;
}
"
>
</xy-table>
</div>
<!-- <div class="related-processes">-->
<!-- <div class="related-processes-title">相关流程进展查看</div>-->
<!-- <div class="related-processes-item">-->
<!-- <div-->
<!-- @click="toOutDetail('caigou')"-->
<!-- :style="{ color: detail.purchase_last_flow_id ? 'green' : 'red' }"-->
<!-- >-->
<!-- 采购流程查看-->
<!-- </div>-->
<!-- <div-->
<!-- @click="toOutDetail('hetong')"-->
<!-- :style="{ color: detail.join_last_flow_id ? 'green' : 'red' }"-->
<!-- >-->
<!-- 合同会签流程查看-->
<!-- </div>-->
<!-- <template-->
<!-- v-if="-->
<!-- detail.purchase_way && detail.purchase_way.remark === 'true'-->
<!-- "-->
<!-- >-->
<!-- <div-->
<!-- @click="seeBidding"-->
<!-- :style="{ color: detail.invite_last_flow_id ? 'green' : 'red' }"-->
<!-- >-->
<!-- 招标审批流程查看-->
<!-- </div>-->
<!-- </template>-->
<!-- <template v-if="detail.is_plan != 1">-->
<!-- <div-->
<!-- @click="seeAskProcess"-->
<!-- :style="{ color: detail.req_last_flow_id ? 'green' : 'red' }"-->
<!-- >-->
<!-- 请示流程查看-->
<!-- </div>-->
<!-- </template>-->
<!-- </div>-->
<!-- </div>-->
<div class="journal">
<div class="journal-title">日志</div>
<xy-table
:height="240"
:table-item="journalTable"
:list="detail.log"
:show-index="false"
>
<template v-slot:btns>
<div></div>
</template>
</xy-table>
</div>
</template>
</xy-dialog>
<detailContractSign
ref="detailContractSign"
@editorSuccess="getDetail(id)"
></detailContractSign>
<Modal
:width="76"
transfer
v-model="showModal"
:footer-hide="true"
title="预览"
>
<template>
<iframe
style="width: 100%; height: 57vh"
:src="codeUri"
border="0"
></iframe>
</template>
</Modal>
</div>
</template>
<script>
import { detailContract } from "@/api/contract/contract";
import {
delContractSign,
getContractSign,
} from "@/api/contractSign/contractSign";
import { parseTime } from "@/utils";
import { getOatoken } from "@/api/oatoken";
import { Message } from "element-ui";
import { moneyFormatter } from "@/utils";
import { getparameter } from "@/api/system/dictionary";
import { getOutDetail, httpCurl } from "@/api/out";
import detailContractSign from "./detailContractSign";
export default {
components: {
detailContractSign,
},
data() {
return {
showModal: false,
codeUri: '',
window: {
width: 0,
height: 0,
top: 0,
left: 0,
},
//合同详情
id: "",
detail: null,
isShowDetail: false,
linkBudgetPlanTable: [
{
label: "ID",
sortable: false,
prop: "id",
width: 130,
},
{
label: "类型",
width: 100,
sortable: false,
customFn: (row) => {
const typeSwitch = (type) => {
let res = this.planTypes.filter((item) => {
return item.id === type;
});
return res[0]?.value || "未知";
};
return (
<div>
<Tag color="primary"> {typeSwitch(row.type)} </Tag>{" "}
</div>
);
},
},
{
label: "项目",
width: 140,
sortable: false,
prop: "name",
},
{
label: "金额",
sortable: false,
prop: "money",
align: "right",
minWidth: 200,
formatter: (v1, v2, value) => {
return Number(value)
.toFixed(2)
.replace(/(\d)(?=(\d{3})+\.)/g, "$1,");
},
},
{
label: "使用金额",
sortable: false,
prop: "useMoney",
align: "right",
minWidth: 200,
formatter: (v1, v2, value) => {
return Number(value)
.toFixed(2)
.replace(/(\d)(?=(\d{3})+\.)/g, "$1,");
},
},
],
journalTable: [
{
label: "ID",
sortable: false,
prop: "id",
},
{
label: "日志类型",
sortable: false,
prop: "type",
},
{
label: "日志内容",
sortable: false,
prop: "remark",
},
{
label: "操作人",
sortable: false,
prop: "admin.name",
},
{
label: "时间",
sortable: false,
prop: "created_at",
width: 160,
formatter: (cell, data, value) => {
return parseTime(new Date(value), "{y}-{m}-{d} {h}:{i}");
},
},
],
signPlan: [],
planTypes: [],
planTable: [
{
prop: "date",
label: "日期",
sortable: false,
formatter: (cell, data, value) => {
return parseTime(new Date(value), "{y}-{m}-{d}");
},
},
{
prop: "money",
label: "金额(元)",
align: "right",
minWidth: 180,
sortable: false,
formatter: (v1, v2, value) => {
return Number(value)
.toFixed(2)
.replace(/(\d)(?=(\d{3})+\.)/g, "$1,");
},
},
{
prop: "content",
label: "内容",
align: "left",
sortable: false,
},
{
prop: "remark",
label: "备注",
align: "left",
sortable: false,
},
],
//out获取到信息
outContractDetail: {},
outCaigouDetail: {},
outPayDetail: {},
};
},
methods: {
async getPlanTypes() {
const res = await getparameter({
number: "money_way",
});
this.planTypes = res.detail;
},
async seeBuyProcess() {
if (!this.detail?.purchase_last_flow_id) {
Message({
type: "warning",
message: "还未进行采购申请",
duration: 2000,
});
return;
}
let res = await getOatoken();
let url = `${process.env.VUE_APP_OUT_URL}/admin/flow/view/${this.detail.purchase_last_flow_id}?oatoken=${res.oatoken}`;
let seeBuy = window.open(
url,
"seeBuy",
`top=${this.window.top},left=${this.window.left},width=${this.window.width},height=${this.window.height},location=0`
);
},
async seeBidding() {
if (!this.detail?.invite_last_flow_id) {
Message({
type: "warning",
message: "还未进行招标申请",
duration: 2000,
});
return;
}
let res = await getOatoken();
let url = `${process.env.VUE_APP_OUT_URL}/admin/flow/view/${this.detail.invite_last_flow_id}?oatoken=${res.oatoken}`;
let seeBidding = window.open(
url,
"seeBidding",
`top=${this.window.top},left=${this.window.left},width=${this.window.width},height=${this.window.height},location=0`
);
},
async seeSignProcess() {
if (!this.detail?.join_last_flow_id) {
Message({
type: "warning",
message: "还未进行会签申请",
duration: 2000,
});
return;
}
let res = await getOatoken();
let url = `${process.env.VUE_APP_OUT_URL}/admin/flow/view/${this.detail.join_last_flow_id}?oatoken=${res.oatoken}`;
let seeSign = window.open(
url,
"seeSign",
`top=${this.window.top},left=${this.window.left},width=${this.window.width},height=${this.window.height},location=0`
);
},
async seeAskProcess() {
if (!this.detail?.req_last_flow_id) {
Message({
type: "warning",
message: "还未进行请示申请",
duration: 2000,
});
return;
}
let res = await getOatoken();
let url = `${process.env.VUE_APP_OUT_URL}/admin/flow/view/${this.detail.req_last_flow_id}?oatoken=${res.oatoken}`;
let seeAsk = window.open(
url,
"seeAsk",
`top=${this.window.top},left=${this.window.left},width=${this.window.width},height=${this.window.height},location=0`
);
},
async getDetail(id) {
this.id = id;
let res = await detailContract({
id: id,
});
this.detail = res;
let plans = res.plans;
let linkPlan = res.plan_link;
let linkPlanTable = plans.map((item) => {
let res = linkPlan.filter((item1) => {
return item1.plan_id === item.id;
})[0];
return {
id: item.id,
type: item.type,
name: item.name,
money: item.money,
useMoney: res.use_money,
};
});
this.detail.plans = linkPlanTable;
console.log(this.detail);
let plan = await getContractSign({
contract_id: id,
});
this.signPlan = plan.data;
},
//删除付款计划
deletePayPlan(row) {
delContractSign({
id: row.id,
}).then((res) => {
this.getSignPlan();
Message({
type: "success",
message: "操作成功",
});
});
},
open(e) {
this.codeUri = `http://view.ali251.langye.net:8012/onlinePreview?url=${encodeURIComponent(
new Buffer(e.url).toString("base64")
)}`;
this.showModal = true;
}
},
computed: {
typeFormatter() {
return function (type) {
switch (type) {
case 1:
return "服务";
break;
case 2:
return "货物";
break;
case 3:
return "工程";
break;
case 4:
return "其他";
break;
default:
return "未知";
}
};
},
moneyWayFormatter() {
return function (arr) {
let res = arr.map((item) => {
return item.value;
});
return res.toString();
};
},
moneyFormat() {
return function (money) {
return moneyFormatter(money);
};
},
statusFormat() {
return function (status) {
if (status === "end") {
return "已办结";
}
if (Number(status)) {
return "进行中";
}
return "待办理";
};
},
},
watch: {
isShowDetail(val) {
if (val) {
httpCurl({ tbname: "hetong", out_contract_id: this.id }).then((res) => {
this.outContractDetail = res;
});
httpCurl({ tbname: "caigou", out_caigou_id: this.id }).then((res) => {
this.outCaigouDetail = res;
});
httpCurl({ tbname: "pay", out_pay_id: this.id }).then((res) => {
this.outPayDetail = res;
});
}
},
},
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;
},
created() {
this.getPlanTypes();
},
};
</script>
<style scoped lang="scss">
.contract-detail {
.base-info {
&-title {
font-weight: 600;
padding: 0 10px;
}
&-item {
display: flex;
margin-top: 8px;
&-title {
padding: 0 20px;
}
&-content {
}
&-unit {
margin-left: 20px;
}
}
}
.link-budget-plan {
margin-top: 20px;
&-title {
@extend .base-info-title;
padding-bottom: 10px;
}
}
.sign-info {
&-title {
@extend .link-budget-plan-title;
}
&-item {
@extend .base-info-item;
&-title {
@extend .base-info-item-title;
}
&-content {
@extend .base-info-item-content;
}
&-unit {
@extend .base-info-item-unit;
}
}
}
.out-sign-info {
margin-top: 20px;
@extend .sign-info;
}
.pay-plan {
margin-top: 20px;
&-title {
@extend .link-budget-plan-title;
}
}
.related-processes {
margin-top: 20px;
&-title {
@extend .link-budget-plan-title;
}
&-item {
//color: red;
display: flex;
& > div {
cursor: pointer;
margin: 0 20px;
}
}
}
.journal {
margin-top: 20px;
&-title {
@extend .link-budget-plan-title;
}
}
}
a {
color: red;
&:hover {
color: red;
text-decoration: underline;
}
}
</style>