fix(project): 修复项目执行管理中的多项问题并优化字典数据功能

- 修复字典数据分页接口命名错误,从 getDictTypePage 改为 getDictDataPage
- 修复字典数据查询排序逻辑,从 orderByDesc 改为 orderByAsc 并增加 id 排序
- 更新字典数据分页请求参数验证,将 dictType 设为必填项并添加非空验证
- 在字典数据简单响应对象中添加备注字段
- 修复项目执行删除权限验证,允许非初始态执行删除但阻止已完成执行删除
- 添加项目执行和任务优先级验证错误码常量
- 优化项目执行删除逻辑,支持级联软删相关任务、工作日志和协办数据
- 添加项目需求关联验证,防止无效需求关联到执行
- 修复执行协办数据批量删除方法的参数验证逻辑
- 添加工时完成难度验证错误码,完善项目需求删除前检查机制
- 更新 CLAUDE.md 文档,补充种子 SQL 编写规范和雪花 ID 处理说明
This commit is contained in:
2026-05-21 21:17:54 +08:00
parent 19637d74a4
commit 1bee5eb05b
45 changed files with 1439 additions and 76 deletions

View File

@@ -123,6 +123,7 @@ public interface ErrorCodeConstants {
ErrorCode PROJECT_EXECUTION_ASSIGNEE_ALREADY_EXISTS = new ErrorCode(1_008_003_004, "该用户已是当前执行的有效协办人");
ErrorCode PROJECT_EXECUTION_ASSIGNEE_NOT_EXISTS = new ErrorCode(1_008_003_005, "执行协办人不存在");
ErrorCode PROJECT_EXECUTION_ASSIGNEE_NOT_ACTIVE = new ErrorCode(1_008_003_006, "当前执行协办人已失效");
// 保留TD-013 解锁后业务路径已不会再触发,预留用于灰度回滚关闭关联能力
ErrorCode PROJECT_EXECUTION_REQUIREMENT_NOT_READY = new ErrorCode(1_008_003_007, "当前阶段不支持给执行绑定项目需求");
ErrorCode PROJECT_EXECUTION_NOT_ALLOW_EDIT = new ErrorCode(1_008_003_008, "当前项目状态不允许维护执行");
ErrorCode PROJECT_EXECUTION_OWNER_HANDOFF_REQUIRED = new ErrorCode(1_008_003_009, "该项目成员仍担任未终态执行负责人,请先完成执行负责人交接");
@@ -135,9 +136,13 @@ public interface ErrorCodeConstants {
ErrorCode PROJECT_EXECUTION_ASSIGNEE_REQUIRED = new ErrorCode(1_008_003_016, "创建执行时必须至少选择一名执行协办人");
ErrorCode PROJECT_EXECUTION_STATUS_OWNER_ONLY = new ErrorCode(1_008_003_017, "只有执行负责人才能执行【{}】动作");
ErrorCode PROJECT_EXECUTION_COMPLETE_TASKS_REQUIRED = new ErrorCode(1_008_003_018, "完成执行前,执行下所有任务必须全部完成或取消");
ErrorCode PROJECT_EXECUTION_NOT_ALLOW_DELETE = new ErrorCode(1_008_003_019, "仅初始态(待开始)的执行允许删除");
ErrorCode PROJECT_EXECUTION_NOT_ALLOW_DELETE = new ErrorCode(1_008_003_019, "已完成的执行允许删除");
ErrorCode PROJECT_EXECUTION_DELETE_NAME_MISMATCH = new ErrorCode(1_008_003_020, "确认执行名称与实际不一致");
ErrorCode PROJECT_EXECUTION_DELETE_CONFIRM_TEXT_INVALID = new ErrorCode(1_008_003_021, "删除确认口令必须为 DELETE 或 删除");
ErrorCode PROJECT_EXECUTION_PRIORITY_INVALID = new ErrorCode(1_008_003_022, "执行优先级不是有效字典值");
ErrorCode PROJECT_EXECUTION_REQUIREMENT_NOT_EXISTS = new ErrorCode(1_008_003_023, "关联的项目需求不存在或已删除");
ErrorCode PROJECT_EXECUTION_REQUIREMENT_NOT_BELONG_TO_PROJECT = new ErrorCode(1_008_003_024, "关联的项目需求不属于当前项目");
ErrorCode PROJECT_EXECUTION_REQUIREMENT_TERMINAL = new ErrorCode(1_008_003_025, "项目需求已处于终态,不允许关联新执行");
// ========== 任务管理 1-008-004-000 ==========
ErrorCode PROJECT_TASK_NOT_EXISTS = new ErrorCode(1_008_004_000, "任务不存在");
@@ -151,9 +156,10 @@ public interface ErrorCodeConstants {
ErrorCode PROJECT_TASK_STATUS_NOT_ALLOW_EDIT = new ErrorCode(1_008_004_008, "当前任务状态不允许维护任务");
ErrorCode PROJECT_TASK_COMPLETE_CHILDREN_REQUIRED = new ErrorCode(1_008_004_010, "父任务完成前,子任务必须全部完成或取消");
ErrorCode PROJECT_TASK_STATUS_OWNER_ONLY = new ErrorCode(1_008_004_011, "只有任务负责人才能执行【{}】动作");
ErrorCode PROJECT_TASK_NOT_ALLOW_DELETE = new ErrorCode(1_008_004_012, "仅初始态(待开始)的任务允许删除");
ErrorCode PROJECT_TASK_NOT_ALLOW_DELETE = new ErrorCode(1_008_004_012, "已完成的任务允许删除");
ErrorCode PROJECT_TASK_DELETE_NAME_MISMATCH = new ErrorCode(1_008_004_013, "确认任务名称与实际不一致");
ErrorCode PROJECT_TASK_DELETE_CONFIRM_TEXT_INVALID = new ErrorCode(1_008_004_014, "删除确认口令必须为 DELETE 或 删除");
ErrorCode PROJECT_TASK_PRIORITY_INVALID = new ErrorCode(1_008_004_015, "任务优先级不是有效字典值");
ErrorCode PROJECT_TASK_LEAF_TO_PARENT_FORBIDDEN_PROGRESS = new ErrorCode(1_008_004_012, "拆子任务前请先将父任务进度清零");
ErrorCode PROJECT_TASK_LEAF_TO_PARENT_FORBIDDEN_WORKLOG = new ErrorCode(1_008_004_013, "拆子任务前请先删除父任务下已填的工时记录");
@@ -175,6 +181,7 @@ public interface ErrorCodeConstants {
ErrorCode PROJECT_TASK_WORKLOG_DATE_RANGE_INVALID = new ErrorCode(1_008_006_007, "段起始日期不能晚于段结束日期");
ErrorCode PROJECT_TASK_WORKLOG_DATE_OVERLAP = new ErrorCode(1_008_006_008, "日期范围与该任务下您已有的工时记录重叠");
ErrorCode PROJECT_TASK_WORKLOG_PROGRESS_NOT_MONOTONIC = new ErrorCode(1_008_006_010, "工时进度与日期顺序不一致:早段进度不得高于晚段、晚段进度不得低于早段");
ErrorCode PROJECT_TASK_WORKLOG_DIFFICULTY_INVALID = new ErrorCode(1_008_006_011, "完成难度不在字典范围内");
// ========== 任务 / 工时附件 1_008_007_xxx ==========
ErrorCode PROJECT_TASK_ATTACHMENT_TOO_MANY = new ErrorCode(1_008_007_001, "附件数量不能超过 {} 个");
@@ -201,6 +208,7 @@ public interface ErrorCodeConstants {
ErrorCode PROJECT_REQUIREMENT_MODULE_HAS_CHILDREN = new ErrorCode(1_008_007_015, "存在子模块,请先删除子模块");
ErrorCode PROJECT_REQUIREMENT_MODULE_HAS_REQUIREMENTS = new ErrorCode(1_008_007_016, "模块下存在项目需求,请先删除需求");
ErrorCode PROJECT_REQUIREMENT_CHILD_NOT_ALLOW_CANCEL = new ErrorCode(1_008_007_017, "只有不存在子需求,或子需求都处于已取消和已拒绝状态时,父需求才允许取消");
ErrorCode PROJECT_REQUIREMENT_HAS_EXECUTIONS_NOT_ALLOW_DELETE = new ErrorCode(1_008_007_018, "该项目需求下存在承接执行,请先解绑或转移");
ErrorCode PROJECT_REQUIREMENT_SYNCED_FROM_PRODUCT_NOT_ALLOW_CANCEL = new ErrorCode(1_008_007_019, "\u7531\u4ea7\u54c1\u9700\u6c42\u6d41\u8f6c\u751f\u6210\u7684\u9879\u76ee\u9700\u6c42\u4e0d\u5141\u8bb8\u53d6\u6d88");
// ========== 个人事项 1_008_008_xxx ==========

View File

@@ -15,4 +15,14 @@ public interface ProjectDictTypeConstants {
*/
String EXECUTION_TYPE = "rdms_project_execution_type";
/**
* 优先级(任务 / 执行 共用P0=最高 ~ P3=最低)。
*/
String REQ_PRIORITY = "rdms_req_priority";
/**
* 工时完成难度。
*/
String WORKLOG_DIFFICULTY = "rdms_worklog_difficulty";
}