|
|
|
|
@ -796,8 +796,9 @@
|
|
|
|
|
:visible.sync="rightDrawerVisible"
|
|
|
|
|
:title="rightDrawerTitle"
|
|
|
|
|
direction="rtl"
|
|
|
|
|
size="60%"
|
|
|
|
|
:size="$store.getters.device === 'mobile' ? '100%' : (rightDrawerType === 'contract' ? '78%' : '60%')"
|
|
|
|
|
:with-header="true"
|
|
|
|
|
custom-class="flow-detail-drawer"
|
|
|
|
|
>
|
|
|
|
|
<!-- 流程详情:iframe -->
|
|
|
|
|
<div v-if="rightDrawerType === 'flow'" style="width: 100%; height: 100%;">
|
|
|
|
|
@ -865,72 +866,135 @@
|
|
|
|
|
<!-- 合同详情:请求数据展示 -->
|
|
|
|
|
<div v-else-if="rightDrawerType === 'contract'" v-loading="loadingContractDrawer">
|
|
|
|
|
<div v-if="contractDrawerDetail">
|
|
|
|
|
<el-descriptions :column="2" border>
|
|
|
|
|
<el-descriptions-item label="合同编号">
|
|
|
|
|
{{ contractDrawerDetail.contract_no || '-' }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="合同名称">
|
|
|
|
|
{{ contractDrawerDetail.title || '-' }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="甲方">
|
|
|
|
|
{{ contractDrawerDetail.party_a || '-' }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="乙方">
|
|
|
|
|
{{ contractDrawerDetail.party_b || '-' }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="合同总额">
|
|
|
|
|
<span style="color: #F56C6C; font-weight: bold;">¥{{ formatAmount(contractDrawerDetail.amount_total) }}</span>
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="金额类型">
|
|
|
|
|
{{ contractDrawerDetail.amount_type === 'open' ? '开口' : (contractDrawerDetail.amount_type === 'fixed' ? '闭口' : '-') }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="合同主要内容" :span="2">
|
|
|
|
|
{{ contractDrawerDetail.main_content || '-' }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="签订日期">
|
|
|
|
|
{{ contractDrawerDetail.sign_date || '-' }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="申请日期">
|
|
|
|
|
{{ contractDrawerDetail.apply_date || '-' }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="履行期限">
|
|
|
|
|
{{ contractDrawerDetail.perform_period || '-' }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="付款方式">
|
|
|
|
|
{{ contractDrawerDetail.pay_method || '-' }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="资金来源">
|
|
|
|
|
{{ contractDrawerDetail.fund_source || '-' }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="采购方式">
|
|
|
|
|
{{ contractDrawerDetail.purchase_method || '-' }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="合同附件" :span="2">
|
|
|
|
|
<template v-if="contractDrawerDetail.attachment && contractDrawerDetail.attachment.url">
|
|
|
|
|
<el-link
|
|
|
|
|
type="primary"
|
|
|
|
|
:underline="false"
|
|
|
|
|
:href="contractDrawerDetail.attachment.url"
|
|
|
|
|
target="_blank"
|
|
|
|
|
>
|
|
|
|
|
{{ contractDrawerDetail.attachment.original_name || contractDrawerDetail.attachment.name || '查看附件' }}
|
|
|
|
|
</el-link>
|
|
|
|
|
</template>
|
|
|
|
|
<span v-else>-</span>
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
</el-descriptions>
|
|
|
|
|
<div class="contract-drawer">
|
|
|
|
|
<el-descriptions :column="2" border class="contract-drawer-descriptions">
|
|
|
|
|
<el-descriptions-item label="合同编号">
|
|
|
|
|
{{ contractDrawerDetail.contract_no || '-' }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="合同名称">
|
|
|
|
|
{{ contractDrawerDetail.title || '-' }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="合同主要内容" :span="2">
|
|
|
|
|
{{ contractDrawerDetail.main_content || '-' }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="甲方">
|
|
|
|
|
{{ contractDrawerDetail.party_a || '-' }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="乙方">
|
|
|
|
|
{{ contractDrawerDetail.party_b || '-' }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="合同金额(元)">
|
|
|
|
|
{{ formatAmount(contractDrawerDetail.amount_total) }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="项目预算金额(元)">
|
|
|
|
|
{{ formatAmount(contractDrawerDetail.budget_amount) }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="金额类型">
|
|
|
|
|
<el-tag v-if="contractDrawerDetail.amount_type === 'fixed'" type="success" size="small">闭口合同</el-tag>
|
|
|
|
|
<el-tag v-else-if="contractDrawerDetail.amount_type === 'open'" type="warning" size="small">开口合同</el-tag>
|
|
|
|
|
<span v-else>-</span>
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="金额说明" v-if="contractDrawerDetail.amount_type === 'open'">
|
|
|
|
|
{{ contractDrawerDetail.amount_description || '-' }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="签订日期">
|
|
|
|
|
{{ formatDate(contractDrawerDetail.sign_date) || '-' }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="申请日期">
|
|
|
|
|
{{ formatDate(contractDrawerDetail.apply_date) || '-' }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="合同履行期">
|
|
|
|
|
{{ contractDrawerDetail.perform_period || '-' }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="付款方式">
|
|
|
|
|
{{ contractDrawerDetail.pay_method || '-' }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="预算年度">
|
|
|
|
|
{{ getContractBudgetYear(contractDrawerDetail) }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="计划资金来源" :span="2">
|
|
|
|
|
{{ getContractPlanFundSource(contractDrawerDetail) }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="实际资金来源" :span="2">
|
|
|
|
|
{{ formatArrayText(contractDrawerDetail.actual_fund_sources) }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="合同类型">
|
|
|
|
|
{{ (contractDrawerDetail.contractType && contractDrawerDetail.contractType.name) || '-' }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="采购类别">
|
|
|
|
|
{{ (contractDrawerDetail.purchaseCategory && contractDrawerDetail.purchaseCategory.name) || '-' }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="采购方式">
|
|
|
|
|
{{ getContractPurchaseMethod(contractDrawerDetail) }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="是否政府采购">
|
|
|
|
|
<el-tag v-if="contractDrawerDetail.is_government_purchase" type="success" size="small">是</el-tag>
|
|
|
|
|
<el-tag v-else type="info" size="small">否</el-tag>
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="招标代理">
|
|
|
|
|
{{ contractDrawerDetail.tender_agent || '-' }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="合同履行情况">
|
|
|
|
|
{{ contractDrawerDetail.perform_status || '-' }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="是否验收">
|
|
|
|
|
<el-tag v-if="contractDrawerDetail.is_accepted" type="success" size="small">是</el-tag>
|
|
|
|
|
<el-tag v-else type="info" size="small">否</el-tag>
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="科室">
|
|
|
|
|
{{ formatDepartmentNames(contractDrawerDetail.owner_department_ids || contractDrawerDetail.owner_department_id) }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="合同签订/变更经办人">
|
|
|
|
|
{{ formatUserNames(contractDrawerDetail.handler_admin_ids) }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="申请科室经办人">
|
|
|
|
|
{{ formatUserNames(contractDrawerDetail.apply_handler_id) }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="采购科室经办人">
|
|
|
|
|
{{ formatUserNames(contractDrawerDetail.purchase_handler_id) }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="已发起付款">
|
|
|
|
|
<span style="font-weight: 600;">
|
|
|
|
|
<span style="color: #409eff;">{{ (contractDrawerDetail.payment_stats && contractDrawerDetail.payment_stats.payment_count) || 0 }} 次</span>
|
|
|
|
|
<span style="color: #67c23a; margin-left: 8px;">{{ formatAmount((contractDrawerDetail.payment_stats && contractDrawerDetail.payment_stats.paid_amount) || 0) }}</span>
|
|
|
|
|
</span>
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="备注" :span="2">
|
|
|
|
|
{{ contractDrawerDetail.remark || '-' }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="附件" :span="2">
|
|
|
|
|
<template v-if="getContractAttachmentUrl(contractDrawerDetail)">
|
|
|
|
|
<el-link
|
|
|
|
|
type="primary"
|
|
|
|
|
:underline="false"
|
|
|
|
|
:href="getContractAttachmentUrl(contractDrawerDetail)"
|
|
|
|
|
target="_blank"
|
|
|
|
|
>
|
|
|
|
|
{{ (contractDrawerDetail.attachment && contractDrawerDetail.attachment.original_name) || (contractDrawerDetail.attachment && contractDrawerDetail.attachment.name) || '查看附件' }}
|
|
|
|
|
</el-link>
|
|
|
|
|
</template>
|
|
|
|
|
<span v-else>-</span>
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
</el-descriptions>
|
|
|
|
|
|
|
|
|
|
<div v-if="contractDrawerDetail.pay_plans && contractDrawerDetail.pay_plans.length" style="margin-top: 16px;">
|
|
|
|
|
<div style="font-weight: 600; margin-bottom: 10px;">付款计划</div>
|
|
|
|
|
<el-table :data="contractDrawerDetail.pay_plans" border size="small" style="width: 100%;">
|
|
|
|
|
<el-divider content-position="left">付款计划</el-divider>
|
|
|
|
|
<el-table :data="contractDrawerDetail.pay_plans || []" border size="small" style="width: 100%;">
|
|
|
|
|
<el-table-column prop="phase_no" label="期次" width="100" />
|
|
|
|
|
<el-table-column prop="due_date" label="计划日期" width="140" />
|
|
|
|
|
<el-table-column label="计划付款日" width="150">
|
|
|
|
|
<template slot-scope="scope">
|
|
|
|
|
{{ formatDate(scope.row.due_date) || '-' }}
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="计划金额" min-width="160" align="right">
|
|
|
|
|
<template slot-scope="scope">
|
|
|
|
|
<span style="color: #F56C6C; font-weight: bold;">¥{{ formatAmount(scope.row.amount_plan) }}</span>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
</el-table>
|
|
|
|
|
|
|
|
|
|
<div v-if="!(contractDrawerDetail.pay_plans && contractDrawerDetail.pay_plans.length)" class="contract-empty-tip">
|
|
|
|
|
暂无付款计划
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div v-else style="color:#909399;">未获取到合同详情</div>
|
|
|
|
|
@ -1615,6 +1679,80 @@ export default {
|
|
|
|
|
if (!date) return '';
|
|
|
|
|
return this.$moment(date).format('YYYY-MM-DD');
|
|
|
|
|
},
|
|
|
|
|
formatArrayText(val) {
|
|
|
|
|
if (!val) return '-';
|
|
|
|
|
if (Array.isArray(val)) {
|
|
|
|
|
const arr = val.map(item => (item === null || item === undefined ? '' : String(item).trim())).filter(Boolean);
|
|
|
|
|
return arr.length ? arr.join(' | ') : '-';
|
|
|
|
|
}
|
|
|
|
|
if (typeof val === 'string') {
|
|
|
|
|
const s = val.trim();
|
|
|
|
|
return s || '-';
|
|
|
|
|
}
|
|
|
|
|
return String(val);
|
|
|
|
|
},
|
|
|
|
|
parseIdList(val) {
|
|
|
|
|
if (val === null || val === undefined || val === '') return [];
|
|
|
|
|
if (Array.isArray(val)) {
|
|
|
|
|
return val
|
|
|
|
|
.map(item => {
|
|
|
|
|
if (item && typeof item === 'object') return item.id || item.value || item.user_id || item.department_id || null;
|
|
|
|
|
return item;
|
|
|
|
|
})
|
|
|
|
|
.filter(item => item !== null && item !== undefined && item !== '');
|
|
|
|
|
}
|
|
|
|
|
if (typeof val === 'number') return [val];
|
|
|
|
|
if (typeof val === 'string') {
|
|
|
|
|
return val
|
|
|
|
|
.split(',')
|
|
|
|
|
.map(item => item.trim())
|
|
|
|
|
.filter(Boolean);
|
|
|
|
|
}
|
|
|
|
|
if (typeof val === 'object') {
|
|
|
|
|
const id = val.id || val.value || val.user_id || val.department_id;
|
|
|
|
|
return id ? [id] : [];
|
|
|
|
|
}
|
|
|
|
|
return [];
|
|
|
|
|
},
|
|
|
|
|
formatDepartmentNames(val) {
|
|
|
|
|
const ids = this.parseIdList(val);
|
|
|
|
|
if (!ids.length) return '-';
|
|
|
|
|
return ids
|
|
|
|
|
.map(id => this.simpleDepartmentMap?.[id] || this.simpleDepartmentMap?.[Number(id)] || `部门ID: ${id}`)
|
|
|
|
|
.join('、');
|
|
|
|
|
},
|
|
|
|
|
formatUserNames(val) {
|
|
|
|
|
const ids = this.parseIdList(val);
|
|
|
|
|
if (!ids.length) return '-';
|
|
|
|
|
return ids
|
|
|
|
|
.map(id => this.simpleUserMap?.[id] || this.simpleUserMap?.[Number(id)] || `用户ID: ${id}`)
|
|
|
|
|
.join('、');
|
|
|
|
|
},
|
|
|
|
|
getContractBudgetYear(detail) {
|
|
|
|
|
const year = detail?.fund_source_year?.year || detail?.fundSourceYear?.year || detail?.fund_source_budget_data?.budget_year?.year || detail?.fundSourceBudgetData?.budget_year?.year;
|
|
|
|
|
return year ? `${year}年` : '-';
|
|
|
|
|
},
|
|
|
|
|
getContractPlanFundSource(detail) {
|
|
|
|
|
return detail?.fund_source_budget_data?.name || detail?.fundSourceBudgetData?.name || detail?.fund_source || '-';
|
|
|
|
|
},
|
|
|
|
|
getContractPurchaseMethod(detail) {
|
|
|
|
|
const relationValue = detail && detail.purchaseMethod;
|
|
|
|
|
if (relationValue && typeof relationValue === 'object') {
|
|
|
|
|
return relationValue.name || relationValue.label || relationValue.title || '-';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const rawValue = detail && detail.purchase_method;
|
|
|
|
|
if (!rawValue) return '-';
|
|
|
|
|
if (typeof rawValue === 'string') return rawValue;
|
|
|
|
|
if (typeof rawValue === 'object') {
|
|
|
|
|
return rawValue.name || rawValue.label || rawValue.title || rawValue.text || '-';
|
|
|
|
|
}
|
|
|
|
|
return String(rawValue);
|
|
|
|
|
},
|
|
|
|
|
getContractAttachmentUrl(detail) {
|
|
|
|
|
const att = detail?.attachment;
|
|
|
|
|
return att?.url || att?.path || att?.file_url || att?.download_url || att?.preview_url || '';
|
|
|
|
|
},
|
|
|
|
|
// 格式化日期时间
|
|
|
|
|
formatDateTime(dateTime) {
|
|
|
|
|
if (!dateTime) return '';
|
|
|
|
|
@ -2113,7 +2251,11 @@ export default {
|
|
|
|
|
this.rightDrawerVisible = true;
|
|
|
|
|
this.loadingContractDrawer = true;
|
|
|
|
|
try {
|
|
|
|
|
const detail = await getBudgetContractDetail(cid);
|
|
|
|
|
const [detail] = await Promise.all([
|
|
|
|
|
getBudgetContractDetail(cid),
|
|
|
|
|
this.loadSimpleDepartmentMap(),
|
|
|
|
|
this.loadSimpleUserMap(),
|
|
|
|
|
]);
|
|
|
|
|
this.contractDrawerDetail = detail || null;
|
|
|
|
|
this.rightDrawerTitle = detail?.title || detail?.contract_no || title || '查看合同详情';
|
|
|
|
|
} catch (e) {
|
|
|
|
|
@ -2929,6 +3071,38 @@ export default {
|
|
|
|
|
word-break: break-word;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.contract-drawer {
|
|
|
|
|
padding: 20px 24px 28px;
|
|
|
|
|
}
|
|
|
|
|
.contract-drawer-descriptions {
|
|
|
|
|
::v-deep .el-descriptions__table {
|
|
|
|
|
width: 100%;
|
|
|
|
|
table-layout: fixed;
|
|
|
|
|
}
|
|
|
|
|
::v-deep .el-descriptions-item__label {
|
|
|
|
|
width: 160px;
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
}
|
|
|
|
|
::v-deep .el-descriptions-item__content {
|
|
|
|
|
word-break: break-word;
|
|
|
|
|
line-height: 1.7;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
.contract-empty-tip {
|
|
|
|
|
padding: 18px 4px 8px;
|
|
|
|
|
color: #909399;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
::v-deep .flow-detail-drawer > .el-drawer__header {
|
|
|
|
|
margin-bottom: 0;
|
|
|
|
|
padding: 20px 24px 16px;
|
|
|
|
|
border-bottom: 1px solid #ebeef5;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
::v-deep .flow-detail-drawer > .el-drawer__body {
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
<style lang="scss">
|
|
|
|
|
.log-table-scroll {
|
|
|
|
|
|