提交代码

This commit is contained in:
zlwu committed 2025-11-14 06:49:39 +08:00
1 parent 970979b2c1
commit dfd5f361fa
2 files changed
+426 -348

No files matched your search

+361 -326
View File
@@ -7,39 +7,46 @@
<el-form :model="queryParams" ref="queryFormRef" label-width="100px">
<el-row :gutter="20">
<el-col :span="6">
<el-form-item label="项目名称" prop="projectName">
<el-form-item label="项目名称" prop="projectName">
<el-input v-model="queryParams.projectName" placeholder="请输入项目名称" clearable @keyup.enter="handleQuery" />
</el-form-item>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="自评年度" prop="evaluationYear">
<el-date-picker v-model="queryParams.evaluationYear" type="year" placeholder="选择年度" clearable value-format="YYYY" style="width: 100%" />
</el-form-item>
<el-form-item label="自评年度" prop="evaluationYear">
<el-date-picker
v-model="queryParams.evaluationYear"
type="year"
placeholder="选择年度"
clearable
value-format="YYYY"
style="width: 100%"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="自评状态" prop="evaluationStatus">
<el-form-item label="自评状态" prop="evaluationStatus">
<el-select v-model="queryParams.evaluationStatus" placeholder="请选择自评状态" clearable style="width: 100%">
<el-option v-for="dict in cw_evaluation_status" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-option v-for="dict in cw_evaluation_status" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="自评等级" prop="selfEvaluationLevel">
<el-form-item label="自评等级" prop="selfEvaluationLevel">
<el-select v-model="queryParams.selfEvaluationLevel" placeholder="请选择自评等级" clearable style="width: 100%">
<el-option v-for="dict in cw_evaluation_level" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-option v-for="dict in cw_evaluation_level" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
<el-row>
<el-col :span="24" class="search-btn-container">
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-form>
</el-card>
</div>
</transition>
@@ -47,15 +54,15 @@
<!-- 表格区域 -->
<el-card shadow="never" class="button-card table-card">
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['cw:evaluation:add']">新增自评</el-button>
</el-col>
<el-col :span="1.5">
</el-col>
<el-col :span="1.5">
<el-button icon="Download" @click="handleExport" v-hasPermi="['cw:evaluation:export']">导出</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
</template>
<div class="table-container">
@@ -68,32 +75,32 @@
class="scroll-table"
>
<el-table-column type="selection" width="55" align="center" fixed="left" />
<el-table-column label="项目名称" align="center" prop="projectName" show-overflow-tooltip min-width="200" />
<el-table-column label="申报编号" align="center" prop="applicationNo" width="150" />
<el-table-column label="自评年度" align="center" prop="evaluationYear" width="100" />
<el-table-column label="自评总分" align="center" prop="totalScore" width="100">
<template #default="scope">
<el-table-column label="项目名称" align="center" prop="projectName" show-overflow-tooltip min-width="200" />
<el-table-column label="申报编号" align="center" prop="applicationNo" width="150" />
<el-table-column label="自评年度" align="center" prop="evaluationYear" width="100" />
<el-table-column label="自评总分" align="center" prop="totalScore" width="100">
<template #default="scope">
<el-tag v-if="scope.row.totalScore >= 90" type="success" size="small">{{ scope.row.totalScore }}</el-tag>
<el-tag v-else-if="scope.row.totalScore >= 80" type="primary" size="small">{{ scope.row.totalScore }}</el-tag>
<el-tag v-else-if="scope.row.totalScore >= 60" type="warning" size="small">{{ scope.row.totalScore }}</el-tag>
<el-tag v-else-if="scope.row.totalScore" type="danger" size="small">{{ scope.row.totalScore }}</el-tag>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="自评等级" align="center" prop="selfEvaluationLevel" width="100">
<template #default="scope">
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="自评等级" align="center" prop="selfEvaluationLevel" width="100">
<template #default="scope">
<el-tag v-if="scope.row.selfEvaluationLevel === '优秀'" type="success" size="small">优秀</el-tag>
<el-tag v-else-if="scope.row.selfEvaluationLevel === '良好'" type="primary" size="small">良好</el-tag>
<el-tag v-else-if="scope.row.selfEvaluationLevel === '合格'" type="warning" size="small">合格</el-tag>
<el-tag v-else-if="scope.row.selfEvaluationLevel === '不合格'" type="danger" size="small">不合格</el-tag>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="自评状态" align="center" prop="evaluationStatus" width="100">
<template #default="scope">
<dict-tag :options="cw_evaluation_status" :value="scope.row.evaluationStatus" />
</template>
</el-table-column>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="自评状态" align="center" prop="evaluationStatus" width="100">
<template #default="scope">
<dict-tag :options="cw_evaluation_status" :value="scope.row.evaluationStatus" />
</template>
</el-table-column>
<el-table-column label="锁定状态" align="center" prop="isLocked" width="120">
<template #default="scope">
<el-tag v-if="scope.row.isLocked === 1" type="warning" effect="dark" size="small">
@@ -102,21 +109,43 @@
<el-tag v-else type="success" effect="plain" size="small">未锁定</el-tag>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<template #default="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<template #default="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="320" fixed="right" class-name="small-padding fixed-width">
<template #default="scope">
<template #default="scope">
<el-button link type="primary" icon="View" @click="handleView(scope.row)" v-hasPermi="['cw:evaluation:query']"></el-button>
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['cw:evaluation:edit']" :disabled="scope.row.isLocked === 1"></el-button>
<el-button
link
type="primary"
icon="Edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['cw:evaluation:edit']"
:disabled="scope.row.isLocked === 1"
></el-button>
<el-button link type="warning" icon="Monitor" @click="handleMonitoring(scope.row)" v-hasPermi="['cw:monitoring:query']"></el-button>
<el-button link type="success" icon="Check" @click="handleSubmit(scope.row)" v-hasPermi="['cw:evaluation:submit']" v-if="scope.row.evaluationStatus === 'draft'" :disabled="scope.row.isLocked === 1"></el-button>
<el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['cw:evaluation:remove']" v-if="scope.row.evaluationStatus === 'draft'"></el-button>
</template>
</el-table-column>
</el-table>
<el-button
link
type="success"
icon="Check"
@click="handleSubmit(scope.row)"
v-hasPermi="['cw:evaluation:submit']"
v-if="scope.row.evaluationStatus === 'draft'"
:disabled="scope.row.isLocked === 1"
></el-button>
<el-button
link
type="danger"
icon="Delete"
@click="handleDelete(scope.row)"
v-hasPermi="['cw:evaluation:remove']"
v-if="scope.row.evaluationStatus === 'draft'"
></el-button>
</template>
</el-table-column>
</el-table>
</div>
<!-- 分页组件 -->
@@ -126,44 +155,26 @@
</el-card>
<!-- 新增/编辑/查看弹窗 - 使用表格样式 -->
<el-dialog
v-model="dialogVisible"
:title="dialogTitle"
width="95%"
top="5vh"
:close-on-click-modal="false"
destroy-on-close
>
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="95%" top="5vh" :close-on-click-modal="false" destroy-on-close>
<!-- 锁定状态提示 -->
<el-alert
v-if="formData.isLocked === 1"
type="warning"
:closable="false"
show-icon
style="margin-bottom: 20px;"
>
<el-alert v-if="formData.isLocked === 1" type="warning" :closable="false" show-icon style="margin-bottom: 20px">
<template #title>
<span>该绩效自评已锁定,不允许修改。锁定时间:{{ formData.lockTime ? parseTime(formData.lockTime) : '-' }},锁定人:{{ formData.lockByName || '-' }}</span>
<span
>该绩效自评已锁定,不允许修改。锁定时间:{{ formData.lockTime ? parseTime(formData.lockTime) : '-' }},锁定人:{{
formData.lockByName || '-'
}}</span
>
</template>
</el-alert>
<!-- 使用表格样式组件 -->
<TableForm
ref="tableFormRef"
:form-data="formData"
:disabled="dialogMode === 'view' || formData.isLocked === 1"
/>
<TableForm ref="tableFormRef" :form-data="formData" :disabled="dialogMode === 'view' || formData.isLocked === 1" />
<!-- 查看详情时显示运行监控数据 -->
<div v-if="dialogMode === 'view'" style="margin-top: 30px;">
<div v-if="dialogMode === 'view'" style="margin-top: 30px">
<el-divider content-position="left">
<h3 style="margin: 0;">运行监控数据</h3>
<h3 style="margin: 0">运行监控数据</h3>
</el-divider>
<el-table
v-if="formData.monitoringList && formData.monitoringList.length > 0"
:data="formData.monitoringList"
border
style="width: 100%;"
>
<el-table v-if="formData.monitoringList && formData.monitoringList.length > 0" :data="formData.monitoringList" border style="width: 100%">
<el-table-column label="序号" type="index" width="60" align="center" />
<el-table-column label="监控周期" align="center" prop="monitoringPeriod" width="150" />
<el-table-column label="填报时间" align="center" prop="createTime" width="160">
@@ -177,12 +188,7 @@
<el-table-column label="绩效目标完成情况" align="center" prop="performanceTargetCompletion" show-overflow-tooltip min-width="200" />
<el-table-column label="操作" align="center" width="100" fixed="right">
<template #default="scope">
<el-button
link
type="primary"
icon="View"
@click="handleViewMonitoringDetail(scope.row)"
>查看</el-button>
<el-button link type="primary" icon="View" @click="handleViewMonitoringDetail(scope.row)">查看</el-button>
</template>
</el-table-column>
</el-table>
@@ -192,18 +198,8 @@
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogVisible = false">{{ dialogMode === 'view' ? '关闭' : '取消' }}</el-button>
<el-button
v-if="dialogMode !== 'view'"
type="info"
@click="handleSaveDraft"
:disabled="formData.isLocked === 1"
>保存草稿</el-button>
<el-button
v-if="dialogMode !== 'view'"
type="primary"
@click="handleFormSubmit"
:disabled="formData.isLocked === 1"
>提交自评</el-button>
<el-button v-if="dialogMode !== 'view'" type="info" @click="handleSaveDraft" :disabled="formData.isLocked === 1">保存草稿</el-button>
<el-button v-if="dialogMode !== 'view'" type="primary" @click="handleFormSubmit" :disabled="formData.isLocked === 1">提交自评</el-button>
</div>
</template>
</el-dialog>
@@ -214,37 +210,49 @@
</template>
<script setup name="CwEvaluation" lang="ts">
import { Lock } from '@element-plus/icons-vue'
import { listEvaluation, getEvaluation, delEvaluation, addEvaluation, updateEvaluation, saveDraft, submitEvaluation, exportEvaluation, listPerformanceMonitoring } from '@/api/cw/performanceEvaluation'
import type { CwProjectPerformanceSelfEvaluationVO, CwProjectPerformanceSelfEvaluationQuery, CwProjectPerformanceSelfEvaluationForm } from '@/api/cw/performanceEvaluation'
import TableForm from './table-form.vue'
import MonitoringDialog from './components/MonitoringDialog.vue'
import { Lock } from '@element-plus/icons-vue';
import {
listEvaluation,
getEvaluation,
delEvaluation,
addEvaluation,
updateEvaluation,
saveDraft,
submitEvaluation,
exportEvaluation,
listPerformanceMonitoring
} from '@/api/cw/performanceEvaluation';
import type {
CwProjectPerformanceSelfEvaluationVO,
CwProjectPerformanceSelfEvaluationQuery,
CwProjectPerformanceSelfEvaluationForm
} from '@/api/cw/performanceEvaluation';
import TableForm from './table-form.vue';
import MonitoringDialog from './components/MonitoringDialog.vue';
const { proxy } = getCurrentInstance() as ComponentInternalInstance
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
// 加载字典数据
const { cw_evaluation_status, cw_evaluation_level } = toRefs<any>(
proxy?.useDict('cw_evaluation_status', 'cw_evaluation_level') || {}
)
const { cw_evaluation_status, cw_evaluation_level } = toRefs<any>(proxy?.useDict('cw_evaluation_status', 'cw_evaluation_level') || {});
const evaluationList = ref<CwProjectPerformanceSelfEvaluationVO[]>([])
const loading = ref(true)
const showSearch = ref(true)
const ids = ref<Array<number>>([])
const single = ref(true)
const multiple = ref(true)
const total = ref(0)
const evaluationList = ref<CwProjectPerformanceSelfEvaluationVO[]>([]);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref<Array<number>>([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const queryFormRef = ref<ElFormInstance>()
const formRef = ref<ElFormInstance>()
const tableFormRef = ref<any>()
const monitoringDialogRef = ref<any>()
const queryFormRef = ref<ElFormInstance>();
const formRef = ref<ElFormInstance>();
const tableFormRef = ref<any>();
const monitoringDialogRef = ref<any>();
// 弹窗相关状态
const dialogVisible = ref(false)
const dialogTitle = ref('')
const dialogMode = ref<'add' | 'edit' | 'view'>('add')
const dateRange = ref<string[]>([])
const dialogVisible = ref(false);
const dialogTitle = ref('');
const dialogMode = ref<'add' | 'edit' | 'view'>('add');
const dateRange = ref<string[]>([]);
// 表单数据
// 🔧 修复:初始化完整的表单对象,包含所有字段
@@ -378,7 +386,7 @@ const formData = ref<CwProjectPerformanceSelfEvaluationForm>({
// 运行监控数据列表(查看详情时返回)
monitoringList: [] as any[]
})
});
// 表单验证规则
const rules = ref({
@@ -400,10 +408,10 @@ const rules = ref({
{ required: true, message: '项目效益得分不能为空', trigger: 'blur' },
{ type: 'number', min: 0, max: 30, message: '得分范围0-30分', trigger: 'blur' }
]
})
});
const data = reactive<{
queryParams: CwProjectPerformanceSelfEvaluationQuery
queryParams: CwProjectPerformanceSelfEvaluationQuery;
}>({
queryParams: {
pageNum: 1,
@@ -413,78 +421,72 @@ const data = reactive<{
evaluationStatus: undefined,
selfEvaluationLevel: undefined
}
})
});
const { queryParams } = toRefs(data)
const { queryParams } = toRefs(data);
// 计算总分
const totalScore = computed(() => {
return (formData.value.decisionScore || 0) +
(formData.value.processScore || 0) +
(formData.value.outputScore || 0) +
(formData.value.benefitScore || 0)
})
return (
(formData.value.decisionScore || 0) + (formData.value.processScore || 0) + (formData.value.outputScore || 0) + (formData.value.benefitScore || 0)
);
});
const totalScoreDisplay = computed(() => totalScore.value.toFixed(2))
const totalScoreDisplay = computed(() => totalScore.value.toFixed(2));
// 自动计算等级
const evaluationLevel = computed(() => {
const score = totalScore.value
if (score >= 90) return '优秀'
if (score >= 80) return '良好'
if (score >= 60) return '合格'
return '不合格'
})
const score = totalScore.value;
if (score >= 90) return '优秀';
if (score >= 80) return '良好';
if (score >= 60) return '合格';
return '不合格';
});
const evaluationLevelDisplay = computed(() => evaluationLevel.value)
const evaluationLevelDisplay = computed(() => evaluationLevel.value);
const levelTagType = computed(() => {
const level = evaluationLevel.value
if (level === '优秀') return 'success'
if (level === '良好') return 'primary'
if (level === '合格') return 'warning'
return 'danger'
})
const level = evaluationLevel.value;
if (level === '优秀') return 'success';
if (level === '良好') return 'primary';
if (level === '合格') return 'warning';
return 'danger';
});
// 计算预算执行率
const budgetExecutionRate = computed(() => {
if (formData.value.annualBudget && formData.value.actualExpenditure) {
return (formData.value.actualExpenditure / formData.value.annualBudget * 100).toFixed(2)
return ((formData.value.actualExpenditure / formData.value.annualBudget) * 100).toFixed(2);
}
return '0.00'
})
return '0.00';
});
const budgetExecutionRateDisplay = computed(() => budgetExecutionRate.value)
const budgetExecutionRateDisplay = computed(() => budgetExecutionRate.value);
// 监听评分变化,自动更新总分和等级
watch([
() => formData.value.decisionScore,
() => formData.value.processScore,
() => formData.value.outputScore,
() => formData.value.benefitScore
], () => {
formData.value.totalScore = totalScore.value
formData.value.selfEvaluationLevel = evaluationLevel.value
})
watch(
[() => formData.value.decisionScore, () => formData.value.processScore, () => formData.value.outputScore, () => formData.value.benefitScore],
() => {
formData.value.totalScore = totalScore.value;
formData.value.selfEvaluationLevel = evaluationLevel.value;
}
);
// 监听预算和支出变化,自动更新执行率
watch([
() => formData.value.annualBudget,
() => formData.value.actualExpenditure
], () => {
watch([() => formData.value.annualBudget, () => formData.value.actualExpenditure], () => {
if (formData.value.annualBudget && formData.value.actualExpenditure) {
formData.value.budgetExecutionRate = parseFloat(budgetExecutionRate.value)
formData.value.budgetExecutionRate = parseFloat(budgetExecutionRate.value);
}
})
});
// 处理日期范围变化
function handleDateRangeChange(dates: string[]) {
if (dates && dates.length === 2) {
formData.value.startDate = dates[0]
formData.value.endDate = dates[1]
formData.value.startDate = dates[0];
formData.value.endDate = dates[1];
} else {
formData.value.startDate = undefined
formData.value.endDate = undefined
formData.value.startDate = undefined;
formData.value.endDate = undefined;
}
}
@@ -618,14 +620,14 @@ function resetForm() {
improvementMeasures: '',
evaluationStatus: 'draft',
remark: ''
}
dateRange.value = []
formRef.value?.resetFields()
};
dateRange.value = [];
formRef.value?.resetFields();
}
/** 转换后端返回的字符串数字为真实数字类型 */
function convertNumberFields(data: any) {
if (!data) return data
if (!data) return data;
// 需要转换为数字的字段列表
const numberFields = [
@@ -676,201 +678,203 @@ function convertNumberFields(data: any) {
'socialValue',
'ecologicalValue',
'satisfactionValue'
]
];
// 转换字段类型:将字符串数字转为真实数字
numberFields.forEach(field => {
numberFields.forEach((field) => {
if (data[field] !== null && data[field] !== undefined && data[field] !== '') {
// 如果是字符串,转为数字
if (typeof data[field] === 'string') {
data[field] = Number(data[field])
data[field] = Number(data[field]);
}
}
})
});
return data
return data;
}
/** 查询项目绩效自评列表 */
async function getList() {
loading.value = true
loading.value = true;
try {
const response = await listEvaluation(queryParams.value)
evaluationList.value = response.rows
const response = await listEvaluation(queryParams.value);
evaluationList.value = response.rows;
// 并行查询所有项目的运行监控数据
const monitoringPromises = evaluationList.value
.filter(item => item.id)
.filter((item) => item.id)
.map(async (item) => {
try {
const monitoringResponse = await listPerformanceMonitoring(item.id!)
const monitoringResponse = await listPerformanceMonitoring(item.id!);
// 如果有运行监控数据,设置hasMonitoringData为true;否则为false
item.hasMonitoringData = monitoringResponse.data && monitoringResponse.data.length > 0
item.hasMonitoringData = monitoringResponse.data && monitoringResponse.data.length > 0;
} catch (error) {
// 如果查询失败,默认不显示运行监控按钮
item.hasMonitoringData = false
item.hasMonitoringData = false;
}
})
});
// 等待所有查询完成
await Promise.all(monitoringPromises)
await Promise.all(monitoringPromises);
// 为没有ID的项目设置默认值
evaluationList.value.forEach(item => {
evaluationList.value.forEach((item) => {
if (!item.id) {
item.hasMonitoringData = false
item.hasMonitoringData = false;
}
})
});
total.value = response.total
total.value = response.total;
} catch (error) {
console.error('查询列表失败:', error)
console.error('查询列表失败:', error);
} finally {
loading.value = false
loading.value = false;
}
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1
getList()
queryParams.value.pageNum = 1;
getList();
}
/** 重置按钮操作 */
function resetQuery() {
queryFormRef.value?.resetFields()
handleQuery()
queryFormRef.value?.resetFields();
handleQuery();
}
/** 多选框选中数据 */
function handleSelectionChange(selection: CwProjectPerformanceSelfEvaluationVO[]) {
ids.value = selection.map(item => item.id!)
single.value = selection.length !== 1
multiple.value = !selection.length
ids.value = selection.map((item) => item.id!);
single.value = selection.length !== 1;
multiple.value = !selection.length;
}
/** 新增按钮操作 */
async function handleAdd() {
resetForm()
dialogMode.value = 'add'
dialogTitle.value = '新增项目绩效自评'
resetForm();
dialogMode.value = 'add';
dialogTitle.value = '新增项目绩效自评';
// 等待下一个tick,确保formData完全初始化后再打开对话框
await nextTick()
dialogVisible.value = true
await nextTick();
dialogVisible.value = true;
}
/** 查看按钮操作 */
async function handleView(row: CwProjectPerformanceSelfEvaluationVO) {
resetForm()
dialogMode.value = 'view'
dialogTitle.value = '查看项目绩效自评'
resetForm();
dialogMode.value = 'view';
dialogTitle.value = '查看项目绩效自评';
const response = await getEvaluation(row.id!)
const response = await getEvaluation(row.id!);
// 🔍 调试:打印后端返回的原始数据
console.log('🔍 后端返回的原始数据:', response.data)
console.log('🔍 检查关键字段是否存在:')
console.log(' - quantityIndicator:', response.data.quantityIndicator)
console.log(' - qualityIndicator:', response.data.qualityIndicator)
console.log(' - performanceGoal:', response.data.performanceGoal)
console.log(' - existingProblems:', response.data.existingProblems)
console.log(' - monitoringList:', response.data.monitoringList)
console.log(' - monitoringList长度:', response.data.monitoringList?.length)
console.log('🔍 后端返回的原始数据:', response.data);
console.log('🔍 检查关键字段是否存在:');
console.log(' - quantityIndicator:', response.data.quantityIndicator);
console.log(' - qualityIndicator:', response.data.qualityIndicator);
console.log(' - performanceGoal:', response.data.performanceGoal);
console.log(' - existingProblems:', response.data.existingProblems);
console.log(' - monitoringList:', response.data.monitoringList);
console.log(' - monitoringList长度:', response.data.monitoringList?.length);
// 🔧 修复:转换后端返回的字符串数字为真实数字类型
formData.value = convertNumberFields(response.data)
formData.value = convertNumberFields(response.data);
// 🔍 调试:打印转换后的数据
console.log('🔍 转换后的formData:', formData.value)
console.log('🔍 转换后的monitoringList:', formData.value.monitoringList)
console.log('🔍 转换后的formData:', formData.value);
console.log('🔍 转换后的monitoringList:', formData.value.monitoringList);
if (response.data.startDate && response.data.endDate) {
dateRange.value = [response.data.startDate, response.data.endDate]
dateRange.value = [response.data.startDate, response.data.endDate];
}
// 等待下一个tick,确保formData完全更新后再打开对话框
await nextTick()
dialogVisible.value = true
await nextTick();
dialogVisible.value = true;
}
/** 修改按钮操作 */
async function handleUpdate(row: CwProjectPerformanceSelfEvaluationVO) {
// 🔒 检查是否已锁定
if (row.isLocked === 1) {
proxy?.$modal.msgWarning('该绩效自评已锁定,不允许修改。如需修改,请联系财务管理员或学校领导解锁')
return
proxy?.$modal.msgWarning('该绩效自评已锁定,不允许修改。如需修改,请联系财务管理员或学校领导解锁');
return;
}
resetForm()
dialogMode.value = 'edit'
dialogTitle.value = '编辑项目绩效自评'
resetForm();
dialogMode.value = 'edit';
dialogTitle.value = '编辑项目绩效自评';
const response = await getEvaluation(row.id!)
const response = await getEvaluation(row.id!);
// 🔧 修复:转换后端返回的字符串数字为真实数字类型
formData.value = convertNumberFields(response.data)
formData.value = convertNumberFields(response.data);
// 🔒 再次检查锁定状态(防止数据被锁定)
if (formData.value.isLocked === 1) {
proxy?.$modal.msgWarning('该绩效自评已锁定,不允许修改。如需修改,请联系财务管理员或学校领导解锁')
return
proxy?.$modal.msgWarning('该绩效自评已锁定,不允许修改。如需修改,请联系财务管理员或学校领导解锁');
return;
}
if (response.data.startDate && response.data.endDate) {
dateRange.value = [response.data.startDate, response.data.endDate]
dateRange.value = [response.data.startDate, response.data.endDate];
}
// 等待下一个tick,确保formData完全更新后再打开对话框
await nextTick()
dialogVisible.value = true
await nextTick();
dialogVisible.value = true;
}
/** 运行监控按钮操作 */
function handleMonitoring(row: CwProjectPerformanceSelfEvaluationVO) {
monitoringDialogRef.value?.open(row.id)
monitoringDialogRef.value?.open(row.id);
}
/** 查看运行监控详情 */
function handleViewMonitoringDetail(row: any) {
if (!row.id || !row.evaluationId) {
proxy?.$modal.msgError('数据异常,无法查看详情')
return
proxy?.$modal.msgError('数据异常,无法查看详情');
return;
}
monitoringDialogRef.value?.viewDetail(row.id, row.evaluationId)
monitoringDialogRef.value?.viewDetail(row.id, row.evaluationId);
}
/** 保存草稿 */
function handleSaveDraft() {
// 🔒 检查是否已锁定
if (formData.value.isLocked === 1) {
proxy?.$modal.msgWarning('该绩效自评已锁定,不允许修改。如需修改,请联系财务管理员或学校领导解锁')
return
proxy?.$modal.msgWarning('该绩效自评已锁定,不允许修改。如需修改,请联系财务管理员或学校领导解锁');
return;
}
saveDraft(formData.value).then(() => {
proxy?.$modal.msgSuccess('保存草稿成功')
dialogVisible.value = false
getList()
}).catch((error: any) => {
// 后端也会检查锁定状态,这里捕获错误提示
if (error?.msg?.includes('锁定')) {
proxy?.$modal.msgError(error.msg)
}
})
saveDraft(formData.value)
.then(() => {
proxy?.$modal.msgSuccess('保存草稿成功');
dialogVisible.value = false;
getList();
})
.catch((error: any) => {
// 后端也会检查锁定状态,这里捕获错误提示
if (error?.msg?.includes('锁定')) {
proxy?.$modal.msgError(error.msg);
}
});
}
/** 提交自评 */
function handleFormSubmit() {
// 🔒 检查是否已锁定
if (formData.value.isLocked === 1) {
proxy?.$modal.msgWarning('该绩效自评已锁定,不允许提交。如需提交,请联系财务管理员或学校领导解锁')
return
proxy?.$modal.msgWarning('该绩效自评已锁定,不允许提交。如需提交,请联系财务管理员或学校领导解锁');
return;
}
// 先调用表格表单的分值校验(提示性质,不阻止提交)
if (tableFormRef.value?.validateTotalValue) {
tableFormRef.value.validateTotalValue()
tableFormRef.value.validateTotalValue();
}
// 🔍 调试:打印提交前的完整数据
console.log('=== 提交前的formData.value ===', JSON.stringify(formData.value, null, 2))
console.log('=== 提交前的formData.value ===', JSON.stringify(formData.value, null, 2));
console.log('=== 关键字段检查 ===', {
totalScore: formData.value.totalScore,
decisionScore: formData.value.decisionScore,
@@ -879,94 +883,113 @@ function handleFormSubmit() {
benefitScore: formData.value.benefitScore,
selfEvaluationLevel: formData.value.selfEvaluationLevel,
budgetExecutionRate: formData.value.budgetExecutionRate
})
});
// 提交数据(不再需要表单校验,因为是表格式填写)
proxy?.$modal.confirm('确认要提交该自评吗?').then(() => {
const submitData = { ...formData.value }
submitData.evaluationStatus = 'submitted'
proxy?.$modal
.confirm('确认要提交该自评吗?')
.then(() => {
const submitData = { ...formData.value };
submitData.evaluationStatus = 'submitted';
// 🔍 调试:打印即将提交的数据
console.log('=== 即将提交的数据 ===', JSON.stringify(submitData, null, 2))
// 🔍 调试:打印即将提交的数据
console.log('=== 即将提交的数据 ===', JSON.stringify(submitData, null, 2));
if (formData.value.id) {
// 编辑模式:直接更新
return updateEvaluation(submitData).then((response) => {
proxy?.$modal.msgSuccess('提交成功')
dialogVisible.value = false
getList()
}).catch((error: any) => {
// 后端也会检查锁定状态,这里捕获错误提示
if (error?.msg?.includes('锁定')) {
proxy?.$modal.msgError(error.msg)
} else {
console.error('提交失败:', error)
}
})
} else {
// 新增模式:先保存获取ID,再更新状态
return addEvaluation(submitData).then((response) => {
console.log('新增返回结果:', response)
if (response.data) {
formData.value.id = response.data
console.log('新增成功,获得ID:', formData.value.id)
}
proxy?.$modal.msgSuccess('提交成功')
dialogVisible.value = false
getList()
}).catch((error: any) => {
// 后端也会检查锁定状态,这里捕获错误提示
if (error?.msg?.includes('锁定')) {
proxy?.$modal.msgError(error.msg)
} else {
console.error('提交失败:', error)
}
})
}
}).catch((error) => {
console.error('提交失败:', error)
})
if (formData.value.id) {
// 编辑模式:直接更新
return updateEvaluation(submitData)
.then((response) => {
proxy?.$modal.msgSuccess('提交成功');
dialogVisible.value = false;
getList();
})
.catch((error: any) => {
// 后端也会检查锁定状态,这里捕获错误提示
if (error?.msg?.includes('锁定')) {
proxy?.$modal.msgError(error.msg);
} else {
console.error('提交失败:', error);
}
});
} else {
// 新增模式:先保存获取ID,再更新状态
return addEvaluation(submitData)
.then((response) => {
console.log('新增返回结果:', response);
if (response.data) {
formData.value.id = response.data;
console.log('新增成功,获得ID:', formData.value.id);
}
proxy?.$modal.msgSuccess('提交成功');
dialogVisible.value = false;
getList();
})
.catch((error: any) => {
// 后端也会检查锁定状态,这里捕获错误提示
if (error?.msg?.includes('锁定')) {
proxy?.$modal.msgError(error.msg);
} else {
console.error('提交失败:', error);
}
});
}
})
.catch((error) => {
console.error('提交失败:', error);
});
}
/** 提交按钮操作 */
function handleSubmit(row: CwProjectPerformanceSelfEvaluationVO) {
// 🔒 检查是否已锁定
if (row.isLocked === 1) {
proxy?.$modal.msgWarning('该绩效自评已锁定,不允许提交。如需提交,请联系财务管理员或学校领导解锁')
return
proxy?.$modal.msgWarning('该绩效自评已锁定,不允许提交。如需提交,请联系财务管理员或学校领导解锁');
return;
}
proxy?.$modal.confirm('确认要提交该自评吗?提交后将不能修改。').then(() => {
return submitEvaluation(row.id!)
}).then(() => {
getList()
proxy?.$modal.msgSuccess('提交成功')
}).catch(() => {})
proxy?.$modal
.confirm('确认要提交该自评吗?提交后将不能修改。')
.then(() => {
return submitEvaluation(row.id!);
})
.then(() => {
getList();
proxy?.$modal.msgSuccess('提交成功');
})
.catch(() => {});
}
/** 删除按钮操作 */
function handleDelete(row?: CwProjectPerformanceSelfEvaluationVO) {
const evaluationIds = row?.id || ids.value
proxy?.$modal.confirm('是否确认删除选中的项目绩效自评?').then(() => {
return delEvaluation(evaluationIds)
}).then(() => {
getList()
proxy?.$modal.msgSuccess('删除成功')
}).catch(() => {})
const evaluationIds = row?.id || ids.value;
proxy?.$modal
.confirm('是否确认删除选中的项目绩效自评?')
.then(() => {
return delEvaluation(evaluationIds);
})
.then(() => {
getList();
proxy?.$modal.msgSuccess('删除成功');
})
.catch(() => {});
}
/** 导出按钮操作 */
function handleExport() {
proxy?.$modal.confirm('是否确认导出所有项目绩效自评数据?').then(() => {
return exportEvaluation(queryParams.value)
}).then((response: any) => {
proxy?.$download.saveAs(response, '项目绩效自评.xlsx')
}).catch(() => {})
proxy?.$modal
.confirm('是否确认导出所有项目绩效自评数据?')
.then(() => {
return exportEvaluation(queryParams.value);
})
.then((response: any) => {
proxy?.$download.saveAs(response, '项目绩效自评.xlsx');
})
.catch(() => {});
}
onMounted(() => {
getList()
})
getList();
});
</script>
<style scoped lang="scss">
@@ -994,4 +1017,16 @@ onMounted(() => {
max-height: 70vh;
overflow-y: auto;
}
/* 搜索按钮容器样式 */
.search-btn-container {
display: flex;
justify-content: flex-end;
margin-top: 10px;
.el-form-item {
margin-bottom: 0 !important;
}
}
</style>
+65 -22
View File
@@ -3,28 +3,60 @@
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div ref="searchRef" v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form-item label="问卷编号" prop="surveyCode">
<el-input v-model="queryParams.surveyCode" placeholder="请输入问卷编号" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="问卷标题" prop="surveyTitle">
<el-input v-model="queryParams.surveyTitle" placeholder="请输入问卷标题" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="开始时间" prop="startTime">
<el-date-picker clearable v-model="queryParams.startTime" type="date" value-format="YYYY-MM-DD" placeholder="请选择开始时间" />
</el-form-item>
<el-form-item label="结束时间" prop="endTime">
<el-date-picker clearable v-model="queryParams.endTime" type="date" value-format="YYYY-MM-DD" placeholder="请选择结束时间" />
</el-form-item>
<el-form-item label="是否匿名" prop="isAnonymous">
<el-select v-model="queryParams.isAnonymous" placeholder="请选择是否匿名" clearable>
<el-option v-for="dict in sys_yesno" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
<el-form ref="queryFormRef" :model="queryParams" label-width="100px">
<el-row :gutter="20">
<el-col :span="6">
<el-form-item label="问卷编号" prop="surveyCode">
<el-input v-model="queryParams.surveyCode" placeholder="请输入问卷编号" clearable @keyup.enter="handleQuery" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="问卷标题" prop="surveyTitle">
<el-input v-model="queryParams.surveyTitle" placeholder="请输入问卷标题" clearable @keyup.enter="handleQuery" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="开始时间" prop="startTime">
<el-date-picker
clearable
v-model="queryParams.startTime"
type="date"
value-format="YYYY-MM-DD"
placeholder="请选择开始时间"
style="width: 100%"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="结束时间" prop="endTime">
<el-date-picker
clearable
v-model="queryParams.endTime"
type="date"
value-format="YYYY-MM-DD"
placeholder="请选择结束时间"
style="width: 100%"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="6">
<el-form-item label="是否匿名" prop="isAnonymous">
<el-select v-model="queryParams.isAnonymous" placeholder="请选择是否匿名" clearable>
<el-option v-for="dict in sys_yesno" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24" class="search-btn-container">
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
</div>
@@ -2028,6 +2060,17 @@ onMounted(() => {
padding: 0px 20px 20px 20px !important;
}
/* 检索栏按钮容器样式 */
.search-btn-container {
display: flex;
justify-content: flex-end;
margin-top: 10px;
.el-form-item {
margin-bottom: 0 !important;
}
}
/* 表格容器 - 支持横向滚动 */
.table-container {
width: 100%;