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
18 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 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">
<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%">
<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%">
<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%">
<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%">
<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">
<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">
<div class="base-info-item-title">资金渠道</div>
<div class="base-info-item-content">
{{ moneyWayFormatter(detail.money_way_detail) }}
</div>
</div>
</div>
<div class="link-budget-plan">
<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">
<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%">
<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="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>
</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 } from "@/api/out";
import detailContractSign from "./detailContractSign";
export default {
components: {
detailContractSign,
},
data() {
return {
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: {},
};
},
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: "操作成功",
});
});
},
},
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);
};
},
},
watch: {
isShowDetail(val) {
if (val) {
getOutDetail({ tbname: "hetong", out_contract_id: this.id }).then(
(res) => {
this.outContractDetail = res;
}
);
getOutDetail({ tbname: "caigou", out_contract_id: this.id }).then(
(res) => {
console.log(11111, res);
this.outCaigouDetail = 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;
},
};
</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;
}
}
}
</style>