diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/controller/CwMonitoringManagementController.java b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/controller/CwMonitoringManagementController.java new file mode 100644 index 00000000..b7b1b4b8 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/controller/CwMonitoringManagementController.java @@ -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 list(CwProjectPerformanceSelfEvaluationBo bo, PageQuery pageQuery) { + return monitoringManagementService.queryPageList(bo, pageQuery); + } + + /** + * 获取绩效自评详细信息(运行监控管理) + */ + @SaCheckPermission("cw:monitoringManagement:query") + @GetMapping("/{id}") + public R 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 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 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 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 unlockBatch(@NotEmpty(message = "主键不能为空") @RequestBody Long[] ids) { + return toAjax(monitoringManagementService.unlockBatch(Arrays.asList(ids))); + } +} + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/controller/CwPerformanceMonitoringController.java b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/controller/CwPerformanceMonitoringController.java new file mode 100644 index 00000000..1b68a5a8 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/controller/CwPerformanceMonitoringController.java @@ -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> listByEvaluationId(@NotNull(message = "自评ID不能为空") @PathVariable Long evaluationId) { + return R.ok(performanceMonitoringService.queryByEvaluationId(evaluationId)); + } + + /** + * 获取绩效运行监控详细信息 + */ + @SaCheckPermission("cw:performanceMonitoring:query") + @GetMapping("/{id}") + public R 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 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 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 remove(@NotNull(message = "主键不能为空") @PathVariable Long id) { + return toAjax(performanceMonitoringService.deleteWithValidByIds(List.of(id), true)); + } +} + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/controller/CwProjectEvaluationIndicatorController.java b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/controller/CwProjectEvaluationIndicatorController.java new file mode 100644 index 00000000..32b1a16a --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/controller/CwProjectEvaluationIndicatorController.java @@ -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 list(CwProjectEvaluationIndicatorBo bo, PageQuery pageQuery) { + return indicatorService.queryPageList(bo, pageQuery); + } + + /** + * 获取项目绩效自评指标明细详细信息 + */ + @SaCheckPermission("cw:indicator:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) { + return R.ok(indicatorService.queryById(id)); + } + + /** + * 根据自评ID查询指标明细列表 + */ + @SaCheckPermission("cw:indicator:query") + @GetMapping("/evaluation/{evaluationId}") + public R> 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> 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 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 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 batchSave(@RequestParam Long evaluationId, @RequestBody List boList) { + return toAjax(indicatorService.batchSave(evaluationId, boList)); + } + + /** + * 删除项目绩效自评指标明细 + */ + @SaCheckPermission("cw:indicator:remove") + @Log(title = "项目绩效自评指标明细", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R 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 list = indicatorService.queryList(bo); + ExcelUtil.exportExcel(list, "项目绩效自评指标明细", CwProjectEvaluationIndicatorVo.class, response); + } +} + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/controller/CwProjectMonthlyMonitoringController.java b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/controller/CwProjectMonthlyMonitoringController.java new file mode 100644 index 00000000..e05e2e6d --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/controller/CwProjectMonthlyMonitoringController.java @@ -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 list(CwProjectMonthlyMonitoringBo bo, PageQuery pageQuery) { + return monitoringService.queryPageList(bo, pageQuery); + } + + /** + * 获取项目月度运行监控详细信息 + */ + @SaCheckPermission("cw:monitoring:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) { + return R.ok(monitoringService.queryById(id)); + } + + /** + * 根据自评ID查询月度监控列表 + */ + @SaCheckPermission("cw:monitoring:query") + @GetMapping("/evaluation/{evaluationId}") + public R> getByEvaluationId(@NotNull(message = "自评ID不能为空") @PathVariable Long evaluationId) { + return R.ok(monitoringService.queryByEvaluationId(evaluationId)); + } + + /** + * 查询某个自评的全年监控数据 + */ + @SaCheckPermission("cw:monitoring:query") + @GetMapping("/year/{evaluationId}/{year}") + public R> 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 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 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 fillMonthlyData(@Validated @RequestBody CwProjectMonthlyMonitoringBo bo) { + return toAjax(monitoringService.fillMonthlyData(bo)); + } + + /** + * 批量保存月度监控数据 + */ + @SaCheckPermission("cw:monitoring:edit") + @Log(title = "批量保存月度监控数据", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PostMapping("/batch") + public R batchSave(@RequestParam Long evaluationId, @RequestBody List boList) { + return toAjax(monitoringService.batchSave(evaluationId, boList)); + } + + /** + * 删除项目月度运行监控 + */ + @SaCheckPermission("cw:monitoring:remove") + @Log(title = "项目月度运行监控", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R 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 list = monitoringService.queryList(bo); + ExcelUtil.exportExcel(list, "项目月度运行监控", CwProjectMonthlyMonitoringVo.class, response); + } +} + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/controller/CwProjectPerformanceSelfEvaluationController.java b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/controller/CwProjectPerformanceSelfEvaluationController.java new file mode 100644 index 00000000..fda1e72a --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/controller/CwProjectPerformanceSelfEvaluationController.java @@ -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 list(CwProjectPerformanceSelfEvaluationBo bo, PageQuery pageQuery) { + return evaluationService.queryPageList(bo, pageQuery); + } + + /** + * 获取项目绩效自评详细信息 + */ + @SaCheckPermission("cw:evaluation:query") + @GetMapping("/{id}") + public R 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 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 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 saveDraft(@RequestBody CwProjectPerformanceSelfEvaluationBo bo) { + return toAjax(evaluationService.saveDraft(bo)); + } + + /** + * 提交自评 + */ + @SaCheckPermission("cw:evaluation:submit") + @Log(title = "提交自评", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PostMapping("/submit/{id}") + public R 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 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 remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ids) { + return toAjax(evaluationService.deleteWithValidByIds(Arrays.asList(ids), true)); + } + + /** + * 查询我的自评列表 + */ + @SaCheckPermission("cw:evaluation:list") + @GetMapping("/my") + public R> myEvaluations() { + return R.ok(evaluationService.queryMyEvaluations(LoginHelper.getUserId())); + } + + /** + * 查询待审核自评列表 + */ + @SaCheckPermission("cw:evaluation:approve") + @GetMapping("/pending") + public R> 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 list = evaluationService.queryList(bo); + ExcelUtil.exportExcel(list, "项目绩效自评", CwProjectPerformanceSelfEvaluationVo.class, response); + } +} + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/CwPerformanceMonitoring.java b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/CwPerformanceMonitoring.java new file mode 100644 index 00000000..6b8b80bb --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/CwPerformanceMonitoring.java @@ -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; +} + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/CwProjectEvaluationIndicator.java b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/CwProjectEvaluationIndicator.java new file mode 100644 index 00000000..6684d20b --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/CwProjectEvaluationIndicator.java @@ -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; +} + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/CwProjectMonthlyMonitoring.java b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/CwProjectMonthlyMonitoring.java new file mode 100644 index 00000000..5d8dfaae --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/CwProjectMonthlyMonitoring.java @@ -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; +} + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/CwProjectPerformanceSelfEvaluation.java b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/CwProjectPerformanceSelfEvaluation.java new file mode 100644 index 00000000..2f16eee9 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/CwProjectPerformanceSelfEvaluation.java @@ -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; +} + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/bo/CwPerformanceMonitoringBo.java b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/bo/CwPerformanceMonitoringBo.java new file mode 100644 index 00000000..d9012d19 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/bo/CwPerformanceMonitoringBo.java @@ -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; +} + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/bo/CwProjectEvaluationIndicatorBo.java b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/bo/CwProjectEvaluationIndicatorBo.java new file mode 100644 index 00000000..859ac0fd --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/bo/CwProjectEvaluationIndicatorBo.java @@ -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; +} + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/bo/CwProjectMonthlyMonitoringBo.java b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/bo/CwProjectMonthlyMonitoringBo.java new file mode 100644 index 00000000..3a46b71b --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/bo/CwProjectMonthlyMonitoringBo.java @@ -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; +} + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/bo/CwProjectPerformanceSelfEvaluationBo.java b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/bo/CwProjectPerformanceSelfEvaluationBo.java new file mode 100644 index 00000000..b2228840 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/bo/CwProjectPerformanceSelfEvaluationBo.java @@ -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; +} + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/vo/CwPerformanceMonitoringVo.java b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/vo/CwPerformanceMonitoringVo.java new file mode 100644 index 00000000..2e18e521 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/vo/CwPerformanceMonitoringVo.java @@ -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; +} + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/vo/CwProjectEvaluationIndicatorVo.java b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/vo/CwProjectEvaluationIndicatorVo.java new file mode 100644 index 00000000..f73e889a --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/vo/CwProjectEvaluationIndicatorVo.java @@ -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; +} + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/vo/CwProjectMonthlyMonitoringVo.java b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/vo/CwProjectMonthlyMonitoringVo.java new file mode 100644 index 00000000..21be2b63 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/vo/CwProjectMonthlyMonitoringVo.java @@ -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; +} + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/vo/CwProjectPerformanceSelfEvaluationVo.java b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/vo/CwProjectPerformanceSelfEvaluationVo.java new file mode 100644 index 00000000..8930cfa6 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/vo/CwProjectPerformanceSelfEvaluationVo.java @@ -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 monitoringList; +} + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/mapper/CwPerformanceMonitoringMapper.java b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/mapper/CwPerformanceMonitoringMapper.java new file mode 100644 index 00000000..991f3e2f --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/mapper/CwPerformanceMonitoringMapper.java @@ -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 { + +} + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/mapper/CwProjectEvaluationIndicatorMapper.java b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/mapper/CwProjectEvaluationIndicatorMapper.java new file mode 100644 index 00000000..285fa7c6 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/mapper/CwProjectEvaluationIndicatorMapper.java @@ -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 { + + /** + * 根据自评ID查询指标列表 + */ + List selectByEvaluationId(@Param("evaluationId") Long evaluationId); + + /** + * 根据自评ID和指标类别查询指标列表 + */ + List selectByEvaluationIdAndCategory(@Param("evaluationId") Long evaluationId, @Param("indicatorCategory") String indicatorCategory); + + /** + * 批量插入指标 + */ + int batchInsert(@Param("list") List list); + + /** + * 根据自评ID删除指标 + */ + int deleteByEvaluationId(@Param("evaluationId") Long evaluationId); +} + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/mapper/CwProjectMonthlyMonitoringMapper.java b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/mapper/CwProjectMonthlyMonitoringMapper.java new file mode 100644 index 00000000..0559356d --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/mapper/CwProjectMonthlyMonitoringMapper.java @@ -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 { + + /** + * 根据自评ID查询月度监控列表 + */ + List selectByEvaluationId(@Param("evaluationId") Long evaluationId); + + /** + * 根据自评ID和年度查询月度监控列表 + */ + List 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 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); +} + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/mapper/CwProjectPerformanceSelfEvaluationMapper.java b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/mapper/CwProjectPerformanceSelfEvaluationMapper.java new file mode 100644 index 00000000..454ae450 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/mapper/CwProjectPerformanceSelfEvaluationMapper.java @@ -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 { + + /** + * 根据项目申报ID和年度查询自评 + */ + CwProjectPerformanceSelfEvaluationVo selectByProjectAndYear(@Param("projectApplicationId") Long projectApplicationId, @Param("evaluationYear") Integer evaluationYear); + + /** + * 查询我的自评列表 + */ + List selectMyEvaluations(@Param("userId") Long userId); + + /** + * 查询待审核的自评列表 + */ + List selectPendingApprovals(); + + /** + * 统计自评数量 + */ + Long countEvaluations(@Param("evaluationYear") Integer evaluationYear, @Param("evaluationStatus") String evaluationStatus); + + /** + * 计算平均分 + */ + BigDecimal calculateAverageScore(@Param("evaluationYear") Integer evaluationYear); + + /** + * 按部门统计自评情况 + */ + List> statisticsByDept(@Param("evaluationYear") Integer evaluationYear); + + /** + * 按等级统计自评数量 + */ + List> statisticsByLevel(@Param("evaluationYear") Integer evaluationYear); +} + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/ICwMonitoringManagementService.java b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/ICwMonitoringManagementService.java new file mode 100644 index 00000000..33373c3a --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/ICwMonitoringManagementService.java @@ -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 queryPageList(CwProjectPerformanceSelfEvaluationBo bo, PageQuery pageQuery); + + /** + * 查询绩效自评列表(运行监控管理) + */ + List queryList(CwProjectPerformanceSelfEvaluationBo bo); + + /** + * 锁定绩效自评(单个) + */ + Boolean lockEvaluation(Long id); + + /** + * 解锁绩效自评(单个) + */ + Boolean unlockEvaluation(Long id); + + /** + * 批量锁定绩效自评 + */ + Boolean lockBatch(List ids); + + /** + * 批量解锁绩效自评 + */ + Boolean unlockBatch(List ids); +} + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/ICwPerformanceMonitoringService.java b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/ICwPerformanceMonitoringService.java new file mode 100644 index 00000000..45a195f4 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/ICwPerformanceMonitoringService.java @@ -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 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 ids, Boolean isValid); + + /** + * 根据自评ID删除所有运行监控数据 + * + * @param evaluationId 自评ID + * @return 是否删除成功 + */ + Boolean deleteByEvaluationId(Long evaluationId); +} + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/ICwProjectEvaluationIndicatorService.java b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/ICwProjectEvaluationIndicatorService.java new file mode 100644 index 00000000..ca430af5 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/ICwProjectEvaluationIndicatorService.java @@ -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 queryList(CwProjectEvaluationIndicatorBo bo); + + /** + * 分页查询项目绩效自评指标明细列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 项目绩效自评指标明细分页列表 + */ + TableDataInfo queryPageList(CwProjectEvaluationIndicatorBo bo, PageQuery pageQuery); + + /** + * 根据自评ID查询指标明细列表 + * + * @param evaluationId 自评ID + * @return 指标明细列表 + */ + List queryByEvaluationId(Long evaluationId); + + /** + * 根据自评ID和指标类型查询指标明细列表 + * + * @param evaluationId 自评ID + * @param indicatorType 指标类型 + * @return 指标明细列表 + */ + List 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 boList); + + /** + * 校验并批量删除项目绩效自评指标明细信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 根据自评ID删除所有指标明细 + * + * @param evaluationId 自评ID + * @return 是否删除成功 + */ + Boolean deleteByEvaluationId(Long evaluationId); +} + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/ICwProjectMonthlyMonitoringService.java b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/ICwProjectMonthlyMonitoringService.java new file mode 100644 index 00000000..7d03da7b --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/ICwProjectMonthlyMonitoringService.java @@ -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 queryList(CwProjectMonthlyMonitoringBo bo); + + /** + * 分页查询项目月度运行监控列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 项目月度运行监控分页列表 + */ + TableDataInfo queryPageList(CwProjectMonthlyMonitoringBo bo, PageQuery pageQuery); + + /** + * 根据自评ID查询月度监控列表 + * + * @param evaluationId 自评ID + * @return 月度监控列表 + */ + List queryByEvaluationId(Long evaluationId); + + /** + * 查询某个自评的全年监控数据 + * + * @param evaluationId 自评ID + * @param year 年份 + * @return 月度数据Map,key为月份(1-12),value为监控数据 + */ + Map 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 boList); + + /** + * 校验并批量删除项目月度运行监控信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 根据自评ID删除所有月度监控数据 + * + * @param evaluationId 自评ID + * @return 是否删除成功 + */ + Boolean deleteByEvaluationId(Long evaluationId); +} + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/ICwProjectPerformanceSelfEvaluationService.java b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/ICwProjectPerformanceSelfEvaluationService.java new file mode 100644 index 00000000..33d6e5a2 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/ICwProjectPerformanceSelfEvaluationService.java @@ -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 queryPageList(CwProjectPerformanceSelfEvaluationBo bo, PageQuery pageQuery); + + /** + * 查询项目绩效自评列表 + */ + List queryList(CwProjectPerformanceSelfEvaluationBo bo); + + /** + * 根据项目申报ID和年度查询自评 + */ + CwProjectPerformanceSelfEvaluationVo queryByProjectAndYear(Long projectApplicationId, Integer evaluationYear); + + /** + * 查询我的自评列表 + */ + List queryMyEvaluations(Long userId); + + /** + * 查询待审核的自评列表 + */ + List 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 ids, Boolean isValid); + + /** + * 统计自评数量 + */ + Long countEvaluations(Integer evaluationYear, String evaluationStatus); + + /** + * 计算平均分 + */ + BigDecimal calculateAverageScore(Integer evaluationYear); + + /** + * 按部门统计自评情况 + */ + List> statisticsByDept(Integer evaluationYear); + + /** + * 按等级统计自评数量 + */ + List> statisticsByLevel(Integer evaluationYear); + + /** + * 导出项目绩效自评 + */ + void export(CwProjectPerformanceSelfEvaluationBo bo); +} + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/impl/CwMonitoringManagementServiceImpl.java b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/impl/CwMonitoringManagementServiceImpl.java new file mode 100644 index 00000000..9b5531f9 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/impl/CwMonitoringManagementServiceImpl.java @@ -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 queryPageList(CwProjectPerformanceSelfEvaluationBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询绩效自评列表(运行监控管理) + */ + @Override + public List queryList(CwProjectPerformanceSelfEvaluationBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + /** + * 构建查询条件 + * 注意:运行监控管理不进行数据权限过滤,财务管理员和学校领导可以看到所有人的数据 + */ + private LambdaQueryWrapper buildQueryWrapper(CwProjectPerformanceSelfEvaluationBo bo) { + LambdaQueryWrapper 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 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 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 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 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 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 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); + } + } +} + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/impl/CwPerformanceMonitoringServiceImpl.java b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/impl/CwPerformanceMonitoringServiceImpl.java new file mode 100644 index 00000000..a1aca5f8 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/impl/CwPerformanceMonitoringServiceImpl.java @@ -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 queryByEvaluationId(Long evaluationId) { + LambdaQueryWrapper 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 ids, Boolean isValid) { + if (isValid) { + // TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteByIds(ids) > 0; + } + + /** + * 根据自评ID删除所有运行监控数据 + */ + @Override + public Boolean deleteByEvaluationId(Long evaluationId) { + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(CwPerformanceMonitoring::getEvaluationId, evaluationId); + return baseMapper.delete(lqw) > 0; + } +} + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/impl/CwProjectEvaluationIndicatorServiceImpl.java b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/impl/CwProjectEvaluationIndicatorServiceImpl.java new file mode 100644 index 00000000..2f52f40c --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/impl/CwProjectEvaluationIndicatorServiceImpl.java @@ -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 queryList(CwProjectEvaluationIndicatorBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + /** + * 分页查询项目绩效自评指标明细列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 项目绩效自评指标明细分页列表 + */ + @Override + public TableDataInfo queryPageList(CwProjectEvaluationIndicatorBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 根据自评ID查询指标明细列表 + * + * @param evaluationId 自评ID + * @return 指标明细列表 + */ + @Override + public List queryByEvaluationId(Long evaluationId) { + LambdaQueryWrapper 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 queryByEvaluationIdAndType(Long evaluationId, String indicatorType) { + LambdaQueryWrapper 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 buildQueryWrapper(CwProjectEvaluationIndicatorBo bo) { + LambdaQueryWrapper 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 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 ids, Boolean isValid) { + if (isValid) { + // 可以在此添加删除前的校验逻辑 + } + return baseMapper.deleteBatchIds(ids) > 0; + } + + /** + * 根据自评ID删除所有指标明细 + * + * @param evaluationId 自评ID + * @return 是否删除成功 + */ + @Override + public Boolean deleteByEvaluationId(Long evaluationId) { + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(CwProjectEvaluationIndicator::getEvaluationId, evaluationId); + return baseMapper.delete(lqw) >= 0; + } +} + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/impl/CwProjectMonthlyMonitoringServiceImpl.java b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/impl/CwProjectMonthlyMonitoringServiceImpl.java new file mode 100644 index 00000000..abdb7e7c --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/impl/CwProjectMonthlyMonitoringServiceImpl.java @@ -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 queryList(CwProjectMonthlyMonitoringBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + /** + * 分页查询项目月度运行监控列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 项目月度运行监控分页列表 + */ + @Override + public TableDataInfo queryPageList(CwProjectMonthlyMonitoringBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 根据自评ID查询月度监控列表 + * + * @param evaluationId 自评ID + * @return 月度监控列表 + */ + @Override + public List queryByEvaluationId(Long evaluationId) { + LambdaQueryWrapper 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 queryYearlyMonitoring(Long evaluationId, Integer year) { + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(CwProjectMonthlyMonitoring::getEvaluationId, evaluationId); + lqw.eq(CwProjectMonthlyMonitoring::getMonitoringYear, year); + lqw.orderByAsc(CwProjectMonthlyMonitoring::getMonitoringMonth); + + List list = baseMapper.selectVoList(lqw); + return list.stream().collect( + Collectors.toMap(CwProjectMonthlyMonitoringVo::getMonitoringMonth, v -> v) + ); + } + + /** + * 构建查询条件 + */ + private LambdaQueryWrapper buildQueryWrapper(CwProjectMonthlyMonitoringBo bo) { + LambdaQueryWrapper 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 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 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 ids, Boolean isValid) { + if (isValid) { + // 可以在此添加删除前的校验逻辑 + } + return baseMapper.deleteBatchIds(ids) > 0; + } + + /** + * 根据自评ID删除所有月度监控数据 + * + * @param evaluationId 自评ID + * @return 是否删除成功 + */ + @Override + public Boolean deleteByEvaluationId(Long evaluationId) { + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(CwProjectMonthlyMonitoring::getEvaluationId, evaluationId); + return baseMapper.delete(lqw) >= 0; + } +} + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/impl/CwProjectPerformanceSelfEvaluationServiceImpl.java b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/impl/CwProjectPerformanceSelfEvaluationServiceImpl.java new file mode 100644 index 00000000..b7d33aa8 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/impl/CwProjectPerformanceSelfEvaluationServiceImpl.java @@ -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 queryPageList(CwProjectPerformanceSelfEvaluationBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询项目绩效自评列表 + */ + @Override + public List queryList(CwProjectPerformanceSelfEvaluationBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(CwProjectPerformanceSelfEvaluationBo bo) { + LambdaQueryWrapper 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 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 queryMyEvaluations(Long userId) { + return baseMapper.selectMyEvaluations(userId); + } + + /** + * 查询待审核的自评列表 + */ + @Override + public List 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 ids, Boolean isValid) { + if (isValid) { + // 校验是否可以删除(例如:已审核的不能删除) + List 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> statisticsByDept(Integer evaluationYear) { + return baseMapper.statisticsByDept(evaluationYear); + } + + /** + * 按等级统计自评数量 + */ + @Override + public List> 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; + } +} + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/check_evaluation_data.sql b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/check_evaluation_data.sql new file mode 100644 index 00000000..4150e74e --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/check_evaluation_data.sql @@ -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; + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/dict_cw_evaluation_status.sql b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/dict_cw_evaluation_status.sql new file mode 100644 index 00000000..0ebcd379 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/dict_cw_evaluation_status.sql @@ -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(), '已审核通过'); + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/fix_application_no_field.sql b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/fix_application_no_field.sql new file mode 100644 index 00000000..488c8cb9 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/fix_application_no_field.sql @@ -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; + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/fix_total_score.sql b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/fix_total_score.sql new file mode 100644 index 00000000..96518f0f --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/fix_total_score.sql @@ -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条记录验证结果 +-- ============================================= + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/upgrade_performance_evaluation_table.sql b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/upgrade_performance_evaluation_table.sql new file mode 100644 index 00000000..d768b538 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/upgrade_performance_evaluation_table.sql @@ -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. 如需回滚,请执行上面注释中的回滚脚本 +-- ============================================= + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/修复唯一索引冲突.sql b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/修复唯一索引冲突.sql new file mode 100644 index 00000000..abc20545 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/修复唯一索引冲突.sql @@ -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. 如需控制重复提交,应在业务层面控制(如:状态为已提交时禁止再次提交) +-- ============================================= + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/修复菜单乱码数据.sql b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/修复菜单乱码数据.sql new file mode 100644 index 00000000..769d05c1 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/修复菜单乱码数据.sql @@ -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; + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/添加允许已提交后编辑字段.sql b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/添加允许已提交后编辑字段.sql new file mode 100644 index 00000000..0fb6eb73 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/添加允许已提交后编辑字段.sql @@ -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; + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/绩效运行监控表建表脚本.sql b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/绩效运行监控表建表脚本.sql new file mode 100644 index 00000000..2c10a0db --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/绩效运行监控表建表脚本.sql @@ -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, ''); + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/绩效运行监控表权限脚本.sql b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/绩效运行监控表权限脚本.sql new file mode 100644 index 00000000..19a62087 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/绩效运行监控表权限脚本.sql @@ -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, ''); + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/运行监控管理-添加锁定字段.sql b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/运行监控管理-添加锁定字段.sql new file mode 100644 index 00000000..648c3528 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/运行监控管理-添加锁定字段.sql @@ -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, ''); + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/项目绩效自评模块建表脚本.sql b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/项目绩效自评模块建表脚本.sql new file mode 100644 index 00000000..3dc3c32c --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/db/项目绩效自评模块建表脚本.sql @@ -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, ''); + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/resources/mapper/cw/CwPerformanceMonitoringMapper.xml b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/mapper/cw/CwPerformanceMonitoringMapper.xml new file mode 100644 index 00000000..6e2c080a --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/mapper/cw/CwPerformanceMonitoringMapper.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/resources/mapper/cw/CwProjectEvaluationIndicatorMapper.xml b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/mapper/cw/CwProjectEvaluationIndicatorMapper.xml new file mode 100644 index 00000000..61641ed6 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/mapper/cw/CwProjectEvaluationIndicatorMapper.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + (#{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}) + + + + + + UPDATE cw_project_evaluation_indicator + SET deleted = 1 + WHERE evaluation_id = #{evaluationId} + + + + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/resources/mapper/cw/CwProjectMonthlyMonitoringMapper.xml b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/mapper/cw/CwProjectMonthlyMonitoringMapper.xml new file mode 100644 index 00000000..0eb93018 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/mapper/cw/CwProjectMonthlyMonitoringMapper.xml @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + (#{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}) + + + + + + UPDATE cw_project_monthly_monitoring + SET deleted = 1 + WHERE evaluation_id = #{evaluationId} + + + + + + + + + + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/resources/mapper/cw/CwProjectPerformanceSelfEvaluationMapper.xml b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/mapper/cw/CwProjectPerformanceSelfEvaluationMapper.xml new file mode 100644 index 00000000..7ccb808a --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/resources/mapper/cw/CwProjectPerformanceSelfEvaluationMapper.xml @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/service/impl/InternshipInfoServiceImpl.java b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/service/impl/InternshipInfoServiceImpl.java index b6d524c6..c13fdbca 100644 --- a/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/service/impl/InternshipInfoServiceImpl.java +++ b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/service/impl/InternshipInfoServiceImpl.java @@ -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 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; } diff --git a/web/src/api/cw/monitoringManagement.ts b/web/src/api/cw/monitoringManagement.ts new file mode 100644 index 00000000..2bf08f65 --- /dev/null +++ b/web/src/api/cw/monitoringManagement.ts @@ -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 { + return request({ + url: '/cw/monitoringManagement/list', + method: 'get', + params: query + }) +} + +/** + * 查询绩效自评详细(运行监控管理) + */ +export function getMonitoringManagement(id: number): AxiosPromise { + return request({ + url: `/cw/monitoringManagement/${id}`, + method: 'get' + }) +} + +/** + * 锁定绩效自评(单个) + */ +export function lockEvaluation(id: number): AxiosPromise { + return request({ + url: `/cw/monitoringManagement/lock/${id}`, + method: 'post' + }) +} + +/** + * 解锁绩效自评(单个) + */ +export function unlockEvaluation(id: number): AxiosPromise { + return request({ + url: `/cw/monitoringManagement/unlock/${id}`, + method: 'post' + }) +} + +/** + * 批量锁定绩效自评 + */ +export function lockBatchEvaluation(ids: number[]): AxiosPromise { + return request({ + url: '/cw/monitoringManagement/lock/batch', + method: 'post', + data: ids + }) +} + +/** + * 批量解锁绩效自评 + */ +export function unlockBatchEvaluation(ids: number[]): AxiosPromise { + return request({ + url: '/cw/monitoringManagement/unlock/batch', + method: 'post', + data: ids + }) +} + diff --git a/web/src/api/cw/performanceEvaluation.ts b/web/src/api/cw/performanceEvaluation.ts new file mode 100644 index 00000000..02afe930 --- /dev/null +++ b/web/src/api/cw/performanceEvaluation.ts @@ -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 { + return request({ + url: '/cw/evaluation/list', + method: 'get', + params: query + }) +} + +/** + * 查询项目绩效自评详细 + */ +export function getEvaluation(id: number): AxiosPromise { + return request({ + url: `/cw/evaluation/${id}`, + method: 'get' + }) +} + +/** + * 新增项目绩效自评 + */ +export function addEvaluation(data: CwProjectPerformanceSelfEvaluationForm): AxiosPromise { + return request({ + url: '/cw/evaluation', + method: 'post', + data + }) +} + +/** + * 修改项目绩效自评 + */ +export function updateEvaluation(data: CwProjectPerformanceSelfEvaluationForm): AxiosPromise { + return request({ + url: '/cw/evaluation', + method: 'put', + data + }) +} + +/** + * 保存自评草稿 + */ +export function saveDraft(data: CwProjectPerformanceSelfEvaluationForm): AxiosPromise { + return request({ + url: '/cw/evaluation/saveDraft', + method: 'post', + data + }) +} + +/** + * 提交自评 + */ +export function submitEvaluation(id: number): AxiosPromise { + return request({ + url: `/cw/evaluation/submit/${id}`, + method: 'post' + }) +} + +/** + * 审核自评 + */ +export function approveEvaluation(id: number, opinion: string, approved: boolean): AxiosPromise { + return request({ + url: `/cw/evaluation/approve/${id}`, + method: 'post', + params: { opinion, approved } + }) +} + +/** + * 删除项目绩效自评 + */ +export function delEvaluation(ids: number | number[]): AxiosPromise { + return request({ + url: `/cw/evaluation/${ids}`, + method: 'delete' + }) +} + +/** + * 查询我的自评列表 + */ +export function getMyEvaluations(): AxiosPromise { + return request({ + url: '/cw/evaluation/my', + method: 'get' + }) +} + +/** + * 查询待审核自评列表 + */ +export function getPendingApprovals(): AxiosPromise { + return request({ + url: '/cw/evaluation/pending', + method: 'get' + }) +} + +/** + * 导出项目绩效自评 + */ +export function exportEvaluation(query: CwProjectPerformanceSelfEvaluationQuery): AxiosPromise { + 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> { + return request({ + url: `/cw/monitoring/year/${evaluationId}/${year}`, + method: 'get' + }) +} + +/** + * 根据自评ID查询月度监控列表 + */ +export function getMonitoringByEvaluationId(evaluationId: number): AxiosPromise { + return request({ + url: `/cw/monitoring/evaluation/${evaluationId}`, + method: 'get' + }) +} + +/** + * 填报月度数据 + */ +export function fillMonthlyData(data: CwProjectMonthlyMonitoringForm): AxiosPromise { + return request({ + url: '/cw/monitoring/fill', + method: 'post', + data + }) +} + +/** + * 批量保存月度数据 + */ +export function batchSaveMonitoring(evaluationId: number, list: CwProjectMonthlyMonitoringForm[]): AxiosPromise { + return request({ + url: '/cw/monitoring/batch', + method: 'post', + data: { + evaluationId, + list + } + }) +} + +/** + * 修改月度监控 + */ +export function updateMonitoring(data: CwProjectMonthlyMonitoringForm): AxiosPromise { + 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 { + return request({ + url: `/cw/performanceMonitoring/list/${evaluationId}`, + method: 'get' + }) +} + +/** + * 获取绩效运行监控详情 + */ +export function getPerformanceMonitoring(id: number): AxiosPromise { + return request({ + url: `/cw/performanceMonitoring/${id}`, + method: 'get' + }) +} + +/** + * 新增绩效运行监控 + */ +export function addPerformanceMonitoring(data: PerformanceMonitoringForm): AxiosPromise { + return request({ + url: '/cw/performanceMonitoring', + method: 'post', + data + }) +} + +/** + * 修改绩效运行监控 + */ +export function updatePerformanceMonitoring(data: PerformanceMonitoringForm): AxiosPromise { + return request({ + url: '/cw/performanceMonitoring', + method: 'put', + data + }) +} + +/** + * 删除绩效运行监控 + */ +export function delPerformanceMonitoring(id: number): AxiosPromise { + return request({ + url: `/cw/performanceMonitoring/${id}`, + method: 'delete' + }) +} + diff --git a/web/src/styles/club-common.scss b/web/src/styles/club-common.scss new file mode 100644 index 00000000..6d0be383 --- /dev/null +++ b/web/src/styles/club-common.scss @@ -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; + } + } +} diff --git a/web/src/views/cw/evaluation/components/MonitoringDialog.vue b/web/src/views/cw/evaluation/components/MonitoringDialog.vue new file mode 100644 index 00000000..869801dd --- /dev/null +++ b/web/src/views/cw/evaluation/components/MonitoringDialog.vue @@ -0,0 +1,668 @@ + + + + + + diff --git a/web/src/views/cw/evaluation/index.vue b/web/src/views/cw/evaluation/index.vue new file mode 100644 index 00000000..ccb03308 --- /dev/null +++ b/web/src/views/cw/evaluation/index.vue @@ -0,0 +1,1000 @@ + + + + + diff --git a/web/src/views/cw/evaluation/table-form.vue b/web/src/views/cw/evaluation/table-form.vue new file mode 100644 index 00000000..060014e6 --- /dev/null +++ b/web/src/views/cw/evaluation/table-form.vue @@ -0,0 +1,1087 @@ + + + + + diff --git a/web/src/views/cw/monitoring/index.vue b/web/src/views/cw/monitoring/index.vue new file mode 100644 index 00000000..8d09b438 --- /dev/null +++ b/web/src/views/cw/monitoring/index.vue @@ -0,0 +1,446 @@ + + + + + + diff --git a/web/src/views/cw/monitoringManagement/index.vue b/web/src/views/cw/monitoringManagement/index.vue new file mode 100644 index 00000000..09ce608f --- /dev/null +++ b/web/src/views/cw/monitoringManagement/index.vue @@ -0,0 +1,488 @@ + + + + + +