|
|
|
|
@ -94,7 +94,7 @@
|
|
|
|
|
<el-table-column prop="party_b" label="乙方" width="150" />
|
|
|
|
|
<el-table-column prop="contract_type_id" label="合同类型" width="100">
|
|
|
|
|
<template #default="{ row }">
|
|
|
|
|
<span v-if="row.contractType">{{ row.contractType.name }}</span>
|
|
|
|
|
<span v-if="row.contract_type">{{ row.contract_type.name }}</span>
|
|
|
|
|
<span v-else>-</span>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
@ -111,7 +111,7 @@
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column prop="amount_total" label="合同金额(元)" width="200" align="right">
|
|
|
|
|
<template #default="{ row }">
|
|
|
|
|
{{ formatAmount(row.amount_total) }}
|
|
|
|
|
{{ formatContractAmount(row) }}
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column prop="amount_description" label="金额说明" width="150" show-overflow-tooltip />
|
|
|
|
|
@ -127,7 +127,7 @@
|
|
|
|
|
<el-table-column prop="tender_agent" label="招标代理" width="150" show-overflow-tooltip />
|
|
|
|
|
<el-table-column prop="purchase_method_id" label="采购方式" width="120" show-overflow-tooltip>
|
|
|
|
|
<template #default="{ row }">
|
|
|
|
|
<span v-if="row.purchaseMethod">{{ row.purchaseMethod.name }}</span>
|
|
|
|
|
<span v-if="row.purchase_method">{{ row.purchase_method.name }}</span>
|
|
|
|
|
<span v-else>-</span>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
@ -140,7 +140,7 @@
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column prop="purchase_category_id" label="采购类别" width="120" show-overflow-tooltip>
|
|
|
|
|
<template #default="{ row }">
|
|
|
|
|
<span v-if="row.purchaseCategory">{{ row.purchaseCategory.name }}</span>
|
|
|
|
|
<span v-if="row.purchase_category">{{ row.purchase_category.name }}</span>
|
|
|
|
|
<span v-else>-</span>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
@ -165,7 +165,7 @@
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column prop="owner_department_id" label="科室" width="150" show-overflow-tooltip>
|
|
|
|
|
<template #default="{ row }">
|
|
|
|
|
{{ getDepartmentName(row.owner_department_id) }}
|
|
|
|
|
{{ formatDepartmentNames(row) }}
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column prop="handler_admin_ids" label="合同签订/变更经办人" width="180" show-overflow-tooltip>
|
|
|
|
|
@ -286,9 +286,9 @@
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="12" v-if="form.amount_type === 'open'">
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
<el-form-item label="金额说明" prop="amount_description">
|
|
|
|
|
<el-input v-model="form.amount_description" type="textarea" :rows="2" placeholder="请说明开口合同的金额情况" />
|
|
|
|
|
<el-input v-model="form.amount_description" type="textarea" :rows="2" placeholder="开口合同必填,闭口合同选填" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
@ -297,8 +297,9 @@
|
|
|
|
|
<el-option
|
|
|
|
|
v-for="type in contractTypeOptions"
|
|
|
|
|
:key="type.id"
|
|
|
|
|
:label="type.name"
|
|
|
|
|
:label="type._historical ? `${type.name}(已停用)` : type.name"
|
|
|
|
|
:value="type.id"
|
|
|
|
|
:disabled="!!type._historical"
|
|
|
|
|
/>
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
@ -342,8 +343,8 @@
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
<el-form-item label="项目经费来源" prop="fund_source_budget_data_id">
|
|
|
|
|
<el-select v-model="form.fund_source_budget_data_id" placeholder="请选择项目经费来源" filterable clearable style="width: 100%">
|
|
|
|
|
<el-form-item label="计划资金来源" prop="fund_source_budget_data_id">
|
|
|
|
|
<el-select v-model="form.fund_source_budget_data_id" placeholder="请选择计划资金来源" filterable clearable style="width: 100%">
|
|
|
|
|
<el-option-group
|
|
|
|
|
v-for="group in fundSourceOptions"
|
|
|
|
|
:key="group.label"
|
|
|
|
|
@ -360,6 +361,8 @@
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
</el-row>
|
|
|
|
|
<el-alert v-if="form.legacy_fund_source_display" type="info" :closable="false"
|
|
|
|
|
:title="`历史计划资金来源:${form.legacy_fund_source_display}。建议补充预算项目关联;未调整资金来源时保留原值。`" />
|
|
|
|
|
<el-row :gutter="20">
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
<el-form-item label="是否为政府采购" prop="is_government_purchase">
|
|
|
|
|
@ -379,8 +382,9 @@
|
|
|
|
|
<el-option
|
|
|
|
|
v-for="method in purchaseMethodOptions"
|
|
|
|
|
:key="method.id"
|
|
|
|
|
:label="method.name"
|
|
|
|
|
:label="method._historical ? `${method.name}(已停用)` : method.name"
|
|
|
|
|
:value="method.id"
|
|
|
|
|
:disabled="!!method._historical"
|
|
|
|
|
/>
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
@ -403,8 +407,9 @@
|
|
|
|
|
<el-option
|
|
|
|
|
v-for="category in purchaseCategoryOptions"
|
|
|
|
|
:key="category.id"
|
|
|
|
|
:label="category.name"
|
|
|
|
|
:label="category._historical ? `${category.name}(已停用)` : category.name"
|
|
|
|
|
:value="category.id"
|
|
|
|
|
:disabled="!!category._historical"
|
|
|
|
|
/>
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
@ -531,14 +536,14 @@
|
|
|
|
|
<el-descriptions-item label="合同主要内容" :span="2">{{ viewData.main_content || '-' }}</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="甲方">{{ viewData.party_a || '-' }}</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="乙方">{{ viewData.party_b || '-' }}</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="合同金额(元)">{{ formatAmount(viewData.amount_total) }}</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="合同金额(元)">{{ formatContractAmount(viewData) }}</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="项目预算金额(元)">{{ formatAmount(viewData.budget_amount) }}</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="金额类型">
|
|
|
|
|
<el-tag v-if="viewData.amount_type === 'fixed'" type="success" size="small">闭口合同</el-tag>
|
|
|
|
|
<el-tag v-else-if="viewData.amount_type === 'open'" type="warning" size="small">开口合同</el-tag>
|
|
|
|
|
<span v-else>-</span>
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="金额说明" v-if="viewData.amount_type === 'open'">{{ viewData.amount_description || '-' }}</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="金额说明">{{ viewData.amount_description || '-' }}</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="签订日期">{{ viewData.sign_date || '-' }}</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="申请日期">{{ viewData.apply_date || '-' }}</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="合同履行期">{{ viewData.perform_period || '-' }}</el-descriptions-item>
|
|
|
|
|
@ -556,15 +561,15 @@
|
|
|
|
|
<span v-else>-</span>
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="合同类型">
|
|
|
|
|
<span v-if="viewData.contractType">{{ viewData.contractType.name }}</span>
|
|
|
|
|
<span v-if="viewData.contract_type">{{ viewData.contract_type.name }}</span>
|
|
|
|
|
<span v-else>-</span>
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="采购类别">
|
|
|
|
|
<span v-if="viewData.purchaseCategory">{{ viewData.purchaseCategory.name }}</span>
|
|
|
|
|
<span v-if="viewData.purchase_category">{{ viewData.purchase_category.name }}</span>
|
|
|
|
|
<span v-else>-</span>
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="采购方式">
|
|
|
|
|
<span v-if="viewData.purchaseMethod">{{ viewData.purchaseMethod.name }}</span>
|
|
|
|
|
<span v-if="viewData.purchase_method">{{ viewData.purchase_method.name }}</span>
|
|
|
|
|
<span v-else>-</span>
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="是否政府采购">
|
|
|
|
|
@ -578,7 +583,7 @@
|
|
|
|
|
<el-tag v-else type="info" size="small">否</el-tag>
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="科室">
|
|
|
|
|
{{ getDepartmentName(viewData.owner_department_id) }}
|
|
|
|
|
{{ formatDepartmentNames(viewData) }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="合同签订/变更经办人">
|
|
|
|
|
{{ formatUserNames(viewData.handler_admin_ids) }}
|
|
|
|
|
@ -1359,7 +1364,11 @@ const rules = {
|
|
|
|
|
main_content: [{ required: true, message: '请填写合同主要内容', trigger: 'blur' }],
|
|
|
|
|
party_a: [{ required: true, message: '请填写甲方', trigger: 'blur' }],
|
|
|
|
|
party_b: [{ required: true, message: '请填写乙方', trigger: 'blur' }],
|
|
|
|
|
amount_total: [{ required: true, message: '请填写合同金额', trigger: 'blur' }],
|
|
|
|
|
amount_total: [{ validator: (rule, value, callback) => {
|
|
|
|
|
if (form.amount_type !== 'open' && (value === null || value === undefined || value === '')) {
|
|
|
|
|
callback(new Error('闭口合同请填写合同金额'))
|
|
|
|
|
} else { callback() }
|
|
|
|
|
}, trigger: ['blur', 'change'] }],
|
|
|
|
|
amount_type: [{ required: true, message: '请选择金额类型', trigger: 'change' }],
|
|
|
|
|
amount_description: [
|
|
|
|
|
{
|
|
|
|
|
@ -1397,7 +1406,7 @@ const rules = {
|
|
|
|
|
validator: (rule, value, callback) => {
|
|
|
|
|
// 默认必填,只有当合同类型明确是"收入类"时才撤销必填校验
|
|
|
|
|
const contractTypeName = getContractTypeName()
|
|
|
|
|
if (contractTypeName === '收入类') {
|
|
|
|
|
if (contractTypeName === '收入类' || canKeepLegacyFundSource()) {
|
|
|
|
|
// 收入类不需要必填
|
|
|
|
|
callback()
|
|
|
|
|
} else {
|
|
|
|
|
@ -1417,7 +1426,7 @@ const rules = {
|
|
|
|
|
validator: (rule, value, callback) => {
|
|
|
|
|
// 默认必填,只有当合同类型明确是"收入类"时才撤销必填校验
|
|
|
|
|
const contractTypeName = getContractTypeName()
|
|
|
|
|
if (contractTypeName === '收入类') {
|
|
|
|
|
if (contractTypeName === '收入类' || canKeepLegacyFundSource()) {
|
|
|
|
|
// 收入类不需要必填
|
|
|
|
|
callback()
|
|
|
|
|
} else {
|
|
|
|
|
@ -1636,6 +1645,12 @@ function fillPartyB() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
watch(() => form.amount_type, () => {
|
|
|
|
|
nextTick(() => {
|
|
|
|
|
formRef.value?.validateField(['amount_total', 'amount_description'], () => {})
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// 监听预算年度变化,刷新经费来源选项
|
|
|
|
|
watch(() => form.fund_source_year_id, (newVal) => {
|
|
|
|
|
if (newVal) {
|
|
|
|
|
@ -1703,6 +1718,8 @@ function getEmptyForm() {
|
|
|
|
|
fund_source_year_id: null,
|
|
|
|
|
fund_source_budget_data_id: null,
|
|
|
|
|
fund_source: '', // 保留旧字段,用于兼容
|
|
|
|
|
legacy_fund_source_display: '',
|
|
|
|
|
original_fund_source_year_id: null,
|
|
|
|
|
is_government_purchase: false,
|
|
|
|
|
tender_agent: '',
|
|
|
|
|
contract_type_id: null,
|
|
|
|
|
@ -1728,6 +1745,9 @@ function getEmptyForm() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function resetContractForm({ withDefaultPayPlan = false } = {}) {
|
|
|
|
|
for (const options of [contractTypeOptions, purchaseCategoryOptions, purchaseMethodOptions]) {
|
|
|
|
|
options.value = options.value.filter(option => !option._historical)
|
|
|
|
|
}
|
|
|
|
|
Object.assign(form, getEmptyForm())
|
|
|
|
|
payPlanDeleteIds.value = []
|
|
|
|
|
attachmentFileList.value = []
|
|
|
|
|
@ -1890,6 +1910,18 @@ async function fetchPurchaseCategoryOptions() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取合同类型名称
|
|
|
|
|
function preserveCurrentOption(options, current) {
|
|
|
|
|
options.value = options.value.filter(option => !option._historical)
|
|
|
|
|
if (current?.id && !options.value.some(option => String(option.id) === String(current.id))) {
|
|
|
|
|
options.value.push({ ...current, _historical: true })
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function canKeepLegacyFundSource() {
|
|
|
|
|
return !!form.id && !!form.legacy_fund_source_display && !form.fund_source_budget_data_id
|
|
|
|
|
&& String(form.fund_source_year_id || '') === String(form.original_fund_source_year_id || '')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getContractTypeName() {
|
|
|
|
|
if (!form.contract_type_id) {
|
|
|
|
|
return null
|
|
|
|
|
@ -2264,11 +2296,14 @@ async function loadDetail(id) {
|
|
|
|
|
if (response && response.code === 0) {
|
|
|
|
|
const data = response.data || response
|
|
|
|
|
|
|
|
|
|
data.original_fund_source_year_id = data.fund_source_year_id || null
|
|
|
|
|
data.legacy_fund_source_display = !data.fund_source_budget_data_id ? (data.fund_source_display || '') : ''
|
|
|
|
|
data.amount_total = data.amount_total == null ? null : Number(data.amount_total)
|
|
|
|
|
// 处理科室多选
|
|
|
|
|
if (data.owner_department_ids) {
|
|
|
|
|
data.owner_department_ids_array = data.owner_department_ids.split(',').filter(id => id)
|
|
|
|
|
} else {
|
|
|
|
|
data.owner_department_ids_array = []
|
|
|
|
|
data.owner_department_ids_array = data.owner_department_id ? [String(data.owner_department_id)] : []
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理经办人多选
|
|
|
|
|
@ -2333,6 +2368,10 @@ async function loadDetail(id) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
preserveCurrentOption(contractTypeOptions, data.contract_type)
|
|
|
|
|
preserveCurrentOption(purchaseCategoryOptions, data.purchase_category)
|
|
|
|
|
preserveCurrentOption(purchaseMethodOptions, data.purchase_method)
|
|
|
|
|
|
|
|
|
|
// 处理附件
|
|
|
|
|
if (data.attachment_id && data.attachment) {
|
|
|
|
|
attachmentFileList.value = [{
|
|
|
|
|
@ -2437,7 +2476,7 @@ function collectPayload() {
|
|
|
|
|
main_content: form.main_content,
|
|
|
|
|
party_a: form.party_a,
|
|
|
|
|
party_b: form.party_b,
|
|
|
|
|
amount_total: form.amount_total || 0,
|
|
|
|
|
amount_total: form.amount_total ?? null,
|
|
|
|
|
amount_type: form.amount_type || 'fixed',
|
|
|
|
|
amount_description: form.amount_description || '',
|
|
|
|
|
budget_amount: form.budget_amount || 0,
|
|
|
|
|
@ -2451,8 +2490,6 @@ function collectPayload() {
|
|
|
|
|
tender_agent: form.tender_agent,
|
|
|
|
|
contract_type_id: form.contract_type_id,
|
|
|
|
|
purchase_method_id: form.purchase_method_id,
|
|
|
|
|
contract_type: form.contract_type, // 保留旧字段,用于兼容
|
|
|
|
|
purchase_method: form.purchase_method, // 保留旧字段,用于兼容
|
|
|
|
|
perform_status: form.perform_status,
|
|
|
|
|
is_accepted: form.is_accepted || false,
|
|
|
|
|
purchase_category_id: form.purchase_category_id,
|
|
|
|
|
@ -2562,7 +2599,7 @@ function openRelatedPayment(payment) {
|
|
|
|
|
// 根据用户ID获取用户名称
|
|
|
|
|
function getUserName(userId) {
|
|
|
|
|
if (!userId) return '-'
|
|
|
|
|
const user = userList.value.find(u => u.id === userId)
|
|
|
|
|
const user = userList.value.find(u => String(u.id) === String(userId))
|
|
|
|
|
return user ? user.name : '-'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -2579,9 +2616,21 @@ function formatUserNames(userIds) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 根据科室ID获取科室名称
|
|
|
|
|
function formatContractAmount(contract) {
|
|
|
|
|
if (contract.amount_total == null || contract.amount_total === '') {
|
|
|
|
|
return contract.amount_type === 'open' ? '未确定' : '-'
|
|
|
|
|
}
|
|
|
|
|
return formatAmount(contract.amount_total)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function formatDepartmentNames(contract) {
|
|
|
|
|
const ids = String(contract.owner_department_ids || contract.owner_department_id || '').split(',').map(id => id.trim()).filter(Boolean)
|
|
|
|
|
return ids.map(id => departmentList.value.find(dept => String(dept.id) === id)?.name || id).join('、') || '-'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getDepartmentName(departmentId) {
|
|
|
|
|
if (!departmentId) return '-'
|
|
|
|
|
const dept = departmentList.value.find(d => d.id === departmentId)
|
|
|
|
|
const dept = departmentList.value.find(d => String(d.id) === String(departmentId))
|
|
|
|
|
return dept ? dept.name : '-'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|