321 lines
10 KiB
Markdown
321 lines
10 KiB
Markdown
# 项目申报表单集成步骤指南
|
||
|
||
## 🎯 目标
|
||
完成项目申报表单的绩效指标组件集成和金额字段修复
|
||
|
||
## 📋 前置条件
|
||
- ✅ 已创建 `PerformanceIndicators.vue` 组件
|
||
- ✅ 已创建 `performanceIndicator.ts` API接口
|
||
- ✅ 已修复表单数据结构
|
||
|
||
## 🔧 集成步骤
|
||
|
||
### 步骤1: 修复form.vue的模板部分
|
||
|
||
需要在 `web/src/views/cw/application/form.vue` 中添加完整的金额字段表单:
|
||
|
||
```vue
|
||
<!-- 第三步:资金预算 -->
|
||
<el-card shadow="never" class="form-card" v-show="currentStep === 2">
|
||
<template #header>
|
||
<div class="card-header">
|
||
<el-icon><Money /></el-icon>
|
||
<span>资金预算安排</span>
|
||
</div>
|
||
</template>
|
||
|
||
<el-form ref="budgetFormRef" :model="form" :rules="rules" label-width="140px">
|
||
<!-- 项目总投资 -->
|
||
<div class="budget-section">
|
||
<h4 class="section-title">项目总投资(万元)</h4>
|
||
<el-row :gutter="20">
|
||
<el-col :span="6">
|
||
<el-form-item label="合计" prop="totalInvestment">
|
||
<el-input-number v-model="form.totalInvestment" :min="0" :precision="2" style="width: 100%" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="6">
|
||
<el-form-item label="市财政资金" prop="totalMunicipalFiscal">
|
||
<el-input-number v-model="form.totalMunicipalFiscal" :min="0" :precision="2" style="width: 100%" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="6">
|
||
<el-form-item label="单位自筹" prop="totalSelfFunding">
|
||
<el-input-number v-model="form.totalSelfFunding" :min="0" :precision="2" style="width: 100%" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="6">
|
||
<el-form-item label="其他资金" prop="totalOtherFunding">
|
||
<el-input-number v-model="form.totalOtherFunding" :min="0" :precision="2" style="width: 100%" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
</div>
|
||
|
||
<!-- 年度预计执行数 -->
|
||
<div class="budget-section">
|
||
<h4 class="section-title">年度预计执行数(万元)</h4>
|
||
<el-row :gutter="20">
|
||
<el-col :span="6">
|
||
<el-form-item label="合计" prop="currentYearTotal">
|
||
<el-input-number v-model="form.currentYearTotal" :min="0" :precision="2" style="width: 100%" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="6">
|
||
<el-form-item label="市财政资金" prop="currentYearMunicipal">
|
||
<el-input-number v-model="form.currentYearMunicipal" :min="0" :precision="2" style="width: 100%" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="6">
|
||
<el-form-item label="单位自筹" prop="currentYearSelf">
|
||
<el-input-number v-model="form.currentYearSelf" :min="0" :precision="2" style="width: 100%" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="6">
|
||
<el-form-item label="其他资金" prop="currentYearOther">
|
||
<el-input-number v-model="form.currentYearOther" :min="0" :precision="2" style="width: 100%" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
</div>
|
||
|
||
<!-- 下年度申请资金 -->
|
||
<div class="budget-section">
|
||
<h4 class="section-title">下年度申请资金(万元)</h4>
|
||
<el-row :gutter="20">
|
||
<el-col :span="6">
|
||
<el-form-item label="合计" prop="nextYearTotal">
|
||
<el-input-number v-model="form.nextYearTotal" :min="0" :precision="2" style="width: 100%" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="6">
|
||
<el-form-item label="市财政资金" prop="nextYearMunicipal">
|
||
<el-input-number v-model="form.nextYearMunicipal" :min="0" :precision="2" style="width: 100%" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="6">
|
||
<el-form-item label="单位自筹" prop="nextYearSelf">
|
||
<el-input-number v-model="form.nextYearSelf" :min="0" :precision="2" style="width: 100%" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="6">
|
||
<el-form-item label="其他资金" prop="nextYearOther">
|
||
<el-input-number v-model="form.nextYearOther" :min="0" :precision="2" style="width: 100%" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
</div>
|
||
|
||
<!-- 以后年度安排 -->
|
||
<div class="budget-section">
|
||
<h4 class="section-title">以后年度安排(万元)</h4>
|
||
<el-row :gutter="20">
|
||
<el-col :span="6">
|
||
<el-form-item label="合计" prop="futureYearTotal">
|
||
<el-input-number v-model="form.futureYearTotal" :min="0" :precision="2" style="width: 100%" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="6">
|
||
<el-form-item label="市财政资金" prop="futureYearMunicipal">
|
||
<el-input-number v-model="form.futureYearMunicipal" :min="0" :precision="2" style="width: 100%" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="6">
|
||
<el-form-item label="单位自筹" prop="futureYearSelf">
|
||
<el-input-number v-model="form.futureYearSelf" :min="0" :precision="2" style="width: 100%" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="6">
|
||
<el-form-item label="其他资金" prop="futureYearOther">
|
||
<el-input-number v-model="form.futureYearOther" :min="0" :precision="2" style="width: 100%" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
</div>
|
||
</el-form>
|
||
</el-card>
|
||
```
|
||
|
||
### 步骤2: 注册PerformanceIndicators组件
|
||
|
||
在 `web/src/views/cw/application/form.vue` 的script部分添加:
|
||
|
||
```javascript
|
||
// 注册组件
|
||
import PerformanceIndicators from './components/PerformanceIndicators.vue'
|
||
|
||
// 在组件定义中添加
|
||
export default {
|
||
components: {
|
||
PerformanceIndicators
|
||
},
|
||
// ... 其他配置
|
||
}
|
||
```
|
||
|
||
### 步骤3: 修复API导入错误
|
||
|
||
确保 `web/src/api/cw/projectApplication.ts` 文件存在并包含正确的API方法:
|
||
|
||
```typescript
|
||
// 项目申报相关API
|
||
export const addProjectApplication = (data: any) => {
|
||
return request({
|
||
url: '/cw/application',
|
||
method: 'post',
|
||
data: data
|
||
});
|
||
};
|
||
|
||
export const updateProjectApplication = (data: any) => {
|
||
return request({
|
||
url: '/cw/application',
|
||
method: 'put',
|
||
data: data
|
||
});
|
||
};
|
||
|
||
export const getProjectApplication = (id: string | number) => {
|
||
return request({
|
||
url: '/cw/application/' + id,
|
||
method: 'get'
|
||
});
|
||
};
|
||
|
||
export const submitApplication = (id: string | number) => {
|
||
return request({
|
||
url: '/cw/application/submit/' + id,
|
||
method: 'post'
|
||
});
|
||
};
|
||
```
|
||
|
||
### 步骤4: 更新保存逻辑
|
||
|
||
修复 `handleSaveDraft` 和 `handleSubmit` 方法:
|
||
|
||
```javascript
|
||
import { batchSavePerformanceIndicator } from '@/api/cw/performanceIndicator'
|
||
|
||
// 保存草稿
|
||
const handleSaveDraft = async () => {
|
||
try {
|
||
savingDraft.value = true
|
||
|
||
// 1. 保存申报基本信息
|
||
let result
|
||
if (form.id) {
|
||
result = await updateProjectApplication(form)
|
||
} else {
|
||
result = await addProjectApplication(form)
|
||
if (result && result.data) {
|
||
form.id = result.data.id
|
||
form.applicationNo = result.data.applicationNo
|
||
}
|
||
}
|
||
|
||
// 2. 保存绩效指标
|
||
if (form.id && form.performanceIndicators.length > 0) {
|
||
await batchSavePerformanceIndicator(form.id, form.applicationNo, form.performanceIndicators)
|
||
}
|
||
|
||
ElMessage.success('草稿保存成功')
|
||
router.push('/cw/application')
|
||
} catch (error) {
|
||
ElMessage.error('保存失败:' + error.message)
|
||
} finally {
|
||
savingDraft.value = false
|
||
}
|
||
}
|
||
|
||
// 提交申报
|
||
const handleSubmit = async () => {
|
||
try {
|
||
// 1. 验证绩效指标
|
||
const performanceValidation = performanceFormRef.value?.validate()
|
||
if (performanceValidation && !performanceValidation.valid) {
|
||
ElMessage.error(performanceValidation.message)
|
||
return
|
||
}
|
||
|
||
submitting.value = true
|
||
|
||
// 2. 先保存草稿
|
||
await handleSaveDraft()
|
||
|
||
// 3. 提交审批
|
||
if (form.id) {
|
||
await submitApplication(form.id)
|
||
ElMessage.success('提交成功,已进入审批流程')
|
||
router.push('/cw/application')
|
||
}
|
||
} catch (error) {
|
||
ElMessage.error('提交失败:' + error.message)
|
||
} finally {
|
||
submitting.value = false
|
||
}
|
||
}
|
||
```
|
||
|
||
### 步骤5: 添加表单验证
|
||
|
||
更新验证规则:
|
||
|
||
```javascript
|
||
const rules = {
|
||
projectName: [
|
||
{ required: true, message: '请输入项目名称', trigger: 'blur' }
|
||
],
|
||
principal: [
|
||
{ required: true, message: '请输入项目负责人', trigger: 'blur' }
|
||
],
|
||
totalInvestment: [
|
||
{ required: true, message: '请填写项目总投资', trigger: 'blur' },
|
||
{ type: 'number', min: 0.01, message: '投资金额必须大于0', trigger: 'blur' }
|
||
],
|
||
// ... 其他验证规则
|
||
}
|
||
```
|
||
|
||
### 步骤6: 测试功能
|
||
|
||
1. **新增申报测试**:
|
||
- 填写基本信息
|
||
- 填写项目内容
|
||
- 填写完整的资金预算(所有金额字段)
|
||
- 添加绩效指标(确保分值总和为100%)
|
||
- 保存草稿,检查数据库是否正确保存
|
||
|
||
2. **修改申报测试**:
|
||
- 打开已保存的申报
|
||
- 修改金额和绩效指标
|
||
- 重新保存,验证数据更新
|
||
|
||
3. **提交流程测试**:
|
||
- 完成申报填写
|
||
- 点击提交,确认审批流程创建成功
|
||
|
||
## 🚨 常见问题解决
|
||
|
||
### 问题1: API导入错误
|
||
**解决方案**: 确保API文件路径正确,检查 `@/api/cw/` 目录下的文件是否存在
|
||
|
||
### 问题2: 绩效指标组件不显示
|
||
**解决方案**: 检查组件导入路径,确保 `PerformanceIndicators.vue` 文件存在
|
||
|
||
### 问题3: 金额字段保存失败
|
||
**解决方案**: 检查前端字段名与后端BO类字段名是否严格匹配
|
||
|
||
### 问题4: 分值验证错误
|
||
**解决方案**: 检查绩效指标组件的 `validate()` 方法是否正确调用
|
||
|
||
## ✅ 验收标准
|
||
|
||
- [ ] 所有金额字段能正确显示和编辑
|
||
- [ ] 绩效指标分类显示正确(产出指标、效益指标、满意度指标)
|
||
- [ ] 绩效指标验证规则正常工作(必填项、分值总和100%)
|
||
- [ ] 保存草稿功能正常
|
||
- [ ] 提交申报功能正常
|
||
- [ ] 数据库中申报信息和绩效指标数据完整
|
||
|
||
完成这些步骤后,项目申报功能将完全满足业务需求。 |