wuzhen 新增财务项目绩效填报模块

This commit is contained in:
wuzhen committed 2025-11-10 15:53:32 +08:00
1 parent 058a4d1cdd
commit 4815b4b3cd
56 files changed
+11914 -8

No files matched your search

@@ -0,0 +1,102 @@
package org.dromara.cw.controller;
import java.util.Arrays;
import java.util.List;
import jakarta.validation.constraints.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.cw.domain.bo.CwProjectPerformanceSelfEvaluationBo;
import org.dromara.cw.domain.vo.CwProjectPerformanceSelfEvaluationVo;
import org.dromara.cw.service.ICwMonitoringManagementService;
/**
* 运行监控管理
* 财务管理员和学校领导使用,用于查看所有人提交的绩效自评,并进行锁定/解锁操作
*
* @author ruoyi
* @date 2025-01-03
*/
@Slf4j
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/cw/monitoringManagement")
public class CwMonitoringManagementController extends BaseController {
private final ICwMonitoringManagementService monitoringManagementService;
/**
* 查询绩效自评列表(运行监控管理)
* 财务管理员和学校领导可以看到所有人的数据
*/
@SaCheckPermission("cw:monitoringManagement:list")
@GetMapping("/list")
public TableDataInfo<CwProjectPerformanceSelfEvaluationVo> list(CwProjectPerformanceSelfEvaluationBo bo, PageQuery pageQuery) {
return monitoringManagementService.queryPageList(bo, pageQuery);
}
/**
* 获取绩效自评详细信息(运行监控管理)
*/
@SaCheckPermission("cw:monitoringManagement:query")
@GetMapping("/{id}")
public R<CwProjectPerformanceSelfEvaluationVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) {
return R.ok(monitoringManagementService.queryById(id));
}
/**
* 锁定绩效自评(单个)
*/
@SaCheckPermission("cw:monitoringManagement:lock")
@Log(title = "运行监控管理", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PostMapping("/lock/{id}")
public R<Void> lock(@NotNull(message = "主键不能为空") @PathVariable Long id) {
return toAjax(monitoringManagementService.lockEvaluation(id));
}
/**
* 解锁绩效自评(单个)
*/
@SaCheckPermission("cw:monitoringManagement:unlock")
@Log(title = "运行监控管理", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PostMapping("/unlock/{id}")
public R<Void> unlock(@NotNull(message = "主键不能为空") @PathVariable Long id) {
return toAjax(monitoringManagementService.unlockEvaluation(id));
}
/**
* 批量锁定绩效自评
*/
@SaCheckPermission("cw:monitoringManagement:lock")
@Log(title = "运行监控管理", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PostMapping("/lock/batch")
public R<Void> lockBatch(@NotEmpty(message = "主键不能为空") @RequestBody Long[] ids) {
return toAjax(monitoringManagementService.lockBatch(Arrays.asList(ids)));
}
/**
* 批量解锁绩效自评
*/
@SaCheckPermission("cw:monitoringManagement:unlock")
@Log(title = "运行监控管理", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PostMapping("/unlock/batch")
public R<Void> unlockBatch(@NotEmpty(message = "主键不能为空") @RequestBody Long[] ids) {
return toAjax(monitoringManagementService.unlockBatch(Arrays.asList(ids)));
}
}
@@ -0,0 +1,85 @@
package org.dromara.cw.controller;
import java.util.List;
import jakarta.validation.constraints.*;
import lombok.RequiredArgsConstructor;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.cw.domain.bo.CwPerformanceMonitoringBo;
import org.dromara.cw.domain.vo.CwPerformanceMonitoringVo;
import org.dromara.cw.service.ICwPerformanceMonitoringService;
/**
* 绩效运行监控
*
* @author ruoyi
* @date 2025-11-04
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/cw/performanceMonitoring")
public class CwPerformanceMonitoringController extends BaseController {
private final ICwPerformanceMonitoringService performanceMonitoringService;
/**
* 根据自评ID查询运行监控列表
*/
@SaCheckPermission("cw:performanceMonitoring:query")
@GetMapping("/list/{evaluationId}")
public R<List<CwPerformanceMonitoringVo>> listByEvaluationId(@NotNull(message = "自评ID不能为空") @PathVariable Long evaluationId) {
return R.ok(performanceMonitoringService.queryByEvaluationId(evaluationId));
}
/**
* 获取绩效运行监控详细信息
*/
@SaCheckPermission("cw:performanceMonitoring:query")
@GetMapping("/{id}")
public R<CwPerformanceMonitoringVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) {
return R.ok(performanceMonitoringService.queryById(id));
}
/**
* 新增绩效运行监控
*/
@SaCheckPermission("cw:performanceMonitoring:add")
@Log(title = "绩效运行监控", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody CwPerformanceMonitoringBo bo) {
return toAjax(performanceMonitoringService.insertByBo(bo));
}
/**
* 修改绩效运行监控
*/
@SaCheckPermission("cw:performanceMonitoring:edit")
@Log(title = "绩效运行监控", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody CwPerformanceMonitoringBo bo) {
return toAjax(performanceMonitoringService.updateByBo(bo));
}
/**
* 删除绩效运行监控
*/
@SaCheckPermission("cw:performanceMonitoring:remove")
@Log(title = "绩效运行监控", businessType = BusinessType.DELETE)
@DeleteMapping("/{id}")
public R<Void> remove(@NotNull(message = "主键不能为空") @PathVariable Long id) {
return toAjax(performanceMonitoringService.deleteWithValidByIds(List.of(id), true));
}
}
@@ -0,0 +1,132 @@
package org.dromara.cw.controller;
import java.util.List;
import java.util.Arrays;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import lombok.RequiredArgsConstructor;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.cw.domain.bo.CwProjectEvaluationIndicatorBo;
import org.dromara.cw.domain.vo.CwProjectEvaluationIndicatorVo;
import org.dromara.cw.service.ICwProjectEvaluationIndicatorService;
/**
* 项目绩效自评指标明细
*
* @author ruoyi
* @date 2025-11-03
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/cw/indicator")
public class CwProjectEvaluationIndicatorController extends BaseController {
private final ICwProjectEvaluationIndicatorService indicatorService;
/**
* 查询项目绩效自评指标明细列表
*/
@SaCheckPermission("cw:indicator:list")
@GetMapping("/list")
public TableDataInfo<CwProjectEvaluationIndicatorVo> list(CwProjectEvaluationIndicatorBo bo, PageQuery pageQuery) {
return indicatorService.queryPageList(bo, pageQuery);
}
/**
* 获取项目绩效自评指标明细详细信息
*/
@SaCheckPermission("cw:indicator:query")
@GetMapping("/{id}")
public R<CwProjectEvaluationIndicatorVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) {
return R.ok(indicatorService.queryById(id));
}
/**
* 根据自评ID查询指标明细列表
*/
@SaCheckPermission("cw:indicator:query")
@GetMapping("/evaluation/{evaluationId}")
public R<List<CwProjectEvaluationIndicatorVo>> getByEvaluationId(@NotNull(message = "自评ID不能为空") @PathVariable Long evaluationId) {
return R.ok(indicatorService.queryByEvaluationId(evaluationId));
}
/**
* 根据自评ID和指标类型查询指标明细列表
*/
@SaCheckPermission("cw:indicator:query")
@GetMapping("/evaluation/{evaluationId}/type/{indicatorType}")
public R<List<CwProjectEvaluationIndicatorVo>> getByEvaluationIdAndType(
@NotNull(message = "自评ID不能为空") @PathVariable Long evaluationId,
@NotBlank(message = "指标类型不能为空") @PathVariable String indicatorType) {
return R.ok(indicatorService.queryByEvaluationIdAndType(evaluationId, indicatorType));
}
/**
* 新增项目绩效自评指标明细
*/
@SaCheckPermission("cw:indicator:add")
@Log(title = "项目绩效自评指标明细", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody CwProjectEvaluationIndicatorBo bo) {
return toAjax(indicatorService.insertByBo(bo));
}
/**
* 修改项目绩效自评指标明细
*/
@SaCheckPermission("cw:indicator:edit")
@Log(title = "项目绩效自评指标明细", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody CwProjectEvaluationIndicatorBo bo) {
return toAjax(indicatorService.updateByBo(bo));
}
/**
* 批量保存指标明细
*/
@SaCheckPermission("cw:indicator:edit")
@Log(title = "批量保存指标明细", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PostMapping("/batch")
public R<Void> batchSave(@RequestParam Long evaluationId, @RequestBody List<CwProjectEvaluationIndicatorBo> boList) {
return toAjax(indicatorService.batchSave(evaluationId, boList));
}
/**
* 删除项目绩效自评指标明细
*/
@SaCheckPermission("cw:indicator:remove")
@Log(title = "项目绩效自评指标明细", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ids) {
return toAjax(indicatorService.deleteWithValidByIds(Arrays.asList(ids), true));
}
/**
* 导出项目绩效自评指标明细列表
*/
@SaCheckPermission("cw:indicator:export")
@Log(title = "项目绩效自评指标明细", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(CwProjectEvaluationIndicatorBo bo, HttpServletResponse response) {
List<CwProjectEvaluationIndicatorVo> list = indicatorService.queryList(bo);
ExcelUtil.exportExcel(list, "项目绩效自评指标明细", CwProjectEvaluationIndicatorVo.class, response);
}
}
@@ -0,0 +1,144 @@
package org.dromara.cw.controller;
import java.util.List;
import java.util.Arrays;
import java.util.Map;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import lombok.RequiredArgsConstructor;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.cw.domain.bo.CwProjectMonthlyMonitoringBo;
import org.dromara.cw.domain.vo.CwProjectMonthlyMonitoringVo;
import org.dromara.cw.service.ICwProjectMonthlyMonitoringService;
/**
* 项目月度运行监控
*
* @author ruoyi
* @date 2025-11-03
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/cw/monitoring")
public class CwProjectMonthlyMonitoringController extends BaseController {
private final ICwProjectMonthlyMonitoringService monitoringService;
/**
* 查询项目月度运行监控列表
*/
@SaCheckPermission("cw:monitoring:list")
@GetMapping("/list")
public TableDataInfo<CwProjectMonthlyMonitoringVo> list(CwProjectMonthlyMonitoringBo bo, PageQuery pageQuery) {
return monitoringService.queryPageList(bo, pageQuery);
}
/**
* 获取项目月度运行监控详细信息
*/
@SaCheckPermission("cw:monitoring:query")
@GetMapping("/{id}")
public R<CwProjectMonthlyMonitoringVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) {
return R.ok(monitoringService.queryById(id));
}
/**
* 根据自评ID查询月度监控列表
*/
@SaCheckPermission("cw:monitoring:query")
@GetMapping("/evaluation/{evaluationId}")
public R<List<CwProjectMonthlyMonitoringVo>> getByEvaluationId(@NotNull(message = "自评ID不能为空") @PathVariable Long evaluationId) {
return R.ok(monitoringService.queryByEvaluationId(evaluationId));
}
/**
* 查询某个自评的全年监控数据
*/
@SaCheckPermission("cw:monitoring:query")
@GetMapping("/year/{evaluationId}/{year}")
public R<Map<Integer, CwProjectMonthlyMonitoringVo>> getYearlyMonitoring(
@NotNull(message = "自评ID不能为空") @PathVariable Long evaluationId,
@NotNull(message = "年份不能为空") @PathVariable Integer year) {
return R.ok(monitoringService.queryYearlyMonitoring(evaluationId, year));
}
/**
* 新增项目月度运行监控
*/
@SaCheckPermission("cw:monitoring:add")
@Log(title = "项目月度运行监控", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody CwProjectMonthlyMonitoringBo bo) {
return toAjax(monitoringService.insertByBo(bo));
}
/**
* 修改项目月度运行监控
*/
@SaCheckPermission("cw:monitoring:edit")
@Log(title = "项目月度运行监控", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody CwProjectMonthlyMonitoringBo bo) {
return toAjax(monitoringService.updateByBo(bo));
}
/**
* 填报月度数据
*/
@SaCheckPermission("cw:monitoring:fill")
@Log(title = "填报月度数据", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PostMapping("/fill")
public R<Void> fillMonthlyData(@Validated @RequestBody CwProjectMonthlyMonitoringBo bo) {
return toAjax(monitoringService.fillMonthlyData(bo));
}
/**
* 批量保存月度监控数据
*/
@SaCheckPermission("cw:monitoring:edit")
@Log(title = "批量保存月度监控数据", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PostMapping("/batch")
public R<Void> batchSave(@RequestParam Long evaluationId, @RequestBody List<CwProjectMonthlyMonitoringBo> boList) {
return toAjax(monitoringService.batchSave(evaluationId, boList));
}
/**
* 删除项目月度运行监控
*/
@SaCheckPermission("cw:monitoring:remove")
@Log(title = "项目月度运行监控", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ids) {
return toAjax(monitoringService.deleteWithValidByIds(Arrays.asList(ids), true));
}
/**
* 导出项目月度运行监控列表
*/
@SaCheckPermission("cw:monitoring:export")
@Log(title = "项目月度运行监控", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(CwProjectMonthlyMonitoringBo bo, HttpServletResponse response) {
List<CwProjectMonthlyMonitoringVo> list = monitoringService.queryList(bo);
ExcelUtil.exportExcel(list, "项目月度运行监控", CwProjectMonthlyMonitoringVo.class, response);
}
}
@@ -0,0 +1,161 @@
package org.dromara.cw.controller;
import java.util.List;
import java.util.Arrays;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.cw.domain.bo.CwProjectPerformanceSelfEvaluationBo;
import org.dromara.cw.domain.vo.CwProjectPerformanceSelfEvaluationVo;
import org.dromara.cw.service.ICwProjectPerformanceSelfEvaluationService;
import org.dromara.common.satoken.utils.LoginHelper;
/**
* 项目绩效自评
*
* @author ruoyi
* @date 2025-11-03
*/
@Slf4j
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/cw/evaluation")
public class CwProjectPerformanceSelfEvaluationController extends BaseController {
private final ICwProjectPerformanceSelfEvaluationService evaluationService;
/**
* 查询项目绩效自评列表
*/
@SaCheckPermission("cw:evaluation:list")
@GetMapping("/list")
public TableDataInfo<CwProjectPerformanceSelfEvaluationVo> list(CwProjectPerformanceSelfEvaluationBo bo, PageQuery pageQuery) {
return evaluationService.queryPageList(bo, pageQuery);
}
/**
* 获取项目绩效自评详细信息
*/
@SaCheckPermission("cw:evaluation:query")
@GetMapping("/{id}")
public R<CwProjectPerformanceSelfEvaluationVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) {
return R.ok(evaluationService.queryById(id));
}
/**
* 新增项目绩效自评
*/
@SaCheckPermission("cw:evaluation:add")
@Log(title = "项目绩效自评", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Long> add(@Validated(AddGroup.class) @RequestBody CwProjectPerformanceSelfEvaluationBo bo) {
boolean result = evaluationService.insertByBo(bo);
if (result) {
return R.ok("新增成功", bo.getId());
}
return R.fail("新增失败");
}
/**
* 修改项目绩效自评
*/
@SaCheckPermission("cw:evaluation:edit")
@Log(title = "项目绩效自评", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody CwProjectPerformanceSelfEvaluationBo bo) {
return toAjax(evaluationService.updateByBo(bo));
}
/**
* 保存草稿
*/
@SaCheckPermission("cw:evaluation:add")
@Log(title = "保存自评草稿", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PostMapping("/saveDraft")
public R<Void> saveDraft(@RequestBody CwProjectPerformanceSelfEvaluationBo bo) {
return toAjax(evaluationService.saveDraft(bo));
}
/**
* 提交自评
*/
@SaCheckPermission("cw:evaluation:submit")
@Log(title = "提交自评", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PostMapping("/submit/{id}")
public R<Void> submit(@NotNull(message = "主键不能为空") @PathVariable Long id) {
return toAjax(evaluationService.submitEvaluation(id));
}
/**
* 审核自评
*/
@SaCheckPermission("cw:evaluation:approve")
@Log(title = "审核自评", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PostMapping("/approve/{id}")
public R<Void> approve(@NotNull(message = "主键不能为空") @PathVariable Long id,
@RequestParam String opinion,
@RequestParam Boolean approved) {
return toAjax(evaluationService.approveEvaluation(id, opinion, approved));
}
/**
* 删除项目绩效自评
*/
@SaCheckPermission("cw:evaluation:remove")
@Log(title = "项目绩效自评", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ids) {
return toAjax(evaluationService.deleteWithValidByIds(Arrays.asList(ids), true));
}
/**
* 查询我的自评列表
*/
@SaCheckPermission("cw:evaluation:list")
@GetMapping("/my")
public R<List<CwProjectPerformanceSelfEvaluationVo>> myEvaluations() {
return R.ok(evaluationService.queryMyEvaluations(LoginHelper.getUserId()));
}
/**
* 查询待审核自评列表
*/
@SaCheckPermission("cw:evaluation:approve")
@GetMapping("/pending")
public R<List<CwProjectPerformanceSelfEvaluationVo>> pendingApprovals() {
return R.ok(evaluationService.queryPendingApprovals());
}
/**
* 导出项目绩效自评列表
*/
@SaCheckPermission("cw:evaluation:export")
@Log(title = "项目绩效自评", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(CwProjectPerformanceSelfEvaluationBo bo, HttpServletResponse response) {
List<CwProjectPerformanceSelfEvaluationVo> list = evaluationService.queryList(bo);
ExcelUtil.exportExcel(list, "项目绩效自评", CwProjectPerformanceSelfEvaluationVo.class, response);
}
}
@@ -0,0 +1,82 @@
package org.dromara.cw.domain;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.mybatis.core.domain.BaseEntity;
/**
* 绩效运行监控对象 cw_performance_monitoring
*
* @author ruoyi
* @date 2025-11-04
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("cw_performance_monitoring")
public class CwPerformanceMonitoring extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(value = "id")
private Long id;
/**
* 绩效自评ID
*/
private Long evaluationId;
/**
* 项目申报ID
*/
private Long projectApplicationId;
/**
* 监控周期
*/
private String monitoringPeriod;
/**
* 资金使用情况
*/
private String fundUsage;
/**
* 绩效目标完成情况
*/
private String performanceTargetCompletion;
/**
* 绩效指标完成情况(JSON数组)
*/
private String indicators;
/**
* 存在问题
*/
private String existingProblems;
/**
* 指标差异率分析和说明
*/
private String indicatorVarianceAnalysis;
/**
* 下一步工作建议和打算
*/
private String nextStepSuggestions;
/**
* 填报人ID
*/
private Long fillBy;
/**
* 填报人姓名
*/
private String fillByName;
}
@@ -0,0 +1,90 @@
package org.dromara.cw.domain;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import java.math.BigDecimal;
/**
* 项目绩效自评指标明细对象 cw_project_evaluation_indicator
*
* @author ruoyi
* @date 2025-11-03
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("cw_project_evaluation_indicator")
public class CwProjectEvaluationIndicator extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(value = "id")
private Long id;
/**
* 绩效自评ID
*/
private Long evaluationId;
/**
* 指标类别(decision-决策/process-过程/output-产出/benefit-效益)
*/
private String indicatorCategory;
/**
* 指标名称
*/
private String indicatorName;
/**
* 指标类型(quantity-数量/quality-质量/time-时效/cost-成本)
*/
private String indicatorType;
/**
* 目标值
*/
private String targetValue;
/**
* 实际完成值
*/
private String actualValue;
/**
* 完成率(%)
*/
private BigDecimal completionRate;
/**
* 指标分值
*/
private BigDecimal standardScore;
/**
* 实际得分
*/
private BigDecimal actualScore;
/**
* 完成情况说明
*/
private String completionDescription;
/**
* 排序号
*/
private Integer sortOrder;
/**
* 逻辑删除标志(0-正常 1-删除)
*/
@TableLogic
private Integer deleted;
}
@@ -0,0 +1,146 @@
package org.dromara.cw.domain;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import java.math.BigDecimal;
import java.util.Date;
/**
* 项目月度运行监控对象 cw_project_monthly_monitoring
*
* @author ruoyi
* @date 2025-11-03
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("cw_project_monthly_monitoring")
public class CwProjectMonthlyMonitoring extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(value = "id")
private Long id;
/**
* 绩效自评ID
*/
private Long evaluationId;
/**
* 项目申报ID
*/
private Long projectApplicationId;
/**
* 监控年度
*/
private Integer monitoringYear;
/**
* 监控月份(1-12)
*/
private Integer monitoringMonth;
/**
* 计划进度(%)
*/
private BigDecimal plannedProgress;
/**
* 实际进度(%)
*/
private BigDecimal actualProgress;
/**
* 进度偏差(%)
*/
private BigDecimal progressVariance;
/**
* 本月预算(万元)
*/
private BigDecimal monthlyBudget;
/**
* 本月实际支出(万元)
*/
private BigDecimal monthlyExpenditure;
/**
* 累计预算(万元)
*/
private BigDecimal cumulativeBudget;
/**
* 累计实际支出(万元)
*/
private BigDecimal cumulativeExpenditure;
/**
* 资金执行率(%)
*/
private BigDecimal fundExecutionRate;
/**
* 本月完成的关键节点
*/
private String keyMilestones;
/**
* 节点完成情况(completed-已完成/delayed-延期/notStarted-未开始)
*/
private String milestoneCompletion;
/**
* 本月遇到的问题
*/
private String problemsEncountered;
/**
* 风险描述
*/
private String riskDescription;
/**
* 应对措施
*/
private String countermeasures;
/**
* 下月工作计划
*/
private String nextMonthPlan;
/**
* 填报状态(not_filled-未填报/filled-已填报)
*/
private String fillStatus;
/**
* 填报时间
*/
private Date fillTime;
/**
* 填报人ID
*/
private Long fillBy;
/**
* 填报人姓名
*/
private String fillByName;
/**
* 逻辑删除标志(0-正常 1-删除)
*/
@TableLogic
private Integer deleted;
}
@@ -0,0 +1,591 @@
package org.dromara.cw.domain;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import java.math.BigDecimal;
import java.util.Date;
/**
* 项目绩效自评对象 cw_project_performance_self_evaluation
*
* @author ruoyi
* @date 2025-11-03
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("cw_project_performance_self_evaluation")
public class CwProjectPerformanceSelfEvaluation extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(value = "id")
private Long id;
/**
* 项目申报ID
*/
private Long projectApplicationId;
/**
* 申报编号
*/
private String applicationNo;
/**
* 项目名称
*/
private String projectName;
/**
* 主管部门
*/
private String supervisoryDept;
/**
* 实施单位
*/
private String implementUnit;
/**
* 自评年度
*/
private Integer evaluationYear;
/**
* 年初预算数(万元)
*/
private BigDecimal initialBudget;
/**
* 项目负责人
*/
private String principal;
/**
* 联系电话
*/
private String contactPhone;
/**
* 项目实施开始时间
*/
private Date startDate;
/**
* 项目实施结束时间
*/
private Date endDate;
/**
* 项目总投资(万元)
*/
private BigDecimal totalInvestment;
/**
* 本年度预算(万元)
*/
private BigDecimal annualBudget;
/**
* 本年度实际支出(万元)
*/
private BigDecimal actualExpenditure;
/**
* 预算执行率(%)
*/
private BigDecimal budgetExecutionRate;
/**
* 资金到位分值
*/
private BigDecimal fundValue;
/**
* 资金执行率(%)
*/
private BigDecimal fundExecutionRate;
/**
* 资金到位得分
*/
private BigDecimal fundScore;
/**
* 当年财政拨款-年初预算数(万元)
*/
private BigDecimal currentYearBudgetInitial;
/**
* 当年财政拨款-全年预算数(万元)
*/
private BigDecimal currentYearBudgetAnnual;
/**
* 当年财政拨款-全年执行数(万元)
*/
private BigDecimal currentYearBudgetActual;
/**
* 当年财政拨款-分值
*/
private BigDecimal currentYearBudgetValue;
/**
* 当年财政拨款-执行率(%)
*/
private BigDecimal currentYearBudgetExecutionRate;
/**
* 当年财政拨款-得分
*/
private BigDecimal currentYearBudgetScore;
/**
* 上年结转资金-年初预算数(万元)
*/
private BigDecimal lastYearCarryoverInitial;
/**
* 上年结转资金-全年预算数(万元)
*/
private BigDecimal lastYearCarryoverAnnual;
/**
* 上年结转资金-全年执行数(万元)
*/
private BigDecimal lastYearCarryoverActual;
/**
* 上年结转资金-分值
*/
private BigDecimal lastYearCarryoverValue;
/**
* 上年结转资金-执行率(%)
*/
private BigDecimal lastYearCarryoverExecutionRate;
/**
* 上年结转资金-得分
*/
private BigDecimal lastYearCarryoverScore;
/**
* 其他资金-年初预算数(万元)
*/
private BigDecimal otherFundsInitial;
/**
* 其他资金-全年预算数(万元)
*/
private BigDecimal otherFundsAnnual;
/**
* 其他资金-全年执行数(万元)
*/
private BigDecimal otherFundsActual;
/**
* 其他资金-分值
*/
private BigDecimal otherFundsValue;
/**
* 其他资金-执行率(%)
*/
private BigDecimal otherFundsExecutionRate;
/**
* 其他资金-得分
*/
private BigDecimal otherFundsScore;
/**
* 年度绩效目标
*/
private String performanceGoal;
/**
* 目标完成情况说明
*/
private String targetCompletion;
/**
* 数量指标名称
*/
private String quantityIndicator;
/**
* 数量指标-指标值
*/
private String quantityTarget;
/**
* 数量指标-实际完成值
*/
private String quantityActual;
/**
* 数量指标-分值
*/
private BigDecimal quantityValue;
/**
* 数量指标-得分
*/
private BigDecimal quantityScore;
/**
* 数量指标-偏差原因分析及改进措施
*/
private String quantityDeviation;
/**
* 质量指标名称
*/
private String qualityIndicator;
/**
* 质量指标-指标值
*/
private String qualityTarget;
/**
* 质量指标-实际完成值
*/
private String qualityActual;
/**
* 质量指标-分值
*/
private BigDecimal qualityValue;
/**
* 质量指标-得分
*/
private BigDecimal qualityScore;
/**
* 质量指标-偏差原因分析及改进措施
*/
private String qualityDeviation;
/**
* 时效指标名称
*/
private String timelinessIndicator;
/**
* 时效指标-指标值
*/
private String timelinessTarget;
/**
* 时效指标-实际完成值
*/
private String timelinessActual;
/**
* 时效指标-分值
*/
private BigDecimal timelinessValue;
/**
* 时效指标-得分
*/
private BigDecimal timelinessScore;
/**
* 时效指标-偏差原因分析及改进措施
*/
private String timelinessDeviation;
/**
* 成本指标名称
*/
private String costIndicator;
/**
* 成本指标-指标值
*/
private String costTarget;
/**
* 成本指标-实际完成值
*/
private String costActual;
/**
* 成本指标-分值
*/
private BigDecimal costValue;
/**
* 成本指标-得分
*/
private BigDecimal costScore;
/**
* 成本指标-偏差原因分析及改进措施
*/
private String costDeviation;
/**
* 经济效益指标名称
*/
private String economicIndicator;
/**
* 经济效益指标-指标值
*/
private String economicTarget;
/**
* 经济效益指标-实际完成值
*/
private String economicActual;
/**
* 经济效益指标-分值
*/
private BigDecimal economicValue;
/**
* 经济效益指标-得分
*/
private BigDecimal economicScore;
/**
* 经济效益指标-偏差原因分析及改进措施
*/
private String economicDeviation;
/**
* 社会效益指标名称
*/
private String socialIndicator;
/**
* 社会效益指标-指标值
*/
private String socialTarget;
/**
* 社会效益指标-实际完成值
*/
private String socialActual;
/**
* 社会效益指标-分值
*/
private BigDecimal socialValue;
/**
* 社会效益指标-得分
*/
private BigDecimal socialScore;
/**
* 社会效益指标-偏差原因分析及改进措施
*/
private String socialDeviation;
/**
* 生态效益指标名称
*/
private String ecologicalIndicator;
/**
* 生态效益指标-指标值
*/
private String ecologicalTarget;
/**
* 生态效益指标-实际完成值
*/
private String ecologicalActual;
/**
* 生态效益指标-分值
*/
private BigDecimal ecologicalValue;
/**
* 生态效益指标-得分
*/
private BigDecimal ecologicalScore;
/**
* 生态效益指标-偏差原因分析及改进措施
*/
private String ecologicalDeviation;
/**
* 满意度指标名称
*/
private String satisfactionIndicator;
/**
* 满意度指标-指标值
*/
private String satisfactionTarget;
/**
* 满意度指标-实际完成值
*/
private String satisfactionActual;
/**
* 满意度指标-分值
*/
private BigDecimal satisfactionValue;
/**
* 满意度指标-得分
*/
private BigDecimal satisfactionScore;
/**
* 满意度指标-偏差原因分析及改进措施
*/
private String satisfactionDeviation;
/**
* 项目决策得分
*/
private BigDecimal decisionScore;
/**
* 项目决策自评内容
*/
private String decisionContent;
/**
* 项目过程得分
*/
private BigDecimal processScore;
/**
* 项目过程自评内容
*/
private String processContent;
/**
* 项目产出得分
*/
private BigDecimal outputScore;
/**
* 项目产出自评内容
*/
private String outputContent;
/**
* 项目效益得分
*/
private BigDecimal benefitScore;
/**
* 项目效益自评内容
*/
private String benefitContent;
/**
* 自评总分
*/
private BigDecimal totalScore;
/**
* 自评等级(优秀/良好/合格/不合格)
*/
private String selfEvaluationLevel;
/**
* 存在的主要问题
*/
private String existingProblems;
/**
* 改进措施和建议
*/
private String improvementMeasures;
/**
* 自评状态(draft-草稿 submitted-已提交 approved-已审核)
*/
private String evaluationStatus;
/**
* 允许已提交后编辑(0-不允许 1-允许)
*/
private Integer allowEditAfterSubmit;
/**
* 提交时间
*/
private Date submitTime;
/**
* 提交人ID
*/
private Long submitBy;
/**
* 提交人姓名
*/
private String submitByName;
/**
* 审核时间
*/
private Date approveTime;
/**
* 审核人ID
*/
private Long approveBy;
/**
* 审核人姓名
*/
private String approveByName;
/**
* 审核意见
*/
private String approveOpinion;
/**
* 是否锁定(0-未锁定 1-已锁定),锁定后不可修改
*/
private Integer isLocked;
/**
* 锁定时间
*/
private Date lockTime;
/**
* 锁定人ID
*/
private Long lockBy;
/**
* 锁定人姓名
*/
private String lockByName;
/**
* 逻辑删除标志(0-正常 1-删除)
*/
@TableLogic
private Integer deleted;
}
@@ -0,0 +1,88 @@
package org.dromara.cw.domain.bo;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.cw.domain.CwPerformanceMonitoring;
/**
* 绩效运行监控业务对象 cw_performance_monitoring
*
* @author ruoyi
* @date 2025-11-04
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = CwPerformanceMonitoring.class, reverseConvertGenerate = false)
public class CwPerformanceMonitoringBo extends BaseEntity {
/**
* 主键ID
*/
@NotNull(message = "主键ID不能为空", groups = { EditGroup.class })
private Long id;
/**
* 绩效自评ID
*/
@NotNull(message = "绩效自评ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long evaluationId;
/**
* 项目申报ID
*/
private Long projectApplicationId;
/**
* 监控周期
*/
@NotBlank(message = "监控周期不能为空", groups = { AddGroup.class, EditGroup.class })
private String monitoringPeriod;
/**
* 资金使用情况
*/
@NotBlank(message = "资金使用情况不能为空", groups = { AddGroup.class, EditGroup.class })
private String fundUsage;
/**
* 绩效目标完成情况
*/
@NotBlank(message = "绩效目标完成情况不能为空", groups = { AddGroup.class, EditGroup.class })
private String performanceTargetCompletion;
/**
* 绩效指标完成情况(JSON数组)
*/
private String indicators;
/**
* 存在问题
*/
private String existingProblems;
/**
* 指标差异率分析和说明
*/
private String indicatorVarianceAnalysis;
/**
* 下一步工作建议和打算
*/
private String nextStepSuggestions;
/**
* 填报人ID
*/
private Long fillBy;
/**
* 填报人姓名
*/
private String fillByName;
}
@@ -0,0 +1,91 @@
package org.dromara.cw.domain.bo;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.cw.domain.CwProjectEvaluationIndicator;
import jakarta.validation.constraints.*;
import java.math.BigDecimal;
/**
* 项目绩效自评指标明细业务对象 cw_project_evaluation_indicator
*
* @author ruoyi
* @date 2025-11-03
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = CwProjectEvaluationIndicator.class, reverseConvertGenerate = false)
public class CwProjectEvaluationIndicatorBo extends BaseEntity {
/**
* 主键ID
*/
@NotNull(message = "主键ID不能为空", groups = {EditGroup.class})
private Long id;
/**
* 绩效自评ID
*/
@NotNull(message = "绩效自评ID不能为空", groups = {AddGroup.class})
private Long evaluationId;
/**
* 指标类别(decision-决策/process-过程/output-产出/benefit-效益)
*/
@NotBlank(message = "指标类别不能为空", groups = {AddGroup.class})
private String indicatorCategory;
/**
* 指标名称
*/
@NotBlank(message = "指标名称不能为空", groups = {AddGroup.class})
private String indicatorName;
/**
* 指标类型(quantity-数量/quality-质量/time-时效/cost-成本)
*/
private String indicatorType;
/**
* 目标值
*/
private String targetValue;
/**
* 实际完成值
*/
private String actualValue;
/**
* 完成率(%)
*/
@DecimalMin(value = "0", message = "完成率不能小于0")
@DecimalMax(value = "200", message = "完成率不能大于200")
private BigDecimal completionRate;
/**
* 指标分值
*/
private BigDecimal standardScore;
/**
* 实际得分
*/
private BigDecimal actualScore;
/**
* 完成情况说明
*/
private String completionDescription;
/**
* 排序号
*/
private Integer sortOrder;
}
@@ -0,0 +1,152 @@
package org.dromara.cw.domain.bo;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.cw.domain.CwProjectMonthlyMonitoring;
import jakarta.validation.constraints.*;
import java.math.BigDecimal;
import java.util.Date;
/**
* 项目月度运行监控业务对象 cw_project_monthly_monitoring
*
* @author ruoyi
* @date 2025-11-03
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = CwProjectMonthlyMonitoring.class, reverseConvertGenerate = false)
public class CwProjectMonthlyMonitoringBo extends BaseEntity {
/**
* 主键ID
*/
@NotNull(message = "主键ID不能为空", groups = {EditGroup.class})
private Long id;
/**
* 绩效自评ID
*/
@NotNull(message = "绩效自评ID不能为空", groups = {AddGroup.class})
private Long evaluationId;
/**
* 项目申报ID
*/
@NotNull(message = "项目申报ID不能为空", groups = {AddGroup.class})
private Long projectApplicationId;
/**
* 监控年度
*/
@NotNull(message = "监控年度不能为空", groups = {AddGroup.class})
private Integer monitoringYear;
/**
* 监控月份(1-12)
*/
@NotNull(message = "监控月份不能为空", groups = {AddGroup.class})
@Min(value = 1, message = "监控月份最小为1")
@Max(value = 12, message = "监控月份最大为12")
private Integer monitoringMonth;
/**
* 计划进度(%)
*/
@DecimalMin(value = "0", message = "计划进度不能小于0")
@DecimalMax(value = "100", message = "计划进度不能大于100")
private BigDecimal plannedProgress;
/**
* 实际进度(%)
*/
@DecimalMin(value = "0", message = "实际进度不能小于0")
@DecimalMax(value = "100", message = "实际进度不能大于100")
private BigDecimal actualProgress;
/**
* 进度偏差(%)
*/
private BigDecimal progressVariance;
/**
* 本月预算(万元)
*/
private BigDecimal monthlyBudget;
/**
* 本月实际支出(万元)
*/
private BigDecimal monthlyExpenditure;
/**
* 累计预算(万元)
*/
private BigDecimal cumulativeBudget;
/**
* 累计实际支出(万元)
*/
private BigDecimal cumulativeExpenditure;
/**
* 资金执行率(%)
*/
private BigDecimal fundExecutionRate;
/**
* 本月完成的关键节点
*/
private String keyMilestones;
/**
* 节点完成情况(completed-已完成/delayed-延期/notStarted-未开始)
*/
private String milestoneCompletion;
/**
* 本月遇到的问题
*/
private String problemsEncountered;
/**
* 风险描述
*/
private String riskDescription;
/**
* 应对措施
*/
private String countermeasures;
/**
* 下月工作计划
*/
private String nextMonthPlan;
/**
* 填报状态(not_filled-未填报/filled-已填报)
*/
private String fillStatus;
/**
* 填报时间
*/
private Date fillTime;
/**
* 填报人ID
*/
private Long fillBy;
/**
* 填报人姓名
*/
private String fillByName;
}
@@ -0,0 +1,583 @@
package org.dromara.cw.domain.bo;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.cw.domain.CwProjectPerformanceSelfEvaluation;
import jakarta.validation.constraints.*;
import java.math.BigDecimal;
import java.util.Date;
/**
* 项目绩效自评业务对象 cw_project_performance_self_evaluation
*
* @author ruoyi
* @date 2025-11-03
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = CwProjectPerformanceSelfEvaluation.class, reverseConvertGenerate = false)
public class CwProjectPerformanceSelfEvaluationBo extends BaseEntity {
/**
* 主键ID
*/
@NotNull(message = "主键ID不能为空", groups = {EditGroup.class})
private Long id;
/**
* 项目申报ID
*/
@NotNull(message = "项目申报ID不能为空", groups = {AddGroup.class})
private Long projectApplicationId;
/**
* 申报编号
*/
private String applicationNo;
/**
* 项目名称
*/
@NotBlank(message = "项目名称不能为空", groups = {AddGroup.class})
private String projectName;
/**
* 主管部门
*/
private String supervisoryDept;
/**
* 实施单位
*/
private String implementUnit;
/**
* 自评年度
*/
@NotNull(message = "自评年度不能为空", groups = {AddGroup.class})
private Integer evaluationYear;
/**
* 年初预算数(万元)
*/
private BigDecimal initialBudget;
/**
* 项目负责人
*/
private String principal;
/**
* 联系电话
*/
private String contactPhone;
/**
* 项目实施开始时间
*/
private Date startDate;
/**
* 项目实施结束时间
*/
private Date endDate;
/**
* 项目总投资(万元)
*/
private BigDecimal totalInvestment;
/**
* 本年度预算(万元)
*/
private BigDecimal annualBudget;
/**
* 本年度实际支出(万元)
*/
private BigDecimal actualExpenditure;
/**
* 预算执行率(%)
*/
private BigDecimal budgetExecutionRate;
/**
* 资金到位分值
*/
private BigDecimal fundValue;
/**
* 资金执行率(%)
*/
private BigDecimal fundExecutionRate;
/**
* 资金到位得分
*/
private BigDecimal fundScore;
/**
* 当年财政拨款-年初预算数(万元)
*/
private BigDecimal currentYearBudgetInitial;
/**
* 当年财政拨款-全年预算数(万元)
*/
private BigDecimal currentYearBudgetAnnual;
/**
* 当年财政拨款-全年执行数(万元)
*/
private BigDecimal currentYearBudgetActual;
/**
* 当年财政拨款-分值
*/
private BigDecimal currentYearBudgetValue;
/**
* 当年财政拨款-执行率(%)
*/
private BigDecimal currentYearBudgetExecutionRate;
/**
* 当年财政拨款-得分
*/
private BigDecimal currentYearBudgetScore;
/**
* 上年结转资金-年初预算数(万元)
*/
private BigDecimal lastYearCarryoverInitial;
/**
* 上年结转资金-全年预算数(万元)
*/
private BigDecimal lastYearCarryoverAnnual;
/**
* 上年结转资金-全年执行数(万元)
*/
private BigDecimal lastYearCarryoverActual;
/**
* 上年结转资金-分值
*/
private BigDecimal lastYearCarryoverValue;
/**
* 上年结转资金-执行率(%)
*/
private BigDecimal lastYearCarryoverExecutionRate;
/**
* 上年结转资金-得分
*/
private BigDecimal lastYearCarryoverScore;
/**
* 其他资金-年初预算数(万元)
*/
private BigDecimal otherFundsInitial;
/**
* 其他资金-全年预算数(万元)
*/
private BigDecimal otherFundsAnnual;
/**
* 其他资金-全年执行数(万元)
*/
private BigDecimal otherFundsActual;
/**
* 其他资金-分值
*/
private BigDecimal otherFundsValue;
/**
* 其他资金-执行率(%)
*/
private BigDecimal otherFundsExecutionRate;
/**
* 其他资金-得分
*/
private BigDecimal otherFundsScore;
/**
* 年度绩效目标
*/
private String performanceGoal;
/**
* 目标完成情况说明
*/
private String targetCompletion;
/**
* 数量指标名称
*/
private String quantityIndicator;
/**
* 数量指标-指标值
*/
private String quantityTarget;
/**
* 数量指标-实际完成值
*/
private String quantityActual;
/**
* 数量指标-分值
*/
private BigDecimal quantityValue;
/**
* 数量指标-得分
*/
private BigDecimal quantityScore;
/**
* 数量指标-偏差原因分析及改进措施
*/
private String quantityDeviation;
/**
* 质量指标名称
*/
private String qualityIndicator;
/**
* 质量指标-指标值
*/
private String qualityTarget;
/**
* 质量指标-实际完成值
*/
private String qualityActual;
/**
* 质量指标-分值
*/
private BigDecimal qualityValue;
/**
* 质量指标-得分
*/
private BigDecimal qualityScore;
/**
* 质量指标-偏差原因分析及改进措施
*/
private String qualityDeviation;
/**
* 时效指标名称
*/
private String timelinessIndicator;
/**
* 时效指标-指标值
*/
private String timelinessTarget;
/**
* 时效指标-实际完成值
*/
private String timelinessActual;
/**
* 时效指标-分值
*/
private BigDecimal timelinessValue;
/**
* 时效指标-得分
*/
private BigDecimal timelinessScore;
/**
* 时效指标-偏差原因分析及改进措施
*/
private String timelinessDeviation;
/**
* 成本指标名称
*/
private String costIndicator;
/**
* 成本指标-指标值
*/
private String costTarget;
/**
* 成本指标-实际完成值
*/
private String costActual;
/**
* 成本指标-分值
*/
private BigDecimal costValue;
/**
* 成本指标-得分
*/
private BigDecimal costScore;
/**
* 成本指标-偏差原因分析及改进措施
*/
private String costDeviation;
/**
* 经济效益指标名称
*/
private String economicIndicator;
/**
* 经济效益指标-指标值
*/
private String economicTarget;
/**
* 经济效益指标-实际完成值
*/
private String economicActual;
/**
* 经济效益指标-分值
*/
private BigDecimal economicValue;
/**
* 经济效益指标-得分
*/
private BigDecimal economicScore;
/**
* 经济效益指标-偏差原因分析及改进措施
*/
private String economicDeviation;
/**
* 社会效益指标名称
*/
private String socialIndicator;
/**
* 社会效益指标-指标值
*/
private String socialTarget;
/**
* 社会效益指标-实际完成值
*/
private String socialActual;
/**
* 社会效益指标-分值
*/
private BigDecimal socialValue;
/**
* 社会效益指标-得分
*/
private BigDecimal socialScore;
/**
* 社会效益指标-偏差原因分析及改进措施
*/
private String socialDeviation;
/**
* 生态效益指标名称
*/
private String ecologicalIndicator;
/**
* 生态效益指标-指标值
*/
private String ecologicalTarget;
/**
* 生态效益指标-实际完成值
*/
private String ecologicalActual;
/**
* 生态效益指标-分值
*/
private BigDecimal ecologicalValue;
/**
* 生态效益指标-得分
*/
private BigDecimal ecologicalScore;
/**
* 生态效益指标-偏差原因分析及改进措施
*/
private String ecologicalDeviation;
/**
* 满意度指标名称
*/
private String satisfactionIndicator;
/**
* 满意度指标-指标值
*/
private String satisfactionTarget;
/**
* 满意度指标-实际完成值
*/
private String satisfactionActual;
/**
* 满意度指标-分值
*/
private BigDecimal satisfactionValue;
/**
* 满意度指标-得分
*/
private BigDecimal satisfactionScore;
/**
* 满意度指标-偏差原因分析及改进措施
*/
private String satisfactionDeviation;
/**
* 项目决策得分
*/
@DecimalMin(value = "0", message = "项目决策得分不能小于0")
@DecimalMax(value = "20", message = "项目决策得分不能大于20")
private BigDecimal decisionScore;
/**
* 项目决策自评内容
*/
private String decisionContent;
/**
* 项目过程得分
*/
@DecimalMin(value = "0", message = "项目过程得分不能小于0")
@DecimalMax(value = "20", message = "项目过程得分不能大于20")
private BigDecimal processScore;
/**
* 项目过程自评内容
*/
private String processContent;
/**
* 项目产出得分
*/
@DecimalMin(value = "0", message = "项目产出得分不能小于0")
@DecimalMax(value = "30", message = "项目产出得分不能大于30")
private BigDecimal outputScore;
/**
* 项目产出自评内容
*/
private String outputContent;
/**
* 项目效益得分
*/
@DecimalMin(value = "0", message = "项目效益得分不能小于0")
@DecimalMax(value = "30", message = "项目效益得分不能大于30")
private BigDecimal benefitScore;
/**
* 项目效益自评内容
*/
private String benefitContent;
/**
* 自评总分
*/
private BigDecimal totalScore;
/**
* 自评等级(优秀/良好/合格/不合格)
*/
private String selfEvaluationLevel;
/**
* 存在的主要问题
*/
private String existingProblems;
/**
* 改进措施和建议
*/
private String improvementMeasures;
/**
* 自评状态(draft-草稿 submitted-已提交 approved-已审核)
*/
private String evaluationStatus;
/**
* 允许已提交后编辑(0-不允许 1-允许)
*/
private Integer allowEditAfterSubmit;
/**
* 提交时间
*/
private Date submitTime;
/**
* 提交人ID
*/
private Long submitBy;
/**
* 提交人姓名
*/
private String submitByName;
/**
* 审核时间
*/
private Date approveTime;
/**
* 审核人ID
*/
private Long approveBy;
/**
* 审核人姓名
*/
private String approveByName;
/**
* 审核意见
*/
private String approveOpinion;
/**
* 是否锁定(0-未锁定 1-已锁定),锁定后不可修改
*/
private Integer isLocked;
}
@@ -0,0 +1,128 @@
package org.dromara.cw.domain.vo;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import org.dromara.cw.domain.CwPerformanceMonitoring;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 绩效运行监控视图对象 cw_performance_monitoring
*
* @author ruoyi
* @date 2025-11-04
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = CwPerformanceMonitoring.class)
public class CwPerformanceMonitoringVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@ExcelProperty(value = "主键ID")
private Long id;
/**
* 绩效自评ID
*/
@ExcelProperty(value = "绩效自评ID")
private Long evaluationId;
/**
* 项目申报ID
*/
@ExcelProperty(value = "项目申报ID")
private Long projectApplicationId;
/**
* 监控周期
*/
@ExcelProperty(value = "监控周期")
private String monitoringPeriod;
/**
* 资金使用情况
*/
@ExcelProperty(value = "资金使用情况")
private String fundUsage;
/**
* 绩效目标完成情况
*/
@ExcelProperty(value = "绩效目标完成情况")
private String performanceTargetCompletion;
/**
* 绩效指标完成情况(JSON数组)
*/
@ExcelProperty(value = "绩效指标完成情况")
private String indicators;
/**
* 存在问题
*/
@ExcelProperty(value = "存在问题")
private String existingProblems;
/**
* 指标差异率分析和说明
*/
@ExcelProperty(value = "指标差异率分析和说明")
private String indicatorVarianceAnalysis;
/**
* 下一步工作建议和打算
*/
@ExcelProperty(value = "下一步工作建议和打算")
private String nextStepSuggestions;
/**
* 填报人ID
*/
private Long fillBy;
/**
* 填报人姓名
*/
@ExcelProperty(value = "填报人")
private String fillByName;
/**
* 备注
*/
@ExcelProperty(value = "备注")
private String remark;
/**
* 创建者
*/
private Long createBy;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ExcelProperty(value = "创建时间")
private Date createTime;
/**
* 更新者
*/
private Long updateBy;
/**
* 更新时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}
@@ -0,0 +1,118 @@
package org.dromara.cw.domain.vo;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import org.dromara.cw.domain.CwProjectEvaluationIndicator;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* 项目绩效自评指标明细视图对象 cw_project_evaluation_indicator
*
* @author ruoyi
* @date 2025-11-03
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = CwProjectEvaluationIndicator.class)
public class CwProjectEvaluationIndicatorVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@ExcelProperty(value = "主键ID")
private Long id;
/**
* 绩效自评ID
*/
@ExcelProperty(value = "绩效自评ID")
private Long evaluationId;
/**
* 指标类别(decision-决策/process-过程/output-产出/benefit-效益)
*/
@ExcelProperty(value = "指标类别")
private String indicatorCategory;
/**
* 指标名称
*/
@ExcelProperty(value = "指标名称")
private String indicatorName;
/**
* 指标类型(quantity-数量/quality-质量/time-时效/cost-成本)
*/
@ExcelProperty(value = "指标类型")
private String indicatorType;
/**
* 目标值
*/
@ExcelProperty(value = "目标值")
private String targetValue;
/**
* 实际完成值
*/
@ExcelProperty(value = "实际完成值")
private String actualValue;
/**
* 完成率(%)
*/
@ExcelProperty(value = "完成率(%)")
private BigDecimal completionRate;
/**
* 指标分值
*/
@ExcelProperty(value = "指标分值")
private BigDecimal standardScore;
/**
* 实际得分
*/
@ExcelProperty(value = "实际得分")
private BigDecimal actualScore;
/**
* 完成情况说明
*/
@ExcelProperty(value = "完成情况说明")
private String completionDescription;
/**
* 排序号
*/
@ExcelProperty(value = "排序号")
private Integer sortOrder;
/**
* 备注
*/
@ExcelProperty(value = "备注")
private String remark;
/**
* 创建时间
*/
@ExcelProperty(value = "创建时间")
private Date createTime;
/**
* 更新时间
*/
@ExcelProperty(value = "更新时间")
private Date updateTime;
}
@@ -0,0 +1,183 @@
package org.dromara.cw.domain.vo;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import org.dromara.cw.domain.CwProjectMonthlyMonitoring;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* 项目月度运行监控视图对象 cw_project_monthly_monitoring
*
* @author ruoyi
* @date 2025-11-03
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = CwProjectMonthlyMonitoring.class)
public class CwProjectMonthlyMonitoringVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@ExcelProperty(value = "主键ID")
private Long id;
/**
* 绩效自评ID
*/
@ExcelProperty(value = "绩效自评ID")
private Long evaluationId;
/**
* 项目申报ID
*/
@ExcelProperty(value = "项目申报ID")
private Long projectApplicationId;
/**
* 监控年度
*/
@ExcelProperty(value = "监控年度")
private Integer monitoringYear;
/**
* 监控月份(1-12)
*/
@ExcelProperty(value = "监控月份")
private Integer monitoringMonth;
/**
* 计划进度(%)
*/
@ExcelProperty(value = "计划进度(%)")
private BigDecimal plannedProgress;
/**
* 实际进度(%)
*/
@ExcelProperty(value = "实际进度(%)")
private BigDecimal actualProgress;
/**
* 进度偏差(%)
*/
@ExcelProperty(value = "进度偏差(%)")
private BigDecimal progressVariance;
/**
* 本月预算(万元)
*/
@ExcelProperty(value = "本月预算(万元)")
private BigDecimal monthlyBudget;
/**
* 本月实际支出(万元)
*/
@ExcelProperty(value = "本月实际支出(万元)")
private BigDecimal monthlyExpenditure;
/**
* 累计预算(万元)
*/
@ExcelProperty(value = "累计预算(万元)")
private BigDecimal cumulativeBudget;
/**
* 累计实际支出(万元)
*/
@ExcelProperty(value = "累计实际支出(万元)")
private BigDecimal cumulativeExpenditure;
/**
* 资金执行率(%)
*/
@ExcelProperty(value = "资金执行率(%)")
private BigDecimal fundExecutionRate;
/**
* 本月完成的关键节点
*/
@ExcelProperty(value = "关键节点")
private String keyMilestones;
/**
* 节点完成情况(completed-已完成/delayed-延期/notStarted-未开始)
*/
@ExcelProperty(value = "节点完成情况")
private String milestoneCompletion;
/**
* 本月遇到的问题
*/
@ExcelProperty(value = "遇到的问题")
private String problemsEncountered;
/**
* 风险描述
*/
@ExcelProperty(value = "风险描述")
private String riskDescription;
/**
* 应对措施
*/
@ExcelProperty(value = "应对措施")
private String countermeasures;
/**
* 下月工作计划
*/
@ExcelProperty(value = "下月工作计划")
private String nextMonthPlan;
/**
* 填报状态(not_filled-未填报/filled-已填报)
*/
@ExcelProperty(value = "填报状态")
private String fillStatus;
/**
* 填报时间
*/
@ExcelProperty(value = "填报时间")
private Date fillTime;
/**
* 填报人ID
*/
private Long fillBy;
/**
* 填报人姓名
*/
@ExcelProperty(value = "填报人姓名")
private String fillByName;
/**
* 备注
*/
@ExcelProperty(value = "备注")
private String remark;
/**
* 创建时间
*/
@ExcelProperty(value = "创建时间")
private Date createTime;
/**
* 更新时间
*/
@ExcelProperty(value = "更新时间")
private Date updateTime;
}
@@ -0,0 +1,666 @@
package org.dromara.cw.domain.vo;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import org.dromara.cw.domain.CwProjectPerformanceSelfEvaluation;
import org.dromara.cw.domain.vo.CwPerformanceMonitoringVo;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
* 项目绩效自评视图对象 cw_project_performance_self_evaluation
*
* @author ruoyi
* @date 2025-11-03
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = CwProjectPerformanceSelfEvaluation.class)
public class CwProjectPerformanceSelfEvaluationVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@ExcelProperty(value = "主键ID")
private Long id;
/**
* 项目申报ID
*/
@ExcelProperty(value = "项目申报ID")
private Long projectApplicationId;
/**
* 申报编号
*/
@ExcelProperty(value = "申报编号")
private String applicationNo;
/**
* 项目名称
*/
@ExcelProperty(value = "项目名称")
private String projectName;
/**
* 主管部门
*/
@ExcelProperty(value = "主管部门")
private String supervisoryDept;
/**
* 实施单位
*/
@ExcelProperty(value = "实施单位")
private String implementUnit;
/**
* 自评年度
*/
@ExcelProperty(value = "自评年度")
private Integer evaluationYear;
/**
* 年初预算数(万元)
*/
@ExcelProperty(value = "年初预算数(万元)")
private BigDecimal initialBudget;
/**
* 项目负责人
*/
@ExcelProperty(value = "项目负责人")
private String principal;
/**
* 联系电话
*/
@ExcelProperty(value = "联系电话")
private String contactPhone;
/**
* 项目实施开始时间
*/
@ExcelProperty(value = "项目实施开始时间")
private Date startDate;
/**
* 项目实施结束时间
*/
@ExcelProperty(value = "项目实施结束时间")
private Date endDate;
/**
* 项目总投资(万元)
*/
@ExcelProperty(value = "项目总投资(万元)")
private BigDecimal totalInvestment;
/**
* 本年度预算(万元)
*/
@ExcelProperty(value = "本年度预算(万元)")
private BigDecimal annualBudget;
/**
* 本年度实际支出(万元)
*/
@ExcelProperty(value = "本年度实际支出(万元)")
private BigDecimal actualExpenditure;
/**
* 预算执行率(%)
*/
@ExcelProperty(value = "预算执行率(%)")
private BigDecimal budgetExecutionRate;
/**
* 资金到位分值
*/
private BigDecimal fundValue;
/**
* 资金执行率(%)
*/
private BigDecimal fundExecutionRate;
/**
* 资金到位得分
*/
private BigDecimal fundScore;
/**
* 当年财政拨款-年初预算数(万元)
*/
private BigDecimal currentYearBudgetInitial;
/**
* 当年财政拨款-全年预算数(万元)
*/
private BigDecimal currentYearBudgetAnnual;
/**
* 当年财政拨款-全年执行数(万元)
*/
private BigDecimal currentYearBudgetActual;
/**
* 当年财政拨款-分值
*/
private BigDecimal currentYearBudgetValue;
/**
* 当年财政拨款-执行率(%)
*/
private BigDecimal currentYearBudgetExecutionRate;
/**
* 当年财政拨款-得分
*/
private BigDecimal currentYearBudgetScore;
/**
* 上年结转资金-年初预算数(万元)
*/
private BigDecimal lastYearCarryoverInitial;
/**
* 上年结转资金-全年预算数(万元)
*/
private BigDecimal lastYearCarryoverAnnual;
/**
* 上年结转资金-全年执行数(万元)
*/
private BigDecimal lastYearCarryoverActual;
/**
* 上年结转资金-分值
*/
private BigDecimal lastYearCarryoverValue;
/**
* 上年结转资金-执行率(%)
*/
private BigDecimal lastYearCarryoverExecutionRate;
/**
* 上年结转资金-得分
*/
private BigDecimal lastYearCarryoverScore;
/**
* 其他资金-年初预算数(万元)
*/
private BigDecimal otherFundsInitial;
/**
* 其他资金-全年预算数(万元)
*/
private BigDecimal otherFundsAnnual;
/**
* 其他资金-全年执行数(万元)
*/
private BigDecimal otherFundsActual;
/**
* 其他资金-分值
*/
private BigDecimal otherFundsValue;
/**
* 其他资金-执行率(%)
*/
private BigDecimal otherFundsExecutionRate;
/**
* 其他资金-得分
*/
private BigDecimal otherFundsScore;
/**
* 年度绩效目标
*/
@ExcelProperty(value = "年度绩效目标")
private String performanceGoal;
/**
* 目标完成情况说明
*/
@ExcelProperty(value = "目标完成情况说明")
private String targetCompletion;
/**
* 数量指标名称
*/
private String quantityIndicator;
/**
* 数量指标-指标值
*/
private String quantityTarget;
/**
* 数量指标-实际完成值
*/
private String quantityActual;
/**
* 数量指标-分值
*/
private BigDecimal quantityValue;
/**
* 数量指标-得分
*/
private BigDecimal quantityScore;
/**
* 数量指标-偏差原因分析及改进措施
*/
private String quantityDeviation;
/**
* 质量指标名称
*/
private String qualityIndicator;
/**
* 质量指标-指标值
*/
private String qualityTarget;
/**
* 质量指标-实际完成值
*/
private String qualityActual;
/**
* 质量指标-分值
*/
private BigDecimal qualityValue;
/**
* 质量指标-得分
*/
private BigDecimal qualityScore;
/**
* 质量指标-偏差原因分析及改进措施
*/
private String qualityDeviation;
/**
* 时效指标名称
*/
private String timelinessIndicator;
/**
* 时效指标-指标值
*/
private String timelinessTarget;
/**
* 时效指标-实际完成值
*/
private String timelinessActual;
/**
* 时效指标-分值
*/
private BigDecimal timelinessValue;
/**
* 时效指标-得分
*/
private BigDecimal timelinessScore;
/**
* 时效指标-偏差原因分析及改进措施
*/
private String timelinessDeviation;
/**
* 成本指标名称
*/
private String costIndicator;
/**
* 成本指标-指标值
*/
private String costTarget;
/**
* 成本指标-实际完成值
*/
private String costActual;
/**
* 成本指标-分值
*/
private BigDecimal costValue;
/**
* 成本指标-得分
*/
private BigDecimal costScore;
/**
* 成本指标-偏差原因分析及改进措施
*/
private String costDeviation;
/**
* 经济效益指标名称
*/
private String economicIndicator;
/**
* 经济效益指标-指标值
*/
private String economicTarget;
/**
* 经济效益指标-实际完成值
*/
private String economicActual;
/**
* 经济效益指标-分值
*/
private BigDecimal economicValue;
/**
* 经济效益指标-得分
*/
private BigDecimal economicScore;
/**
* 经济效益指标-偏差原因分析及改进措施
*/
private String economicDeviation;
/**
* 社会效益指标名称
*/
private String socialIndicator;
/**
* 社会效益指标-指标值
*/
private String socialTarget;
/**
* 社会效益指标-实际完成值
*/
private String socialActual;
/**
* 社会效益指标-分值
*/
private BigDecimal socialValue;
/**
* 社会效益指标-得分
*/
private BigDecimal socialScore;
/**
* 社会效益指标-偏差原因分析及改进措施
*/
private String socialDeviation;
/**
* 生态效益指标名称
*/
private String ecologicalIndicator;
/**
* 生态效益指标-指标值
*/
private String ecologicalTarget;
/**
* 生态效益指标-实际完成值
*/
private String ecologicalActual;
/**
* 生态效益指标-分值
*/
private BigDecimal ecologicalValue;
/**
* 生态效益指标-得分
*/
private BigDecimal ecologicalScore;
/**
* 生态效益指标-偏差原因分析及改进措施
*/
private String ecologicalDeviation;
/**
* 满意度指标名称
*/
private String satisfactionIndicator;
/**
* 满意度指标-指标值
*/
private String satisfactionTarget;
/**
* 满意度指标-实际完成值
*/
private String satisfactionActual;
/**
* 满意度指标-分值
*/
private BigDecimal satisfactionValue;
/**
* 满意度指标-得分
*/
private BigDecimal satisfactionScore;
/**
* 满意度指标-偏差原因分析及改进措施
*/
private String satisfactionDeviation;
/**
* 项目决策得分
*/
@ExcelProperty(value = "项目决策得分")
private BigDecimal decisionScore;
/**
* 项目决策自评内容
*/
@ExcelProperty(value = "项目决策自评内容")
private String decisionContent;
/**
* 项目过程得分
*/
@ExcelProperty(value = "项目过程得分")
private BigDecimal processScore;
/**
* 项目过程自评内容
*/
@ExcelProperty(value = "项目过程自评内容")
private String processContent;
/**
* 项目产出得分
*/
@ExcelProperty(value = "项目产出得分")
private BigDecimal outputScore;
/**
* 项目产出自评内容
*/
@ExcelProperty(value = "项目产出自评内容")
private String outputContent;
/**
* 项目效益得分
*/
@ExcelProperty(value = "项目效益得分")
private BigDecimal benefitScore;
/**
* 项目效益自评内容
*/
@ExcelProperty(value = "项目效益自评内容")
private String benefitContent;
/**
* 自评总分
*/
@ExcelProperty(value = "自评总分")
private BigDecimal totalScore;
/**
* 自评等级(优秀/良好/合格/不合格)
*/
@ExcelProperty(value = "自评等级")
private String selfEvaluationLevel;
/**
* 存在的主要问题
*/
@ExcelProperty(value = "存在的主要问题")
private String existingProblems;
/**
* 改进措施和建议
*/
@ExcelProperty(value = "改进措施和建议")
private String improvementMeasures;
/**
* 自评状态(draft-草稿 submitted-已提交 approved-已审核)
*/
@ExcelProperty(value = "自评状态")
private String evaluationStatus;
/**
* 允许已提交后编辑(0-不允许 1-允许)
*/
@ExcelProperty(value = "允许已提交后编辑")
private Integer allowEditAfterSubmit;
/**
* 提交时间
*/
@ExcelProperty(value = "提交时间")
private Date submitTime;
/**
* 提交人ID
*/
private Long submitBy;
/**
* 提交人姓名
*/
@ExcelProperty(value = "提交人姓名")
private String submitByName;
/**
* 审核时间
*/
@ExcelProperty(value = "审核时间")
private Date approveTime;
/**
* 审核人ID
*/
private Long approveBy;
/**
* 审核人姓名
*/
@ExcelProperty(value = "审核人姓名")
private String approveByName;
/**
* 审核意见
*/
@ExcelProperty(value = "审核意见")
private String approveOpinion;
/**
* 是否锁定(0-未锁定 1-已锁定),锁定后不可修改
*/
@ExcelProperty(value = "锁定状态")
private Integer isLocked;
/**
* 锁定时间
*/
@ExcelProperty(value = "锁定时间")
private Date lockTime;
/**
* 锁定人ID
*/
private Long lockBy;
/**
* 锁定人姓名
*/
@ExcelProperty(value = "锁定人")
private String lockByName;
/**
* 备注
*/
@ExcelProperty(value = "备注")
private String remark;
/**
* 创建者
*/
private Long createBy;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ExcelProperty(value = "创建时间")
private Date createTime;
/**
* 更新者
*/
private Long updateBy;
/**
* 更新时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ExcelProperty(value = "更新时间")
private Date updateTime;
/**
* 运行监控数据列表(查看详情时返回)
*/
private List<CwPerformanceMonitoringVo> monitoringList;
}
@@ -0,0 +1,16 @@
package org.dromara.cw.mapper;
import org.dromara.cw.domain.CwPerformanceMonitoring;
import org.dromara.cw.domain.vo.CwPerformanceMonitoringVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 绩效运行监控Mapper接口
*
* @author ruoyi
* @date 2025-11-04
*/
public interface CwPerformanceMonitoringMapper extends BaseMapperPlus<CwPerformanceMonitoring, CwPerformanceMonitoringVo> {
}
@@ -0,0 +1,38 @@
package org.dromara.cw.mapper;
import org.apache.ibatis.annotations.Param;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import org.dromara.cw.domain.CwProjectEvaluationIndicator;
import org.dromara.cw.domain.vo.CwProjectEvaluationIndicatorVo;
import java.util.List;
/**
* 项目绩效自评指标明细Mapper接口
*
* @author ruoyi
* @date 2025-11-03
*/
public interface CwProjectEvaluationIndicatorMapper extends BaseMapperPlus<CwProjectEvaluationIndicator, CwProjectEvaluationIndicatorVo> {
/**
* 根据自评ID查询指标列表
*/
List<CwProjectEvaluationIndicatorVo> selectByEvaluationId(@Param("evaluationId") Long evaluationId);
/**
* 根据自评ID和指标类别查询指标列表
*/
List<CwProjectEvaluationIndicatorVo> selectByEvaluationIdAndCategory(@Param("evaluationId") Long evaluationId, @Param("indicatorCategory") String indicatorCategory);
/**
* 批量插入指标
*/
int batchInsert(@Param("list") List<CwProjectEvaluationIndicator> list);
/**
* 根据自评ID删除指标
*/
int deleteByEvaluationId(@Param("evaluationId") Long evaluationId);
}
@@ -0,0 +1,54 @@
package org.dromara.cw.mapper;
import org.apache.ibatis.annotations.Param;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import org.dromara.cw.domain.CwProjectMonthlyMonitoring;
import org.dromara.cw.domain.vo.CwProjectMonthlyMonitoringVo;
import java.math.BigDecimal;
import java.util.List;
/**
* 项目月度运行监控Mapper接口
*
* @author ruoyi
* @date 2025-11-03
*/
public interface CwProjectMonthlyMonitoringMapper extends BaseMapperPlus<CwProjectMonthlyMonitoring, CwProjectMonthlyMonitoringVo> {
/**
* 根据自评ID查询月度监控列表
*/
List<CwProjectMonthlyMonitoringVo> selectByEvaluationId(@Param("evaluationId") Long evaluationId);
/**
* 根据自评ID和年度查询月度监控列表
*/
List<CwProjectMonthlyMonitoringVo> selectByEvaluationIdAndYear(@Param("evaluationId") Long evaluationId, @Param("monitoringYear") Integer monitoringYear);
/**
* 根据自评ID、年度和月份查询月度监控
*/
CwProjectMonthlyMonitoringVo selectByEvaluationIdAndMonth(@Param("evaluationId") Long evaluationId, @Param("monitoringYear") Integer monitoringYear, @Param("monitoringMonth") Integer monitoringMonth);
/**
* 批量插入月度监控数据
*/
int batchInsert(@Param("list") List<CwProjectMonthlyMonitoring> list);
/**
* 根据自评ID删除月度监控数据
*/
int deleteByEvaluationId(@Param("evaluationId") Long evaluationId);
/**
* 计算年度累计进度
*/
BigDecimal calculateYearlyProgress(@Param("evaluationId") Long evaluationId, @Param("monitoringYear") Integer monitoringYear);
/**
* 计算年度累计支出
*/
BigDecimal calculateYearlyExpenditure(@Param("evaluationId") Long evaluationId, @Param("monitoringYear") Integer monitoringYear);
}
@@ -0,0 +1,55 @@
package org.dromara.cw.mapper;
import org.apache.ibatis.annotations.Param;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import org.dromara.cw.domain.CwProjectPerformanceSelfEvaluation;
import org.dromara.cw.domain.vo.CwProjectPerformanceSelfEvaluationVo;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
/**
* 项目绩效自评Mapper接口
*
* @author ruoyi
* @date 2025-11-03
*/
public interface CwProjectPerformanceSelfEvaluationMapper extends BaseMapperPlus<CwProjectPerformanceSelfEvaluation, CwProjectPerformanceSelfEvaluationVo> {
/**
* 根据项目申报ID和年度查询自评
*/
CwProjectPerformanceSelfEvaluationVo selectByProjectAndYear(@Param("projectApplicationId") Long projectApplicationId, @Param("evaluationYear") Integer evaluationYear);
/**
* 查询我的自评列表
*/
List<CwProjectPerformanceSelfEvaluationVo> selectMyEvaluations(@Param("userId") Long userId);
/**
* 查询待审核的自评列表
*/
List<CwProjectPerformanceSelfEvaluationVo> selectPendingApprovals();
/**
* 统计自评数量
*/
Long countEvaluations(@Param("evaluationYear") Integer evaluationYear, @Param("evaluationStatus") String evaluationStatus);
/**
* 计算平均分
*/
BigDecimal calculateAverageScore(@Param("evaluationYear") Integer evaluationYear);
/**
* 按部门统计自评情况
*/
List<Map<String, Object>> statisticsByDept(@Param("evaluationYear") Integer evaluationYear);
/**
* 按等级统计自评数量
*/
List<Map<String, Object>> statisticsByLevel(@Param("evaluationYear") Integer evaluationYear);
}
@@ -0,0 +1,56 @@
package org.dromara.cw.service;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.cw.domain.bo.CwProjectPerformanceSelfEvaluationBo;
import org.dromara.cw.domain.vo.CwProjectPerformanceSelfEvaluationVo;
import java.util.List;
/**
* 运行监控管理Service接口
* 财务管理员和学校领导使用,用于查看所有人提交的绩效自评,并进行锁定/解锁操作
*
* @author ruoyi
* @date 2025-01-03
*/
public interface ICwMonitoringManagementService {
/**
* 查询绩效自评(运行监控管理)
* 财务管理员和学校领导可以看到所有人的数据
*/
CwProjectPerformanceSelfEvaluationVo queryById(Long id);
/**
* 查询绩效自评列表(运行监控管理)
* 财务管理员和学校领导可以看到所有人的数据
*/
TableDataInfo<CwProjectPerformanceSelfEvaluationVo> queryPageList(CwProjectPerformanceSelfEvaluationBo bo, PageQuery pageQuery);
/**
* 查询绩效自评列表(运行监控管理)
*/
List<CwProjectPerformanceSelfEvaluationVo> queryList(CwProjectPerformanceSelfEvaluationBo bo);
/**
* 锁定绩效自评(单个)
*/
Boolean lockEvaluation(Long id);
/**
* 解锁绩效自评(单个)
*/
Boolean unlockEvaluation(Long id);
/**
* 批量锁定绩效自评
*/
Boolean lockBatch(List<Long> ids);
/**
* 批量解锁绩效自评
*/
Boolean unlockBatch(List<Long> ids);
}
@@ -0,0 +1,66 @@
package org.dromara.cw.service;
import org.dromara.cw.domain.vo.CwPerformanceMonitoringVo;
import org.dromara.cw.domain.bo.CwPerformanceMonitoringBo;
import java.util.Collection;
import java.util.List;
/**
* 绩效运行监控Service接口
*
* @author ruoyi
* @date 2025-11-04
*/
public interface ICwPerformanceMonitoringService {
/**
* 查询绩效运行监控
*
* @param id 主键
* @return 绩效运行监控
*/
CwPerformanceMonitoringVo queryById(Long id);
/**
* 根据自评ID查询运行监控列表
*
* @param evaluationId 自评ID
* @return 运行监控列表
*/
List<CwPerformanceMonitoringVo> queryByEvaluationId(Long evaluationId);
/**
* 新增绩效运行监控
*
* @param bo 绩效运行监控
* @return 是否新增成功
*/
Boolean insertByBo(CwPerformanceMonitoringBo bo);
/**
* 修改绩效运行监控
*
* @param bo 绩效运行监控
* @return 是否修改成功
*/
Boolean updateByBo(CwPerformanceMonitoringBo bo);
/**
* 校验并批量删除绩效运行监控信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
* 根据自评ID删除所有运行监控数据
*
* @param evaluationId 自评ID
* @return 是否删除成功
*/
Boolean deleteByEvaluationId(Long evaluationId);
}
@@ -0,0 +1,103 @@
package org.dromara.cw.service;
import org.dromara.cw.domain.vo.CwProjectEvaluationIndicatorVo;
import org.dromara.cw.domain.bo.CwProjectEvaluationIndicatorBo;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import java.util.Collection;
import java.util.List;
/**
* 项目绩效自评指标明细Service接口
*
* @author ruoyi
* @date 2025-11-03
*/
public interface ICwProjectEvaluationIndicatorService {
/**
* 查询项目绩效自评指标明细
*
* @param id 主键
* @return 项目绩效自评指标明细
*/
CwProjectEvaluationIndicatorVo queryById(Long id);
/**
* 查询项目绩效自评指标明细列表
*
* @param bo 查询条件
* @return 项目绩效自评指标明细列表
*/
List<CwProjectEvaluationIndicatorVo> queryList(CwProjectEvaluationIndicatorBo bo);
/**
* 分页查询项目绩效自评指标明细列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 项目绩效自评指标明细分页列表
*/
TableDataInfo<CwProjectEvaluationIndicatorVo> queryPageList(CwProjectEvaluationIndicatorBo bo, PageQuery pageQuery);
/**
* 根据自评ID查询指标明细列表
*
* @param evaluationId 自评ID
* @return 指标明细列表
*/
List<CwProjectEvaluationIndicatorVo> queryByEvaluationId(Long evaluationId);
/**
* 根据自评ID和指标类型查询指标明细列表
*
* @param evaluationId 自评ID
* @param indicatorType 指标类型
* @return 指标明细列表
*/
List<CwProjectEvaluationIndicatorVo> queryByEvaluationIdAndType(Long evaluationId, String indicatorType);
/**
* 新增项目绩效自评指标明细
*
* @param bo 项目绩效自评指标明细
* @return 是否新增成功
*/
Boolean insertByBo(CwProjectEvaluationIndicatorBo bo);
/**
* 修改项目绩效自评指标明细
*
* @param bo 项目绩效自评指标明细
* @return 是否修改成功
*/
Boolean updateByBo(CwProjectEvaluationIndicatorBo bo);
/**
* 批量保存指标明细
*
* @param evaluationId 自评ID
* @param boList 指标明细列表
* @return 是否保存成功
*/
Boolean batchSave(Long evaluationId, List<CwProjectEvaluationIndicatorBo> boList);
/**
* 校验并批量删除项目绩效自评指标明细信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
* 根据自评ID删除所有指标明细
*
* @param evaluationId 自评ID
* @return 是否删除成功
*/
Boolean deleteByEvaluationId(Long evaluationId);
}
@@ -0,0 +1,112 @@
package org.dromara.cw.service;
import org.dromara.cw.domain.vo.CwProjectMonthlyMonitoringVo;
import org.dromara.cw.domain.bo.CwProjectMonthlyMonitoringBo;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* 项目月度运行监控Service接口
*
* @author ruoyi
* @date 2025-11-03
*/
public interface ICwProjectMonthlyMonitoringService {
/**
* 查询项目月度运行监控
*
* @param id 主键
* @return 项目月度运行监控
*/
CwProjectMonthlyMonitoringVo queryById(Long id);
/**
* 查询项目月度运行监控列表
*
* @param bo 查询条件
* @return 项目月度运行监控列表
*/
List<CwProjectMonthlyMonitoringVo> queryList(CwProjectMonthlyMonitoringBo bo);
/**
* 分页查询项目月度运行监控列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 项目月度运行监控分页列表
*/
TableDataInfo<CwProjectMonthlyMonitoringVo> queryPageList(CwProjectMonthlyMonitoringBo bo, PageQuery pageQuery);
/**
* 根据自评ID查询月度监控列表
*
* @param evaluationId 自评ID
* @return 月度监控列表
*/
List<CwProjectMonthlyMonitoringVo> queryByEvaluationId(Long evaluationId);
/**
* 查询某个自评的全年监控数据
*
* @param evaluationId 自评ID
* @param year 年份
* @return 月度数据Map,key为月份(1-12),value为监控数据
*/
Map<Integer, CwProjectMonthlyMonitoringVo> queryYearlyMonitoring(Long evaluationId, Integer year);
/**
* 新增项目月度运行监控
*
* @param bo 项目月度运行监控
* @return 是否新增成功
*/
Boolean insertByBo(CwProjectMonthlyMonitoringBo bo);
/**
* 修改项目月度运行监控
*
* @param bo 项目月度运行监控
* @return 是否修改成功
*/
Boolean updateByBo(CwProjectMonthlyMonitoringBo bo);
/**
* 填报月度数据
*
* @param bo 月度监控数据
* @return 是否填报成功
*/
Boolean fillMonthlyData(CwProjectMonthlyMonitoringBo bo);
/**
* 批量保存月度监控数据
*
* @param evaluationId 自评ID
* @param boList 月度监控数据列表
* @return 是否保存成功
*/
Boolean batchSave(Long evaluationId, List<CwProjectMonthlyMonitoringBo> boList);
/**
* 校验并批量删除项目月度运行监控信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
* 根据自评ID删除所有月度监控数据
*
* @param evaluationId 自评ID
* @return 是否删除成功
*/
Boolean deleteByEvaluationId(Long evaluationId);
}
@@ -0,0 +1,106 @@
package org.dromara.cw.service;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.cw.domain.bo.CwProjectPerformanceSelfEvaluationBo;
import org.dromara.cw.domain.vo.CwProjectPerformanceSelfEvaluationVo;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* 项目绩效自评Service接口
*
* @author ruoyi
* @date 2025-11-03
*/
public interface ICwProjectPerformanceSelfEvaluationService {
/**
* 查询项目绩效自评
*/
CwProjectPerformanceSelfEvaluationVo queryById(Long id);
/**
* 查询项目绩效自评列表
*/
TableDataInfo<CwProjectPerformanceSelfEvaluationVo> queryPageList(CwProjectPerformanceSelfEvaluationBo bo, PageQuery pageQuery);
/**
* 查询项目绩效自评列表
*/
List<CwProjectPerformanceSelfEvaluationVo> queryList(CwProjectPerformanceSelfEvaluationBo bo);
/**
* 根据项目申报ID和年度查询自评
*/
CwProjectPerformanceSelfEvaluationVo queryByProjectAndYear(Long projectApplicationId, Integer evaluationYear);
/**
* 查询我的自评列表
*/
List<CwProjectPerformanceSelfEvaluationVo> queryMyEvaluations(Long userId);
/**
* 查询待审核的自评列表
*/
List<CwProjectPerformanceSelfEvaluationVo> queryPendingApprovals();
/**
* 新增项目绩效自评
*/
Boolean insertByBo(CwProjectPerformanceSelfEvaluationBo bo);
/**
* 修改项目绩效自评
*/
Boolean updateByBo(CwProjectPerformanceSelfEvaluationBo bo);
/**
* 保存草稿
*/
Boolean saveDraft(CwProjectPerformanceSelfEvaluationBo bo);
/**
* 提交自评
*/
Boolean submitEvaluation(Long id);
/**
* 审核自评
*/
Boolean approveEvaluation(Long id, String opinion, Boolean approved);
/**
* 校验并批量删除项目绩效自评信息
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
* 统计自评数量
*/
Long countEvaluations(Integer evaluationYear, String evaluationStatus);
/**
* 计算平均分
*/
BigDecimal calculateAverageScore(Integer evaluationYear);
/**
* 按部门统计自评情况
*/
List<Map<String, Object>> statisticsByDept(Integer evaluationYear);
/**
* 按等级统计自评数量
*/
List<Map<String, Object>> statisticsByLevel(Integer evaluationYear);
/**
* 导出项目绩效自评
*/
void export(CwProjectPerformanceSelfEvaluationBo bo);
}
@@ -0,0 +1,306 @@
package org.dromara.cw.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.cw.domain.CwProjectPerformanceSelfEvaluation;
import org.dromara.cw.domain.bo.CwProjectPerformanceSelfEvaluationBo;
import org.dromara.cw.domain.vo.CwProjectPerformanceSelfEvaluationVo;
import org.dromara.cw.mapper.CwProjectPerformanceSelfEvaluationMapper;
import org.dromara.cw.service.ICwMonitoringManagementService;
import org.dromara.cw.service.ICwPerformanceMonitoringService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
/**
* 运行监控管理Service业务层处理
* 财务管理员和学校领导使用,用于查看所有人提交的绩效自评,并进行锁定/解锁操作
*
* @author ruoyi
* @date 2025-01-03
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class CwMonitoringManagementServiceImpl implements ICwMonitoringManagementService {
private final CwProjectPerformanceSelfEvaluationMapper baseMapper;
private final ICwPerformanceMonitoringService performanceMonitoringService;
/**
* 查询绩效自评(运行监控管理)
* 财务管理员和学校领导可以看到所有人的数据,不进行数据权限过滤
*/
@Override
public CwProjectPerformanceSelfEvaluationVo queryById(Long id) {
CwProjectPerformanceSelfEvaluationVo vo = baseMapper.selectVoById(id);
if (vo != null) {
// 加载运行监控数据
vo.setMonitoringList(performanceMonitoringService.queryByEvaluationId(id));
}
return vo;
}
/**
* 查询绩效自评列表(运行监控管理)
* 财务管理员和学校领导可以看到所有人的数据,不进行数据权限过滤
*/
@Override
public TableDataInfo<CwProjectPerformanceSelfEvaluationVo> queryPageList(CwProjectPerformanceSelfEvaluationBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<CwProjectPerformanceSelfEvaluation> lqw = buildQueryWrapper(bo);
Page<CwProjectPerformanceSelfEvaluationVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询绩效自评列表(运行监控管理)
*/
@Override
public List<CwProjectPerformanceSelfEvaluationVo> queryList(CwProjectPerformanceSelfEvaluationBo bo) {
LambdaQueryWrapper<CwProjectPerformanceSelfEvaluation> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
/**
* 构建查询条件
* 注意:运行监控管理不进行数据权限过滤,财务管理员和学校领导可以看到所有人的数据
*/
private LambdaQueryWrapper<CwProjectPerformanceSelfEvaluation> buildQueryWrapper(CwProjectPerformanceSelfEvaluationBo bo) {
LambdaQueryWrapper<CwProjectPerformanceSelfEvaluation> lqw = Wrappers.lambdaQuery();
// 🔧 修复:只有当projectApplicationId > 0时才作为查询条件
lqw.eq(bo.getProjectApplicationId() != null && bo.getProjectApplicationId() > 0,
CwProjectPerformanceSelfEvaluation::getProjectApplicationId, bo.getProjectApplicationId());
lqw.like(StringUtils.isNotBlank(bo.getApplicationNo()), CwProjectPerformanceSelfEvaluation::getApplicationNo, bo.getApplicationNo());
lqw.like(StringUtils.isNotBlank(bo.getProjectName()), CwProjectPerformanceSelfEvaluation::getProjectName, bo.getProjectName());
lqw.eq(bo.getEvaluationYear() != null, CwProjectPerformanceSelfEvaluation::getEvaluationYear, bo.getEvaluationYear());
lqw.eq(StringUtils.isNotBlank(bo.getEvaluationStatus()), CwProjectPerformanceSelfEvaluation::getEvaluationStatus, bo.getEvaluationStatus());
lqw.eq(StringUtils.isNotBlank(bo.getSelfEvaluationLevel()), CwProjectPerformanceSelfEvaluation::getSelfEvaluationLevel, bo.getSelfEvaluationLevel());
lqw.eq(bo.getIsLocked() != null, CwProjectPerformanceSelfEvaluation::getIsLocked, bo.getIsLocked());
// 🔒 运行监控管理:不进行数据权限过滤,财务管理员和学校领导可以看到所有人的数据
lqw.orderByDesc(CwProjectPerformanceSelfEvaluation::getCreateTime);
return lqw;
}
/**
* 锁定绩效自评(单个)
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean lockEvaluation(Long id) {
try {
// 获取当前登录用户信息
var loginUser = LoginHelper.getLoginUser();
if (loginUser == null) {
log.error("无法获取登录用户信息,锁定失败");
return false;
}
Long userId = loginUser.getUserId();
String userName = loginUser.getUsername();
// 检查记录是否存在
CwProjectPerformanceSelfEvaluation evaluation = baseMapper.selectById(id);
if (evaluation == null) {
log.error("绩效自评记录不存在,ID: {}", id);
return false;
}
// 检查是否已经锁定
if (evaluation.getIsLocked() != null && evaluation.getIsLocked() == 1) {
log.warn("绩效自评记录已锁定,ID: {}", id);
return false;
}
// 执行锁定
LambdaUpdateWrapper<CwProjectPerformanceSelfEvaluation> updateWrapper = Wrappers.lambdaUpdate();
updateWrapper.eq(CwProjectPerformanceSelfEvaluation::getId, id)
.set(CwProjectPerformanceSelfEvaluation::getIsLocked, 1)
.set(CwProjectPerformanceSelfEvaluation::getLockTime, new Date())
.set(CwProjectPerformanceSelfEvaluation::getLockBy, userId)
.set(CwProjectPerformanceSelfEvaluation::getLockByName, userName);
int result = baseMapper.update(null, updateWrapper);
log.info("锁定绩效自评成功,ID: {}, 操作人: {}", id, userName);
return result > 0;
} catch (Exception e) {
log.error("锁定绩效自评异常,ID: {}", id, e);
throw new RuntimeException("锁定绩效自评失败: " + e.getMessage(), e);
}
}
/**
* 解锁绩效自评(单个)
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean unlockEvaluation(Long id) {
try {
// 获取当前登录用户信息
var loginUser = LoginHelper.getLoginUser();
if (loginUser == null) {
log.error("无法获取登录用户信息,解锁失败");
return false;
}
String userName = loginUser.getUsername();
// 检查记录是否存在
CwProjectPerformanceSelfEvaluation evaluation = baseMapper.selectById(id);
if (evaluation == null) {
log.error("绩效自评记录不存在,ID: {}", id);
return false;
}
// 检查是否已经解锁
if (evaluation.getIsLocked() == null || evaluation.getIsLocked() == 0) {
log.warn("绩效自评记录未锁定,ID: {}", id);
return false;
}
// 执行解锁
LambdaUpdateWrapper<CwProjectPerformanceSelfEvaluation> updateWrapper = Wrappers.lambdaUpdate();
updateWrapper.eq(CwProjectPerformanceSelfEvaluation::getId, id)
.set(CwProjectPerformanceSelfEvaluation::getIsLocked, 0)
.set(CwProjectPerformanceSelfEvaluation::getLockTime, null)
.set(CwProjectPerformanceSelfEvaluation::getLockBy, null)
.set(CwProjectPerformanceSelfEvaluation::getLockByName, null);
int result = baseMapper.update(null, updateWrapper);
log.info("解锁绩效自评成功,ID: {}, 操作人: {}", id, userName);
return result > 0;
} catch (Exception e) {
log.error("解锁绩效自评异常,ID: {}", id, e);
throw new RuntimeException("解锁绩效自评失败: " + e.getMessage(), e);
}
}
/**
* 批量锁定绩效自评
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean lockBatch(List<Long> ids) {
try {
// 获取当前登录用户信息
var loginUser = LoginHelper.getLoginUser();
if (loginUser == null) {
log.error("无法获取登录用户信息,批量锁定失败");
return false;
}
Long userId = loginUser.getUserId();
String userName = loginUser.getUsername();
// 批量锁定
int successCount = 0;
for (Long id : ids) {
try {
// 检查记录是否存在
CwProjectPerformanceSelfEvaluation evaluation = baseMapper.selectById(id);
if (evaluation == null) {
log.warn("绩效自评记录不存在,跳过,ID: {}", id);
continue;
}
// 检查是否已经锁定
if (evaluation.getIsLocked() != null && evaluation.getIsLocked() == 1) {
log.warn("绩效自评记录已锁定,跳过,ID: {}", id);
continue;
}
// 执行锁定
LambdaUpdateWrapper<CwProjectPerformanceSelfEvaluation> updateWrapper = Wrappers.lambdaUpdate();
updateWrapper.eq(CwProjectPerformanceSelfEvaluation::getId, id)
.set(CwProjectPerformanceSelfEvaluation::getIsLocked, 1)
.set(CwProjectPerformanceSelfEvaluation::getLockTime, new Date())
.set(CwProjectPerformanceSelfEvaluation::getLockBy, userId)
.set(CwProjectPerformanceSelfEvaluation::getLockByName, userName);
int result = baseMapper.update(null, updateWrapper);
if (result > 0) {
successCount++;
}
} catch (Exception e) {
log.error("锁定绩效自评失败,ID: {}", id, e);
}
}
log.info("批量锁定绩效自评完成,总数: {}, 成功: {}, 操作人: {}", ids.size(), successCount, userName);
return successCount > 0;
} catch (Exception e) {
log.error("批量锁定绩效自评异常", e);
throw new RuntimeException("批量锁定绩效自评失败: " + e.getMessage(), e);
}
}
/**
* 批量解锁绩效自评
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean unlockBatch(List<Long> ids) {
try {
// 获取当前登录用户信息
var loginUser = LoginHelper.getLoginUser();
if (loginUser == null) {
log.error("无法获取登录用户信息,批量解锁失败");
return false;
}
String userName = loginUser.getUsername();
// 批量解锁
int successCount = 0;
for (Long id : ids) {
try {
// 检查记录是否存在
CwProjectPerformanceSelfEvaluation evaluation = baseMapper.selectById(id);
if (evaluation == null) {
log.warn("绩效自评记录不存在,跳过,ID: {}", id);
continue;
}
// 检查是否已经解锁
if (evaluation.getIsLocked() == null || evaluation.getIsLocked() == 0) {
log.warn("绩效自评记录未锁定,跳过,ID: {}", id);
continue;
}
// 执行解锁
LambdaUpdateWrapper<CwProjectPerformanceSelfEvaluation> updateWrapper = Wrappers.lambdaUpdate();
updateWrapper.eq(CwProjectPerformanceSelfEvaluation::getId, id)
.set(CwProjectPerformanceSelfEvaluation::getIsLocked, 0)
.set(CwProjectPerformanceSelfEvaluation::getLockTime, null)
.set(CwProjectPerformanceSelfEvaluation::getLockBy, null)
.set(CwProjectPerformanceSelfEvaluation::getLockByName, null);
int result = baseMapper.update(null, updateWrapper);
if (result > 0) {
successCount++;
}
} catch (Exception e) {
log.error("解锁绩效自评失败,ID: {}", id, e);
}
}
log.info("批量解锁绩效自评完成,总数: {}, 成功: {}, 操作人: {}", ids.size(), successCount, userName);
return successCount > 0;
} catch (Exception e) {
log.error("批量解锁绩效自评异常", e);
throw new RuntimeException("批量解锁绩效自评失败: " + e.getMessage(), e);
}
}
}
@@ -0,0 +1,145 @@
package org.dromara.cw.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.cw.domain.CwPerformanceMonitoring;
import org.dromara.cw.domain.bo.CwPerformanceMonitoringBo;
import org.dromara.cw.domain.vo.CwPerformanceMonitoringVo;
import org.dromara.cw.mapper.CwPerformanceMonitoringMapper;
import org.dromara.cw.service.ICwPerformanceMonitoringService;
import org.springframework.stereotype.Service;
import java.util.Collection;
import java.util.List;
/**
* 绩效运行监控Service业务层处理
*
* @author ruoyi
* @date 2025-11-04
*/
@RequiredArgsConstructor
@Service
public class CwPerformanceMonitoringServiceImpl implements ICwPerformanceMonitoringService {
private final CwPerformanceMonitoringMapper baseMapper;
/**
* 查询绩效运行监控
*/
@Override
public CwPerformanceMonitoringVo queryById(Long id) {
return baseMapper.selectVoById(id);
}
/**
* 根据自评ID查询运行监控列表
*/
@Override
public List<CwPerformanceMonitoringVo> queryByEvaluationId(Long evaluationId) {
LambdaQueryWrapper<CwPerformanceMonitoring> lqw = Wrappers.lambdaQuery();
lqw.eq(CwPerformanceMonitoring::getEvaluationId, evaluationId);
lqw.orderByDesc(CwPerformanceMonitoring::getCreateTime);
return baseMapper.selectVoList(lqw);
}
/**
* 新增绩效运行监控
*/
@Override
public Boolean insertByBo(CwPerformanceMonitoringBo bo) {
CwPerformanceMonitoring add = MapstructUtils.convert(bo, CwPerformanceMonitoring.class);
validEntityBeforeSave(add);
// 设置填报人信息
Long userId = getUserIdSafely();
String username = LoginHelper.getUsername();
String nickname = LoginHelper.getNickname();
add.setFillBy(userId);
// 优先使用昵称,如果昵称为空则使用用户名
add.setFillByName(StringUtils.isNotBlank(nickname) ? nickname : username);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 安全获取用户ID,处理可能的字符串格式(如 "sys_user:1")
*/
private Long getUserIdSafely() {
try {
Long userId = LoginHelper.getUserId();
if (userId != null) {
return userId;
}
} catch (Exception e) {
// 如果getUserId()失败,尝试从getUserIdStr()解析
}
// 尝试从字符串格式解析
try {
String userIdStr = LoginHelper.getUserIdStr();
if (StringUtils.isNotBlank(userIdStr)) {
// 处理 "sys_user:1" 这种格式,提取数字部分
if (userIdStr.contains(":")) {
String[] parts = userIdStr.split(":");
if (parts.length > 1) {
return Long.parseLong(parts[1]);
}
} else {
return Long.parseLong(userIdStr);
}
}
} catch (Exception e) {
// 解析失败,返回null或抛出异常
}
return null;
}
/**
* 修改绩效运行监控
*/
@Override
public Boolean updateByBo(CwPerformanceMonitoringBo bo) {
CwPerformanceMonitoring update = MapstructUtils.convert(bo, CwPerformanceMonitoring.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(CwPerformanceMonitoring entity) {
// TODO 做一些数据校验,如唯一约束
}
/**
* 批量删除绩效运行监控
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
// TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
/**
* 根据自评ID删除所有运行监控数据
*/
@Override
public Boolean deleteByEvaluationId(Long evaluationId) {
LambdaQueryWrapper<CwPerformanceMonitoring> lqw = Wrappers.lambdaQuery();
lqw.eq(CwPerformanceMonitoring::getEvaluationId, evaluationId);
return baseMapper.delete(lqw) > 0;
}
}
@@ -0,0 +1,203 @@
package org.dromara.cw.service.impl;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.dromara.cw.domain.bo.CwProjectEvaluationIndicatorBo;
import org.dromara.cw.domain.vo.CwProjectEvaluationIndicatorVo;
import org.dromara.cw.domain.CwProjectEvaluationIndicator;
import org.dromara.cw.mapper.CwProjectEvaluationIndicatorMapper;
import org.dromara.cw.service.ICwProjectEvaluationIndicatorService;
import java.util.List;
import java.util.Collection;
/**
* 项目绩效自评指标明细Service业务层处理
*
* @author ruoyi
* @date 2025-11-03
*/
@RequiredArgsConstructor
@Service
public class CwProjectEvaluationIndicatorServiceImpl implements ICwProjectEvaluationIndicatorService {
private final CwProjectEvaluationIndicatorMapper baseMapper;
/**
* 查询项目绩效自评指标明细
*
* @param id 主键
* @return 项目绩效自评指标明细
*/
@Override
public CwProjectEvaluationIndicatorVo queryById(Long id) {
return baseMapper.selectVoById(id);
}
/**
* 查询项目绩效自评指标明细列表
*
* @param bo 查询条件
* @return 项目绩效自评指标明细列表
*/
@Override
public List<CwProjectEvaluationIndicatorVo> queryList(CwProjectEvaluationIndicatorBo bo) {
LambdaQueryWrapper<CwProjectEvaluationIndicator> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
/**
* 分页查询项目绩效自评指标明细列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 项目绩效自评指标明细分页列表
*/
@Override
public TableDataInfo<CwProjectEvaluationIndicatorVo> queryPageList(CwProjectEvaluationIndicatorBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<CwProjectEvaluationIndicator> lqw = buildQueryWrapper(bo);
Page<CwProjectEvaluationIndicatorVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 根据自评ID查询指标明细列表
*
* @param evaluationId 自评ID
* @return 指标明细列表
*/
@Override
public List<CwProjectEvaluationIndicatorVo> queryByEvaluationId(Long evaluationId) {
LambdaQueryWrapper<CwProjectEvaluationIndicator> lqw = Wrappers.lambdaQuery();
lqw.eq(CwProjectEvaluationIndicator::getEvaluationId, evaluationId);
lqw.orderByAsc(CwProjectEvaluationIndicator::getIndicatorType);
lqw.orderByAsc(CwProjectEvaluationIndicator::getSortOrder);
return baseMapper.selectVoList(lqw);
}
/**
* 根据自评ID和指标类型查询指标明细列表
*
* @param evaluationId 自评ID
* @param indicatorType 指标类型
* @return 指标明细列表
*/
@Override
public List<CwProjectEvaluationIndicatorVo> queryByEvaluationIdAndType(Long evaluationId, String indicatorType) {
LambdaQueryWrapper<CwProjectEvaluationIndicator> lqw = Wrappers.lambdaQuery();
lqw.eq(CwProjectEvaluationIndicator::getEvaluationId, evaluationId);
lqw.eq(StringUtils.isNotBlank(indicatorType), CwProjectEvaluationIndicator::getIndicatorType, indicatorType);
lqw.orderByAsc(CwProjectEvaluationIndicator::getSortOrder);
return baseMapper.selectVoList(lqw);
}
/**
* 构建查询条件
*/
private LambdaQueryWrapper<CwProjectEvaluationIndicator> buildQueryWrapper(CwProjectEvaluationIndicatorBo bo) {
LambdaQueryWrapper<CwProjectEvaluationIndicator> lqw = Wrappers.lambdaQuery();
lqw.eq(bo.getEvaluationId() != null, CwProjectEvaluationIndicator::getEvaluationId, bo.getEvaluationId());
lqw.eq(StringUtils.isNotBlank(bo.getIndicatorType()), CwProjectEvaluationIndicator::getIndicatorType, bo.getIndicatorType());
lqw.like(StringUtils.isNotBlank(bo.getIndicatorName()), CwProjectEvaluationIndicator::getIndicatorName, bo.getIndicatorName());
lqw.orderByAsc(CwProjectEvaluationIndicator::getIndicatorType);
lqw.orderByAsc(CwProjectEvaluationIndicator::getSortOrder);
return lqw;
}
/**
* 新增项目绩效自评指标明细
*
* @param bo 项目绩效自评指标明细
* @return 是否新增成功
*/
@Override
public Boolean insertByBo(CwProjectEvaluationIndicatorBo bo) {
CwProjectEvaluationIndicator add = MapstructUtils.convert(bo, CwProjectEvaluationIndicator.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改项目绩效自评指标明细
*
* @param bo 项目绩效自评指标明细
* @return 是否修改成功
*/
@Override
public Boolean updateByBo(CwProjectEvaluationIndicatorBo bo) {
CwProjectEvaluationIndicator update = MapstructUtils.convert(bo, CwProjectEvaluationIndicator.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 批量保存指标明细
*
* @param evaluationId 自评ID
* @param boList 指标明细列表
* @return 是否保存成功
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean batchSave(Long evaluationId, List<CwProjectEvaluationIndicatorBo> boList) {
// 先删除该自评下的所有指标
deleteByEvaluationId(evaluationId);
// 批量插入新的指标
if (boList != null && !boList.isEmpty()) {
for (CwProjectEvaluationIndicatorBo bo : boList) {
bo.setEvaluationId(evaluationId);
insertByBo(bo);
}
}
return true;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(CwProjectEvaluationIndicator entity) {
// 可以在此添加业务校验逻辑
}
/**
* 批量删除项目绩效自评指标明细
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
// 可以在此添加删除前的校验逻辑
}
return baseMapper.deleteBatchIds(ids) > 0;
}
/**
* 根据自评ID删除所有指标明细
*
* @param evaluationId 自评ID
* @return 是否删除成功
*/
@Override
public Boolean deleteByEvaluationId(Long evaluationId) {
LambdaQueryWrapper<CwProjectEvaluationIndicator> lqw = Wrappers.lambdaQuery();
lqw.eq(CwProjectEvaluationIndicator::getEvaluationId, evaluationId);
return baseMapper.delete(lqw) >= 0;
}
}
@@ -0,0 +1,319 @@
package org.dromara.cw.service.impl;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.dromara.cw.domain.bo.CwProjectMonthlyMonitoringBo;
import org.dromara.cw.domain.vo.CwProjectMonthlyMonitoringVo;
import org.dromara.cw.domain.CwProjectMonthlyMonitoring;
import org.dromara.cw.mapper.CwProjectMonthlyMonitoringMapper;
import org.dromara.cw.service.ICwProjectMonthlyMonitoringService;
import org.dromara.common.satoken.utils.LoginHelper;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Collection;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 项目月度运行监控Service业务层处理
*
* @author ruoyi
* @date 2025-11-03
*/
@RequiredArgsConstructor
@Service
public class CwProjectMonthlyMonitoringServiceImpl implements ICwProjectMonthlyMonitoringService {
private final CwProjectMonthlyMonitoringMapper baseMapper;
/**
* 查询项目月度运行监控
*
* @param id 主键
* @return 项目月度运行监控
*/
@Override
public CwProjectMonthlyMonitoringVo queryById(Long id) {
return baseMapper.selectVoById(id);
}
/**
* 查询项目月度运行监控列表
*
* @param bo 查询条件
* @return 项目月度运行监控列表
*/
@Override
public List<CwProjectMonthlyMonitoringVo> queryList(CwProjectMonthlyMonitoringBo bo) {
LambdaQueryWrapper<CwProjectMonthlyMonitoring> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
/**
* 分页查询项目月度运行监控列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 项目月度运行监控分页列表
*/
@Override
public TableDataInfo<CwProjectMonthlyMonitoringVo> queryPageList(CwProjectMonthlyMonitoringBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<CwProjectMonthlyMonitoring> lqw = buildQueryWrapper(bo);
Page<CwProjectMonthlyMonitoringVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 根据自评ID查询月度监控列表
*
* @param evaluationId 自评ID
* @return 月度监控列表
*/
@Override
public List<CwProjectMonthlyMonitoringVo> queryByEvaluationId(Long evaluationId) {
LambdaQueryWrapper<CwProjectMonthlyMonitoring> lqw = Wrappers.lambdaQuery();
lqw.eq(CwProjectMonthlyMonitoring::getEvaluationId, evaluationId);
lqw.orderByAsc(CwProjectMonthlyMonitoring::getMonitoringYear);
lqw.orderByAsc(CwProjectMonthlyMonitoring::getMonitoringMonth);
return baseMapper.selectVoList(lqw);
}
/**
* 查询某个自评的全年监控数据
*
* @param evaluationId 自评ID
* @param year 年份
* @return 月度数据Map,key为月份(1-12),value为监控数据
*/
@Override
public Map<Integer, CwProjectMonthlyMonitoringVo> queryYearlyMonitoring(Long evaluationId, Integer year) {
LambdaQueryWrapper<CwProjectMonthlyMonitoring> lqw = Wrappers.lambdaQuery();
lqw.eq(CwProjectMonthlyMonitoring::getEvaluationId, evaluationId);
lqw.eq(CwProjectMonthlyMonitoring::getMonitoringYear, year);
lqw.orderByAsc(CwProjectMonthlyMonitoring::getMonitoringMonth);
List<CwProjectMonthlyMonitoringVo> list = baseMapper.selectVoList(lqw);
return list.stream().collect(
Collectors.toMap(CwProjectMonthlyMonitoringVo::getMonitoringMonth, v -> v)
);
}
/**
* 构建查询条件
*/
private LambdaQueryWrapper<CwProjectMonthlyMonitoring> buildQueryWrapper(CwProjectMonthlyMonitoringBo bo) {
LambdaQueryWrapper<CwProjectMonthlyMonitoring> lqw = Wrappers.lambdaQuery();
lqw.eq(bo.getEvaluationId() != null, CwProjectMonthlyMonitoring::getEvaluationId, bo.getEvaluationId());
lqw.eq(bo.getProjectApplicationId() != null, CwProjectMonthlyMonitoring::getProjectApplicationId, bo.getProjectApplicationId());
lqw.eq(bo.getMonitoringYear() != null, CwProjectMonthlyMonitoring::getMonitoringYear, bo.getMonitoringYear());
lqw.eq(bo.getMonitoringMonth() != null, CwProjectMonthlyMonitoring::getMonitoringMonth, bo.getMonitoringMonth());
lqw.eq(StringUtils.isNotBlank(bo.getFillStatus()), CwProjectMonthlyMonitoring::getFillStatus, bo.getFillStatus());
lqw.orderByDesc(CwProjectMonthlyMonitoring::getMonitoringYear);
lqw.orderByAsc(CwProjectMonthlyMonitoring::getMonitoringMonth);
return lqw;
}
/**
* 新增项目月度运行监控
*
* @param bo 项目月度运行监控
* @return 是否新增成功
*/
@Override
public Boolean insertByBo(CwProjectMonthlyMonitoringBo bo) {
CwProjectMonthlyMonitoring add = MapstructUtils.convert(bo, CwProjectMonthlyMonitoring.class);
validEntityBeforeSave(add);
// 自动计算
calculateFields(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改项目月度运行监控
*
* @param bo 项目月度运行监控
* @return 是否修改成功
*/
@Override
public Boolean updateByBo(CwProjectMonthlyMonitoringBo bo) {
CwProjectMonthlyMonitoring update = MapstructUtils.convert(bo, CwProjectMonthlyMonitoring.class);
validEntityBeforeSave(update);
// 自动计算
calculateFields(update);
return baseMapper.updateById(update) > 0;
}
/**
* 填报月度数据
*
* @param bo 月度监控数据
* @return 是否填报成功
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean fillMonthlyData(CwProjectMonthlyMonitoringBo bo) {
// 检查是否已存在该月数据
LambdaQueryWrapper<CwProjectMonthlyMonitoring> lqw = Wrappers.lambdaQuery();
lqw.eq(CwProjectMonthlyMonitoring::getEvaluationId, bo.getEvaluationId());
lqw.eq(CwProjectMonthlyMonitoring::getMonitoringYear, bo.getMonitoringYear());
lqw.eq(CwProjectMonthlyMonitoring::getMonitoringMonth, bo.getMonitoringMonth());
CwProjectMonthlyMonitoring existing = baseMapper.selectOne(lqw);
if (existing != null) {
// 如果已存在,则更新
bo.setId(existing.getId());
return updateByBo(bo);
} else {
// 如果不存在,则新增
bo.setFillStatus("filled");
bo.setFillTime(new Date());
bo.setFillBy(getUserIdSafely());
return insertByBo(bo);
}
}
/**
* 批量保存月度监控数据
*
* @param evaluationId 自评ID
* @param boList 月度监控数据列表
* @return 是否保存成功
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean batchSave(Long evaluationId, List<CwProjectMonthlyMonitoringBo> boList) {
if (boList == null || boList.isEmpty()) {
return true;
}
for (CwProjectMonthlyMonitoringBo bo : boList) {
bo.setEvaluationId(evaluationId);
fillMonthlyData(bo);
}
return true;
}
/**
* 安全获取用户ID,处理可能的字符串格式(如 "sys_user:1")
*/
private Long getUserIdSafely() {
try {
Long userId = LoginHelper.getUserId();
if (userId != null) {
return userId;
}
} catch (Exception e) {
// 如果getUserId()失败,尝试从getUserIdStr()解析
}
// 尝试从字符串格式解析
try {
String userIdStr = LoginHelper.getUserIdStr();
if (StringUtils.isNotBlank(userIdStr)) {
// 处理 "sys_user:1" 这种格式,提取数字部分
if (userIdStr.contains(":")) {
String[] parts = userIdStr.split(":");
if (parts.length > 1) {
return Long.parseLong(parts[1]);
}
} else {
return Long.parseLong(userIdStr);
}
}
} catch (Exception e) {
// 解析失败,返回null或抛出异常
}
return null;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(CwProjectMonthlyMonitoring entity) {
// 校验月份范围
if (entity.getMonitoringMonth() != null) {
if (entity.getMonitoringMonth() < 1 || entity.getMonitoringMonth() > 12) {
throw new RuntimeException("月份必须在1-12之间");
}
}
// 校验进度范围
if (entity.getPlannedProgress() != null) {
if (entity.getPlannedProgress().compareTo(BigDecimal.ZERO) < 0
|| entity.getPlannedProgress().compareTo(new BigDecimal("100")) > 0) {
throw new RuntimeException("计划进度必须在0-100之间");
}
}
if (entity.getActualProgress() != null) {
if (entity.getActualProgress().compareTo(BigDecimal.ZERO) < 0
|| entity.getActualProgress().compareTo(new BigDecimal("100")) > 0) {
throw new RuntimeException("实际进度必须在0-100之间");
}
}
}
/**
* 自动计算字段
*/
private void calculateFields(CwProjectMonthlyMonitoring entity) {
// 计算进度偏差 = 实际进度 - 计划进度
if (entity.getPlannedProgress() != null && entity.getActualProgress() != null) {
BigDecimal variance = entity.getActualProgress().subtract(entity.getPlannedProgress());
entity.setProgressVariance(variance);
}
// 计算资金执行率 = (累计实际支出 / 累计预算) × 100
if (entity.getCumulativeBudget() != null && entity.getCumulativeExpenditure() != null
&& entity.getCumulativeBudget().compareTo(BigDecimal.ZERO) > 0) {
BigDecimal rate = entity.getCumulativeExpenditure()
.divide(entity.getCumulativeBudget(), 4, BigDecimal.ROUND_HALF_UP)
.multiply(new BigDecimal("100"));
entity.setFundExecutionRate(rate);
}
}
/**
* 批量删除项目月度运行监控
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
// 可以在此添加删除前的校验逻辑
}
return baseMapper.deleteBatchIds(ids) > 0;
}
/**
* 根据自评ID删除所有月度监控数据
*
* @param evaluationId 自评ID
* @return 是否删除成功
*/
@Override
public Boolean deleteByEvaluationId(Long evaluationId) {
LambdaQueryWrapper<CwProjectMonthlyMonitoring> lqw = Wrappers.lambdaQuery();
lqw.eq(CwProjectMonthlyMonitoring::getEvaluationId, evaluationId);
return baseMapper.delete(lqw) >= 0;
}
}
@@ -0,0 +1,581 @@
package org.dromara.cw.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.cw.domain.CwProjectPerformanceSelfEvaluation;
import org.dromara.cw.domain.bo.CwProjectPerformanceSelfEvaluationBo;
import org.dromara.cw.domain.vo.CwProjectPerformanceSelfEvaluationVo;
import org.dromara.cw.mapper.CwProjectPerformanceSelfEvaluationMapper;
import org.dromara.cw.service.ICwProjectPerformanceSelfEvaluationService;
import org.dromara.cw.service.ICwPerformanceMonitoringService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* 项目绩效自评Service业务层处理
*
* @author ruoyi
* @date 2025-11-03
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class CwProjectPerformanceSelfEvaluationServiceImpl implements ICwProjectPerformanceSelfEvaluationService {
private final CwProjectPerformanceSelfEvaluationMapper baseMapper;
private final ICwPerformanceMonitoringService performanceMonitoringService;
/**
* 查询项目绩效自评
*/
@Override
public CwProjectPerformanceSelfEvaluationVo queryById(Long id) {
CwProjectPerformanceSelfEvaluationVo vo = baseMapper.selectVoById(id);
if (vo != null) {
// 🔒 数据权限验证:普通用户只能查看自己创建的数据
if (!hasDataPermission(vo)) {
log.warn("用户尝试访问无权限的绩效自评数据,ID: {}", id);
throw new RuntimeException("无权访问该绩效自评数据");
}
// 查询并设置运行监控数据
vo.setMonitoringList(performanceMonitoringService.queryByEvaluationId(id));
}
return vo;
}
/**
* 验证用户是否有查看指定绩效自评的权限
* 只有超级管理员可以看到所有数据,其他用户(包括财务管理员)只能查看自己创建的数据
*
* @param vo 绩效自评数据
* @return 是否有权限
*/
private boolean hasDataPermission(CwProjectPerformanceSelfEvaluationVo vo) {
try {
// 获取当前登录用户信息
var loginUser = LoginHelper.getLoginUser();
if (loginUser == null) {
log.warn("无法获取登录用户信息,拒绝数据访问");
return false;
}
Long currentUserId = loginUser.getUserId();
// 超级管理员拥有所有权限
if (LoginHelper.isSuperAdmin(currentUserId)) {
return true;
}
// 所有其他用户(包括财务管理员):只能查看自己创建的数据
return currentUserId.equals(vo.getCreateBy());
} catch (Exception e) {
log.error("数据权限验证异常: {}", e.getMessage(), e);
return false;
}
}
/**
* 查询项目绩效自评列表
*/
@Override
public TableDataInfo<CwProjectPerformanceSelfEvaluationVo> queryPageList(CwProjectPerformanceSelfEvaluationBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<CwProjectPerformanceSelfEvaluation> lqw = buildQueryWrapper(bo);
Page<CwProjectPerformanceSelfEvaluationVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询项目绩效自评列表
*/
@Override
public List<CwProjectPerformanceSelfEvaluationVo> queryList(CwProjectPerformanceSelfEvaluationBo bo) {
LambdaQueryWrapper<CwProjectPerformanceSelfEvaluation> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<CwProjectPerformanceSelfEvaluation> buildQueryWrapper(CwProjectPerformanceSelfEvaluationBo bo) {
LambdaQueryWrapper<CwProjectPerformanceSelfEvaluation> lqw = Wrappers.lambdaQuery();
// 🔧 修复:只有当projectApplicationId > 0时才作为查询条件
lqw.eq(bo.getProjectApplicationId() != null && bo.getProjectApplicationId() > 0,
CwProjectPerformanceSelfEvaluation::getProjectApplicationId, bo.getProjectApplicationId());
lqw.like(StringUtils.isNotBlank(bo.getApplicationNo()), CwProjectPerformanceSelfEvaluation::getApplicationNo, bo.getApplicationNo());
lqw.like(StringUtils.isNotBlank(bo.getProjectName()), CwProjectPerformanceSelfEvaluation::getProjectName, bo.getProjectName());
lqw.eq(bo.getEvaluationYear() != null, CwProjectPerformanceSelfEvaluation::getEvaluationYear, bo.getEvaluationYear());
lqw.eq(StringUtils.isNotBlank(bo.getEvaluationStatus()), CwProjectPerformanceSelfEvaluation::getEvaluationStatus, bo.getEvaluationStatus());
lqw.eq(StringUtils.isNotBlank(bo.getSelfEvaluationLevel()), CwProjectPerformanceSelfEvaluation::getSelfEvaluationLevel, bo.getSelfEvaluationLevel());
// 🔒 数据权限过滤:普通用户只能看到自己提交的数据
addDataPermissionFilter(lqw);
lqw.orderByDesc(CwProjectPerformanceSelfEvaluation::getCreateTime);
return lqw;
}
/**
* 添加数据权限过滤
* 只有超级管理员可以看到所有数据,其他用户(包括财务管理员)只能看到自己创建的数据
*/
private void addDataPermissionFilter(LambdaQueryWrapper<CwProjectPerformanceSelfEvaluation> lqw) {
try {
// 获取当前登录用户信息
var loginUser = LoginHelper.getLoginUser();
if (loginUser == null) {
// 如果无法获取用户信息,默认只能看到自己的数据(通过设置一个不存在的用户ID)
lqw.eq(CwProjectPerformanceSelfEvaluation::getCreateBy, -1L);
log.warn("无法获取登录用户信息,应用最严格的数据权限过滤");
return;
}
Long userId = loginUser.getUserId();
// 超级管理员不过滤数据
if (LoginHelper.isSuperAdmin(userId)) {
log.info("✅ [超级管理员权限] 用户ID: {}, 可以查看所有绩效自评数据", userId);
return;
}
// 所有其他用户(包括财务管理员):只能看到自己创建的数据
lqw.eq(CwProjectPerformanceSelfEvaluation::getCreateBy, userId);
log.info("🔒 [个人权限过滤] 用户ID: {}, 只能查看自己提交的绩效自评数据", userId);
} catch (Exception e) {
log.error("❌ 数据权限过滤异常: {}", e.getMessage(), e);
// 异常情况下,应用最严格的数据权限过滤
try {
Long userId = LoginHelper.getUserId();
if (userId != null) {
lqw.eq(CwProjectPerformanceSelfEvaluation::getCreateBy, userId);
} else {
// 完全无法获取用户ID时,返回空结果
lqw.eq(CwProjectPerformanceSelfEvaluation::getCreateBy, -1L);
}
} catch (Exception ex) {
log.error("❌ 获取当前用户ID失败: {}", ex.getMessage(), ex);
// 完全失败时返回空结果
lqw.eq(CwProjectPerformanceSelfEvaluation::getCreateBy, -1L);
}
}
}
/**
* 根据项目申报ID和年度查询自评
*/
@Override
public CwProjectPerformanceSelfEvaluationVo queryByProjectAndYear(Long projectApplicationId, Integer evaluationYear) {
return baseMapper.selectByProjectAndYear(projectApplicationId, evaluationYear);
}
/**
* 查询我的自评列表
*/
@Override
public List<CwProjectPerformanceSelfEvaluationVo> queryMyEvaluations(Long userId) {
return baseMapper.selectMyEvaluations(userId);
}
/**
* 查询待审核的自评列表
*/
@Override
public List<CwProjectPerformanceSelfEvaluationVo> queryPendingApprovals() {
return baseMapper.selectPendingApprovals();
}
/**
* 新增项目绩效自评
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean insertByBo(CwProjectPerformanceSelfEvaluationBo bo) {
// 🔍 调试:打印接收到的Bo对象
log.info("========== 新增绩效自评 - 接收到的Bo对象 ==========");
log.info("项目名称: {}", bo.getProjectName());
log.info("主管部门: {}", bo.getSupervisoryDept());
log.info("实施单位: {}", bo.getImplementUnit());
log.info("绩效目标: {}", bo.getPerformanceGoal());
log.info("目标完成情况: {}", bo.getTargetCompletion());
log.info("数量指标: {}", bo.getQuantityIndicator());
log.info("质量指标: {}", bo.getQualityIndicator());
log.info("时效指标: {}", bo.getTimelinessIndicator());
log.info("成本指标: {}", bo.getCostIndicator());
log.info("经济指标: {}", bo.getEconomicIndicator());
log.info("社会指标: {}", bo.getSocialIndicator());
log.info("生态指标: {}", bo.getEcologicalIndicator());
log.info("满意度指标: {}", bo.getSatisfactionIndicator());
log.info("总分: {}", bo.getTotalScore());
log.info("======================================================");
CwProjectPerformanceSelfEvaluation add = MapstructUtils.convert(bo, CwProjectPerformanceSelfEvaluation.class);
// 🔍 调试:打印转换后的Entity对象
log.info("========== 转换后的Entity对象 ==========");
log.info("主管部门: {}", add.getSupervisoryDept());
log.info("实施单位: {}", add.getImplementUnit());
log.info("数量指标: {}", add.getQuantityIndicator());
log.info("质量指标: {}", add.getQualityIndicator());
log.info("=========================================");
validEntityBeforeSave(add);
// 如果申报编号为空,设置默认值
if (StringUtils.isBlank(add.getApplicationNo())) {
// 如果有项目申报ID且不为0,使用项目申报ID
if (add.getProjectApplicationId() != null && add.getProjectApplicationId() > 0) {
add.setApplicationNo("APP-" + add.getProjectApplicationId());
} else {
// 否则使用时间戳生成唯一编号
add.setApplicationNo("TEMP-" + System.currentTimeMillis());
}
}
// 设置默认状态为草稿
if (StringUtils.isBlank(add.getEvaluationStatus())) {
add.setEvaluationStatus("draft");
}
// 计算预算执行率
if (add.getAnnualBudget() != null && add.getActualExpenditure() != null
&& add.getAnnualBudget().compareTo(BigDecimal.ZERO) > 0) {
BigDecimal rate = add.getActualExpenditure()
.divide(add.getAnnualBudget(), 4, BigDecimal.ROUND_HALF_UP)
.multiply(new BigDecimal("100"));
add.setBudgetExecutionRate(rate);
}
// 🔧 新增:保存时自动计算总分和等级
calculateTotalScoreAndLevel(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改项目绩效自评
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean updateByBo(CwProjectPerformanceSelfEvaluationBo bo) {
// 先查询原始记录,检查状态
CwProjectPerformanceSelfEvaluation existing = baseMapper.selectById(bo.getId());
if (existing == null) {
throw new RuntimeException("自评记录不存在");
}
// 🔒 检查是否已锁定:锁定状态的绩效自评不允许修改
if (existing.getIsLocked() != null && existing.getIsLocked() == 1) {
throw new RuntimeException("该绩效自评已锁定,不允许修改。如需修改,请联系财务管理员或学校领导解锁");
}
// 🔧 已移除编辑限制:允许所有状态的自评都可以编辑
// 原限制逻辑:检查是否允许修改:草稿状态 OR (已提交状态 AND 允许已提交后编辑)
// if (!"draft".equals(existing.getEvaluationStatus())) {
// // 如果不是草稿状态,检查是否允许已提交后编辑
// if (existing.getAllowEditAfterSubmit() == null || existing.getAllowEditAfterSubmit() == 0) {
// throw new RuntimeException("该自评已提交,不允许修改。如需修改,请先设置允许已提交后编辑");
// }
// }
CwProjectPerformanceSelfEvaluation update = MapstructUtils.convert(bo, CwProjectPerformanceSelfEvaluation.class);
validEntityBeforeSave(update);
// 计算预算执行率
if (update.getAnnualBudget() != null && update.getActualExpenditure() != null
&& update.getAnnualBudget().compareTo(BigDecimal.ZERO) > 0) {
BigDecimal rate = update.getActualExpenditure()
.divide(update.getAnnualBudget(), 4, BigDecimal.ROUND_HALF_UP)
.multiply(new BigDecimal("100"));
update.setBudgetExecutionRate(rate);
}
// 🔧 新增:更新时自动计算总分和等级
calculateTotalScoreAndLevel(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存草稿
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean saveDraft(CwProjectPerformanceSelfEvaluationBo bo) {
bo.setEvaluationStatus("draft");
if (bo.getId() == null) {
return insertByBo(bo);
} else {
return updateByBo(bo);
}
}
/**
* 提交自评
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean submitEvaluation(Long id) {
CwProjectPerformanceSelfEvaluation evaluation = baseMapper.selectById(id);
if (evaluation == null) {
throw new RuntimeException("自评记录不存在");
}
// 🔒 检查是否已锁定:锁定状态的绩效自评不允许提交
if (evaluation.getIsLocked() != null && evaluation.getIsLocked() == 1) {
throw new RuntimeException("该绩效自评已锁定,不允许提交。如需提交,请联系财务管理员或学校领导解锁");
}
if (!"draft".equals(evaluation.getEvaluationStatus())) {
throw new RuntimeException("只能提交草稿状态的自评");
}
// 验证必填字段
validateForSubmit(evaluation);
// 🔧 修复:使用统一的计算方法(支持新的9个得分字段)
calculateTotalScoreAndLevel(evaluation);
// 更新状态
evaluation.setEvaluationStatus("submitted");
evaluation.setSubmitTime(new Date());
evaluation.setSubmitBy(getUserIdSafely());
evaluation.setSubmitByName(LoginHelper.getUsername());
return baseMapper.updateById(evaluation) > 0;
}
/**
* 审核自评
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean approveEvaluation(Long id, String opinion, Boolean approved) {
CwProjectPerformanceSelfEvaluation evaluation = baseMapper.selectById(id);
if (evaluation == null) {
throw new RuntimeException("自评记录不存在");
}
// 🔒 检查是否已锁定:锁定状态的绩效自评不允许审核
if (evaluation.getIsLocked() != null && evaluation.getIsLocked() == 1) {
throw new RuntimeException("该绩效自评已锁定,不允许审核。如需审核,请联系财务管理员或学校领导解锁");
}
if (!"submitted".equals(evaluation.getEvaluationStatus())) {
throw new RuntimeException("只能审核已提交状态的自评");
}
// 更新审核信息
evaluation.setEvaluationStatus("approved");
evaluation.setApproveTime(new Date());
evaluation.setApproveBy(getUserIdSafely());
evaluation.setApproveByName(LoginHelper.getUsername());
evaluation.setApproveOpinion(opinion);
return baseMapper.updateById(evaluation) > 0;
}
/**
* 批量删除项目绩效自评
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
// 校验是否可以删除(例如:已审核的不能删除)
List<CwProjectPerformanceSelfEvaluation> list = baseMapper.selectBatchIds(ids);
for (CwProjectPerformanceSelfEvaluation evaluation : list) {
if ("approved".equals(evaluation.getEvaluationStatus())) {
throw new RuntimeException("已审核的自评不能删除");
}
}
}
return baseMapper.deleteBatchIds(ids) > 0;
}
/**
* 统计自评数量
*/
@Override
public Long countEvaluations(Integer evaluationYear, String evaluationStatus) {
return baseMapper.countEvaluations(evaluationYear, evaluationStatus);
}
/**
* 计算平均分
*/
@Override
public BigDecimal calculateAverageScore(Integer evaluationYear) {
return baseMapper.calculateAverageScore(evaluationYear);
}
/**
* 按部门统计自评情况
*/
@Override
public List<Map<String, Object>> statisticsByDept(Integer evaluationYear) {
return baseMapper.statisticsByDept(evaluationYear);
}
/**
* 按等级统计自评数量
*/
@Override
public List<Map<String, Object>> statisticsByLevel(Integer evaluationYear) {
return baseMapper.statisticsByLevel(evaluationYear);
}
/**
* 导出项目绩效自评
*/
@Override
public void export(CwProjectPerformanceSelfEvaluationBo bo) {
// TODO: 实现导出功能
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(CwProjectPerformanceSelfEvaluation entity) {
// 校验项目名称不能为空
if (StringUtils.isBlank(entity.getProjectName())) {
throw new RuntimeException("项目名称不能为空");
}
// 校验自评年度不能为空
if (entity.getEvaluationYear() == null) {
throw new RuntimeException("自评年度不能为空");
}
}
/**
* 提交前验证必填字段
*/
private void validateForSubmit(CwProjectPerformanceSelfEvaluation entity) {
if (StringUtils.isBlank(entity.getProjectName())) {
throw new RuntimeException("项目名称不能为空");
}
if (entity.getEvaluationYear() == null) {
throw new RuntimeException("自评年度不能为空");
}
if (entity.getTotalInvestment() == null) {
throw new RuntimeException("项目总投资不能为空");
}
// ... 可以添加更多必填字段验证
}
/**
* 根据总分计算等级
*/
private String calculateLevel(BigDecimal totalScore) {
if (totalScore.compareTo(new BigDecimal("90")) >= 0) {
return "优秀";
} else if (totalScore.compareTo(new BigDecimal("80")) >= 0) {
return "良好";
} else if (totalScore.compareTo(new BigDecimal("60")) >= 0) {
return "合格";
} else {
return "不合格";
}
}
/**
* 计算总分和等级(保存时自动计算)
*/
private void calculateTotalScoreAndLevel(CwProjectPerformanceSelfEvaluation entity) {
// 🔧 修复:使用新的9个得分字段计算总分(而非旧的4个字段)
BigDecimal totalScore = BigDecimal.ZERO;
// 资金到位得分
if (entity.getFundScore() != null) {
totalScore = totalScore.add(entity.getFundScore());
}
// 产出指标得分(4项)
if (entity.getQuantityScore() != null) {
totalScore = totalScore.add(entity.getQuantityScore());
}
if (entity.getQualityScore() != null) {
totalScore = totalScore.add(entity.getQualityScore());
}
if (entity.getTimelinessScore() != null) {
totalScore = totalScore.add(entity.getTimelinessScore());
}
if (entity.getCostScore() != null) {
totalScore = totalScore.add(entity.getCostScore());
}
// 效益指标得分(4项)
if (entity.getEconomicScore() != null) {
totalScore = totalScore.add(entity.getEconomicScore());
}
if (entity.getSocialScore() != null) {
totalScore = totalScore.add(entity.getSocialScore());
}
if (entity.getEcologicalScore() != null) {
totalScore = totalScore.add(entity.getEcologicalScore());
}
if (entity.getSatisfactionScore() != null) {
totalScore = totalScore.add(entity.getSatisfactionScore());
}
// 只有当总分大于0时才设置
if (totalScore.compareTo(BigDecimal.ZERO) > 0) {
entity.setTotalScore(totalScore);
// 根据总分自动判定等级
String level = calculateLevel(totalScore);
entity.setSelfEvaluationLevel(level);
}
}
/**
* 安全获取用户ID,处理可能的字符串格式(如 "sys_user:1")
*/
private Long getUserIdSafely() {
try {
Long userId = LoginHelper.getUserId();
if (userId != null) {
return userId;
}
} catch (Exception e) {
// 如果getUserId()失败,尝试从getUserIdStr()解析
}
// 尝试从字符串格式解析
try {
String userIdStr = LoginHelper.getUserIdStr();
if (StringUtils.isNotBlank(userIdStr)) {
// 处理 "sys_user:1" 这种格式,提取数字部分
if (userIdStr.contains(":")) {
String[] parts = userIdStr.split(":");
if (parts.length > 1) {
return Long.parseLong(parts[1]);
}
} else {
return Long.parseLong(userIdStr);
}
}
} catch (Exception e) {
// 解析失败,返回null或抛出异常
}
return null;
}
}
@@ -0,0 +1,87 @@
-- =============================================
-- 检查绩效自评数据完整性
-- 功能:查看指定记录的所有字段值
-- 创建时间:2025-11-04
-- =============================================
USE `hzdyjs_xg`;
-- 查询最新的一条记录,显示所有字段
SELECT
-- 基本信息
id,
project_name,
supervisory_dept,
implement_unit,
evaluation_year,
-- 资金信息
initial_budget,
annual_budget,
actual_expenditure,
fund_score,
-- 绩效目标
performance_goal,
target_completion,
-- 数量指标
quantity_indicator,
quantity_target,
quantity_actual,
quantity_value,
quantity_score,
quantity_deviation,
-- 质量指标
quality_indicator,
quality_target,
quality_actual,
quality_value,
quality_score,
quality_deviation,
-- 时效指标
timeliness_indicator,
timeliness_target,
timeliness_actual,
timeliness_value,
timeliness_score,
timeliness_deviation,
-- 成本指标
cost_indicator,
cost_target,
cost_actual,
cost_value,
cost_score,
cost_deviation,
-- 效益指标
economic_indicator,
social_indicator,
ecological_indicator,
satisfaction_indicator,
-- 总分和等级
total_score,
self_evaluation_level,
-- 状态
evaluation_status,
create_time
FROM `cw_project_performance_self_evaluation`
WHERE deleted = 0
ORDER BY create_time DESC
LIMIT 1;
-- 统计各字段的NULL值数量
SELECT
'项目名称' as field_name, COUNT(*) - COUNT(project_name) as null_count FROM cw_project_performance_self_evaluation WHERE deleted = 0
UNION ALL SELECT '主管部门', COUNT(*) - COUNT(supervisory_dept) FROM cw_project_performance_self_evaluation WHERE deleted = 0
UNION ALL SELECT '实施单位', COUNT(*) - COUNT(implement_unit) FROM cw_project_performance_self_evaluation WHERE deleted = 0
UNION ALL SELECT '绩效目标', COUNT(*) - COUNT(performance_goal) FROM cw_project_performance_self_evaluation WHERE deleted = 0
UNION ALL SELECT '目标完成情况', COUNT(*) - COUNT(target_completion) FROM cw_project_performance_self_evaluation WHERE deleted = 0
UNION ALL SELECT '数量指标名称', COUNT(*) - COUNT(quantity_indicator) FROM cw_project_performance_self_evaluation WHERE deleted = 0
UNION ALL SELECT '质量指标名称', COUNT(*) - COUNT(quality_indicator) FROM cw_project_performance_self_evaluation WHERE deleted = 0;
@@ -0,0 +1,27 @@
-- 项目绩效自评状态字典
-- 删除旧数据(如果存在)
DELETE FROM sys_dict_data WHERE dict_type = 'cw_evaluation_status';
DELETE FROM sys_dict_type WHERE dict_type = 'cw_evaluation_status';
-- 插入字典类型
INSERT INTO sys_dict_type (dict_id, tenant_id, dict_name, dict_type, create_dept, create_by, create_time, update_by, update_time, remark)
VALUES (
NEXT VALUE FOR sys_dict_type_seq, -- dict_id 使用序列生成
'000000', -- tenant_id
'绩效自评状态', -- dict_name
'cw_evaluation_status', -- dict_type
103, -- create_dept
1, -- create_by
NOW(), -- create_time
1, -- update_by
NOW(), -- update_time
'项目绩效自评的状态' -- remark
);
-- 插入字典数据项
INSERT INTO sys_dict_data (dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark)
VALUES
(NEXT VALUE FOR sys_dict_data_seq, '000000', 1, '草稿', 'draft', 'cw_evaluation_status', '', 'info', 'N', 103, 1, NOW(), 1, NOW(), '草稿状态'),
(NEXT VALUE FOR sys_dict_data_seq, '000000', 2, '已提交', 'submitted', 'cw_evaluation_status', '', 'primary', 'N', 103, 1, NOW(), 1, NOW(), '已提交待审核'),
(NEXT VALUE FOR sys_dict_data_seq, '000000', 3, '已审核', 'approved', 'cw_evaluation_status', '', 'success', 'N', 103, 1, NOW(), 1, NOW(), '已审核通过');
@@ -0,0 +1,22 @@
-- ========================================
-- 修复 application_no 字段问题
-- 日期: 2025-01-03
-- 描述: 允许 application_no 字段为空并设置默认值
-- ========================================
-- 修改 application_no 字段:允许为空,设置默认空字符串
ALTER TABLE cw_project_performance_self_evaluation
MODIFY COLUMN application_no varchar(50) NULL DEFAULT '' COMMENT '项目申报编号';
-- 更新现有的空值或无效值记录
UPDATE cw_project_performance_self_evaluation
SET application_no = CONCAT('TEMP-', id)
WHERE application_no IS NULL
OR application_no = ''
OR application_no = 'APP-0';
-- 验证修改结果
SELECT COUNT(*) as total_count,
SUM(CASE WHEN application_no IS NULL OR application_no = '' THEN 1 ELSE 0 END) as empty_count
FROM cw_project_performance_self_evaluation;
@@ -0,0 +1,66 @@
-- =============================================
-- 修复绩效自评总分计算脚本
-- 功能:重新计算所有记录的total_score(使用新的9个得分字段)
-- 创建时间:2025-11-04
-- =============================================
USE `hzdyjs_xg`;
-- 更新所有记录的总分(使用新的9个得分字段)
UPDATE `cw_project_performance_self_evaluation`
SET
total_score = COALESCE(fund_score, 0)
+ COALESCE(quantity_score, 0)
+ COALESCE(quality_score, 0)
+ COALESCE(timeliness_score, 0)
+ COALESCE(cost_score, 0)
+ COALESCE(economic_score, 0)
+ COALESCE(social_score, 0)
+ COALESCE(ecological_score, 0)
+ COALESCE(satisfaction_score, 0),
-- 根据总分自动判定等级
self_evaluation_level = CASE
WHEN (COALESCE(fund_score, 0) + COALESCE(quantity_score, 0) + COALESCE(quality_score, 0)
+ COALESCE(timeliness_score, 0) + COALESCE(cost_score, 0) + COALESCE(economic_score, 0)
+ COALESCE(social_score, 0) + COALESCE(ecological_score, 0) + COALESCE(satisfaction_score, 0)) >= 90 THEN '优秀'
WHEN (COALESCE(fund_score, 0) + COALESCE(quantity_score, 0) + COALESCE(quality_score, 0)
+ COALESCE(timeliness_score, 0) + COALESCE(cost_score, 0) + COALESCE(economic_score, 0)
+ COALESCE(social_score, 0) + COALESCE(ecological_score, 0) + COALESCE(satisfaction_score, 0)) >= 80 THEN '良好'
WHEN (COALESCE(fund_score, 0) + COALESCE(quantity_score, 0) + COALESCE(quality_score, 0)
+ COALESCE(timeliness_score, 0) + COALESCE(cost_score, 0) + COALESCE(economic_score, 0)
+ COALESCE(social_score, 0) + COALESCE(ecological_score, 0) + COALESCE(satisfaction_score, 0)) >= 60 THEN '合格'
ELSE '不合格'
END
WHERE deleted = 0;
-- 查看更新结果
SELECT
id,
project_name,
fund_score,
quantity_score,
quality_score,
timeliness_score,
cost_score,
economic_score,
social_score,
ecological_score,
satisfaction_score,
total_score,
self_evaluation_level,
evaluation_status
FROM `cw_project_performance_self_evaluation`
WHERE deleted = 0
ORDER BY create_time DESC
LIMIT 10;
-- =============================================
-- 说明
-- =============================================
-- 1. 本脚本重新计算所有记录的总分(基于新的9个得分字段)
-- 2. 同时更新自评等级(优秀≥90分,良好≥80分,合格≥60分)
-- 3. 只更新未删除的记录(deleted = 0)
-- 4. 执行后可以查看最近10条记录验证结果
-- =============================================
@@ -0,0 +1,237 @@
-- =============================================
-- 绩效自评表结构升级脚本 (方案一:完整版)
-- 功能:补全52个缺失字段,支持完整的杭州市绩效自评标准
-- 创建时间:2025-11-03
-- 执行前请备份数据库!
-- =============================================
USE `hzdyjs_xg`;
-- =============================================
-- 第一部分:基础信息字段(2个)
-- =============================================
ALTER TABLE `cw_project_performance_self_evaluation`
ADD COLUMN `supervisory_dept` varchar(100) DEFAULT NULL COMMENT '主管部门' AFTER `project_name`,
ADD COLUMN `implement_unit` varchar(100) DEFAULT NULL COMMENT '实施单位' AFTER `supervisory_dept`;
-- =============================================
-- 第二部分:项目资金详细字段(18个)
-- =============================================
-- 2.1 年度资金总额(4个字段)
ALTER TABLE `cw_project_performance_self_evaluation`
ADD COLUMN `initial_budget` decimal(15,2) DEFAULT NULL COMMENT '年初预算数(万元)' AFTER `evaluation_year`,
ADD COLUMN `fund_value` decimal(5,2) DEFAULT NULL COMMENT '资金到位分值' AFTER `actual_expenditure`,
ADD COLUMN `fund_execution_rate` decimal(5,2) DEFAULT NULL COMMENT '资金执行率(%)' AFTER `fund_value`,
ADD COLUMN `fund_score` decimal(5,2) DEFAULT NULL COMMENT '资金到位得分' AFTER `fund_execution_rate`;
-- 2.2 当年财政拨款(6个字段)
ALTER TABLE `cw_project_performance_self_evaluation`
ADD COLUMN `current_year_budget_initial` decimal(15,2) DEFAULT NULL COMMENT '当年财政拨款-年初预算数(万元)' AFTER `fund_score`,
ADD COLUMN `current_year_budget_annual` decimal(15,2) DEFAULT NULL COMMENT '当年财政拨款-全年预算数(万元)' AFTER `current_year_budget_initial`,
ADD COLUMN `current_year_budget_actual` decimal(15,2) DEFAULT NULL COMMENT '当年财政拨款-全年执行数(万元)' AFTER `current_year_budget_annual`,
ADD COLUMN `current_year_budget_value` decimal(5,2) DEFAULT NULL COMMENT '当年财政拨款-分值' AFTER `current_year_budget_actual`,
ADD COLUMN `current_year_budget_execution_rate` decimal(5,2) DEFAULT NULL COMMENT '当年财政拨款-执行率(%)' AFTER `current_year_budget_value`,
ADD COLUMN `current_year_budget_score` decimal(5,2) DEFAULT NULL COMMENT '当年财政拨款-得分' AFTER `current_year_budget_execution_rate`;
-- 2.3 上年结转资金(6个字段)
ALTER TABLE `cw_project_performance_self_evaluation`
ADD COLUMN `last_year_carryover_initial` decimal(15,2) DEFAULT NULL COMMENT '上年结转资金-年初预算数(万元)' AFTER `current_year_budget_score`,
ADD COLUMN `last_year_carryover_annual` decimal(15,2) DEFAULT NULL COMMENT '上年结转资金-全年预算数(万元)' AFTER `last_year_carryover_initial`,
ADD COLUMN `last_year_carryover_actual` decimal(15,2) DEFAULT NULL COMMENT '上年结转资金-全年执行数(万元)' AFTER `last_year_carryover_annual`,
ADD COLUMN `last_year_carryover_value` decimal(5,2) DEFAULT NULL COMMENT '上年结转资金-分值' AFTER `last_year_carryover_actual`,
ADD COLUMN `last_year_carryover_execution_rate` decimal(5,2) DEFAULT NULL COMMENT '上年结转资金-执行率(%)' AFTER `last_year_carryover_value`,
ADD COLUMN `last_year_carryover_score` decimal(5,2) DEFAULT NULL COMMENT '上年结转资金-得分' AFTER `last_year_carryover_execution_rate`;
-- 2.4 其他资金(6个字段)
ALTER TABLE `cw_project_performance_self_evaluation`
ADD COLUMN `other_funds_initial` decimal(15,2) DEFAULT NULL COMMENT '其他资金-年初预算数(万元)' AFTER `last_year_carryover_score`,
ADD COLUMN `other_funds_annual` decimal(15,2) DEFAULT NULL COMMENT '其他资金-全年预算数(万元)' AFTER `other_funds_initial`,
ADD COLUMN `other_funds_actual` decimal(15,2) DEFAULT NULL COMMENT '其他资金-全年执行数(万元)' AFTER `other_funds_annual`,
ADD COLUMN `other_funds_value` decimal(5,2) DEFAULT NULL COMMENT '其他资金-分值' AFTER `other_funds_actual`,
ADD COLUMN `other_funds_execution_rate` decimal(5,2) DEFAULT NULL COMMENT '其他资金-执行率(%)' AFTER `other_funds_value`,
ADD COLUMN `other_funds_score` decimal(5,2) DEFAULT NULL COMMENT '其他资金-得分' AFTER `other_funds_execution_rate`;
-- =============================================
-- 第三部分:产出指标字段(24个)
-- =============================================
-- 3.1 数量指标(6个字段)
ALTER TABLE `cw_project_performance_self_evaluation`
ADD COLUMN `quantity_indicator` varchar(200) DEFAULT NULL COMMENT '数量指标名称' AFTER `target_completion`,
ADD COLUMN `quantity_target` varchar(100) DEFAULT NULL COMMENT '数量指标-指标值' AFTER `quantity_indicator`,
ADD COLUMN `quantity_actual` varchar(100) DEFAULT NULL COMMENT '数量指标-实际完成值' AFTER `quantity_target`,
ADD COLUMN `quantity_value` decimal(5,2) DEFAULT NULL COMMENT '数量指标-分值' AFTER `quantity_actual`,
ADD COLUMN `quantity_score` decimal(5,2) DEFAULT NULL COMMENT '数量指标-得分' AFTER `quantity_value`,
ADD COLUMN `quantity_deviation` text DEFAULT NULL COMMENT '数量指标-偏差原因分析及改进措施' AFTER `quantity_score`;
-- 3.2 质量指标(6个字段)
ALTER TABLE `cw_project_performance_self_evaluation`
ADD COLUMN `quality_indicator` varchar(200) DEFAULT NULL COMMENT '质量指标名称' AFTER `quantity_deviation`,
ADD COLUMN `quality_target` varchar(100) DEFAULT NULL COMMENT '质量指标-指标值' AFTER `quality_indicator`,
ADD COLUMN `quality_actual` varchar(100) DEFAULT NULL COMMENT '质量指标-实际完成值' AFTER `quality_target`,
ADD COLUMN `quality_value` decimal(5,2) DEFAULT NULL COMMENT '质量指标-分值' AFTER `quality_actual`,
ADD COLUMN `quality_score` decimal(5,2) DEFAULT NULL COMMENT '质量指标-得分' AFTER `quality_value`,
ADD COLUMN `quality_deviation` text DEFAULT NULL COMMENT '质量指标-偏差原因分析及改进措施' AFTER `quality_score`;
-- 3.3 时效指标(6个字段)
ALTER TABLE `cw_project_performance_self_evaluation`
ADD COLUMN `timeliness_indicator` varchar(200) DEFAULT NULL COMMENT '时效指标名称' AFTER `quality_deviation`,
ADD COLUMN `timeliness_target` varchar(100) DEFAULT NULL COMMENT '时效指标-指标值' AFTER `timeliness_indicator`,
ADD COLUMN `timeliness_actual` varchar(100) DEFAULT NULL COMMENT '时效指标-实际完成值' AFTER `timeliness_target`,
ADD COLUMN `timeliness_value` decimal(5,2) DEFAULT NULL COMMENT '时效指标-分值' AFTER `timeliness_actual`,
ADD COLUMN `timeliness_score` decimal(5,2) DEFAULT NULL COMMENT '时效指标-得分' AFTER `timeliness_value`,
ADD COLUMN `timeliness_deviation` text DEFAULT NULL COMMENT '时效指标-偏差原因分析及改进措施' AFTER `timeliness_score`;
-- 3.4 成本指标(6个字段)
ALTER TABLE `cw_project_performance_self_evaluation`
ADD COLUMN `cost_indicator` varchar(200) DEFAULT NULL COMMENT '成本指标名称' AFTER `timeliness_deviation`,
ADD COLUMN `cost_target` varchar(100) DEFAULT NULL COMMENT '成本指标-指标值' AFTER `cost_indicator`,
ADD COLUMN `cost_actual` varchar(100) DEFAULT NULL COMMENT '成本指标-实际完成值' AFTER `cost_target`,
ADD COLUMN `cost_value` decimal(5,2) DEFAULT NULL COMMENT '成本指标-分值' AFTER `cost_actual`,
ADD COLUMN `cost_score` decimal(5,2) DEFAULT NULL COMMENT '成本指标-得分' AFTER `cost_value`,
ADD COLUMN `cost_deviation` text DEFAULT NULL COMMENT '成本指标-偏差原因分析及改进措施' AFTER `cost_score`;
-- =============================================
-- 第四部分:效益指标字段(24个)
-- =============================================
-- 4.1 经济效益指标(6个字段)
ALTER TABLE `cw_project_performance_self_evaluation`
ADD COLUMN `economic_indicator` varchar(200) DEFAULT NULL COMMENT '经济效益指标名称' AFTER `cost_deviation`,
ADD COLUMN `economic_target` varchar(100) DEFAULT NULL COMMENT '经济效益指标-指标值' AFTER `economic_indicator`,
ADD COLUMN `economic_actual` varchar(100) DEFAULT NULL COMMENT '经济效益指标-实际完成值' AFTER `economic_target`,
ADD COLUMN `economic_value` decimal(5,2) DEFAULT NULL COMMENT '经济效益指标-分值' AFTER `economic_actual`,
ADD COLUMN `economic_score` decimal(5,2) DEFAULT NULL COMMENT '经济效益指标-得分' AFTER `economic_value`,
ADD COLUMN `economic_deviation` text DEFAULT NULL COMMENT '经济效益指标-偏差原因分析及改进措施' AFTER `economic_score`;
-- 4.2 社会效益指标(6个字段)
ALTER TABLE `cw_project_performance_self_evaluation`
ADD COLUMN `social_indicator` varchar(200) DEFAULT NULL COMMENT '社会效益指标名称' AFTER `economic_deviation`,
ADD COLUMN `social_target` varchar(100) DEFAULT NULL COMMENT '社会效益指标-指标值' AFTER `social_indicator`,
ADD COLUMN `social_actual` varchar(100) DEFAULT NULL COMMENT '社会效益指标-实际完成值' AFTER `social_target`,
ADD COLUMN `social_value` decimal(5,2) DEFAULT NULL COMMENT '社会效益指标-分值' AFTER `social_actual`,
ADD COLUMN `social_score` decimal(5,2) DEFAULT NULL COMMENT '社会效益指标-得分' AFTER `social_value`,
ADD COLUMN `social_deviation` text DEFAULT NULL COMMENT '社会效益指标-偏差原因分析及改进措施' AFTER `social_score`;
-- 4.3 生态效益指标(6个字段)
ALTER TABLE `cw_project_performance_self_evaluation`
ADD COLUMN `ecological_indicator` varchar(200) DEFAULT NULL COMMENT '生态效益指标名称' AFTER `social_deviation`,
ADD COLUMN `ecological_target` varchar(100) DEFAULT NULL COMMENT '生态效益指标-指标值' AFTER `ecological_indicator`,
ADD COLUMN `ecological_actual` varchar(100) DEFAULT NULL COMMENT '生态效益指标-实际完成值' AFTER `ecological_target`,
ADD COLUMN `ecological_value` decimal(5,2) DEFAULT NULL COMMENT '生态效益指标-分值' AFTER `ecological_actual`,
ADD COLUMN `ecological_score` decimal(5,2) DEFAULT NULL COMMENT '生态效益指标-得分' AFTER `ecological_value`,
ADD COLUMN `ecological_deviation` text DEFAULT NULL COMMENT '生态效益指标-偏差原因分析及改进措施' AFTER `ecological_score`;
-- 4.4 满意度指标(6个字段)
ALTER TABLE `cw_project_performance_self_evaluation`
ADD COLUMN `satisfaction_indicator` varchar(200) DEFAULT NULL COMMENT '满意度指标名称' AFTER `ecological_deviation`,
ADD COLUMN `satisfaction_target` varchar(100) DEFAULT NULL COMMENT '满意度指标-指标值' AFTER `satisfaction_indicator`,
ADD COLUMN `satisfaction_actual` varchar(100) DEFAULT NULL COMMENT '满意度指标-实际完成值' AFTER `satisfaction_target`,
ADD COLUMN `satisfaction_value` decimal(5,2) DEFAULT NULL COMMENT '满意度指标-分值' AFTER `satisfaction_actual`,
ADD COLUMN `satisfaction_score` decimal(5,2) DEFAULT NULL COMMENT '满意度指标-得分' AFTER `satisfaction_value`,
ADD COLUMN `satisfaction_deviation` text DEFAULT NULL COMMENT '满意度指标-偏差原因分析及改进措施' AFTER `satisfaction_score`;
-- =============================================
-- 升级完成验证
-- =============================================
-- 查看表结构
DESC `cw_project_performance_self_evaluation`;
-- 统计字段数量(应该是89个字段:原37个 + 新增52个)
SELECT COUNT(*) AS total_columns
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = 'hzdyjs_xg'
AND TABLE_NAME = 'cw_project_performance_self_evaluation';
-- =============================================
-- 回滚脚本(如果升级失败需要回滚)
-- =============================================
/*
-- 删除所有新增字段
ALTER TABLE `cw_project_performance_self_evaluation`
DROP COLUMN `supervisory_dept`,
DROP COLUMN `implement_unit`,
DROP COLUMN `initial_budget`,
DROP COLUMN `fund_value`,
DROP COLUMN `fund_execution_rate`,
DROP COLUMN `fund_score`,
DROP COLUMN `current_year_budget_initial`,
DROP COLUMN `current_year_budget_annual`,
DROP COLUMN `current_year_budget_actual`,
DROP COLUMN `current_year_budget_value`,
DROP COLUMN `current_year_budget_execution_rate`,
DROP COLUMN `current_year_budget_score`,
DROP COLUMN `last_year_carryover_initial`,
DROP COLUMN `last_year_carryover_annual`,
DROP COLUMN `last_year_carryover_actual`,
DROP COLUMN `last_year_carryover_value`,
DROP COLUMN `last_year_carryover_execution_rate`,
DROP COLUMN `last_year_carryover_score`,
DROP COLUMN `other_funds_initial`,
DROP COLUMN `other_funds_annual`,
DROP COLUMN `other_funds_actual`,
DROP COLUMN `other_funds_value`,
DROP COLUMN `other_funds_execution_rate`,
DROP COLUMN `other_funds_score`,
DROP COLUMN `quantity_indicator`,
DROP COLUMN `quantity_target`,
DROP COLUMN `quantity_actual`,
DROP COLUMN `quantity_value`,
DROP COLUMN `quantity_score`,
DROP COLUMN `quantity_deviation`,
DROP COLUMN `quality_indicator`,
DROP COLUMN `quality_target`,
DROP COLUMN `quality_actual`,
DROP COLUMN `quality_value`,
DROP COLUMN `quality_score`,
DROP COLUMN `quality_deviation`,
DROP COLUMN `timeliness_indicator`,
DROP COLUMN `timeliness_target`,
DROP COLUMN `timeliness_actual`,
DROP COLUMN `timeliness_value`,
DROP COLUMN `timeliness_score`,
DROP COLUMN `timeliness_deviation`,
DROP COLUMN `cost_indicator`,
DROP COLUMN `cost_target`,
DROP COLUMN `cost_actual`,
DROP COLUMN `cost_value`,
DROP COLUMN `cost_score`,
DROP COLUMN `cost_deviation`,
DROP COLUMN `economic_indicator`,
DROP COLUMN `economic_target`,
DROP COLUMN `economic_actual`,
DROP COLUMN `economic_value`,
DROP COLUMN `economic_score`,
DROP COLUMN `economic_deviation`,
DROP COLUMN `social_indicator`,
DROP COLUMN `social_target`,
DROP COLUMN `social_actual`,
DROP COLUMN `social_value`,
DROP COLUMN `social_score`,
DROP COLUMN `social_deviation`,
DROP COLUMN `ecological_indicator`,
DROP COLUMN `ecological_target`,
DROP COLUMN `ecological_actual`,
DROP COLUMN `ecological_value`,
DROP COLUMN `ecological_score`,
DROP COLUMN `ecological_deviation`,
DROP COLUMN `satisfaction_indicator`,
DROP COLUMN `satisfaction_target`,
DROP COLUMN `satisfaction_actual`,
DROP COLUMN `satisfaction_value`,
DROP COLUMN `satisfaction_score`,
DROP COLUMN `satisfaction_deviation`;
*/
-- =============================================
-- 升级说明
-- =============================================
-- 1. 执行前请备份数据库
-- 2. 本脚本增加了52个新字段,完整支持杭州市绩效自评表标准格式
-- 3. 所有新字段均允许为NULL,不影响现有数据
-- 4. 升级后前端表单所有字段都能正常保存和显示
-- 5. 如需回滚,请执行上面注释中的回滚脚本
-- =============================================
@@ -0,0 +1,29 @@
-- =============================================
-- 修复唯一索引冲突问题
-- 问题:原唯一索引导致同一项目同一年度无法创建多条自评记录
-- 解决:删除旧索引,添加新的合理索引
-- 创建时间:2025-11-03
-- =============================================
USE `hzdyjs_xg`;
-- 1. 删除原有的唯一索引
ALTER TABLE `cw_project_performance_self_evaluation`
DROP INDEX `uk_application_evaluation`;
-- 2. 添加普通索引(允许重复,但便于查询)
ALTER TABLE `cw_project_performance_self_evaluation`
ADD INDEX `idx_application_year` (`project_application_id`, `evaluation_year`, `tenant_id`)
COMMENT '项目-年度-租户联合索引';
-- 3. 验证索引
SHOW INDEX FROM `cw_project_performance_self_evaluation`;
-- =============================================
-- 说明:
-- 1. 删除了唯一约束,允许同一项目同一年度创建多条自评记录
-- 2. 保留普通索引以提升查询性能
-- 3. 用户可以创建多个草稿,最终只提交一个
-- 4. 如需控制重复提交,应在业务层面控制(如:状态为已提交时禁止再次提交)
-- =============================================
@@ -0,0 +1,257 @@
-- =============================================
-- 修复菜单乱码数据脚本
-- 创建时间: 2025-01-03
-- 说明: 修复因INSERT语句字段顺序错误导致的菜单数据乱码问题
-- =============================================
-- 修复绩效自评管理菜单(menu_id = 4050)
UPDATE `sys_menu` SET
`menu_name` = CONVERT(UNHEX('e7bba9e69588e887aae8af84e7aea1e79086') USING utf8mb4),
`perms` = 'cw:evaluation:list',
`icon` = 'chart',
`create_dept` = NULL,
`create_by` = NULL,
`create_time` = NOW(),
`update_by` = NULL,
`update_time` = NULL,
`remark` = CONVERT(UNHEX('e9a1b9e79baee7bba9e69588e887aae8af84e7aea1e79086e88f9ce58d95') USING utf8mb4)
WHERE `menu_id` = 4050;
-- 修复绩效自评管理按钮权限
UPDATE `sys_menu` SET
`menu_name` = CONVERT(UNHEX('e7bba9e69588e887aae8af84e69fa5e8afa2') USING utf8mb4),
`perms` = 'cw:evaluation:query',
`icon` = '#',
`create_dept` = NULL,
`create_by` = NULL,
`create_time` = NOW(),
`update_by` = NULL,
`update_time` = NULL,
`remark` = ''
WHERE `menu_id` = 405001;
UPDATE `sys_menu` SET
`menu_name` = CONVERT(UNHEX('e7bba9e69588e887aae8af84e696b0e5a29e') USING utf8mb4),
`perms` = 'cw:evaluation:add',
`icon` = '#',
`create_dept` = NULL,
`create_by` = NULL,
`create_time` = NOW(),
`update_by` = NULL,
`update_time` = NULL,
`remark` = ''
WHERE `menu_id` = 405002;
UPDATE `sys_menu` SET
`menu_name` = CONVERT(UNHEX('e7bba9e69588e887aae8af84e4bfaee694b9') USING utf8mb4),
`perms` = 'cw:evaluation:edit',
`icon` = '#',
`create_dept` = NULL,
`create_by` = NULL,
`create_time` = NOW(),
`update_by` = NULL,
`update_time` = NULL,
`remark` = ''
WHERE `menu_id` = 405003;
UPDATE `sys_menu` SET
`menu_name` = CONVERT(UNHEX('e7bba9e69588e887aae8af84e588a0e999a4') USING utf8mb4),
`perms` = 'cw:evaluation:remove',
`icon` = '#',
`create_dept` = NULL,
`create_by` = NULL,
`create_time` = NOW(),
`update_by` = NULL,
`update_time` = NULL,
`remark` = ''
WHERE `menu_id` = 405004;
UPDATE `sys_menu` SET
`menu_name` = CONVERT(UNHEX('e7bba9e69588e887aae8af84e68f90e4baa4') USING utf8mb4),
`perms` = 'cw:evaluation:submit',
`icon` = '#',
`create_dept` = NULL,
`create_by` = NULL,
`create_time` = NOW(),
`update_by` = NULL,
`update_time` = NULL,
`remark` = ''
WHERE `menu_id` = 405005;
UPDATE `sys_menu` SET
`menu_name` = CONVERT(UNHEX('e7bba9e69588e887aae8af84e5aea1e6a0b8') USING utf8mb4),
`perms` = 'cw:evaluation:approve',
`icon` = '#',
`create_dept` = NULL,
`create_by` = NULL,
`create_time` = NOW(),
`update_by` = NULL,
`update_time` = NULL,
`remark` = ''
WHERE `menu_id` = 405006;
UPDATE `sys_menu` SET
`menu_name` = CONVERT(UNHEX('e7bba9e69588e887aae8af84e5afbce587ba') USING utf8mb4),
`perms` = 'cw:evaluation:export',
`icon` = '#',
`create_dept` = NULL,
`create_by` = NULL,
`create_time` = NOW(),
`update_by` = NULL,
`update_time` = NULL,
`remark` = ''
WHERE `menu_id` = 405007;
-- 修复运行监控管理菜单(menu_id = 4052)
UPDATE `sys_menu` SET
`menu_name` = CONVERT(UNHEX('e8bf90e8a18ce79b91e68ea7e7aea1e79086') USING utf8mb4),
`perms` = 'cw:monitoringManagement:list',
`icon` = 'monitor',
`create_dept` = NULL,
`create_by` = NULL,
`create_time` = NOW(),
`update_by` = NULL,
`update_time` = NULL,
`remark` = CONVERT(UNHEX('e9a1b9e79baee8bf90e8a18ce79b91e68ea7e7aea1e79086e88f9ce58d95') USING utf8mb4)
WHERE `menu_id` = 4052;
-- 修复运行监控管理按钮权限
UPDATE `sys_menu` SET
`menu_name` = CONVERT(UNHEX('e8bf90e8a18ce79b91e68ea7e69fa5e8afa2') USING utf8mb4),
`perms` = 'cw:monitoring:query',
`icon` = '#',
`create_dept` = NULL,
`create_by` = NULL,
`create_time` = NOW(),
`update_by` = NULL,
`update_time` = NULL,
`remark` = ''
WHERE `menu_id` = 405101;
UPDATE `sys_menu` SET
`menu_name` = CONVERT(UNHEX('e8bf90e8a18ce79b91e68ea7e5a1abe68aa5') USING utf8mb4),
`perms` = 'cw:monitoring:fill',
`icon` = '#',
`create_dept` = NULL,
`create_by` = NULL,
`create_time` = NOW(),
`update_by` = NULL,
`update_time` = NULL,
`remark` = ''
WHERE `menu_id` = 405102;
UPDATE `sys_menu` SET
`menu_name` = CONVERT(UNHEX('e8bf90e8a18ce79b91e68ea7e4bfaee694b9') USING utf8mb4),
`perms` = 'cw:monitoring:edit',
`icon` = '#',
`create_dept` = NULL,
`create_by` = NULL,
`create_time` = NOW(),
`update_by` = NULL,
`update_time` = NULL,
`remark` = ''
WHERE `menu_id` = 405103;
-- 修复绩效运行监控按钮权限
UPDATE `sys_menu` SET
`menu_name` = CONVERT(UNHEX('e8bf90e8a18ce79b91e68ea7e69fa5e79c8b') USING utf8mb4),
`perms` = 'cw:performanceMonitoring:query',
`icon` = '#',
`create_dept` = NULL,
`create_by` = NULL,
`create_time` = NOW(),
`update_by` = NULL,
`update_time` = NULL,
`remark` = ''
WHERE `menu_id` = 405008;
UPDATE `sys_menu` SET
`menu_name` = CONVERT(UNHEX('e8bf90e8a18ce79b91e68ea7e696b0e5a29e') USING utf8mb4),
`perms` = 'cw:performanceMonitoring:add',
`icon` = '#',
`create_dept` = NULL,
`create_by` = NULL,
`create_time` = NOW(),
`update_by` = NULL,
`update_time` = NULL,
`remark` = ''
WHERE `menu_id` = 405009;
UPDATE `sys_menu` SET
`menu_name` = CONVERT(UNHEX('e8bf90e8a18ce79b91e68ea7e7bc96e8be91') USING utf8mb4),
`perms` = 'cw:performanceMonitoring:edit',
`icon` = '#',
`create_dept` = NULL,
`create_by` = NULL,
`create_time` = NOW(),
`update_by` = NULL,
`update_time` = NULL,
`remark` = ''
WHERE `menu_id` = 405010;
UPDATE `sys_menu` SET
`menu_name` = CONVERT(UNHEX('e8bf90e8a18ce79b91e68ea7e588a0e999a4') USING utf8mb4),
`perms` = 'cw:performanceMonitoring:remove',
`icon` = '#',
`create_dept` = NULL,
`create_by` = NULL,
`create_time` = NOW(),
`update_by` = NULL,
`update_time` = NULL,
`remark` = ''
WHERE `menu_id` = 405011;
-- 修复运行监控管理按钮权限(menu_id = 405201, 405202, 405203)
UPDATE `sys_menu` SET
`menu_name` = CONVERT(UNHEX('e8bf90e8a18ce79b91e68ea7e69fa5e8afa2') USING utf8mb4),
`perms` = 'cw:monitoringManagement:query',
`icon` = '',
`create_dept` = NULL,
`create_by` = NULL,
`create_time` = NOW(),
`update_by` = NULL,
`update_time` = NULL,
`remark` = ''
WHERE `menu_id` = 405201;
UPDATE `sys_menu` SET
`menu_name` = CONVERT(UNHEX('e8bf90e8a18ce79b91e68ea7e99481e5ae9a') USING utf8mb4),
`perms` = 'cw:monitoringManagement:lock',
`icon` = '',
`create_dept` = NULL,
`create_by` = NULL,
`create_time` = NOW(),
`update_by` = NULL,
`update_time` = NULL,
`remark` = ''
WHERE `menu_id` = 405202;
UPDATE `sys_menu` SET
`menu_name` = CONVERT(UNHEX('e8bf90e8a18ce79b91e68ea7e8a7a3e99481') USING utf8mb4),
`perms` = 'cw:monitoringManagement:unlock',
`icon` = '',
`create_dept` = NULL,
`create_by` = NULL,
`create_time` = NOW(),
`update_by` = NULL,
`update_time` = NULL,
`remark` = ''
WHERE `menu_id` = 405203;
-- =============================================
-- 验证修复结果
-- =============================================
-- 检查修复后的菜单数据
SELECT
menu_id,
menu_name,
perms,
icon,
remark
FROM `sys_menu`
WHERE menu_id IN (4050, 405001, 405002, 405003, 405004, 405005, 405006, 405007,
4051, 405101, 405102, 405103,
405008, 405009, 405010, 405011,
4052, 405201, 405202, 405203)
ORDER BY menu_id;
@@ -0,0 +1,15 @@
-- =============================================
-- 添加允许已提交后编辑字段
-- 创建时间: 2025-01-03
-- 说明: 允许已提交的项目在特定条件下可以修改
-- =============================================
-- 添加允许已提交后编辑字段
ALTER TABLE `cw_project_performance_self_evaluation`
ADD COLUMN `allow_edit_after_submit` tinyint(1) DEFAULT '0' COMMENT '允许已提交后编辑(0-不允许 1-允许)'
AFTER `evaluation_status`;
-- 添加索引(可选,如果需要根据此字段查询)
-- ALTER TABLE `cw_project_performance_self_evaluation`
-- ADD INDEX `idx_allow_edit` (`allow_edit_after_submit`) USING BTREE;
@@ -0,0 +1,63 @@
-- =============================================
-- 绩效运行监控表建表脚本
-- 创建时间: 2025-11-04
-- 说明: 基于PDF模板的绩效运行监控表
-- =============================================
-- =============================================
-- 表: 绩效运行监控表
-- =============================================
CREATE TABLE `cw_performance_monitoring` (
`id` bigint(20) NOT NULL COMMENT '主键ID',
`tenant_id` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT '000000' COMMENT '租户ID',
-- 关联信息
`evaluation_id` bigint(20) NOT NULL COMMENT '绩效自评ID',
`project_application_id` bigint(20) DEFAULT NULL COMMENT '项目申报ID',
-- 监控周期
`monitoring_period` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '监控周期(例如:2024年度1-6月)',
-- 项目概况
`fund_usage` text COLLATE utf8mb4_unicode_ci COMMENT '资金使用情况',
`performance_target_completion` text COLLATE utf8mb4_unicode_ci COMMENT '绩效目标完成情况',
-- 绩效指标完成情况(JSON格式存储)
`indicators` text COLLATE utf8mb4_unicode_ci COMMENT '绩效指标完成情况(JSON数组)',
-- 绩效运行分析
`existing_problems` text COLLATE utf8mb4_unicode_ci COMMENT '存在问题',
`indicator_variance_analysis` text COLLATE utf8mb4_unicode_ci COMMENT '指标差异率分析和说明',
`next_step_suggestions` text COLLATE utf8mb4_unicode_ci COMMENT '下一步工作建议和打算',
-- 填报信息
`fill_by` bigint(20) DEFAULT NULL COMMENT '填报人ID',
`fill_by_name` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '填报人姓名',
-- 系统字段
`remark` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '备注',
`create_dept` bigint(20) DEFAULT NULL COMMENT '创建部门',
`create_by` bigint(20) DEFAULT NULL COMMENT '创建者',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_by` bigint(20) DEFAULT NULL COMMENT '更新者',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` tinyint(1) DEFAULT '0' COMMENT '删除标志',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_evaluation_id` (`evaluation_id`) USING BTREE,
KEY `idx_project_application` (`project_application_id`) USING BTREE,
KEY `idx_tenant` (`tenant_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='绩效运行监控表';
-- =============================================
-- 菜单权限配置(如果需要独立菜单)
-- =============================================
-- 注:这里只添加按钮权限,因为运行监控作为绩效自评的子功能
-- 绩效运行监控按钮权限
INSERT INTO `sys_menu` VALUES
(405008, '运行监控查看', 4050, 8, '', NULL, NULL, 1, 0, 'F', '0', '0', 'cw:performanceMonitoring:query', '#', NULL, NULL, NOW(), NULL, NULL, ''),
(405009, '运行监控新增', 4050, 9, '', NULL, NULL, 1, 0, 'F', '0', '0', 'cw:performanceMonitoring:add', '#', NULL, NULL, NOW(), NULL, NULL, ''),
(405010, '运行监控编辑', 4050, 10, '', NULL, NULL, 1, 0, 'F', '0', '0', 'cw:performanceMonitoring:edit', '#', NULL, NULL, NOW(), NULL, NULL, ''),
(405011, '运行监控删除', 4050, 11, '', NULL, NULL, 1, 0, 'F', '0', '0', 'cw:performanceMonitoring:remove', '#', NULL, NULL, NOW(), NULL, NULL, '');
@@ -0,0 +1,35 @@
-- =============================================
-- 绩效运行监控菜单权限脚本
-- 创建时间: 2025-11-04
-- =============================================
-- 绩效运行监控按钮权限
-- 注:这里只添加按钮权限,因为运行监控作为绩效自评的子功能
INSERT INTO `sys_menu` (
`menu_id`,
`menu_name`,
`parent_id`,
`order_num`,
`path`,
`component`,
`query_param`,
`is_frame`,
`is_cache`,
`menu_type`,
`visible`,
`status`,
`perms`,
`icon`,
`create_dept`,
`create_by`,
`create_time`,
`update_by`,
`update_time`,
`remark`
) VALUES
(405008, '运行监控查看', 4050, 8, '', NULL, NULL, 1, 0, 'F', '0', '0', 'cw:performanceMonitoring:query', '#', NULL, NULL, NOW(), NULL, NULL, ''),
(405009, '运行监控新增', 4050, 9, '', NULL, NULL, 1, 0, 'F', '0', '0', 'cw:performanceMonitoring:add', '#', NULL, NULL, NOW(), NULL, NULL, ''),
(405010, '运行监控编辑', 4050, 10, '', NULL, NULL, 1, 0, 'F', '0', '0', 'cw:performanceMonitoring:edit', '#', NULL, NULL, NOW(), NULL, NULL, ''),
(405011, '运行监控删除', 4050, 11, '', NULL, NULL, 1, 0, 'F', '0', '0', 'cw:performanceMonitoring:remove', '#', NULL, NULL, NOW(), NULL, NULL, '');
@@ -0,0 +1,88 @@
-- =============================================
-- 运行监控管理功能 - 添加锁定字段
-- 创建时间: 2025-01-03
-- 说明: 为绩效自评表添加锁定字段,用于运行监控管理功能
-- =============================================
-- 添加锁定字段(如果字段已存在则跳过)
-- 检查并添加 is_locked 字段
SET @exist := (SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'cw_project_performance_self_evaluation' AND COLUMN_NAME = 'is_locked');
SET @sqlstmt := IF(@exist = 0, 'ALTER TABLE `cw_project_performance_self_evaluation` ADD COLUMN `is_locked` tinyint(1) DEFAULT ''0'' COMMENT ''是否锁定(0-未锁定 1-已锁定),锁定后不可修改'' AFTER `approve_opinion`', 'SELECT ''字段 is_locked 已存在,跳过添加''');
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 检查并添加 lock_time 字段
SET @exist := (SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'cw_project_performance_self_evaluation' AND COLUMN_NAME = 'lock_time');
SET @sqlstmt := IF(@exist = 0, 'ALTER TABLE `cw_project_performance_self_evaluation` ADD COLUMN `lock_time` datetime DEFAULT NULL COMMENT ''锁定时间'' AFTER `is_locked`', 'SELECT ''字段 lock_time 已存在,跳过添加''');
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 检查并添加 lock_by 字段
SET @exist := (SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'cw_project_performance_self_evaluation' AND COLUMN_NAME = 'lock_by');
SET @sqlstmt := IF(@exist = 0, 'ALTER TABLE `cw_project_performance_self_evaluation` ADD COLUMN `lock_by` bigint(20) DEFAULT NULL COMMENT ''锁定人ID'' AFTER `lock_time`', 'SELECT ''字段 lock_by 已存在,跳过添加''');
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 检查并添加 lock_by_name 字段
SET @exist := (SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'cw_project_performance_self_evaluation' AND COLUMN_NAME = 'lock_by_name');
SET @sqlstmt := IF(@exist = 0, 'ALTER TABLE `cw_project_performance_self_evaluation` ADD COLUMN `lock_by_name` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT ''锁定人姓名'' AFTER `lock_by`', 'SELECT ''字段 lock_by_name 已存在,跳过添加''');
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 添加锁定状态索引(如果索引已存在则跳过)
SET @exist := (SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'cw_project_performance_self_evaluation' AND INDEX_NAME = 'idx_is_locked');
SET @sqlstmt := IF(@exist = 0, 'ALTER TABLE `cw_project_performance_self_evaluation` ADD KEY `idx_is_locked` (`is_locked`) USING BTREE', 'SELECT ''索引 idx_is_locked 已存在,跳过添加''');
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- =============================================
-- 菜单权限配置 - 运行监控管理
-- =============================================
-- 注意:运行监控管理作为绩效自评的同级菜单,父菜单ID为6000(与绩效自评4050同级)
-- 如果菜单ID 4052 已被使用,请修改为其他未使用的ID
-- 二级菜单:运行监控管理(如果已存在则跳过,请根据实际情况调整菜单ID)
INSERT INTO `sys_menu` (menu_id, menu_name, parent_id, order_num, path, component, query_param, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) VALUES
(4052, '运行监控管理', 6000, 8, 'monitoringManagement', 'cw/monitoringManagement/index', NULL, 1, 0, 'C', '0', '0', 'cw:monitoringManagement:list', 'monitor', NULL, NULL, NOW(), NULL, NULL, '项目运行监控管理菜单(财务管理员和学校领导使用)')
ON DUPLICATE KEY UPDATE menu_name = '运行监控管理', path = 'monitoringManagement', component = 'cw/monitoringManagement/index', perms = 'cw:monitoringManagement:list';
-- 运行监控管理按钮权限
INSERT INTO `sys_menu` (menu_id, menu_name, parent_id, order_num, path, component, query_param, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) VALUES
(405201, '运行监控查询', 4052, 1, '', NULL, NULL, 1, 0, 'F', '0', '0', 'cw:monitoringManagement:query', '', NULL, NULL, NOW(), NULL, NULL, '')
ON DUPLICATE KEY UPDATE
menu_name = '运行监控查询',
perms = 'cw:monitoringManagement:query',
icon = '',
create_time = NOW();
INSERT INTO `sys_menu` (menu_id, menu_name, parent_id, order_num, path, component, query_param, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) VALUES
(405202, '运行监控锁定', 4052, 2, '', NULL, NULL, 1, 0, 'F', '0', '0', 'cw:monitoringManagement:lock', '', NULL, NULL, NOW(), NULL, NULL, '')
ON DUPLICATE KEY UPDATE
menu_name = '运行监控锁定',
perms = 'cw:monitoringManagement:lock',
icon = '',
create_time = NOW();
INSERT INTO `sys_menu` (menu_id, menu_name, parent_id, order_num, path, component, query_param, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) VALUES
(405203, '运行监控解锁', 4052, 3, '', NULL, NULL, 1, 0, 'F', '0', '0', 'cw:monitoringManagement:unlock', '', NULL, NULL, NOW(), NULL, NULL, '')
ON DUPLICATE KEY UPDATE
menu_name = '运行监控解锁',
perms = 'cw:monitoringManagement:unlock',
icon = '',
create_time = NOW();
-- =============================================
-- 数据字典配置 - 锁定状态
-- =============================================
-- 锁定状态字典(如果已存在则跳过)
-- INSERT INTO `sys_dict_type` VALUES (NULL, '000000', '绩效自评锁定状态', 'cw_evaluation_locked', '0', NULL, NOW(), NULL, NULL, '项目绩效自评锁定状态字典');
-- INSERT INTO `sys_dict_data` VALUES (NULL, '000000', 1, '未锁定', '0', 'cw_evaluation_locked', NULL, 'success', 'N', '0', NULL, NOW(), NULL, NULL, '');
-- INSERT INTO `sys_dict_data` VALUES (NULL, '000000', 2, '已锁定', '1', 'cw_evaluation_locked', NULL, 'danger', 'N', '0', NULL, NOW(), NULL, NULL, '');
@@ -0,0 +1,253 @@
-- =============================================
-- 项目绩效自评模块建表脚本
-- 创建时间: 2025-11-03
-- 说明: 项目支出绩效自评和运行监控管理
-- 版本: v1.0
-- =============================================
-- =============================================
-- 表1: 项目绩效自评表 (主表)
-- =============================================
CREATE TABLE `cw_project_performance_self_evaluation` (
`id` bigint(20) NOT NULL COMMENT '主键ID',
`tenant_id` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT '000000' COMMENT '租户ID',
-- 关联项目申报
`project_application_id` bigint(20) NOT NULL COMMENT '项目申报ID(关联cw_project_application表)',
`application_no` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '申报编号',
`project_name` varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '项目名称',
-- 基本信息
`evaluation_year` int(11) NOT NULL COMMENT '自评年度',
`principal` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '项目负责人',
`contact_phone` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '联系电话',
`start_date` date DEFAULT NULL COMMENT '项目实施开始时间',
`end_date` date DEFAULT NULL COMMENT '项目实施结束时间',
-- 资金情况 (单位:万元)
`total_investment` decimal(15,2) DEFAULT NULL COMMENT '项目总投资',
`annual_budget` decimal(15,2) DEFAULT NULL COMMENT '本年度预算',
`actual_expenditure` decimal(15,2) DEFAULT NULL COMMENT '本年度实际支出',
`budget_execution_rate` decimal(5,2) DEFAULT NULL COMMENT '预算执行率(%)',
-- 绩效目标
`performance_goal` text COLLATE utf8mb4_unicode_ci COMMENT '年度绩效目标',
`target_completion` text COLLATE utf8mb4_unicode_ci COMMENT '目标完成情况说明',
-- 绩效自评 (决策、过程、产出、效益四个维度)
`decision_score` decimal(5,2) DEFAULT NULL COMMENT '项目决策得分',
`decision_content` text COLLATE utf8mb4_unicode_ci COMMENT '项目决策自评内容',
`process_score` decimal(5,2) DEFAULT NULL COMMENT '项目过程得分',
`process_content` text COLLATE utf8mb4_unicode_ci COMMENT '项目过程自评内容',
`output_score` decimal(5,2) DEFAULT NULL COMMENT '项目产出得分',
`output_content` text COLLATE utf8mb4_unicode_ci COMMENT '项目产出自评内容',
`benefit_score` decimal(5,2) DEFAULT NULL COMMENT '项目效益得分',
`benefit_content` text COLLATE utf8mb4_unicode_ci COMMENT '项目效益自评内容',
`total_score` decimal(5,2) DEFAULT NULL COMMENT '自评总分',
`self_evaluation_level` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '自评等级(优秀/良好/合格/不合格)',
-- 存在的问题和改进措施
`existing_problems` text COLLATE utf8mb4_unicode_ci COMMENT '存在的主要问题',
`improvement_measures` text COLLATE utf8mb4_unicode_ci COMMENT '改进措施和建议',
-- 状态管理
`evaluation_status` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT 'draft' COMMENT '自评状态(draft-草稿 submitted-已提交 approved-已审核)',
`submit_time` datetime DEFAULT NULL COMMENT '提交时间',
`submit_by` bigint(20) DEFAULT NULL COMMENT '提交人ID',
`submit_by_name` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '提交人姓名',
-- 审核信息
`approve_time` datetime DEFAULT NULL COMMENT '审核时间',
`approve_by` bigint(20) DEFAULT NULL COMMENT '审核人ID',
`approve_by_name` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '审核人姓名',
`approve_opinion` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '审核意见',
-- 系统字段
`remark` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '备注',
`create_dept` bigint(20) DEFAULT NULL COMMENT '创建部门',
`create_by` bigint(20) DEFAULT NULL COMMENT '创建者',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_by` bigint(20) DEFAULT NULL COMMENT '更新者',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` tinyint(1) DEFAULT '0' COMMENT '删除标志(0-正常 1-删除)',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_application_year` (`project_application_id`,`evaluation_year`,`tenant_id`) USING BTREE COMMENT '项目-年度-租户联合索引',
KEY `idx_application_no` (`application_no`) USING BTREE,
KEY `idx_evaluation_year` (`evaluation_year`) USING BTREE,
KEY `idx_status` (`evaluation_status`) USING BTREE,
KEY `idx_tenant` (`tenant_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='项目绩效自评表(允许同一项目同一年度创建多条自评)';
-- =============================================
-- 表2: 项目绩效自评指标明细表
-- =============================================
CREATE TABLE `cw_project_evaluation_indicator` (
`id` bigint(20) NOT NULL COMMENT '主键ID',
`tenant_id` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT '000000' COMMENT '租户ID',
-- 关联自评表
`evaluation_id` bigint(20) NOT NULL COMMENT '绩效自评ID',
-- 指标分类
`indicator_category` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '指标类别(decision-决策/process-过程/output-产出/benefit-效益)',
`indicator_name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '指标名称',
`indicator_type` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '指标类型(quantity-数量/quality-质量/time-时效/cost-成本)',
-- 指标内容
`target_value` varchar(200) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '目标值',
`actual_value` varchar(200) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '实际完成值',
`completion_rate` decimal(5,2) DEFAULT NULL COMMENT '完成率(%)',
-- 评分
`standard_score` decimal(5,2) DEFAULT NULL COMMENT '指标分值',
`actual_score` decimal(5,2) DEFAULT NULL COMMENT '实际得分',
-- 说明
`completion_description` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '完成情况说明',
`sort_order` int(11) DEFAULT '0' COMMENT '排序号',
-- 系统字段
`remark` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '备注',
`create_dept` bigint(20) DEFAULT NULL COMMENT '创建部门',
`create_by` bigint(20) DEFAULT NULL COMMENT '创建者',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_by` bigint(20) DEFAULT NULL COMMENT '更新者',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` tinyint(1) DEFAULT '0' COMMENT '删除标志',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_evaluation_id` (`evaluation_id`) USING BTREE,
KEY `idx_category` (`indicator_category`) USING BTREE,
KEY `idx_tenant` (`tenant_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='项目绩效自评指标明细表';
-- =============================================
-- 表3: 项目月度运行监控表
-- =============================================
CREATE TABLE `cw_project_monthly_monitoring` (
`id` bigint(20) NOT NULL COMMENT '主键ID',
`tenant_id` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT '000000' COMMENT '租户ID',
-- 关联自评表
`evaluation_id` bigint(20) NOT NULL COMMENT '绩效自评ID',
`project_application_id` bigint(20) NOT NULL COMMENT '项目申报ID',
-- 月度信息
`monitoring_year` int(11) NOT NULL COMMENT '监控年度',
`monitoring_month` int(11) NOT NULL COMMENT '监控月份(1-12)',
-- 执行情况
`planned_progress` decimal(5,2) DEFAULT NULL COMMENT '计划进度(%)',
`actual_progress` decimal(5,2) DEFAULT NULL COMMENT '实际进度(%)',
`progress_variance` decimal(5,2) DEFAULT NULL COMMENT '进度偏差(%) = 实际进度 - 计划进度',
-- 资金情况 (单位:万元)
`monthly_budget` decimal(15,2) DEFAULT NULL COMMENT '本月预算',
`monthly_expenditure` decimal(15,2) DEFAULT NULL COMMENT '本月实际支出',
`cumulative_budget` decimal(15,2) DEFAULT NULL COMMENT '累计预算',
`cumulative_expenditure` decimal(15,2) DEFAULT NULL COMMENT '累计实际支出',
`fund_execution_rate` decimal(5,2) DEFAULT NULL COMMENT '资金执行率(%)',
-- 关键节点
`key_milestones` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '本月完成的关键节点',
`milestone_completion` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '节点完成情况(completed-已完成/delayed-延期/notStarted-未开始)',
-- 问题与风险
`problems_encountered` text COLLATE utf8mb4_unicode_ci COMMENT '本月遇到的问题',
`risk_description` text COLLATE utf8mb4_unicode_ci COMMENT '风险描述',
`countermeasures` text COLLATE utf8mb4_unicode_ci COMMENT '应对措施',
-- 下月计划
`next_month_plan` text COLLATE utf8mb4_unicode_ci COMMENT '下月工作计划',
-- 填报信息
`fill_status` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT 'not_filled' COMMENT '填报状态(not_filled-未填报/filled-已填报)',
`fill_time` datetime DEFAULT NULL COMMENT '填报时间',
`fill_by` bigint(20) DEFAULT NULL COMMENT '填报人ID',
`fill_by_name` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '填报人姓名',
-- 系统字段
`remark` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '备注',
`create_dept` bigint(20) DEFAULT NULL COMMENT '创建部门',
`create_by` bigint(20) DEFAULT NULL COMMENT '创建者',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_by` bigint(20) DEFAULT NULL COMMENT '更新者',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` tinyint(1) DEFAULT '0' COMMENT '删除标志',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `uk_evaluation_month` (`evaluation_id`,`monitoring_year`,`monitoring_month`,`tenant_id`,`deleted`) USING BTREE COMMENT '同一项目同一年同一月只能有一条记录',
KEY `idx_project_application` (`project_application_id`) USING BTREE,
KEY `idx_year_month` (`monitoring_year`,`monitoring_month`) USING BTREE,
KEY `idx_fill_status` (`fill_status`) USING BTREE,
KEY `idx_tenant` (`tenant_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='项目月度运行监控表';
-- =============================================
-- 菜单权限配置
-- =============================================
-- 注意:请根据实际的项目申报管理菜单ID调整父菜单ID
-- 假设项目申报管理的菜单ID为 4040(请根据实际情况调整)
-- 二级菜单:绩效自评管理
INSERT INTO `sys_menu` VALUES
(4050, '绩效自评管理', 4040, 5, 'evaluation', 'cw/evaluation/index', NULL, 1, 0, 'C', '0', '0', 'cw:evaluation:list', 'chart', NULL, NULL, NOW(), NULL, NULL, '项目绩效自评管理菜单');
-- 绩效自评管理按钮权限
INSERT INTO `sys_menu` VALUES
(405001, '绩效自评查询', 4050, 1, '', NULL, NULL, 1, 0, 'F', '0', '0', 'cw:evaluation:query', '#', NULL, NULL, NOW(), NULL, NULL, ''),
(405002, '绩效自评新增', 4050, 2, '', NULL, NULL, 1, 0, 'F', '0', '0', 'cw:evaluation:add', '#', NULL, NULL, NOW(), NULL, NULL, ''),
(405003, '绩效自评修改', 4050, 3, '', NULL, NULL, 1, 0, 'F', '0', '0', 'cw:evaluation:edit', '#', NULL, NULL, NOW(), NULL, NULL, ''),
(405004, '绩效自评删除', 4050, 4, '', NULL, NULL, 1, 0, 'F', '0', '0', 'cw:evaluation:remove', '#', NULL, NULL, NOW(), NULL, NULL, ''),
(405005, '绩效自评提交', 4050, 5, '', NULL, NULL, 1, 0, 'F', '0', '0', 'cw:evaluation:submit', '#', NULL, NULL, NOW(), NULL, NULL, ''),
(405006, '绩效自评审核', 4050, 6, '', NULL, NULL, 1, 0, 'F', '0', '0', 'cw:evaluation:approve', '#', NULL, NULL, NOW(), NULL, NULL, ''),
(405007, '绩效自评导出', 4050, 7, '', NULL, NULL, 1, 0, 'F', '0', '0', 'cw:evaluation:export', '#', NULL, NULL, NOW(), NULL, NULL, '');
-- 二级菜单:运行监控管理
INSERT INTO `sys_menu` VALUES
(4051, '运行监控管理', 4040, 6, 'monitoring', 'cw/monitoring/index', NULL, 1, 0, 'C', '0', '0', 'cw:monitoring:list', 'monitor', NULL, NULL, NOW(), NULL, NULL, '项目运行监控管理菜单');
-- 运行监控管理按钮权限
INSERT INTO `sys_menu` VALUES
(405101, '运行监控查询', 4051, 1, '', NULL, NULL, 1, 0, 'F', '0', '0', 'cw:monitoring:query', '#', NULL, NULL, NOW(), NULL, NULL, ''),
(405102, '运行监控填报', 4051, 2, '', NULL, NULL, 1, 0, 'F', '0', '0', 'cw:monitoring:fill', '#', NULL, NULL, NOW(), NULL, NULL, ''),
(405103, '运行监控修改', 4051, 3, '', NULL, NULL, 1, 0, 'F', '0', '0', 'cw:monitoring:edit', '#', NULL, NULL, NOW(), NULL, NULL, '');
-- =============================================
-- 数据字典配置
-- =============================================
-- 自评状态
INSERT INTO `sys_dict_type` VALUES (NULL, '000000', '绩效自评状态', 'cw_evaluation_status', '0', NULL, NOW(), NULL, NULL, '项目绩效自评状态字典');
INSERT INTO `sys_dict_data` VALUES (NULL, '000000', 1, '草稿', 'draft', 'cw_evaluation_status', NULL, 'info', 'N', '0', NULL, NOW(), NULL, NULL, '');
INSERT INTO `sys_dict_data` VALUES (NULL, '000000', 2, '已提交', 'submitted', 'cw_evaluation_status', NULL, 'primary', 'N', '0', NULL, NOW(), NULL, NULL, '');
INSERT INTO `sys_dict_data` VALUES (NULL, '000000', 3, '已审核', 'approved', 'cw_evaluation_status', NULL, 'success', 'N', '0', NULL, NOW(), NULL, NULL, '');
-- 自评等级
INSERT INTO `sys_dict_type` VALUES (NULL, '000000', '绩效自评等级', 'cw_evaluation_level', '0', NULL, NOW(), NULL, NULL, '项目绩效自评等级字典');
INSERT INTO `sys_dict_data` VALUES (NULL, '000000', 1, '优秀', '优秀', 'cw_evaluation_level', NULL, 'success', 'N', '0', NULL, NOW(), NULL, NULL, '');
INSERT INTO `sys_dict_data` VALUES (NULL, '000000', 2, '良好', '良好', 'cw_evaluation_level', NULL, 'primary', 'N', '0', NULL, NOW(), NULL, NULL, '');
INSERT INTO `sys_dict_data` VALUES (NULL, '000000', 3, '合格', '合格', 'cw_evaluation_level', NULL, 'warning', 'N', '0', NULL, NOW(), NULL, NULL, '');
INSERT INTO `sys_dict_data` VALUES (NULL, '000000', 4, '不合格', '不合格', 'cw_evaluation_level', NULL, 'danger', 'N', '0', NULL, NOW(), NULL, NULL, '');
-- 节点完成情况
INSERT INTO `sys_dict_type` VALUES (NULL, '000000', '节点完成情况', 'cw_milestone_completion', '0', NULL, NOW(), NULL, NULL, '项目节点完成情况字典');
INSERT INTO `sys_dict_data` VALUES (NULL, '000000', 1, '已完成', 'completed', 'cw_milestone_completion', NULL, 'success', 'N', '0', NULL, NOW(), NULL, NULL, '');
INSERT INTO `sys_dict_data` VALUES (NULL, '000000', 2, '延期', 'delayed', 'cw_milestone_completion', NULL, 'warning', 'N', '0', NULL, NOW(), NULL, NULL, '');
INSERT INTO `sys_dict_data` VALUES (NULL, '000000', 3, '未开始', 'notStarted', 'cw_milestone_completion', NULL, 'info', 'N', '0', NULL, NOW(), NULL, NULL, '');
-- 月度填报状态
INSERT INTO `sys_dict_type` VALUES (NULL, '000000', '月度填报状态', 'cw_monthly_fill_status', '0', NULL, NOW(), NULL, NULL, '月度监控填报状态字典');
INSERT INTO `sys_dict_data` VALUES (NULL, '000000', 1, '未填报', 'not_filled', 'cw_monthly_fill_status', NULL, 'info', 'N', '0', NULL, NOW(), NULL, NULL, '');
INSERT INTO `sys_dict_data` VALUES (NULL, '000000', 2, '已填报', 'filled', 'cw_monthly_fill_status', NULL, 'success', 'N', '0', NULL, NOW(), NULL, NULL, '');
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.cw.mapper.CwPerformanceMonitoringMapper">
<resultMap type="org.dromara.cw.domain.CwPerformanceMonitoring" id="CwPerformanceMonitoringResult">
<result property="id" column="id"/>
<result property="evaluationId" column="evaluation_id"/>
<result property="projectApplicationId" column="project_application_id"/>
<result property="monitoringPeriod" column="monitoring_period"/>
<result property="fundUsage" column="fund_usage"/>
<result property="performanceTargetCompletion" column="performance_target_completion"/>
<result property="indicators" column="indicators"/>
<result property="existingProblems" column="existing_problems"/>
<result property="indicatorVarianceAnalysis" column="indicator_variance_analysis"/>
<result property="nextStepSuggestions" column="next_step_suggestions"/>
<result property="fillBy" column="fill_by"/>
<result property="fillByName" column="fill_by_name"/>
<result property="remark" column="remark"/>
<result property="createDept" column="create_dept"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
</resultMap>
</mapper>
@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.cw.mapper.CwProjectEvaluationIndicatorMapper">
<resultMap type="org.dromara.cw.domain.CwProjectEvaluationIndicator" id="CwProjectEvaluationIndicatorResult">
<result property="id" column="id"/>
<result property="evaluationId" column="evaluation_id"/>
<result property="indicatorCategory" column="indicator_category"/>
<result property="indicatorName" column="indicator_name"/>
<result property="indicatorType" column="indicator_type"/>
<result property="targetValue" column="target_value"/>
<result property="actualValue" column="actual_value"/>
<result property="completionRate" column="completion_rate"/>
<result property="standardScore" column="standard_score"/>
<result property="actualScore" column="actual_score"/>
<result property="completionDescription" column="completion_description"/>
<result property="sortOrder" column="sort_order"/>
<result property="remark" column="remark"/>
<result property="createDept" column="create_dept"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="deleted" column="deleted"/>
</resultMap>
<!-- 根据自评ID查询指标列表 -->
<select id="selectByEvaluationId" resultMap="CwProjectEvaluationIndicatorResult">
SELECT *
FROM cw_project_evaluation_indicator
WHERE evaluation_id = #{evaluationId}
AND deleted = 0
ORDER BY indicator_category, sort_order
</select>
<!-- 根据自评ID和指标类别查询指标列表 -->
<select id="selectByEvaluationIdAndCategory" resultMap="CwProjectEvaluationIndicatorResult">
SELECT *
FROM cw_project_evaluation_indicator
WHERE evaluation_id = #{evaluationId}
AND indicator_category = #{indicatorCategory}
AND deleted = 0
ORDER BY sort_order
</select>
<!-- 批量插入指标 -->
<insert id="batchInsert" parameterType="java.util.List">
INSERT INTO cw_project_evaluation_indicator
(id, tenant_id, evaluation_id, indicator_category, indicator_name, indicator_type,
target_value, actual_value, completion_rate, standard_score, actual_score,
completion_description, sort_order, remark, create_dept, create_by, create_time)
VALUES
<foreach collection="list" item="item" separator=",">
(#{item.id}, #{item.tenantId}, #{item.evaluationId}, #{item.indicatorCategory},
#{item.indicatorName}, #{item.indicatorType}, #{item.targetValue}, #{item.actualValue},
#{item.completionRate}, #{item.standardScore}, #{item.actualScore},
#{item.completionDescription}, #{item.sortOrder}, #{item.remark},
#{item.createDept}, #{item.createBy}, #{item.createTime})
</foreach>
</insert>
<!-- 根据自评ID删除指标 -->
<delete id="deleteByEvaluationId">
UPDATE cw_project_evaluation_indicator
SET deleted = 1
WHERE evaluation_id = #{evaluationId}
</delete>
</mapper>
@@ -0,0 +1,119 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.cw.mapper.CwProjectMonthlyMonitoringMapper">
<resultMap type="org.dromara.cw.domain.CwProjectMonthlyMonitoring" id="CwProjectMonthlyMonitoringResult">
<result property="id" column="id"/>
<result property="evaluationId" column="evaluation_id"/>
<result property="projectApplicationId" column="project_application_id"/>
<result property="monitoringYear" column="monitoring_year"/>
<result property="monitoringMonth" column="monitoring_month"/>
<result property="plannedProgress" column="planned_progress"/>
<result property="actualProgress" column="actual_progress"/>
<result property="progressVariance" column="progress_variance"/>
<result property="monthlyBudget" column="monthly_budget"/>
<result property="monthlyExpenditure" column="monthly_expenditure"/>
<result property="cumulativeBudget" column="cumulative_budget"/>
<result property="cumulativeExpenditure" column="cumulative_expenditure"/>
<result property="fundExecutionRate" column="fund_execution_rate"/>
<result property="keyMilestones" column="key_milestones"/>
<result property="milestoneCompletion" column="milestone_completion"/>
<result property="problemsEncountered" column="problems_encountered"/>
<result property="riskDescription" column="risk_description"/>
<result property="countermeasures" column="countermeasures"/>
<result property="nextMonthPlan" column="next_month_plan"/>
<result property="fillStatus" column="fill_status"/>
<result property="fillTime" column="fill_time"/>
<result property="fillBy" column="fill_by"/>
<result property="fillByName" column="fill_by_name"/>
<result property="remark" column="remark"/>
<result property="createDept" column="create_dept"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="deleted" column="deleted"/>
</resultMap>
<!-- 根据自评ID查询月度监控列表 -->
<select id="selectByEvaluationId" resultMap="CwProjectMonthlyMonitoringResult">
SELECT *
FROM cw_project_monthly_monitoring
WHERE evaluation_id = #{evaluationId}
AND deleted = 0
ORDER BY monitoring_year, monitoring_month
</select>
<!-- 根据自评ID和年度查询月度监控列表 -->
<select id="selectByEvaluationIdAndYear" resultMap="CwProjectMonthlyMonitoringResult">
SELECT *
FROM cw_project_monthly_monitoring
WHERE evaluation_id = #{evaluationId}
AND monitoring_year = #{monitoringYear}
AND deleted = 0
ORDER BY monitoring_month
</select>
<!-- 根据自评ID、年度和月份查询月度监控 -->
<select id="selectByEvaluationIdAndMonth" resultMap="CwProjectMonthlyMonitoringResult">
SELECT *
FROM cw_project_monthly_monitoring
WHERE evaluation_id = #{evaluationId}
AND monitoring_year = #{monitoringYear}
AND monitoring_month = #{monitoringMonth}
AND deleted = 0
LIMIT 1
</select>
<!-- 批量插入月度监控数据 -->
<insert id="batchInsert" parameterType="java.util.List">
INSERT INTO cw_project_monthly_monitoring
(id, tenant_id, evaluation_id, project_application_id, monitoring_year, monitoring_month,
planned_progress, actual_progress, progress_variance, monthly_budget, monthly_expenditure,
cumulative_budget, cumulative_expenditure, fund_execution_rate, key_milestones,
milestone_completion, problems_encountered, risk_description, countermeasures,
next_month_plan, fill_status, fill_time, fill_by, fill_by_name,
remark, create_dept, create_by, create_time)
VALUES
<foreach collection="list" item="item" separator=",">
(#{item.id}, #{item.tenantId}, #{item.evaluationId}, #{item.projectApplicationId},
#{item.monitoringYear}, #{item.monitoringMonth}, #{item.plannedProgress},
#{item.actualProgress}, #{item.progressVariance}, #{item.monthlyBudget},
#{item.monthlyExpenditure}, #{item.cumulativeBudget}, #{item.cumulativeExpenditure},
#{item.fundExecutionRate}, #{item.keyMilestones}, #{item.milestoneCompletion},
#{item.problemsEncountered}, #{item.riskDescription}, #{item.countermeasures},
#{item.nextMonthPlan}, #{item.fillStatus}, #{item.fillTime}, #{item.fillBy},
#{item.fillByName}, #{item.remark}, #{item.createDept}, #{item.createBy},
#{item.createTime})
</foreach>
</insert>
<!-- 根据自评ID删除月度监控数据 -->
<delete id="deleteByEvaluationId">
UPDATE cw_project_monthly_monitoring
SET deleted = 1
WHERE evaluation_id = #{evaluationId}
</delete>
<!-- 计算年度累计进度 -->
<select id="calculateYearlyProgress" resultType="java.math.BigDecimal">
SELECT MAX(actual_progress)
FROM cw_project_monthly_monitoring
WHERE evaluation_id = #{evaluationId}
AND monitoring_year = #{monitoringYear}
AND deleted = 0
</select>
<!-- 计算年度累计支出 -->
<select id="calculateYearlyExpenditure" resultType="java.math.BigDecimal">
SELECT MAX(cumulative_expenditure)
FROM cw_project_monthly_monitoring
WHERE evaluation_id = #{evaluationId}
AND monitoring_year = #{monitoringYear}
AND deleted = 0
</select>
</mapper>
@@ -0,0 +1,206 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.cw.mapper.CwProjectPerformanceSelfEvaluationMapper">
<resultMap type="org.dromara.cw.domain.CwProjectPerformanceSelfEvaluation" id="CwProjectPerformanceSelfEvaluationResult">
<result property="id" column="id"/>
<result property="projectApplicationId" column="project_application_id"/>
<result property="applicationNo" column="application_no"/>
<result property="projectName" column="project_name"/>
<result property="supervisoryDept" column="supervisory_dept"/>
<result property="implementUnit" column="implement_unit"/>
<result property="evaluationYear" column="evaluation_year"/>
<result property="initialBudget" column="initial_budget"/>
<result property="principal" column="principal"/>
<result property="contactPhone" column="contact_phone"/>
<result property="startDate" column="start_date"/>
<result property="endDate" column="end_date"/>
<result property="totalInvestment" column="total_investment"/>
<result property="annualBudget" column="annual_budget"/>
<result property="actualExpenditure" column="actual_expenditure"/>
<result property="budgetExecutionRate" column="budget_execution_rate"/>
<result property="fundValue" column="fund_value"/>
<result property="fundExecutionRate" column="fund_execution_rate"/>
<result property="fundScore" column="fund_score"/>
<result property="currentYearBudgetInitial" column="current_year_budget_initial"/>
<result property="currentYearBudgetAnnual" column="current_year_budget_annual"/>
<result property="currentYearBudgetActual" column="current_year_budget_actual"/>
<result property="currentYearBudgetValue" column="current_year_budget_value"/>
<result property="currentYearBudgetExecutionRate" column="current_year_budget_execution_rate"/>
<result property="currentYearBudgetScore" column="current_year_budget_score"/>
<result property="lastYearCarryoverInitial" column="last_year_carryover_initial"/>
<result property="lastYearCarryoverAnnual" column="last_year_carryover_annual"/>
<result property="lastYearCarryoverActual" column="last_year_carryover_actual"/>
<result property="lastYearCarryoverValue" column="last_year_carryover_value"/>
<result property="lastYearCarryoverExecutionRate" column="last_year_carryover_execution_rate"/>
<result property="lastYearCarryoverScore" column="last_year_carryover_score"/>
<result property="otherFundsInitial" column="other_funds_initial"/>
<result property="otherFundsAnnual" column="other_funds_annual"/>
<result property="otherFundsActual" column="other_funds_actual"/>
<result property="otherFundsValue" column="other_funds_value"/>
<result property="otherFundsExecutionRate" column="other_funds_execution_rate"/>
<result property="otherFundsScore" column="other_funds_score"/>
<result property="performanceGoal" column="performance_goal"/>
<result property="targetCompletion" column="target_completion"/>
<result property="quantityIndicator" column="quantity_indicator"/>
<result property="quantityTarget" column="quantity_target"/>
<result property="quantityActual" column="quantity_actual"/>
<result property="quantityValue" column="quantity_value"/>
<result property="quantityScore" column="quantity_score"/>
<result property="quantityDeviation" column="quantity_deviation"/>
<result property="qualityIndicator" column="quality_indicator"/>
<result property="qualityTarget" column="quality_target"/>
<result property="qualityActual" column="quality_actual"/>
<result property="qualityValue" column="quality_value"/>
<result property="qualityScore" column="quality_score"/>
<result property="qualityDeviation" column="quality_deviation"/>
<result property="timelinessIndicator" column="timeliness_indicator"/>
<result property="timelinessTarget" column="timeliness_target"/>
<result property="timelinessActual" column="timeliness_actual"/>
<result property="timelinessValue" column="timeliness_value"/>
<result property="timelinessScore" column="timeliness_score"/>
<result property="timelinessDeviation" column="timeliness_deviation"/>
<result property="costIndicator" column="cost_indicator"/>
<result property="costTarget" column="cost_target"/>
<result property="costActual" column="cost_actual"/>
<result property="costValue" column="cost_value"/>
<result property="costScore" column="cost_score"/>
<result property="costDeviation" column="cost_deviation"/>
<result property="economicIndicator" column="economic_indicator"/>
<result property="economicTarget" column="economic_target"/>
<result property="economicActual" column="economic_actual"/>
<result property="economicValue" column="economic_value"/>
<result property="economicScore" column="economic_score"/>
<result property="economicDeviation" column="economic_deviation"/>
<result property="socialIndicator" column="social_indicator"/>
<result property="socialTarget" column="social_target"/>
<result property="socialActual" column="social_actual"/>
<result property="socialValue" column="social_value"/>
<result property="socialScore" column="social_score"/>
<result property="socialDeviation" column="social_deviation"/>
<result property="ecologicalIndicator" column="ecological_indicator"/>
<result property="ecologicalTarget" column="ecological_target"/>
<result property="ecologicalActual" column="ecological_actual"/>
<result property="ecologicalValue" column="ecological_value"/>
<result property="ecologicalScore" column="ecological_score"/>
<result property="ecologicalDeviation" column="ecological_deviation"/>
<result property="satisfactionIndicator" column="satisfaction_indicator"/>
<result property="satisfactionTarget" column="satisfaction_target"/>
<result property="satisfactionActual" column="satisfaction_actual"/>
<result property="satisfactionValue" column="satisfaction_value"/>
<result property="satisfactionScore" column="satisfaction_score"/>
<result property="satisfactionDeviation" column="satisfaction_deviation"/>
<result property="decisionScore" column="decision_score"/>
<result property="decisionContent" column="decision_content"/>
<result property="processScore" column="process_score"/>
<result property="processContent" column="process_content"/>
<result property="outputScore" column="output_score"/>
<result property="outputContent" column="output_content"/>
<result property="benefitScore" column="benefit_score"/>
<result property="benefitContent" column="benefit_content"/>
<result property="totalScore" column="total_score"/>
<result property="selfEvaluationLevel" column="self_evaluation_level"/>
<result property="existingProblems" column="existing_problems"/>
<result property="improvementMeasures" column="improvement_measures"/>
<result property="evaluationStatus" column="evaluation_status"/>
<result property="allowEditAfterSubmit" column="allow_edit_after_submit"/>
<result property="submitTime" column="submit_time"/>
<result property="submitBy" column="submit_by"/>
<result property="submitByName" column="submit_by_name"/>
<result property="approveTime" column="approve_time"/>
<result property="approveBy" column="approve_by"/>
<result property="approveByName" column="approve_by_name"/>
<result property="approveOpinion" column="approve_opinion"/>
<result property="remark" column="remark"/>
<result property="createDept" column="create_dept"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="deleted" column="deleted"/>
</resultMap>
<!-- 根据项目申报ID和年度查询自评 -->
<select id="selectByProjectAndYear" resultMap="CwProjectPerformanceSelfEvaluationResult">
SELECT *
FROM cw_project_performance_self_evaluation
WHERE project_application_id = #{projectApplicationId}
AND evaluation_year = #{evaluationYear}
AND deleted = 0
LIMIT 1
</select>
<!-- 查询我的自评列表 -->
<select id="selectMyEvaluations" resultMap="CwProjectPerformanceSelfEvaluationResult">
SELECT *
FROM cw_project_performance_self_evaluation
WHERE create_by = #{userId}
AND deleted = 0
ORDER BY create_time DESC
</select>
<!-- 查询待审核的自评列表 -->
<select id="selectPendingApprovals" resultMap="CwProjectPerformanceSelfEvaluationResult">
SELECT *
FROM cw_project_performance_self_evaluation
WHERE evaluation_status = 'submitted'
AND deleted = 0
ORDER BY submit_time ASC
</select>
<!-- 统计自评数量 -->
<select id="countEvaluations" resultType="java.lang.Long">
SELECT COUNT(*)
FROM cw_project_performance_self_evaluation
WHERE deleted = 0
<if test="evaluationYear != null">
AND evaluation_year = #{evaluationYear}
</if>
<if test="evaluationStatus != null and evaluationStatus != ''">
AND evaluation_status = #{evaluationStatus}
</if>
</select>
<!-- 计算平均分 -->
<select id="calculateAverageScore" resultType="java.math.BigDecimal">
SELECT AVG(total_score)
FROM cw_project_performance_self_evaluation
WHERE deleted = 0
AND total_score IS NOT NULL
<if test="evaluationYear != null">
AND evaluation_year = #{evaluationYear}
</if>
</select>
<!-- 按部门统计自评情况 -->
<select id="statisticsByDept" resultType="java.util.HashMap">
SELECT
create_dept AS deptId,
COUNT(*) AS count,
AVG(total_score) AS avgScore
FROM cw_project_performance_self_evaluation
WHERE deleted = 0
<if test="evaluationYear != null">
AND evaluation_year = #{evaluationYear}
</if>
GROUP BY create_dept
</select>
<!-- 按等级统计自评数量 -->
<select id="statisticsByLevel" resultType="java.util.HashMap">
SELECT
self_evaluation_level AS level,
COUNT(*) AS count
FROM cw_project_performance_self_evaluation
WHERE deleted = 0
AND self_evaluation_level IS NOT NULL
<if test="evaluationYear != null">
AND evaluation_year = #{evaluationYear}
</if>
GROUP BY self_evaluation_level
</select>
</mapper>
@@ -469,34 +469,34 @@ public class InternshipInfoServiceImpl implements IInternshipInfoService {
@Override
public InternshipInfoVO getCurrentStudentInternship() {
log.info("开始获取当前学生的实习信息");
// 获取当前登录用户ID
Long currentUserId = LoginHelper.getUserId();
log.info("当前登录用户ID:{}", currentUserId);
if (currentUserId == null) {
log.error("当前用户未登录");
throw new ServiceException("用户未登录");
}
// 根据用户ID查询实习信息
LambdaQueryWrapper<ZsjyInternshipInfo> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(ZsjyInternshipInfo::getStudentId, currentUserId)
.eq(ZsjyInternshipInfo::getDeleted, 0)
.orderByDesc(ZsjyInternshipInfo::getCreateTime)
.last("LIMIT 1"); // 只取最新的一条记录
ZsjyInternshipInfo internshipInfo = zsjyInternshipInfoMapper.selectOne(wrapper);
log.info("查询到的实习信息:{}", internshipInfo != null ? internshipInfo.getInternshipId() : "无");
if (internshipInfo == null) {
log.info("当前学生没有实习信息");
return null;
}
// 转换为VO
InternshipInfoVO vo = BeanUtil.toBean(internshipInfo, InternshipInfoVO.class);
// 查询学生信息并设置到VO中
XgStudentMsgVo studentInfo = getStudentInfo(currentUserId);
vo.setStudentName(studentInfo.getName());
@@ -505,7 +505,7 @@ public class InternshipInfoServiceImpl implements IInternshipInfoService {
vo.setMajorName(studentInfo.getMajorName());
vo.setCollegeName(studentInfo.getCollegeName());
vo.setGrade(studentInfo.getGrade());
log.info("成功获取当前学生实习信息,实习ID:{}", vo.getInternshipId());
return vo;
}
+79
View File
@@ -0,0 +1,79 @@
import request from '@/utils/request'
import type { AxiosPromise } from 'axios'
import type { CwProjectPerformanceSelfEvaluationVO, CwProjectPerformanceSelfEvaluationQuery } from './performanceEvaluation'
/**
* 运行监控管理API
* 财务管理员和学校领导使用,用于查看所有人提交的绩效自评,并进行锁定/解锁操作
*/
/**
* 运行监控管理查询对象
*/
export interface MonitoringManagementQuery extends CwProjectPerformanceSelfEvaluationQuery {
isLocked?: number
}
/**
* 查询绩效自评列表(运行监控管理)
*/
export function listMonitoringManagement(query: MonitoringManagementQuery): AxiosPromise<any> {
return request({
url: '/cw/monitoringManagement/list',
method: 'get',
params: query
})
}
/**
* 查询绩效自评详细(运行监控管理)
*/
export function getMonitoringManagement(id: number): AxiosPromise<CwProjectPerformanceSelfEvaluationVO> {
return request({
url: `/cw/monitoringManagement/${id}`,
method: 'get'
})
}
/**
* 锁定绩效自评(单个)
*/
export function lockEvaluation(id: number): AxiosPromise<any> {
return request({
url: `/cw/monitoringManagement/lock/${id}`,
method: 'post'
})
}
/**
* 解锁绩效自评(单个)
*/
export function unlockEvaluation(id: number): AxiosPromise<any> {
return request({
url: `/cw/monitoringManagement/unlock/${id}`,
method: 'post'
})
}
/**
* 批量锁定绩效自评
*/
export function lockBatchEvaluation(ids: number[]): AxiosPromise<any> {
return request({
url: '/cw/monitoringManagement/lock/batch',
method: 'post',
data: ids
})
}
/**
* 批量解锁绩效自评
*/
export function unlockBatchEvaluation(ids: number[]): AxiosPromise<any> {
return request({
url: '/cw/monitoringManagement/unlock/batch',
method: 'post',
data: ids
})
}
+629
View File
@@ -0,0 +1,629 @@
import request from '@/utils/request'
import type { AxiosPromise } from 'axios'
// ========== 绩效自评API ==========
/**
* 项目绩效自评视图对象
*/
export interface CwProjectPerformanceSelfEvaluationVO {
id?: number
tenantId?: string
projectApplicationId: number
applicationNo: string
projectName: string
supervisoryDept?: string
implementUnit?: string
evaluationYear: number
initialBudget?: number
principal?: string
contactPhone?: string
startDate?: string
endDate?: string
totalInvestment?: number
annualBudget?: number
actualExpenditure?: number
budgetExecutionRate?: number
// 资金到位(年度资金总额)
fundValue?: number
fundExecutionRate?: number
fundScore?: number
// 当年财政拨款
currentYearBudgetInitial?: number
currentYearBudgetAnnual?: number
currentYearBudgetActual?: number
currentYearBudgetValue?: number
currentYearBudgetExecutionRate?: number
currentYearBudgetScore?: number
// 上年结转资金
lastYearCarryoverInitial?: number
lastYearCarryoverAnnual?: number
lastYearCarryoverActual?: number
lastYearCarryoverValue?: number
lastYearCarryoverExecutionRate?: number
lastYearCarryoverScore?: number
// 其他资金
otherFundsInitial?: number
otherFundsAnnual?: number
otherFundsActual?: number
otherFundsValue?: number
otherFundsExecutionRate?: number
otherFundsScore?: number
performanceGoal?: string
targetCompletion?: string
// 数量指标
quantityIndicator?: string
quantityTarget?: string
quantityActual?: string
quantityValue?: number
quantityScore?: number
quantityDeviation?: string
// 质量指标
qualityIndicator?: string
qualityTarget?: string
qualityActual?: string
qualityValue?: number
qualityScore?: number
qualityDeviation?: string
// 时效指标
timelinessIndicator?: string
timelinessTarget?: string
timelinessActual?: string
timelinessValue?: number
timelinessScore?: number
timelinessDeviation?: string
// 成本指标
costIndicator?: string
costTarget?: string
costActual?: string
costValue?: number
costScore?: number
costDeviation?: string
// 经济效益指标
economicIndicator?: string
economicTarget?: string
economicActual?: string
economicValue?: number
economicScore?: number
economicDeviation?: string
// 社会效益指标
socialIndicator?: string
socialTarget?: string
socialActual?: string
socialValue?: number
socialScore?: number
socialDeviation?: string
// 生态效益指标
ecologicalIndicator?: string
ecologicalTarget?: string
ecologicalActual?: string
ecologicalValue?: number
ecologicalScore?: number
ecologicalDeviation?: string
// 满意度指标
satisfactionIndicator?: string
satisfactionTarget?: string
satisfactionActual?: string
satisfactionValue?: number
satisfactionScore?: number
satisfactionDeviation?: string
decisionScore?: number
decisionContent?: string
processScore?: number
processContent?: string
outputScore?: number
outputContent?: string
benefitScore?: number
benefitContent?: string
totalScore?: number
selfEvaluationLevel?: string
existingProblems?: string
improvementMeasures?: string
evaluationStatus: string
allowEditAfterSubmit?: number
submitTime?: string
submitBy?: number
submitByName?: string
approveTime?: string
approveBy?: number
approveByName?: string
approveOpinion?: string
remark?: string
// 锁定相关字段
isLocked?: number
lockTime?: string
lockBy?: number
lockByName?: string
createTime?: string
updateTime?: string
// 前端使用的字段,用于标记是否有运行监控数据
hasMonitoringData?: boolean
// 运行监控数据列表
monitoringList?: CwPerformanceMonitoringVO[]
}
/**
* 项目绩效自评表单对象
*/
export interface CwProjectPerformanceSelfEvaluationForm {
id?: number
projectApplicationId: number
applicationNo?: string
projectName: string
supervisoryDept?: string
implementUnit?: string
evaluationYear: number
initialBudget?: number
principal?: string
contactPhone?: string
startDate?: string
endDate?: string
totalInvestment?: number
annualBudget?: number
actualExpenditure?: number
budgetExecutionRate?: number
// 资金到位(年度资金总额)
fundValue?: number
fundExecutionRate?: number
fundScore?: number
// 当年财政拨款
currentYearBudgetInitial?: number
currentYearBudgetAnnual?: number
currentYearBudgetActual?: number
currentYearBudgetValue?: number
currentYearBudgetExecutionRate?: number
currentYearBudgetScore?: number
// 上年结转资金
lastYearCarryoverInitial?: number
lastYearCarryoverAnnual?: number
lastYearCarryoverActual?: number
lastYearCarryoverValue?: number
lastYearCarryoverExecutionRate?: number
lastYearCarryoverScore?: number
// 其他资金
otherFundsInitial?: number
otherFundsAnnual?: number
otherFundsActual?: number
otherFundsValue?: number
otherFundsExecutionRate?: number
otherFundsScore?: number
performanceGoal?: string
targetCompletion?: string
// 数量指标
quantityIndicator?: string
quantityTarget?: string
quantityActual?: string
quantityValue?: number
quantityScore?: number
quantityDeviation?: string
// 质量指标
qualityIndicator?: string
qualityTarget?: string
qualityActual?: string
qualityValue?: number
qualityScore?: number
qualityDeviation?: string
// 时效指标
timelinessIndicator?: string
timelinessTarget?: string
timelinessActual?: string
timelinessValue?: number
timelinessScore?: number
timelinessDeviation?: string
// 成本指标
costIndicator?: string
costTarget?: string
costActual?: string
costValue?: number
costScore?: number
costDeviation?: string
// 经济效益指标
economicIndicator?: string
economicTarget?: string
economicActual?: string
economicValue?: number
economicScore?: number
economicDeviation?: string
// 社会效益指标
socialIndicator?: string
socialTarget?: string
socialActual?: string
socialValue?: number
socialScore?: number
socialDeviation?: string
// 生态效益指标
ecologicalIndicator?: string
ecologicalTarget?: string
ecologicalActual?: string
ecologicalValue?: number
ecologicalScore?: number
ecologicalDeviation?: string
// 满意度指标
satisfactionIndicator?: string
satisfactionTarget?: string
satisfactionActual?: string
satisfactionValue?: number
satisfactionScore?: number
satisfactionDeviation?: string
decisionScore?: number
decisionContent?: string
processScore?: number
processContent?: string
outputScore?: number
outputContent?: string
benefitScore?: number
benefitContent?: string
totalScore?: number
selfEvaluationLevel?: string
existingProblems?: string
improvementMeasures?: string
evaluationStatus?: string
remark?: string
}
/**
* 项目绩效自评查询对象
*/
export interface CwProjectPerformanceSelfEvaluationQuery {
pageNum?: number
pageSize?: number
projectApplicationId?: number
applicationNo?: string
projectName?: string
evaluationYear?: number
evaluationStatus?: string
selfEvaluationLevel?: string
}
/**
* 查询项目绩效自评列表
*/
export function listEvaluation(query: CwProjectPerformanceSelfEvaluationQuery): AxiosPromise<any> {
return request({
url: '/cw/evaluation/list',
method: 'get',
params: query
})
}
/**
* 查询项目绩效自评详细
*/
export function getEvaluation(id: number): AxiosPromise<CwProjectPerformanceSelfEvaluationVO> {
return request({
url: `/cw/evaluation/${id}`,
method: 'get'
})
}
/**
* 新增项目绩效自评
*/
export function addEvaluation(data: CwProjectPerformanceSelfEvaluationForm): AxiosPromise<any> {
return request({
url: '/cw/evaluation',
method: 'post',
data
})
}
/**
* 修改项目绩效自评
*/
export function updateEvaluation(data: CwProjectPerformanceSelfEvaluationForm): AxiosPromise<any> {
return request({
url: '/cw/evaluation',
method: 'put',
data
})
}
/**
* 保存自评草稿
*/
export function saveDraft(data: CwProjectPerformanceSelfEvaluationForm): AxiosPromise<any> {
return request({
url: '/cw/evaluation/saveDraft',
method: 'post',
data
})
}
/**
* 提交自评
*/
export function submitEvaluation(id: number): AxiosPromise<any> {
return request({
url: `/cw/evaluation/submit/${id}`,
method: 'post'
})
}
/**
* 审核自评
*/
export function approveEvaluation(id: number, opinion: string, approved: boolean): AxiosPromise<any> {
return request({
url: `/cw/evaluation/approve/${id}`,
method: 'post',
params: { opinion, approved }
})
}
/**
* 删除项目绩效自评
*/
export function delEvaluation(ids: number | number[]): AxiosPromise<any> {
return request({
url: `/cw/evaluation/${ids}`,
method: 'delete'
})
}
/**
* 查询我的自评列表
*/
export function getMyEvaluations(): AxiosPromise<CwProjectPerformanceSelfEvaluationVO[]> {
return request({
url: '/cw/evaluation/my',
method: 'get'
})
}
/**
* 查询待审核自评列表
*/
export function getPendingApprovals(): AxiosPromise<CwProjectPerformanceSelfEvaluationVO[]> {
return request({
url: '/cw/evaluation/pending',
method: 'get'
})
}
/**
* 导出项目绩效自评
*/
export function exportEvaluation(query: CwProjectPerformanceSelfEvaluationQuery): AxiosPromise<any> {
return request({
url: '/cw/evaluation/export',
method: 'post',
data: query,
responseType: 'blob'
})
}
// ========== 月度运行监控API ==========
/**
* 项目月度运行监控视图对象
*/
export interface CwProjectMonthlyMonitoringVO {
id?: number
evaluationId: number
projectApplicationId: number
monitoringYear: number
monitoringMonth: number
plannedProgress?: number
actualProgress?: number
progressVariance?: number
monthlyBudget?: number
monthlyExpenditure?: number
cumulativeBudget?: number
cumulativeExpenditure?: number
fundExecutionRate?: number
keyMilestones?: string
milestoneCompletion?: string
problemsEncountered?: string
riskDescription?: string
countermeasures?: string
nextMonthPlan?: string
fillStatus: string
fillTime?: string
fillBy?: number
fillByName?: string
remark?: string
createTime?: string
updateTime?: string
}
/**
* 项目月度运行监控表单对象
*/
export interface CwProjectMonthlyMonitoringForm {
id?: number
evaluationId: number
projectApplicationId: number
monitoringYear: number
monitoringMonth: number
plannedProgress?: number
actualProgress?: number
progressVariance?: number
monthlyBudget?: number
monthlyExpenditure?: number
cumulativeBudget?: number
cumulativeExpenditure?: number
fundExecutionRate?: number
keyMilestones?: string
milestoneCompletion?: string
problemsEncountered?: string
riskDescription?: string
countermeasures?: string
nextMonthPlan?: string
fillStatus?: string
remark?: string
}
/**
* 查询某个自评的全年监控数据
*/
export function getYearlyMonitoring(evaluationId: number, year: number): AxiosPromise<Record<number, CwProjectMonthlyMonitoringVO>> {
return request({
url: `/cw/monitoring/year/${evaluationId}/${year}`,
method: 'get'
})
}
/**
* 根据自评ID查询月度监控列表
*/
export function getMonitoringByEvaluationId(evaluationId: number): AxiosPromise<CwProjectMonthlyMonitoringVO[]> {
return request({
url: `/cw/monitoring/evaluation/${evaluationId}`,
method: 'get'
})
}
/**
* 填报月度数据
*/
export function fillMonthlyData(data: CwProjectMonthlyMonitoringForm): AxiosPromise<any> {
return request({
url: '/cw/monitoring/fill',
method: 'post',
data
})
}
/**
* 批量保存月度数据
*/
export function batchSaveMonitoring(evaluationId: number, list: CwProjectMonthlyMonitoringForm[]): AxiosPromise<any> {
return request({
url: '/cw/monitoring/batch',
method: 'post',
data: {
evaluationId,
list
}
})
}
/**
* 修改月度监控
*/
export function updateMonitoring(data: CwProjectMonthlyMonitoringForm): AxiosPromise<any> {
return request({
url: '/cw/monitoring',
method: 'put',
data
})
}
// ========== 绩效运行监控API ==========
/**
* 绩效运行监控视图对象
*/
export interface CwPerformanceMonitoringVO {
id?: number
evaluationId: number
monitoringPeriod: string
fundUsage: string
performanceTargetCompletion: string
indicators?: string // JSON字符串,存储指标数组
existingProblems?: string
indicatorVarianceAnalysis?: string
nextStepSuggestions?: string
fillBy?: number
fillByName?: string
createTime?: string
updateTime?: string
}
/**
* 绩效运行监控表单数据结构
*/
export interface PerformanceMonitoringForm {
id?: number
evaluationId: number
monitoringPeriod: string
fundUsage: string
performanceTargetCompletion: string
indicators: string // JSON字符串,存储指标数组
existingProblems?: string
indicatorVarianceAnalysis?: string
nextStepSuggestions?: string
fillByName?: string
createTime?: string
}
/**
* 查询绩效运行监控列表
*/
export function listPerformanceMonitoring(evaluationId: number): AxiosPromise<PerformanceMonitoringForm[]> {
return request({
url: `/cw/performanceMonitoring/list/${evaluationId}`,
method: 'get'
})
}
/**
* 获取绩效运行监控详情
*/
export function getPerformanceMonitoring(id: number): AxiosPromise<PerformanceMonitoringForm> {
return request({
url: `/cw/performanceMonitoring/${id}`,
method: 'get'
})
}
/**
* 新增绩效运行监控
*/
export function addPerformanceMonitoring(data: PerformanceMonitoringForm): AxiosPromise<any> {
return request({
url: '/cw/performanceMonitoring',
method: 'post',
data
})
}
/**
* 修改绩效运行监控
*/
export function updatePerformanceMonitoring(data: PerformanceMonitoringForm): AxiosPromise<any> {
return request({
url: '/cw/performanceMonitoring',
method: 'put',
data
})
}
/**
* 删除绩效运行监控
*/
export function delPerformanceMonitoring(id: number): AxiosPromise<any> {
return request({
url: `/cw/performanceMonitoring/${id}`,
method: 'delete'
})
}
+202
View File
@@ -0,0 +1,202 @@
/* 社团管理通用样式 - 参考后勤管理模块 */
/* 页面容器 */
.page-container {
height: 100%;
display: flex;
flex-direction: column;
}
/* 搜索按钮容器 */
.search-btn-container {
display: flex;
justify-content: flex-end;
padding-top: 10px;
}
/* 卡片样式 */
.button-card,
.table-card {
border-radius: 8px;
border: 1px solid #e4e7ed;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
margin-bottom: 16px;
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
}
}
.button-card {
:deep(.el-card__body) {
padding: 16px !important;
}
}
.table-card {
:deep(.el-card__body) {
padding: 0 !important;
}
}
/* 表格容器 */
.table-container {
width: 100%;
}
/* 表格样式 */
.scroll-table {
:deep(.el-table__header-wrapper) {
.el-table__header {
th {
background-color: #f8f9fa;
color: #333;
font-weight: 600;
}
}
}
:deep(.el-table__body-wrapper) {
.el-table__row {
&:hover {
background-color: #f5f7fa;
}
}
}
}
/* 统计卡片样式 */
.stat-card {
border-radius: 8px;
transition: all 0.3s ease;
height: 90px;
&:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
}
.stat-content {
display: flex;
align-items: center;
padding: 5px 12px;
height: 100%;
box-sizing: border-box;
.stat-icon {
font-size: 24px;
margin-right: 12px;
opacity: 0.8;
}
.stat-info {
flex: 1;
.stat-value {
font-size: 20px;
font-weight: bold;
line-height: 1;
margin-bottom: 3px;
}
.stat-label {
font-size: 13px;
opacity: 0.7;
line-height: 1;
}
}
}
&.stat-card-primary {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
&.stat-card-success {
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
color: white;
}
&.stat-card-warning {
background: linear-gradient(135deg, #ff9a56 0%, #ffad56 100%);
color: white;
}
&.stat-card-info {
background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
color: #333;
}
}
/* 分页容器样式 */
.pagination-container {
display: flex;
justify-content: flex-end;
padding: 16px 20px 0 0 !important;
background-color: #fff;
margin-top: 0px !important;
}
/* 移除按钮栏底部边框 */
.button-card :deep(.el-card__header) {
border-bottom: none !important;
}
/* 工具栏标题样式 */
.toolbar-title {
font-size: 16px;
font-weight: 600;
color: #303133;
line-height: 32px;
}
/* 操作按钮样式 */
.action-buttons {
display: flex;
gap: 8px;
justify-content: center;
align-items: center;
white-space: nowrap;
}
/* 确保操作按钮宽度一致 */
.action-buttons .el-button {
width: 27px !important;
height: 27px !important;
padding: 0 !important;
display: flex;
align-items: center;
justify-content: center;
}
/* 对话框样式 */
.dialog-footer-right {
display: flex;
justify-content: flex-end;
gap: 10px;
}
/* 信息框样式 */
.info-box {
width: 100%;
box-sizing: border-box;
background-color: #f8f9fa;
padding: 16px;
border-radius: 8px;
border-left: 4px solid #409eff;
p {
margin: 8px 0;
line-height: 1.5;
&:first-child {
margin-top: 0;
}
&:last-child {
margin-bottom: 0;
}
}
}
@@ -0,0 +1,668 @@
<template>
<el-dialog
v-model="dialogVisible"
:title="dialogTitle"
width="95%"
top="5vh"
:close-on-click-modal="false"
destroy-on-close
>
<!-- 运行监控数据列表 -->
<div class="monitoring-list" v-if="!showForm">
<div class="list-header">
<el-button
type="primary"
icon="Plus"
@click="handleAdd"
v-hasPermi="['cw:monitoring:fill']"
>新增运行监控</el-button>
</div>
<el-table
:data="monitoringList"
border
style="width: 100%; margin-top: 15px;"
>
<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" />
<el-table-column label="填报人" align="center" prop="fillByName" width="120" />
<el-table-column label="资金使用情况" align="center" prop="fundUsage" show-overflow-tooltip min-width="200" />
<el-table-column label="操作" align="center" width="200" fixed="right">
<template #default="scope">
<el-button
link
type="primary"
icon="View"
@click="handleView(scope.row)"
>查看</el-button>
<el-button
link
type="primary"
icon="Edit"
@click="handleEdit(scope.row)"
v-hasPermi="['cw:monitoring:edit']"
>编辑</el-button>
<el-button
link
type="danger"
icon="Delete"
@click="handleDelete(scope.row)"
v-hasPermi="['cw:monitoring:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
<!-- 运行监控表单 -->
<div class="monitoring-form" v-else>
<el-form
ref="monitoringFormRef"
:model="formData"
:rules="rules"
label-width="150px"
:disabled="formMode === 'view'"
>
<!-- 项目基本信息 -->
<div class="table-section">
<div class="section-title">
<h3>绩效运行监控表(20**年度 1-6 月)</h3>
</div>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="项目名称">
<el-input v-model="projectInfo.projectName" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目性质">
<el-input v-model="projectInfo.projectNature" disabled />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="监控周期" prop="monitoringPeriod">
<div style="display: flex; align-items: center; gap: 10px;">
<el-select
v-model="formData.startMonth"
placeholder="起始月份"
style="width: 120px"
@change="updateMonitoringPeriod"
>
<el-option
v-for="month in 12"
:key="month"
:label="`${month}月`"
:value="month"
/>
</el-select>
<span>至</span>
<el-select
v-model="formData.endMonth"
placeholder="结束月份"
style="width: 120px"
@change="updateMonitoringPeriod"
>
<el-option
v-for="month in 12"
:key="month"
:label="`${month}月`"
:value="month"
/>
</el-select>
<span style="color: #909399; margin-left: 10px;">
{{ formData.monitoringPeriod || '请选择监控周期' }}
</span>
</div>
</el-form-item>
</el-col>
</el-row>
</div>
<!-- 项目概况 -->
<div class="table-section">
<div class="section-title">
<h4>项目概况</h4>
</div>
<el-form-item label="资金使用情况" prop="fundUsage">
<el-input
v-model="formData.fundUsage"
type="textarea"
:rows="3"
placeholder="请描述资金使用情况"
/>
</el-form-item>
<el-form-item label="绩效目标完成情况" prop="performanceTargetCompletion">
<el-input
v-model="formData.performanceTargetCompletion"
type="textarea"
:rows="3"
placeholder="请描述绩效目标完成情况"
/>
</el-form-item>
</div>
<!-- 绩效指标完成情况 -->
<div class="table-section">
<div class="section-title">
<h4>绩效指标完成情况</h4>
</div>
<div class="indicator-table">
<el-button
type="primary"
icon="Plus"
size="small"
@click="addIndicatorRow"
v-if="formMode !== 'view'"
style="margin-bottom: 10px"
>添加指标</el-button>
<el-table
:data="formData.indicators"
border
style="width: 100%"
max-height="400"
>
<el-table-column label="一级指标" align="center" width="120">
<template #default="scope">
<el-select
v-model="scope.row.level1Indicator"
placeholder="请选择"
style="width: 100%"
>
<el-option label="产出指标" value="产出指标" />
<el-option label="效益指标" value="效益指标" />
<el-option label="满意度指标" value="满意度指标" />
</el-select>
</template>
</el-table-column>
<el-table-column label="二级指标" align="center" width="120">
<template #default="scope">
<el-select
v-model="scope.row.level2Indicator"
placeholder="请选择"
style="width: 100%"
>
<template v-if="scope.row.level1Indicator === '产出指标'">
<el-option label="数量指标" value="数量指标" />
<el-option label="质量指标" value="质量指标" />
<el-option label="时效指标" value="时效指标" />
<el-option label="成本指标" value="成本指标" />
</template>
<template v-else-if="scope.row.level1Indicator === '效益指标'">
<el-option label="经济效益指标" value="经济效益指标" />
<el-option label="社会效益指标" value="社会效益指标" />
<el-option label="生态效益指标" value="生态效益指标" />
<el-option label="可持续性指标" value="可持续性指标" />
</template>
<template v-else-if="scope.row.level1Indicator === '满意度指标'">
<el-option label="服务对象满意度指标" value="服务对象满意度指标" />
</template>
</el-select>
</template>
</el-table-column>
<el-table-column label="指标名称" align="center" min-width="150">
<template #default="scope">
<el-input v-model="scope.row.indicatorName" placeholder="请输入" />
</template>
</el-table-column>
<el-table-column label="年度预期值" align="center" width="120">
<template #default="scope">
<el-input v-model="scope.row.annualExpectedValue" placeholder="请输入" />
</template>
</el-table-column>
<el-table-column :label="completedValueLabel" align="center" width="130">
<template #default="scope">
<el-input v-model="scope.row.completedValue" placeholder="请输入" />
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="80" v-if="formMode !== 'view'">
<template #default="scope">
<el-button
link
type="danger"
icon="Delete"
@click="removeIndicatorRow(scope.$index)"
>删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
<!-- 绩效运行分析 -->
<div class="table-section">
<div class="section-title">
<h4>绩效运行分析</h4>
</div>
<el-form-item label="存在问题">
<el-input
v-model="formData.existingProblems"
type="textarea"
:rows="3"
placeholder="请输入存在的问题"
/>
</el-form-item>
<el-form-item label="指标差异率分析">
<el-input
v-model="formData.indicatorVarianceAnalysis"
type="textarea"
:rows="3"
placeholder="请输入指标差异率分析和说明"
/>
</el-form-item>
<el-form-item label="下一步工作建议">
<el-input
v-model="formData.nextStepSuggestions"
type="textarea"
:rows="3"
placeholder="请输入下一步工作建议和打算"
/>
</el-form-item>
</div>
</el-form>
<!-- 表单操作按钮 -->
<div class="form-footer" v-if="formMode !== 'view'">
<el-button @click="cancelForm">取消</el-button>
<el-button type="primary" @click="submitForm">保存</el-button>
</div>
<div class="form-footer" v-else>
<el-button @click="cancelForm">关闭</el-button>
</div>
</div>
<template #footer v-if="!showForm">
<el-button @click="closeDialog">关闭</el-button>
</template>
</el-dialog>
</template>
<script setup lang="ts" name="MonitoringDialog">
import { ref, reactive, computed, getCurrentInstance, ComponentInternalInstance } from 'vue'
import type { FormInstance, FormRules } from 'element-plus'
import { getEvaluation, listPerformanceMonitoring, getPerformanceMonitoring, addPerformanceMonitoring, updatePerformanceMonitoring, delPerformanceMonitoring } from '@/api/cw/performanceEvaluation'
import type { PerformanceMonitoringForm } from '@/api/cw/performanceEvaluation'
const { proxy } = getCurrentInstance() as ComponentInternalInstance
// ========== 对话框状态 ==========
const dialogVisible = ref(false)
const dialogTitle = ref('运行监控管理')
const showForm = ref(false)
const formMode = ref<'add' | 'edit' | 'view'>('add')
// ========== 项目信息 ==========
const projectInfo = ref({
projectName: '',
projectNature: '',
evaluationId: 0
})
// ========== 监控数据列表 ==========
const monitoringList = ref<any[]>([])
// ========== 表单数据 ==========
interface IndicatorRow {
level1Indicator: string
level2Indicator: string
indicatorName: string
annualExpectedValue: string
completedValue: string
}
interface MonitoringFormData {
id?: number
evaluationId?: number
startMonth?: number
endMonth?: number
monitoringPeriod: string
fundUsage: string
performanceTargetCompletion: string
indicators: IndicatorRow[]
existingProblems: string
indicatorVarianceAnalysis: string
nextStepSuggestions: string
}
const defaultFormData: MonitoringFormData = {
startMonth: undefined,
endMonth: undefined,
monitoringPeriod: '',
fundUsage: '',
performanceTargetCompletion: '',
indicators: [],
existingProblems: '',
indicatorVarianceAnalysis: '',
nextStepSuggestions: ''
}
const formData = ref<MonitoringFormData>({ ...defaultFormData })
const monitoringFormRef = ref<FormInstance>()
// ========== 表单验证规则 ==========
const rules = reactive<FormRules>({
monitoringPeriod: [
{ required: true, message: '请输入监控周期', trigger: 'blur' }
],
fundUsage: [
{ required: true, message: '请输入资金使用情况', trigger: 'blur' }
],
performanceTargetCompletion: [
{ required: true, message: '请输入绩效目标完成情况', trigger: 'blur' }
]
})
// ========== 计算属性 ==========
/** 完成值列标题 */
const completedValueLabel = computed(() => {
if (formData.value.startMonth && formData.value.endMonth) {
return `${formData.value.startMonth}至${formData.value.endMonth}月份完成值`
}
return '完成值'
})
// ========== 监控周期相关方法 ==========
/** 更新监控周期 */
function updateMonitoringPeriod() {
const currentYear = new Date().getFullYear()
if (formData.value.startMonth && formData.value.endMonth) {
formData.value.monitoringPeriod = `${currentYear}年度${formData.value.startMonth}-${formData.value.endMonth}月`
} else {
formData.value.monitoringPeriod = ''
}
}
/** 从监控周期字符串解析起止月份 */
function parseMonitoringPeriod(period: string) {
if (!period) return
// 匹配格式:2024年度1-6月
const match = period.match(/(\d+)年度(\d+)-(\d+)月/)
if (match) {
formData.value.startMonth = parseInt(match[2])
formData.value.endMonth = parseInt(match[3])
}
}
// ========== 指标表格操作 ==========
/** 添加指标行 */
function addIndicatorRow() {
formData.value.indicators.push({
level1Indicator: '',
level2Indicator: '',
indicatorName: '',
annualExpectedValue: '',
completedValue: ''
})
}
/** 删除指标行 */
function removeIndicatorRow(index: number) {
formData.value.indicators.splice(index, 1)
}
// ========== 对外暴露方法 ==========
/** 打开对话框 */
async function open(evaluationId: number) {
dialogVisible.value = true
showForm.value = false
// 加载项目信息
const response = await getEvaluation(evaluationId)
projectInfo.value = {
projectName: response.data.projectName || '',
projectNature: response.data.projectNature || '',
evaluationId: evaluationId
}
// 加载运行监控数据列表
loadMonitoringList(evaluationId)
}
/** 加载监控数据列表 */
async function loadMonitoringList(evaluationId: number) {
try {
const response = await listPerformanceMonitoring(evaluationId)
monitoringList.value = response.data.map((item: PerformanceMonitoringForm) => {
// 解析JSON字符串为对象
return {
...item,
indicators: item.indicators ? JSON.parse(item.indicators) : []
}
})
} catch (error) {
console.error('加载运行监控数据失败:', error)
monitoringList.value = []
}
}
/** 新增运行监控 */
function handleAdd() {
formMode.value = 'add'
formData.value = {
...defaultFormData,
evaluationId: projectInfo.value.evaluationId,
indicators: []
}
showForm.value = true
}
/** 编辑运行监控 */
function handleEdit(row: any) {
formMode.value = 'edit'
formData.value = { ...row }
if (!formData.value.indicators || !Array.isArray(formData.value.indicators)) {
formData.value.indicators = []
}
// 解析监控周期,回显起止月份
parseMonitoringPeriod(formData.value.monitoringPeriod)
showForm.value = true
}
/** 查看运行监控 */
function handleView(row: any) {
formMode.value = 'view'
formData.value = { ...row }
if (!formData.value.indicators || !Array.isArray(formData.value.indicators)) {
formData.value.indicators = []
}
// 解析监控周期,回显起止月份
parseMonitoringPeriod(formData.value.monitoringPeriod)
showForm.value = true
}
/** 删除运行监控 */
function handleDelete(row: any) {
proxy?.$modal.confirm('确认删除该运行监控数据吗?').then(async () => {
try {
await delPerformanceMonitoring(row.id)
proxy?.$modal.msgSuccess('删除成功')
loadMonitoringList(projectInfo.value.evaluationId)
} catch (error) {
console.error('删除失败:', error)
}
}).catch(() => {})
}
/** 提交表单 */
function submitForm() {
monitoringFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
try {
// 准备提交数据,将indicators数组转换为JSON字符串
const data: PerformanceMonitoringForm = {
...formData.value,
evaluationId: projectInfo.value.evaluationId,
indicators: JSON.stringify(formData.value.indicators)
}
if (formMode.value === 'add') {
await addPerformanceMonitoring(data)
proxy?.$modal.msgSuccess('新增成功')
} else {
await updatePerformanceMonitoring(data)
proxy?.$modal.msgSuccess('修改成功')
}
cancelForm()
loadMonitoringList(projectInfo.value.evaluationId)
} catch (error) {
console.error('保存失败:', error)
}
}
})
}
/** 取消表单 */
function cancelForm() {
showForm.value = false
formData.value = { ...defaultFormData }
}
/** 关闭对话框 */
function closeDialog() {
dialogVisible.value = false
}
/** 查看单条运行监控数据详情 */
async function viewDetail(monitoringId: number, evaluationId: number) {
dialogVisible.value = true
showForm.value = true
formMode.value = 'view'
// 加载项目信息
const response = await getEvaluation(evaluationId)
projectInfo.value = {
projectName: response.data.projectName || '',
projectNature: response.data.projectNature || '',
evaluationId: evaluationId
}
// 加载运行监控数据详情
try {
const monitoringResponse = await getPerformanceMonitoring(monitoringId)
const data = monitoringResponse.data
formData.value = { ...data }
// 处理indicators字段:如果是JSON字符串,需要解析为数组
if (data.indicators) {
if (typeof data.indicators === 'string') {
try {
formData.value.indicators = JSON.parse(data.indicators)
} catch (e) {
console.error('解析indicators失败:', e)
formData.value.indicators = []
}
} else if (Array.isArray(data.indicators)) {
formData.value.indicators = data.indicators
} else {
formData.value.indicators = []
}
} else {
formData.value.indicators = []
}
// 解析监控周期,回显起止月份
parseMonitoringPeriod(formData.value.monitoringPeriod)
} catch (error) {
console.error('加载运行监控详情失败:', error)
proxy?.$modal.msgError('加载运行监控详情失败')
}
}
// 暴露方法给父组件
defineExpose({
open,
viewDetail
})
</script>
<style scoped lang="scss">
.monitoring-list {
padding: 10px;
.list-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
}
}
.monitoring-form {
max-height: 70vh;
overflow-y: auto;
padding: 20px;
}
.table-section {
margin-bottom: 30px;
border: 1px solid #dcdfe6;
border-radius: 4px;
padding: 20px;
background-color: #f9f9f9;
.section-title {
margin-bottom: 20px;
padding-bottom: 10px;
border-bottom: 2px solid #409eff;
h3 {
margin: 0;
font-size: 18px;
font-weight: bold;
color: #303133;
text-align: center;
}
h4 {
margin: 0;
font-size: 16px;
font-weight: bold;
color: #606266;
}
}
}
.indicator-table {
margin-top: 15px;
}
.form-footer {
display: flex;
justify-content: center;
gap: 20px;
margin-top: 30px;
padding-top: 20px;
border-top: 1px solid #dcdfe6;
}
:deep(.el-form-item__label) {
font-weight: 500;
}
:deep(.el-table) {
font-size: 14px;
}
:deep(.el-input__inner) {
font-size: 14px;
}
</style>
+1000
View File
@@ -0,0 +1,1000 @@
<template>
<div class="p-2 page-container">
<!-- 搜索区域 -->
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover">
<el-form :model="queryParams" ref="queryFormRef" label-width="100px">
<el-row :gutter="20">
<el-col :span="6">
<el-form-item label="项目名称" prop="projectName">
<el-input v-model="queryParams.projectName" placeholder="请输入项目名称" clearable @keyup.enter="handleQuery" />
</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-col>
<el-col :span="6">
<el-form-item label="自评状态" prop="evaluationStatus">
<el-select v-model="queryParams.evaluationStatus" placeholder="请选择自评状态" clearable style="width: 100%">
<el-option label="草稿" value="draft" />
<el-option label="已提交" value="submitted" />
<el-option label="已审核" value="approved" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="自评等级" prop="selfEvaluationLevel">
<el-select v-model="queryParams.selfEvaluationLevel" placeholder="请选择自评等级" clearable style="width: 100%">
<el-option label="优秀" value="优秀" />
<el-option label="良好" value="良好" />
<el-option label="合格" value="合格" />
<el-option label="不合格" 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-col>
</el-row>
</el-form>
</el-card>
</div>
</transition>
<!-- 表格区域 -->
<el-card shadow="never" class="button-card table-card">
<template #header>
<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-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>
</template>
<div class="table-container">
<el-table
v-loading="loading"
border
:data="evaluationList"
@selection-change="handleSelectionChange"
style="width: 100%"
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-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">
<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>
<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">
<el-icon><Lock /></el-icon> 已锁定
</el-tag>
<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" width="320" fixed="right" class-name="small-padding fixed-width">
<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="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>
</div>
<!-- 分页组件 -->
<div class="pagination-container">
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
</div>
</el-card>
<!-- 新增/编辑/查看弹窗 - 使用表格样式 -->
<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;"
>
<template #title>
<span>该绩效自评已锁定,不允许修改。锁定时间:{{ formData.lockTime ? parseTime(formData.lockTime) : '-' }},锁定人:{{ formData.lockByName || '-' }}</span>
</template>
</el-alert>
<!-- 使用表格样式组件 -->
<TableForm
ref="tableFormRef"
:form-data="formData"
:disabled="dialogMode === 'view' || formData.isLocked === 1"
/>
<!-- 查看详情时显示运行监控数据 -->
<div v-if="dialogMode === 'view'" style="margin-top: 30px;">
<el-divider content-position="left">
<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-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">
<template #default="scope">
<span v-if="scope.row.createTime">{{ proxy.parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}') }}</span>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="填报人" align="center" prop="fillByName" width="120" />
<el-table-column label="资金使用情况" align="center" prop="fundUsage" show-overflow-tooltip min-width="200" />
<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>
</template>
</el-table-column>
</el-table>
<el-empty v-else description="暂无运行监控数据" :image-size="100" />
</div>
<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>
</div>
</template>
</el-dialog>
<!-- 运行监控弹窗 -->
<MonitoringDialog ref="monitoringDialogRef" />
</div>
</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'
const { proxy } = getCurrentInstance() as ComponentInternalInstance
// 加载字典数据
const { cw_evaluation_status } = toRefs<any>(proxy?.useDict('cw_evaluation_status') || {})
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 dialogVisible = ref(false)
const dialogTitle = ref('')
const dialogMode = ref<'add' | 'edit' | 'view'>('add')
const dateRange = ref<string[]>([])
// 表单数据
// 🔧 修复:初始化完整的表单对象,包含所有字段
// Vue 3的响应式系统需要在创建时就定义所有属性,否则后续添加的属性可能不响应
const formData = ref<CwProjectPerformanceSelfEvaluationForm>({
// 基本信息
projectName: '',
evaluationYear: new Date().getFullYear(),
projectApplicationId: 0,
applicationNo: '',
supervisoryDept: '',
implementUnit: '',
principal: '',
contactPhone: '',
startDate: undefined,
endDate: undefined,
// 项目资金
initialBudget: undefined,
annualBudget: undefined,
actualExpenditure: undefined,
fundValue: undefined,
fundExecutionRate: undefined,
fundScore: undefined,
// 当年预算资金
currentYearBudgetInitial: undefined,
currentYearBudgetAnnual: undefined,
currentYearBudgetActual: undefined,
currentYearBudgetValue: undefined,
currentYearBudgetExecutionRate: undefined,
currentYearBudgetScore: undefined,
// 上年结转资金
lastYearCarryoverInitial: undefined,
lastYearCarryoverAnnual: undefined,
lastYearCarryoverActual: undefined,
lastYearCarryoverValue: undefined,
lastYearCarryoverExecutionRate: undefined,
lastYearCarryoverScore: undefined,
// 其他资金
otherFundsInitial: undefined,
otherFundsAnnual: undefined,
otherFundsActual: undefined,
otherFundsValue: undefined,
otherFundsExecutionRate: undefined,
otherFundsScore: undefined,
// 绩效目标
performanceGoal: '',
targetCompletion: '',
// 产出指标
quantityIndicator: '',
quantityTarget: '',
quantityActual: '',
quantityValue: undefined,
quantityScore: undefined,
quantityDeviation: '',
qualityIndicator: '',
qualityTarget: '',
qualityActual: '',
qualityValue: undefined,
qualityScore: undefined,
qualityDeviation: '',
timelinessIndicator: '',
timelinessTarget: '',
timelinessActual: '',
timelinessValue: undefined,
timelinessScore: undefined,
timelinessDeviation: '',
costIndicator: '',
costTarget: '',
costActual: '',
costValue: undefined,
costScore: undefined,
costDeviation: '',
// 效益指标
economicIndicator: '',
economicTarget: '',
economicActual: '',
economicValue: undefined,
economicScore: undefined,
economicDeviation: '',
socialIndicator: '',
socialTarget: '',
socialActual: '',
socialValue: undefined,
socialScore: undefined,
socialDeviation: '',
ecologicalIndicator: '',
ecologicalTarget: '',
ecologicalActual: '',
ecologicalValue: undefined,
ecologicalScore: undefined,
ecologicalDeviation: '',
satisfactionIndicator: '',
satisfactionTarget: '',
satisfactionActual: '',
satisfactionValue: undefined,
satisfactionScore: undefined,
satisfactionDeviation: '',
// 综合评分
decisionScore: 0,
decisionContent: '',
processScore: 0,
processContent: '',
outputScore: 0,
outputContent: '',
benefitScore: 0,
benefitContent: '',
// 总分和等级
totalScore: undefined,
selfEvaluationLevel: '',
// 其他信息
existingProblems: '',
improvementMeasures: '',
evaluationStatus: 'draft',
remark: '',
// 运行监控数据列表(查看详情时返回)
monitoringList: [] as any[]
})
// 表单验证规则
const rules = ref({
projectName: [{ required: true, message: '项目名称不能为空', trigger: 'blur' }],
evaluationYear: [{ required: true, message: '自评年度不能为空', trigger: 'change' }],
decisionScore: [
{ required: true, message: '项目决策得分不能为空', trigger: 'blur' },
{ type: 'number', min: 0, max: 20, message: '得分范围0-20分', trigger: 'blur' }
],
processScore: [
{ required: true, message: '项目过程得分不能为空', trigger: 'blur' },
{ type: 'number', min: 0, max: 20, message: '得分范围0-20分', trigger: 'blur' }
],
outputScore: [
{ required: true, message: '项目产出得分不能为空', trigger: 'blur' },
{ type: 'number', min: 0, max: 30, message: '得分范围0-30分', trigger: 'blur' }
],
benefitScore: [
{ required: true, message: '项目效益得分不能为空', trigger: 'blur' },
{ type: 'number', min: 0, max: 30, message: '得分范围0-30分', trigger: 'blur' }
]
})
const data = reactive<{
queryParams: CwProjectPerformanceSelfEvaluationQuery
}>({
queryParams: {
pageNum: 1,
pageSize: 10,
projectName: undefined,
evaluationYear: undefined,
evaluationStatus: undefined,
selfEvaluationLevel: undefined
}
})
const { queryParams } = toRefs(data)
// 计算总分
const totalScore = computed(() => {
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 evaluationLevel = computed(() => {
const score = totalScore.value
if (score >= 90) return '优秀'
if (score >= 80) return '良好'
if (score >= 60) return '合格'
return '不合格'
})
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 budgetExecutionRate = computed(() => {
if (formData.value.annualBudget && formData.value.actualExpenditure) {
return (formData.value.actualExpenditure / formData.value.annualBudget * 100).toFixed(2)
}
return '0.00'
})
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.annualBudget,
() => formData.value.actualExpenditure
], () => {
if (formData.value.annualBudget && formData.value.actualExpenditure) {
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]
} else {
formData.value.startDate = undefined
formData.value.endDate = undefined
}
}
// 重置表单
function resetForm() {
// 🔧 修复:初始化完整的表单字段对象,确保所有字段都有初始值
// 这样Vue的响应式系统才能正确追踪所有字段的变化
formData.value = {
// 基本信息
projectName: '',
evaluationYear: new Date().getFullYear(),
projectApplicationId: 0,
applicationNo: '',
supervisoryDept: '',
implementUnit: '',
principal: '',
contactPhone: '',
startDate: undefined,
endDate: undefined,
// 项目资金
initialBudget: undefined,
annualBudget: undefined,
actualExpenditure: undefined,
fundValue: undefined,
fundExecutionRate: undefined,
fundScore: undefined,
// 当年预算资金
currentYearBudgetInitial: undefined,
currentYearBudgetAnnual: undefined,
currentYearBudgetActual: undefined,
currentYearBudgetValue: undefined,
currentYearBudgetExecutionRate: undefined,
currentYearBudgetScore: undefined,
// 上年结转资金
lastYearCarryoverInitial: undefined,
lastYearCarryoverAnnual: undefined,
lastYearCarryoverActual: undefined,
lastYearCarryoverValue: undefined,
lastYearCarryoverExecutionRate: undefined,
lastYearCarryoverScore: undefined,
// 其他资金
otherFundsInitial: undefined,
otherFundsAnnual: undefined,
otherFundsActual: undefined,
otherFundsValue: undefined,
otherFundsExecutionRate: undefined,
otherFundsScore: undefined,
// 绩效目标
performanceGoal: '',
targetCompletion: '',
// 产出指标
quantityIndicator: '',
quantityTarget: '',
quantityActual: '',
quantityValue: undefined,
quantityScore: undefined,
quantityDeviation: '',
qualityIndicator: '',
qualityTarget: '',
qualityActual: '',
qualityValue: undefined,
qualityScore: undefined,
qualityDeviation: '',
timelinessIndicator: '',
timelinessTarget: '',
timelinessActual: '',
timelinessValue: undefined,
timelinessScore: undefined,
timelinessDeviation: '',
costIndicator: '',
costTarget: '',
costActual: '',
costValue: undefined,
costScore: undefined,
costDeviation: '',
// 效益指标
economicIndicator: '',
economicTarget: '',
economicActual: '',
economicValue: undefined,
economicScore: undefined,
economicDeviation: '',
socialIndicator: '',
socialTarget: '',
socialActual: '',
socialValue: undefined,
socialScore: undefined,
socialDeviation: '',
ecologicalIndicator: '',
ecologicalTarget: '',
ecologicalActual: '',
ecologicalValue: undefined,
ecologicalScore: undefined,
ecologicalDeviation: '',
satisfactionIndicator: '',
satisfactionTarget: '',
satisfactionActual: '',
satisfactionValue: undefined,
satisfactionScore: undefined,
satisfactionDeviation: '',
// 综合评分
decisionScore: 0,
decisionContent: '',
processScore: 0,
processContent: '',
outputScore: 0,
outputContent: '',
benefitScore: 0,
benefitContent: '',
// 总分和等级
totalScore: undefined,
selfEvaluationLevel: '',
// 其他信息
existingProblems: '',
improvementMeasures: '',
evaluationStatus: 'draft',
remark: ''
}
dateRange.value = []
formRef.value?.resetFields()
}
/** 转换后端返回的字符串数字为真实数字类型 */
function convertNumberFields(data: any) {
if (!data) return data
// 需要转换为数字的字段列表
const numberFields = [
'evaluationYear',
'annualBudget',
'actualExpenditure',
'budgetExecutionRate',
'fundScore',
'quantityScore',
'qualityScore',
'timelinessScore',
'costScore',
'economicScore',
'socialScore',
'ecologicalScore',
'satisfactionScore',
'decisionScore',
'processScore',
'outputScore',
'benefitScore',
'totalScore',
'initialBudget',
'fundValue',
'fundExecutionRate',
'currentYearBudgetInitial',
'currentYearBudgetAnnual',
'currentYearBudgetActual',
'currentYearBudgetValue',
'currentYearBudgetExecutionRate',
'currentYearBudgetScore',
'lastYearCarryoverInitial',
'lastYearCarryoverAnnual',
'lastYearCarryoverActual',
'lastYearCarryoverValue',
'lastYearCarryoverExecutionRate',
'lastYearCarryoverScore',
'otherFundsInitial',
'otherFundsAnnual',
'otherFundsActual',
'otherFundsValue',
'otherFundsExecutionRate',
'otherFundsScore',
'quantityValue',
'qualityValue',
'timelinessValue',
'costValue',
'economicValue',
'socialValue',
'ecologicalValue',
'satisfactionValue'
]
// 转换字段类型:将字符串数字转为真实数字
numberFields.forEach(field => {
if (data[field] !== null && data[field] !== undefined && data[field] !== '') {
// 如果是字符串,转为数字
if (typeof data[field] === 'string') {
data[field] = Number(data[field])
}
}
})
return data
}
/** 查询项目绩效自评列表 */
async function getList() {
loading.value = true
try {
const response = await listEvaluation(queryParams.value)
evaluationList.value = response.rows
// 并行查询所有项目的运行监控数据
const monitoringPromises = evaluationList.value
.filter(item => item.id)
.map(async (item) => {
try {
const monitoringResponse = await listPerformanceMonitoring(item.id!)
// 如果有运行监控数据,设置hasMonitoringData为true;否则为false
item.hasMonitoringData = monitoringResponse.data && monitoringResponse.data.length > 0
} catch (error) {
// 如果查询失败,默认不显示运行监控按钮
item.hasMonitoringData = false
}
})
// 等待所有查询完成
await Promise.all(monitoringPromises)
// 为没有ID的项目设置默认值
evaluationList.value.forEach(item => {
if (!item.id) {
item.hasMonitoringData = false
}
})
total.value = response.total
} catch (error) {
console.error('查询列表失败:', error)
} finally {
loading.value = false
}
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1
getList()
}
/** 重置按钮操作 */
function resetQuery() {
queryFormRef.value?.resetFields()
handleQuery()
}
/** 多选框选中数据 */
function handleSelectionChange(selection: CwProjectPerformanceSelfEvaluationVO[]) {
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 = '新增项目绩效自评'
// 等待下一个tick,确保formData完全初始化后再打开对话框
await nextTick()
dialogVisible.value = true
}
/** 查看按钮操作 */
async function handleView(row: CwProjectPerformanceSelfEvaluationVO) {
resetForm()
dialogMode.value = 'view'
dialogTitle.value = '查看项目绩效自评'
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)
// 🔧 修复:转换后端返回的字符串数字为真实数字类型
formData.value = convertNumberFields(response.data)
// 🔍 调试:打印转换后的数据
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]
}
// 等待下一个tick,确保formData完全更新后再打开对话框
await nextTick()
dialogVisible.value = true
}
/** 修改按钮操作 */
async function handleUpdate(row: CwProjectPerformanceSelfEvaluationVO) {
// 🔒 检查是否已锁定
if (row.isLocked === 1) {
proxy?.$modal.msgWarning('该绩效自评已锁定,不允许修改。如需修改,请联系财务管理员或学校领导解锁')
return
}
resetForm()
dialogMode.value = 'edit'
dialogTitle.value = '编辑项目绩效自评'
const response = await getEvaluation(row.id!)
// 🔧 修复:转换后端返回的字符串数字为真实数字类型
formData.value = convertNumberFields(response.data)
// 🔒 再次检查锁定状态(防止数据被锁定)
if (formData.value.isLocked === 1) {
proxy?.$modal.msgWarning('该绩效自评已锁定,不允许修改。如需修改,请联系财务管理员或学校领导解锁')
return
}
if (response.data.startDate && response.data.endDate) {
dateRange.value = [response.data.startDate, response.data.endDate]
}
// 等待下一个tick,确保formData完全更新后再打开对话框
await nextTick()
dialogVisible.value = true
}
/** 运行监控按钮操作 */
function handleMonitoring(row: CwProjectPerformanceSelfEvaluationVO) {
monitoringDialogRef.value?.open(row.id)
}
/** 查看运行监控详情 */
function handleViewMonitoringDetail(row: any) {
if (!row.id || !row.evaluationId) {
proxy?.$modal.msgError('数据异常,无法查看详情')
return
}
monitoringDialogRef.value?.viewDetail(row.id, row.evaluationId)
}
/** 保存草稿 */
function handleSaveDraft() {
// 🔒 检查是否已锁定
if (formData.value.isLocked === 1) {
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)
}
})
}
/** 提交自评 */
function handleFormSubmit() {
// 🔒 检查是否已锁定
if (formData.value.isLocked === 1) {
proxy?.$modal.msgWarning('该绩效自评已锁定,不允许提交。如需提交,请联系财务管理员或学校领导解锁')
return
}
// 先调用表格表单的分值校验(提示性质,不阻止提交)
if (tableFormRef.value?.validateTotalValue) {
tableFormRef.value.validateTotalValue()
}
// 🔍 调试:打印提交前的完整数据
console.log('=== 提交前的formData.value ===', JSON.stringify(formData.value, null, 2))
console.log('=== 关键字段检查 ===', {
totalScore: formData.value.totalScore,
decisionScore: formData.value.decisionScore,
processScore: formData.value.processScore,
outputScore: formData.value.outputScore,
benefitScore: formData.value.benefitScore,
selfEvaluationLevel: formData.value.selfEvaluationLevel,
budgetExecutionRate: formData.value.budgetExecutionRate
})
// 提交数据(不再需要表单校验,因为是表格式填写)
proxy?.$modal.confirm('确认要提交该自评吗?').then(() => {
const submitData = { ...formData.value }
submitData.evaluationStatus = 'submitted'
// 🔍 调试:打印即将提交的数据
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)
})
}
/** 提交按钮操作 */
function handleSubmit(row: CwProjectPerformanceSelfEvaluationVO) {
// 🔒 检查是否已锁定
if (row.isLocked === 1) {
proxy?.$modal.msgWarning('该绩效自评已锁定,不允许提交。如需提交,请联系财务管理员或学校领导解锁')
return
}
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(() => {})
}
/** 导出按钮操作 */
function handleExport() {
proxy?.$modal.confirm('是否确认导出所有项目绩效自评数据?').then(() => {
return exportEvaluation(queryParams.value)
}).then((response: any) => {
proxy?.$download.saveAs(response, '项目绩效自评.xlsx')
}).catch(() => {})
}
onMounted(() => {
getList()
})
</script>
<style scoped lang="scss">
.score-card {
margin-bottom: 20px;
}
.score-header {
display: flex;
justify-content: space-between;
align-items: center;
font-weight: bold;
}
.total-score-card {
margin: 20px 0;
background: #f5f7fa;
}
:deep(.el-divider__text) {
background: #fff;
}
:deep(.el-dialog__body) {
max-height: 70vh;
overflow-y: auto;
}
</style>
File diff suppressed because it is too large. Load diff
+446
View File
@@ -0,0 +1,446 @@
<template>
<div class="app-container">
<el-card class="box-card">
<template #header>
<div class="card-header">
<span class="card-title">项目月度运行监控</span>
<div>
<el-button type="primary" icon="Document" @click="handleBatchSave">批量保存</el-button>
<el-button icon="Back" @click="handleBack">返回</el-button>
</div>
</div>
</template>
<!-- 项目信息 -->
<el-descriptions :column="3" border class="project-info">
<el-descriptions-item label="项目名称">{{ projectInfo.projectName }}</el-descriptions-item>
<el-descriptions-item label="申报编号">{{ projectInfo.applicationNo }}</el-descriptions-item>
<el-descriptions-item label="自评年度">{{ projectInfo.evaluationYear }}</el-descriptions-item>
<el-descriptions-item label="项目负责人">{{ projectInfo.principal }}</el-descriptions-item>
<el-descriptions-item label="联系电话">{{ projectInfo.contactPhone }}</el-descriptions-item>
<el-descriptions-item label="本年度预算">{{ projectInfo.annualBudget }} 万元</el-descriptions-item>
</el-descriptions>
<!-- 月度监控Tab -->
<el-tabs v-model="activeMonth" class="monitoring-tabs">
<el-tab-pane
v-for="month in 12"
:key="month"
:label="monthLabel(month)"
:name="month.toString()"
>
<el-form
:ref="(el: any) => setFormRef(month, el)"
:model="monthlyData[month]"
:rules="rules"
label-width="150px"
class="monitoring-form"
>
<!-- 进度信息 -->
<el-divider content-position="left"><h4>进度信息</h4></el-divider>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="计划进度(%)" prop="plannedProgress">
<el-input-number
v-model="monthlyData[month].plannedProgress"
:precision="2"
:min="0"
:max="100"
style="width: 100%"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="实际进度(%)" prop="actualProgress">
<el-input-number
v-model="monthlyData[month].actualProgress"
:precision="2"
:min="0"
:max="100"
style="width: 100%"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="进度偏差(%)">
<el-input :value="calculateProgressVariance(month)" disabled>
<template #append>
<el-tag :type="getVarianceTagType(calculateProgressVariance(month))" size="small">
{{ getVarianceStatus(calculateProgressVariance(month)) }}
</el-tag>
</template>
</el-input>
</el-form-item>
</el-col>
</el-row>
<!-- 资金信息 -->
<el-divider content-position="left"><h4>资金信息</h4></el-divider>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="本月预算(万元)" prop="monthlyBudget">
<el-input-number
v-model="monthlyData[month].monthlyBudget"
:precision="2"
:min="0"
style="width: 100%"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="本月支出(万元)" prop="monthlyExpenditure">
<el-input-number
v-model="monthlyData[month].monthlyExpenditure"
:precision="2"
:min="0"
style="width: 100%"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="累计预算(万元)" prop="cumulativeBudget">
<el-input-number
v-model="monthlyData[month].cumulativeBudget"
:precision="2"
:min="0"
style="width: 100%"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="累计支出(万元)" prop="cumulativeExpenditure">
<el-input-number
v-model="monthlyData[month].cumulativeExpenditure"
:precision="2"
:min="0"
style="width: 100%"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="资金执行率(%)">
<el-input :value="calculateFundExecutionRate(month)" disabled>
<template #append>
<el-tag :type="getRateTagType(calculateFundExecutionRate(month))" size="small">
{{ getRateStatus(calculateFundExecutionRate(month)) }}
</el-tag>
</template>
</el-input>
</el-form-item>
</el-col>
</el-row>
<!-- 里程碑 -->
<el-divider content-position="left"><h4>里程碑管理</h4></el-divider>
<el-form-item label="关键里程碑">
<el-input
v-model="monthlyData[month].keyMilestones"
type="textarea"
:rows="2"
placeholder="请输入本月关键里程碑"
/>
</el-form-item>
<el-form-item label="里程碑完成情况">
<el-input
v-model="monthlyData[month].milestoneCompletion"
type="textarea"
:rows="2"
placeholder="请输入里程碑完成情况"
/>
</el-form-item>
<!-- 问题与对策 -->
<el-divider content-position="left"><h4>问题与对策</h4></el-divider>
<el-form-item label="遇到的问题">
<el-input
v-model="monthlyData[month].problemsEncountered"
type="textarea"
:rows="3"
placeholder="请输入本月遇到的问题"
/>
</el-form-item>
<el-form-item label="风险描述">
<el-input
v-model="monthlyData[month].riskDescription"
type="textarea"
:rows="2"
placeholder="请输入风险描述"
/>
</el-form-item>
<el-form-item label="应对措施">
<el-input
v-model="monthlyData[month].countermeasures"
type="textarea"
:rows="3"
placeholder="请输入应对措施"
/>
</el-form-item>
<!-- 下月计划 -->
<el-divider content-position="left"><h4>下月计划</h4></el-divider>
<el-form-item label="下月工作计划">
<el-input
v-model="monthlyData[month].nextMonthPlan"
type="textarea"
:rows="4"
placeholder="请输入下月工作计划"
/>
</el-form-item>
<el-form-item label="备注">
<el-input
v-model="monthlyData[month].remark"
type="textarea"
:rows="2"
placeholder="请输入备注信息"
/>
</el-form-item>
<!-- 填报状态 -->
<el-form-item label="填报状态">
<el-tag :type="monthlyData[month].fillStatus === 'filled' ? 'success' : 'info'">
{{ monthlyData[month].fillStatus === 'filled' ? '已填报' : '未填报' }}
</el-tag>
<span v-if="monthlyData[month].fillTime" style="margin-left: 10px">
填报时间:{{ monthlyData[month].fillTime }}
</span>
</el-form-item>
<!-- 操作按钮 -->
<el-form-item>
<el-button type="primary" @click="handleSaveMonth(month)">保存{{ month }}月数据</el-button>
</el-form-item>
</el-form>
</el-tab-pane>
</el-tabs>
</el-card>
</div>
</template>
<script setup name="CwMonitoring" lang="ts">
import { getEvaluation } from '@/api/cw/performanceEvaluation'
import { getYearlyMonitoring, fillMonthlyData, batchSaveMonitoring } from '@/api/cw/performanceEvaluation'
import type { CwProjectPerformanceSelfEvaluationVO, CwProjectMonthlyMonitoringForm } from '@/api/cw/performanceEvaluation'
const route = useRoute()
const router = useRouter()
const { proxy } = getCurrentInstance() as ComponentInternalInstance
const activeMonth = ref('1')
const evaluationId = ref<number>(0)
const projectInfo = ref<CwProjectPerformanceSelfEvaluationVO>({} as CwProjectPerformanceSelfEvaluationVO)
const monthlyData = ref<Record<number, CwProjectMonthlyMonitoringForm>>({})
const formRefs = ref<Record<number, any>>({})
// 初始化月度数据
function initMonthlyData() {
for (let month = 1; month <= 12; month++) {
monthlyData.value[month] = {
evaluationId: evaluationId.value,
projectApplicationId: projectInfo.value.projectApplicationId,
monitoringYear: projectInfo.value.evaluationYear,
monitoringMonth: month,
fillStatus: 'unfilled'
}
}
}
// 设置表单引用
function setFormRef(month: number, el: any) {
if (el) {
formRefs.value[month] = el
}
}
// 月份标签
function monthLabel(month: number): string {
const status = monthlyData.value[month]?.fillStatus === 'filled' ? '✓' : ''
return `${month}月 ${status}`
}
// 计算进度偏差
function calculateProgressVariance(month: number): string {
const data = monthlyData.value[month]
if (data.plannedProgress !== undefined && data.actualProgress !== undefined) {
const variance = data.actualProgress - data.plannedProgress
return variance.toFixed(2)
}
return '0.00'
}
// 计算资金执行率
function calculateFundExecutionRate(month: number): string {
const data = monthlyData.value[month]
if (data.cumulativeBudget && data.cumulativeExpenditure && data.cumulativeBudget > 0) {
const rate = (data.cumulativeExpenditure / data.cumulativeBudget) * 100
return rate.toFixed(2)
}
return '0.00'
}
// 获取偏差标签类型
function getVarianceTagType(variance: string): string {
const val = parseFloat(variance)
if (val > 0) return 'success'
if (val < -5) return 'danger'
return 'warning'
}
// 获取偏差状态
function getVarianceStatus(variance: string): string {
const val = parseFloat(variance)
if (val > 0) return '超前'
if (val < -5) return '滞后'
return '正常'
}
// 获取执行率标签类型
function getRateTagType(rate: string): string {
const val = parseFloat(rate)
if (val >= 90 && val <= 110) return 'success'
if (val < 80 || val > 120) return 'danger'
return 'warning'
}
// 获取执行率状态
function getRateStatus(rate: string): string {
const val = parseFloat(rate)
if (val >= 90 && val <= 110) return '良好'
if (val < 80) return '偏低'
if (val > 120) return '偏高'
return '正常'
}
// 表单验证规则
const rules = ref({
plannedProgress: [
{ type: 'number', min: 0, max: 100, message: '计划进度范围0-100', trigger: 'blur' }
],
actualProgress: [
{ type: 'number', min: 0, max: 100, message: '实际进度范围0-100', trigger: 'blur' }
]
})
// 保存单月数据
function handleSaveMonth(month: number) {
const formRef = formRefs.value[month]
if (!formRef) return
formRef.validate((valid: boolean) => {
if (valid) {
const data = { ...monthlyData.value[month] }
fillMonthlyData(data).then(() => {
proxy?.$modal.msgSuccess(`${month}月数据保存成功`)
// 重新加载数据
loadMonitoringData()
})
}
})
}
// 批量保存
function handleBatchSave() {
proxy?.$modal.confirm('确认批量保存所有已填写的月度数据?').then(() => {
const dataList = Object.values(monthlyData.value).filter(data => {
// 过滤掉完全空白的数据
return data.plannedProgress !== undefined ||
data.actualProgress !== undefined ||
data.monthlyBudget !== undefined ||
data.monthlyExpenditure !== undefined
})
if (dataList.length === 0) {
proxy?.$modal.msgWarning('没有可保存的数据')
return
}
batchSaveMonitoring(evaluationId.value, dataList).then(() => {
proxy?.$modal.msgSuccess('批量保存成功')
loadMonitoringData()
})
}).catch(() => {})
}
// 返回
function handleBack() {
router.back()
}
// 加载监控数据
function loadMonitoringData() {
const year = projectInfo.value.evaluationYear
getYearlyMonitoring(evaluationId.value, year).then(response => {
const dataMap = response.data
// 合并已有数据
for (let month = 1; month <= 12; month++) {
if (dataMap[month]) {
monthlyData.value[month] = { ...monthlyData.value[month], ...dataMap[month] }
}
}
})
}
// 初始化
onMounted(() => {
evaluationId.value = parseInt(route.query.evaluationId as string)
// 加载项目信息
getEvaluation(evaluationId.value).then(response => {
projectInfo.value = response.data
// 初始化月度数据
initMonthlyData()
// 加载已有的监控数据
loadMonitoringData()
})
})
</script>
<style scoped lang="scss">
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.card-title {
font-size: 18px;
font-weight: bold;
}
.project-info {
margin-bottom: 20px;
}
.monitoring-tabs {
margin-top: 20px;
}
.monitoring-form {
padding: 20px;
}
:deep(.el-divider__text) {
background: #fff;
}
:deep(.el-tabs__item) {
font-weight: 500;
}
:deep(.el-tabs__item.is-active) {
color: #409eff;
font-weight: bold;
}
</style>
@@ -0,0 +1,488 @@
<template>
<div class="p-2 page-container">
<!-- 搜索区域 -->
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover">
<el-form :model="queryParams" ref="queryFormRef" label-width="100px">
<el-row :gutter="20">
<el-col :span="6">
<el-form-item label="项目名称" prop="projectName">
<el-input v-model="queryParams.projectName" placeholder="请输入项目名称" clearable @keyup.enter="handleQuery" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="申报编号" prop="applicationNo">
<el-input v-model="queryParams.applicationNo" placeholder="请输入申报编号" clearable @keyup.enter="handleQuery" />
</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-col>
<el-col :span="6">
<el-form-item label="自评状态" prop="evaluationStatus">
<el-select v-model="queryParams.evaluationStatus" placeholder="请选择自评状态" clearable style="width: 100%">
<el-option label="草稿" value="draft" />
<el-option label="已提交" value="submitted" />
<el-option label="已审核" value="approved" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="6">
<el-form-item label="自评等级" prop="selfEvaluationLevel">
<el-select v-model="queryParams.selfEvaluationLevel" placeholder="请选择自评等级" clearable style="width: 100%">
<el-option label="优秀" value="优秀" />
<el-option label="良好" value="良好" />
<el-option label="合格" value="合格" />
<el-option label="不合格" value="不合格" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="锁定状态" prop="isLocked">
<el-select v-model="queryParams.isLocked" placeholder="请选择锁定状态" clearable style="width: 100%">
<el-option label="未锁定" :value="0" />
<el-option label="已锁定" :value="1" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<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>
</transition>
<!-- 表格区域 -->
<el-card shadow="never" class="button-card table-card">
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="warning" plain icon="Lock" :disabled="multiple" @click="handleBatchLock" v-hasPermi="['cw:monitoringManagement:lock']">批量锁定</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Unlock" :disabled="multiple" @click="handleBatchUnlock" v-hasPermi="['cw:monitoringManagement:unlock']">批量解锁</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
</template>
<div class="table-container">
<el-table
v-loading="loading"
border
:data="evaluationList"
@selection-change="handleSelectionChange"
style="width: 100%"
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-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">
<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>
<el-table-column label="锁定状态" align="center" prop="isLocked" width="120">
<template #default="scope">
<el-tag v-if="scope.row.isLocked === 1" type="warning" size="small">已锁定</el-tag>
<el-tag v-else type="success" size="small">未锁定</el-tag>
</template>
</el-table-column>
<el-table-column label="锁定人" align="center" prop="lockByName" width="120" />
<el-table-column label="锁定时间" align="center" prop="lockTime" width="180">
<template #default="scope">
<span v-if="scope.row.lockTime">{{ parseTime(scope.row.lockTime) }}</span>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="创建人" align="center" prop="createBy" width="120" />
<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="300" fixed="right" class-name="small-padding fixed-width">
<template #default="scope">
<el-button link type="primary" icon="View" @click="handleView(scope.row)" v-hasPermi="['cw:monitoringManagement:query']"></el-button>
<el-button
v-if="scope.row.isLocked !== 1"
link
type="primary"
icon="Edit"
@click="handleEdit(scope.row)"
v-hasPermi="['cw:monitoringManagement:editEvaluation']"
></el-button>
<el-button v-if="scope.row.isLocked !== 1" link type="warning" icon="Lock" @click="handleLock(scope.row)" v-hasPermi="['cw:monitoringManagement:lock']"></el-button>
<el-button v-if="scope.row.isLocked === 1" link type="success" icon="Unlock" @click="handleUnlock(scope.row)" v-hasPermi="['cw:monitoringManagement:unlock']"></el-button>
</template>
</el-table-column>
</el-table>
</div>
<!-- 分页组件 -->
<div class="pagination-container">
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
</div>
</el-card>
<!-- 查看详情弹窗 -->
<el-dialog
v-model="dialogVisible"
:title="dialogTitle"
width="95%"
top="5vh"
:close-on-click-modal="false"
destroy-on-close
>
<!-- 使用表格样式组件 -->
<TableForm
ref="tableFormRef"
:form-data="formData"
:disabled="dialogMode === 'view' || formData.isLocked === 1"
/>
<!-- 显示运行监控数据 -->
<div style="margin-top: 30px;">
<el-divider content-position="left">
<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-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">
<template #default="scope">
<span v-if="scope.row.createTime">{{ proxy.parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}') }}</span>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="填报人" align="center" prop="fillByName" width="120" />
<el-table-column label="资金使用情况" align="center" prop="fundUsage" show-overflow-tooltip min-width="200" />
<el-table-column label="绩效目标完成情况" align="center" prop="performanceTargetCompletion" show-overflow-tooltip min-width="200" />
</el-table>
<el-empty v-else description="暂无运行监控数据" :image-size="100" />
</div>
<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>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="CwMonitoringManagement" lang="ts">
import { listMonitoringManagement, getMonitoringManagement, lockEvaluation, unlockEvaluation, lockBatchEvaluation, unlockBatchEvaluation, type MonitoringManagementQuery } from '@/api/cw/monitoringManagement'
import { saveDraft, updateEvaluation, submitEvaluation } from '@/api/cw/performanceEvaluation'
import type { CwProjectPerformanceSelfEvaluationVO } from '@/api/cw/performanceEvaluation'
import TableForm from '../evaluation/table-form.vue'
const { proxy } = getCurrentInstance() as ComponentInternalInstance
// 加载字典数据
const { cw_evaluation_status } = toRefs<any>(proxy?.useDict('cw_evaluation_status') || {})
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 tableFormRef = ref<any>()
// 弹窗相关状态
const dialogVisible = ref(false)
const formData = ref<any>({})
const dialogMode = ref<'view' | 'edit'>('view')
const dialogTitle = ref('查看绩效自评详情')
// 查询参数
const data = reactive<{
queryParams: MonitoringManagementQuery
}>({
queryParams: {
pageNum: 1,
pageSize: 10,
projectName: undefined,
applicationNo: undefined,
evaluationYear: undefined,
evaluationStatus: undefined,
selfEvaluationLevel: undefined,
isLocked: undefined
}
})
const { queryParams } = toRefs(data)
/** 查询绩效自评列表 */
async function getList() {
loading.value = true
try {
const response = await listMonitoringManagement(queryParams.value)
evaluationList.value = response.rows
total.value = response.total
} catch (error) {
console.error('查询列表失败:', error)
} finally {
loading.value = false
}
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1
getList()
}
/** 重置按钮操作 */
function resetQuery() {
queryFormRef.value?.resetFields()
handleQuery()
}
/** 多选框选中数据 */
function handleSelectionChange(selection: CwProjectPerformanceSelfEvaluationVO[]) {
ids.value = selection.map(item => item.id!)
single.value = selection.length !== 1
multiple.value = !selection.length
}
/** 查看按钮操作 */
async function handleView(row: CwProjectPerformanceSelfEvaluationVO) {
const response = await getMonitoringManagement(row.id!)
formData.value = response.data
dialogMode.value = 'view'
dialogTitle.value = '查看绩效自评详情'
dialogVisible.value = true
}
/** 编辑按钮操作(受权限控制) */
async function handleEdit(row: CwProjectPerformanceSelfEvaluationVO) {
if (row.isLocked === 1) {
proxy.$modal.msgWarning('该绩效自评已锁定,不允许修改。如需修改,请联系财务管理员或学校领导解锁')
return
}
const response = await getMonitoringManagement(row.id!)
formData.value = convertNumberFields(response.data || {})
dialogMode.value = 'edit'
dialogTitle.value = '编辑绩效自评'
dialogVisible.value = true
}
/** 转换后端返回的字符串数字为真实数字类型(与自评页一致) */
function convertNumberFields(data: any) {
if (!data) return data
const numberFields = [
'evaluationYear',
'annualBudget',
'actualExpenditure',
'budgetExecutionRate',
'fundScore',
'quantityScore',
'qualityScore',
'timelinessScore',
'costScore',
'economicScore',
'socialScore',
'ecologicalScore',
'satisfactionScore',
'decisionScore',
'processScore',
'outputScore',
'benefitScore',
'totalScore',
'initialBudget',
'fundValue',
'fundExecutionRate',
'currentYearBudgetInitial',
'currentYearBudgetAnnual',
'currentYearBudgetActual',
'currentYearBudgetValue',
'currentYearBudgetExecutionRate',
'currentYearBudgetScore',
'lastYearCarryoverInitial',
'lastYearCarryoverAnnual',
'lastYearCarryoverActual',
'lastYearCarryoverValue',
'lastYearCarryoverExecutionRate',
'lastYearCarryoverScore',
'otherFundsInitial',
'otherFundsAnnual',
'otherFundsActual',
'otherFundsValue',
'otherFundsExecutionRate',
'otherFundsScore',
'quantityValue',
'qualityValue',
'timelinessValue',
'costValue',
'economicValue',
'socialValue',
'ecologicalValue',
'satisfactionValue'
]
numberFields.forEach((field) => {
if (data[field] !== null && data[field] !== undefined && data[field] !== '' && typeof data[field] === 'string') {
data[field] = Number(data[field])
}
})
return data
}
/** 保存草稿(编辑弹窗内) */
function handleSaveDraft() {
if (formData.value.isLocked === 1) {
proxy.$modal.msgWarning('该绩效自评已锁定,不允许修改。如需修改,请联系财务管理员或学校领导解锁')
return
}
saveDraft(formData.value).then(() => {
proxy.$modal.msgSuccess('保存草稿成功')
dialogVisible.value = false
getList()
})
}
/** 提交自评(编辑弹窗内) */
function handleFormSubmit() {
if (formData.value.isLocked === 1) {
proxy.$modal.msgWarning('该绩效自评已锁定,不允许提交。如需提交,请联系财务管理员或学校领导解锁')
return
}
if (tableFormRef.value?.validateTotalValue) {
tableFormRef.value.validateTotalValue()
}
proxy.$modal.confirm('确认要提交该自评吗?').then(() => {
const submitData = { ...formData.value }
submitData.evaluationStatus = 'submitted'
if (submitData.id) {
return updateEvaluation(submitData).then(() => {
proxy.$modal.msgSuccess('提交成功')
dialogVisible.value = false
getList()
})
} else {
// 若无ID则作为独立提交入口兜底:走提交接口(按需)
return submitEvaluation(submitData.id)
.then(() => {
proxy.$modal.msgSuccess('提交成功')
dialogVisible.value = false
getList()
})
}
}).catch(() => {})
}
/** 锁定按钮操作 */
async function handleLock(row: CwProjectPerformanceSelfEvaluationVO) {
try {
await proxy.$modal.confirm('确定要锁定该绩效自评吗?锁定后将不允许修改。')
await lockEvaluation(row.id!)
proxy.$modal.msgSuccess('锁定成功')
getList()
} catch (error) {
console.error('锁定失败:', error)
}
}
/** 解锁按钮操作 */
async function handleUnlock(row: CwProjectPerformanceSelfEvaluationVO) {
try {
await proxy.$modal.confirm('确定要解锁该绩效自评吗?')
await unlockEvaluation(row.id!)
proxy.$modal.msgSuccess('解锁成功')
getList()
} catch (error) {
console.error('解锁失败:', error)
}
}
/** 批量锁定 */
async function handleBatchLock() {
if (ids.value.length === 0) {
proxy.$modal.msgWarning('请选择要锁定的数据')
return
}
try {
await proxy.$modal.confirm('确定要批量锁定选中的绩效自评吗?锁定后将不允许修改。')
await lockBatchEvaluation(ids.value)
proxy.$modal.msgSuccess('批量锁定成功')
getList()
} catch (error) {
console.error('批量锁定失败:', error)
}
}
/** 批量解锁 */
async function handleBatchUnlock() {
if (ids.value.length === 0) {
proxy.$modal.msgWarning('请选择要解锁的数据')
return
}
try {
await proxy.$modal.confirm('确定要批量解锁选中的绩效自评吗?')
await unlockBatchEvaluation(ids.value)
proxy.$modal.msgSuccess('批量解锁成功')
getList()
} catch (error) {
console.error('批量解锁失败:', error)
}
}
onMounted(() => {
getList()
})
</script>
<style scoped lang="scss">
</style>