weizong song 4 months ago
parent 00a562d210
commit 9501e691a9

@ -156,4 +156,5 @@ export function getEconomicClassifications(params) {
method: 'get',
params
})
}
}

@ -100,3 +100,20 @@ export function getChildrenPerformanceIndicators(parentId) {
params: { parent_id: parentId }
})
}
// 获取多包汇总提交数据
export function getMultiPackageDecomposition(packageId) {
return request({
url: `/api/ht/budget-decompositions/${packageId}`,
method: 'get'
})
}
// 提交多包汇总分解表(原多包汇总提交)
export function submitMultiPackageDecomposition(data) {
return request({
url: '/api/ht/budget-decompositions/multi-package',
method: 'post',
data
})
}

@ -0,0 +1,388 @@
<template>
<div class="big-package-detail-container">
<!-- 大包基本信息 -->
<div class="detail-section">
<div class="section-title">
<i class="el-icon-info"></i>
大包基本信息
</div>
<div class="info-grid">
<div class="info-item">
<label>预算包名称</label>
<span>{{ packageData.name || '-' }}</span>
</div>
<div class="info-item">
<label>预算年度</label>
<span>{{ packageData.budget_year ? packageData.budget_year.year + '年' : '-' }}</span>
</div>
<div class="info-item">
<label>负责科室</label>
<span>{{ getDepartmentName(packageData.department_id) }}</span>
</div>
<div class="info-item">
<label>分配金额</label>
<span class="amount">{{ formatCurrency(packageData.allocated_amount) }} 万元</span>
</div>
<div class="info-item">
<label>层级</label>
<el-tag :type="getLevelTagType(packageData.level)" size="small">
{{ getLevelText(packageData.level) }}
</el-tag>
</div>
<div class="info-item">
<label>创建时间</label>
<span>{{ formatDate(packageData.created_at) }}</span>
</div>
</div>
</div>
<!-- 下级预算包汇总 -->
<div class="detail-section" v-if="childPackages.length > 0">
<div class="section-title">
<i class="el-icon-s-data"></i>
下级预算包情况
</div>
<el-table
:data="childPackages"
border
size="small"
show-summary
:summary-method="getChildPackageSummaries"
>
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column label="预算包名称" min-width="200">
<template slot-scope="scope">
<span>{{ scope.row.name }}</span>
</template>
</el-table-column>
<el-table-column label="层级" width="80" align="center">
<template slot-scope="scope">
<el-tag :type="getLevelTagType(scope.row.level)" size="mini">
{{ getLevelText(scope.row.level) }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="负责科室" width="120" align="center">
<template slot-scope="scope">
<span>{{ getDepartmentName(scope.row.department_id) }}</span>
</template>
</el-table-column>
<el-table-column label="分配金额(万元)" width="120" align="right">
<template slot-scope="scope">
<span style="color: #409EFF; font-weight: bold;">{{ formatCurrency(scope.row.allocated_amount) }}</span>
</template>
</el-table-column>
<el-table-column label="分解金额(万元)" width="120" align="right">
<template slot-scope="scope">
<span v-if="scope.row.decomposed_amount" style="color: #67C23A; font-weight: bold;">
{{ formatCurrency(scope.row.decomposed_amount) }}
</span>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="创建时间" width="160" align="center">
<template slot-scope="scope">
<span>{{ formatDate(scope.row.created_at) }}</span>
</template>
</el-table-column>
</el-table>
</div>
<!-- 经济分类汇总 -->
<div class="detail-section" v-if="economicSummary.length > 0">
<div class="section-title">
<i class="el-icon-s-grid"></i>
经济分类汇总
</div>
<el-table
:data="economicSummary"
border
size="small"
show-summary
:summary-method="getEconomicSummaries"
>
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column label="经济分类" min-width="200">
<template slot-scope="scope">
<span>{{ scope.row.name }}</span>
</template>
</el-table-column>
<el-table-column label="金额(万元)" width="150" align="right">
<template slot-scope="scope">
<span style="color: #67C23A; font-weight: bold;">{{ formatCurrency(scope.row.amount) }}</span>
</template>
</el-table-column>
<el-table-column label="占比" width="100" align="center">
<template slot-scope="scope">
<span>{{ getPercentage(scope.row.amount, packageData.allocated_amount) }}%</span>
</template>
</el-table-column>
</el-table>
</div>
<!-- 统计信息 -->
<div class="detail-section">
<div class="section-title">
<i class="el-icon-data-analysis"></i>
统计信息
</div>
<div class="stats-grid">
<div class="stat-item">
<div class="stat-label">下级预算包数量</div>
<div class="stat-value">{{ childPackages.length }} </div>
</div>
<div class="stat-item">
<div class="stat-label">经济分类数量</div>
<div class="stat-value">{{ economicSummary.length }} </div>
</div>
<div class="stat-item">
<div class="stat-label">总分配金额</div>
<div class="stat-value amount">{{ formatCurrency(packageData.allocated_amount) }} 万元</div>
</div>
<div class="stat-item">
<div class="stat-label">总分解金额</div>
<div class="stat-value amount">{{ formatCurrency(getTotalDecomposedAmount()) }} 万元</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'BigPackageDetailView',
props: {
packageData: {
type: Object,
required: true
},
childPackages: {
type: Array,
default: () => []
},
economicSummary: {
type: Array,
default: () => []
},
departmentOptions: {
type: Object,
default: () => ({ data: [] })
}
},
methods: {
getDepartmentName(departmentId) {
if (!departmentId || !this.departmentOptions.data) return '-'
const dept = this.departmentOptions.data.find(d => d.id === departmentId)
return dept ? dept.name : '-'
},
getLevelTagType(level) {
const typeMap = {
1: 'primary',
2: 'success',
3: 'warning'
}
return typeMap[level] || 'info'
},
getLevelText(level) {
const textMap = {
1: '大包',
2: '中包',
3: '经济分类'
}
return textMap[level] || '未知'
},
getChildPackageSummaries(param) {
const { columns, data } = param
const sums = []
columns.forEach((column, index) => {
if (index === 0) {
sums[index] = '合计'
return
}
if (index === 4) { //
const total = data.reduce((prev, curr) => {
return prev + (Number(curr.allocated_amount) || 0)
}, 0)
sums[index] = this.formatCurrency(total)
} else if (index === 5) { //
const total = data.reduce((prev, curr) => {
return prev + (Number(curr.decomposed_amount) || 0)
}, 0)
sums[index] = this.formatCurrency(total)
} else {
sums[index] = ''
}
})
return sums
},
getEconomicSummaries(param) {
const { columns, data } = param
const sums = []
columns.forEach((column, index) => {
if (index === 0) {
sums[index] = '合计'
return
}
if (index === 2) { //
const total = data.reduce((prev, curr) => {
return prev + (Number(curr.amount) || 0)
}, 0)
sums[index] = this.formatCurrency(total)
} else {
sums[index] = ''
}
})
return sums
},
getTotalDecomposedAmount() {
return this.childPackages.reduce((total, pkg) => {
return total + (Number(pkg.decomposed_amount) || 0)
}, 0)
},
getPercentage(amount, total) {
if (!total || total === 0) return '0.0'
const percentage = (amount / total) * 100
return percentage.toFixed(1)
},
formatCurrency(amount) {
if (amount === null || amount === undefined || amount === '') return '0.0'
const num = Number(amount)
return isFinite(num) ? num.toFixed(1) : '0.0'
},
formatDate(dateStr) {
if (!dateStr) return '-'
const date = new Date(dateStr)
return date.toLocaleDateString('zh-CN') + ' ' + date.toLocaleTimeString('zh-CN', {
hour12: false,
hour: '2-digit',
minute: '2-digit'
})
}
}
}
</script>
<style scoped>
.big-package-detail-container {
padding: 20px;
max-height: 80vh;
overflow-y: auto;
}
.detail-section {
margin-bottom: 30px;
border: 1px solid #ebeef5;
border-radius: 4px;
overflow: hidden;
}
.section-title {
display: flex;
align-items: center;
font-size: 16px;
font-weight: bold;
color: #303133;
padding: 15px 20px;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
border-bottom: 1px solid #ebeef5;
}
.section-title i {
margin-right: 8px;
color: #409EFF;
}
.info-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 15px;
padding: 20px;
}
.info-item {
display: flex;
align-items: center;
}
.info-item label {
font-weight: bold;
color: #606266;
width: 100px;
flex-shrink: 0;
}
.info-item span {
color: #303133;
}
.info-item .amount {
color: #409EFF;
font-weight: bold;
}
.stats-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
padding: 20px;
}
.stat-item {
text-align: center;
padding: 15px;
background-color: #f8f9fa;
border-radius: 6px;
border: 1px solid #e9ecef;
}
.stat-label {
font-size: 14px;
color: #606266;
margin-bottom: 8px;
}
.stat-value {
font-size: 18px;
font-weight: bold;
color: #303133;
}
.stat-value.amount {
color: #409EFF;
}
/* 表格内容样式 */
.detail-section >>> .el-table {
margin: 0;
}
.detail-section >>> .el-table th {
background-color: #f8f9fa !important;
color: #606266;
font-weight: 600;
}
.detail-section >>> .el-table__footer-wrapper .el-table__footer {
font-weight: bold;
background-color: #f0f9ff;
}
.detail-section >>> .el-table td {
border-color: #ebeef5;
}
</style>

@ -800,8 +800,8 @@ export default {
console.warn('获取项目名称失败:', error.message)
}
// packagesubmission
if (this.packageData.level == 2) {
// packagesubmission
if (this.packageData.level == 1 || this.packageData.level == 2) {
this.parentSubmissionInfo = {
application_basis: (this.packageData.application_basis) || '',
application_purpose: (this.packageData.application_purpose) || '',

@ -879,6 +879,7 @@ export default {
},
async initFormData() {
console.log('initFormData', this.packageData)
this.formData.packageId = this.packageData.id
this.formData.leadDepartmentName = this.packageData.lead_department ? this.packageData.lead_department.name : ''
this.formData.budgetYear = this.packageData.budget_year ? this.packageData.budget_year.year + '年' : ''
@ -1198,7 +1199,7 @@ export default {
otherNotes: data.otherNotes || data.other_notes || ''
}
console.log('从API获取的汇总数据:', this.formData)
console.log('从API获取的数据:', this.formData)
//
if (data.economicSummary && data.economicSummary.length > 0) {

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save