From e82060a8c8b26b9ca7004156a76902aee03efeb0 Mon Sep 17 00:00:00 2001 From: wkc <978997012@qq.com> Date: Thu, 26 Feb 2026 16:31:24 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=B7=BB=E5=8A=A0=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E5=8A=9F=E8=83=BD=E8=AE=BE=E8=AE=A1=E6=96=87?= =?UTF-8?q?=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/plans/2026-02-26-create-project-design.md | 902 ++++++++++++++++++ .../ScreenShot_2026-02-26_153149_900.png | Bin 0 -> 22005 bytes doc/创建项目功能/task.md | 0 3 files changed, 902 insertions(+) create mode 100644 doc/plans/2026-02-26-create-project-design.md create mode 100644 doc/创建项目功能/ScreenShot_2026-02-26_153149_900.png create mode 100644 doc/创建项目功能/task.md diff --git a/doc/plans/2026-02-26-create-project-design.md b/doc/plans/2026-02-26-create-project-design.md new file mode 100644 index 0000000..b597bb2 --- /dev/null +++ b/doc/plans/2026-02-26-create-project-design.md @@ -0,0 +1,902 @@ +# 创建项目功能设计文档 + +**文档版本:** v1.0 +**创建日期:** 2026-02-26 +**设计人员:** Claude Code + +--- + +## 1. 概述 + +### 1.1 功能描述 + +新增"创建项目"功能,允许用户在首页点击"新建项目"按钮后,通过弹窗表单创建新的纪检初核项目。 + +### 1.2 核心需求 + +- 弹窗包含3个字段:项目名称、项目描述、配置方式 +- 配置方式为单选按钮:全局默认模型参数配置 / 自定义项目规则参数配置 +- 项目列表展示项目名称和描述(上下排列)、状态、目标人数、预警人数、创建人、创建时间 +- 预警人数为各级别风险人数之和,悬停显示详细分布 + +--- + +## 2. 数据库设计 + +### 2.1 表结构 + +**表名:** `ccdi_project` + +**字段列表:** + +| 字段名 | 类型 | 长度 | 必填 | 默认值 | 说明 | +|--------|------|------|------|--------|------| +| project_id | BIGINT | - | 是 | 自增 | 项目ID(主键) | +| project_name | VARCHAR | 100 | 是 | - | 项目名称 | +| project_desc | VARCHAR | 500 | 否 | NULL | 项目描述 | +| config_type | VARCHAR | 20 | 是 | 'default' | 配置方式:default-全局默认,custom-自定义 | +| project_status | CHAR | 1 | 是 | '0' | 项目状态:0-进行中,1-已完成,2-已归档 | +| target_count | INT | - | 是 | 0 | 目标人数 | +| high_risk_count | INT | - | 是 | 0 | 高风险人数 | +| medium_risk_count | INT | - | 是 | 0 | 中风险人数 | +| low_risk_count | INT | - | 是 | 0 | 低风险人数 | +| create_by | VARCHAR | 64 | 否 | '' | 创建者 | +| create_time | DATETIME | - | 否 | CURRENT_TIMESTAMP | 创建时间 | +| update_by | VARCHAR | 64 | 否 | '' | 更新者 | +| update_time | DATETIME | - | 否 | CURRENT_TIMESTAMP | 更新时间 | +| remark | VARCHAR | 500 | 否 | NULL | 备注 | + +**索引设计:** +- 主键索引:`PRIMARY KEY (project_id)` +- 项目名称索引:`INDEX idx_project_name (project_name)` +- 项目状态索引:`INDEX idx_project_status (project_status)` +- 创建时间索引:`INDEX idx_create_time (create_time)` + +### 2.2 SQL 脚本 + +```sql +-- 创建项目表 +CREATE TABLE `ccdi_project` ( + `project_id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '项目ID', + `project_name` VARCHAR(100) NOT NULL COMMENT '项目名称', + `project_desc` VARCHAR(500) DEFAULT NULL COMMENT '项目描述', + `config_type` VARCHAR(20) NOT NULL DEFAULT 'default' COMMENT '配置方式:default-全局默认,custom-自定义', + `project_status` CHAR(1) NOT NULL DEFAULT '0' COMMENT '项目状态:0-进行中,1-已完成,2-已归档', + `target_count` INT NOT NULL DEFAULT 0 COMMENT '目标人数', + `high_risk_count` INT NOT NULL DEFAULT 0 COMMENT '高风险人数', + `medium_risk_count` INT NOT NULL DEFAULT 0 COMMENT '中风险人数', + `low_risk_count` INT NOT NULL DEFAULT 0 COMMENT '低风险人数', + `create_by` VARCHAR(64) DEFAULT '' COMMENT '创建者', + `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_by` VARCHAR(64) DEFAULT '' COMMENT '更新者', + `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `remark` VARCHAR(500) DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`project_id`), + INDEX `idx_project_name` (`project_name`), + INDEX `idx_project_status` (`project_status`), + INDEX `idx_create_time` (`create_time`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='纪检初核项目表'; + +-- 插入项目状态字典 +INSERT INTO sys_dict_type (dict_name, dict_type, status, create_by, create_time, remark) +VALUES ('项目状态', 'ccdi_project_status', '0', 'admin', NOW(), '纪检初核项目状态'); + +INSERT INTO sys_dict_data (dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time) +VALUES +(1, '进行中', '0', 'ccdi_project_status', '', 'primary', 'Y', '0', 'admin', NOW()), +(2, '已完成', '1', 'ccdi_project_status', '', 'success', 'N', '0', 'admin', NOW()), +(3, '已归档', '2', 'ccdi_project_status', '', 'info', 'N', '0', 'admin', NOW()); + +-- 插入配置方式字典 +INSERT INTO sys_dict_type (dict_name, dict_type, status, create_by, create_time, remark) +VALUES ('配置方式', 'ccdi_config_type', '0', 'admin', NOW(), '项目配置方式'); + +INSERT INTO sys_dict_data (dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time) +VALUES +(1, '全局默认模型参数配置', 'default', 'ccdi_config_type', '', 'primary', 'Y', '0', 'admin', NOW()), +(2, '自定义项目规则参数配置', 'custom', 'ccdi_config_type', '', 'warning', 'N', '0', 'admin', NOW()); + +-- 插入菜单权限 +INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, menu_type, visible, status, perms, icon, create_by, create_time) +VALUES ('纪检初核管理', 0, 1, 'ccdi', NULL, 'M', '0', '0', '', 'monitor', 'admin', NOW()); + +SET @parent_id = LAST_INSERT_ID(); + +INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, menu_type, visible, status, perms, icon, create_by, create_time) +VALUES ('项目管理', @parent_id, 1, 'project', 'ccdiProject/index', 'C', '0', '0', 'ccdi:project:list', 'project', 'admin', NOW()); + +SET @menu_id = LAST_INSERT_ID(); + +INSERT INTO sys_menu (menu_name, parent_id, order_num, menu_type, visible, status, perms, create_by, create_time) +VALUES +('创建项目', @menu_id, 1, 'F', '0', '0', 'ccdi:project:add', 'admin', NOW()), +('编辑项目', @menu_id, 2, 'F', '0', '0', 'ccdi:project:edit', 'admin', NOW()), +('删除项目', @menu_id, 3, 'F', '0', '0', 'ccdi:project:remove', 'admin', NOW()), +('查询项目', @menu_id, 4, 'F', '0', '0', 'ccdi:project:query', 'admin', NOW()); + +-- 为管理员角色分配权限 +INSERT INTO sys_role_menu (role_id, menu_id) +SELECT 1, menu_id FROM sys_menu WHERE perms LIKE 'ccdi:project:%' OR perms = 'ccdi:project:list'; +``` + +--- + +## 3. 后端架构设计 + +### 3.1 实体类 + +**类名:** `CcdiProject` +**位置:** `ruoyi-info-collection/src/main/java/com/ruoyi/info/collection/domain/` + +```java +@Data +public class CcdiProject { + /** 项目ID */ + private Long projectId; + + /** 项目名称 */ + private String projectName; + + /** 项目描述 */ + private String projectDesc; + + /** 配置方式:default-全局默认,custom-自定义 */ + private String configType; + + /** 项目状态:0-进行中,1-已完成,2-已归档 */ + private String projectStatus; + + /** 目标人数 */ + private Integer targetCount; + + /** 高风险人数 */ + private Integer highRiskCount; + + /** 中风险人数 */ + private Integer mediumRiskCount; + + /** 低风险人数 */ + private Integer lowRiskCount; + + /** 创建者 */ + private String createBy; + + /** 创建时间 */ + private Date createTime; + + /** 更新者 */ + private String updateBy; + + /** 更新时间 */ + private Date updateTime; + + /** 备注 */ + private String remark; +} +``` + +### 3.2 DTO 设计 + +**类名:** `CcdiProjectSaveDTO` +**位置:** `ruoyi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/` + +```java +@Data +public class CcdiProjectSaveDTO { + /** 项目名称(必填) */ + @NotBlank(message = "项目名称不能为空") + @Length(max = 100, message = "项目名称长度不能超过100个字符") + private String projectName; + + /** 项目描述(可选) */ + @Length(max = 500, message = "项目描述长度不能超过500个字符") + private String projectDesc; + + /** 配置方式(必填):default-全局默认,custom-自定义 */ + @NotBlank(message = "配置方式不能为空") + private String configType; +} +``` + +### 3.3 VO 设计 + +**类名:** `CcdiProjectVO` +**位置:** `ruoyi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/` + +```java +@Data +public class CcdiProjectVO { + /** 项目ID */ + private Long projectId; + + /** 项目名称 */ + private String projectName; + + /** 项目描述 */ + private String projectDesc; + + /** 配置方式 */ + private String configType; + + /** 项目状态 */ + private String projectStatus; + + /** 目标人数 */ + private Integer targetCount; + + /** 高风险人数 */ + private Integer highRiskCount; + + /** 中风险人数 */ + private Integer mediumRiskCount; + + /** 低风险人数 */ + private Integer lowRiskCount; + + /** 创建时间 */ + private Date createTime; + + /** 创建者 */ + private String createBy; +} +``` + +### 3.4 Controller 接口 + +**类名:** `CcdiProjectController` +**位置:** `ruoyi-info-collection/src/main/java/com/ruoyi/info/collection/controller/` + +**接口列表:** + +| 接口路径 | 方法 | 说明 | 权限标识 | +|---------|------|------|---------| +| `/ccdi/project` | POST | 创建项目 | `ccdi:project:add` | +| `/ccdi/project` | PUT | 更新项目 | `ccdi:project:edit` | +| `/ccdi/project/{projectId}` | DELETE | 删除项目 | `ccdi:project:remove` | +| `/ccdi/project/{projectId}` | GET | 查询项目详情 | `ccdi:project:query` | +| `/ccdi/project/list` | GET | 查询项目列表(分页) | `ccdi:project:list` | + +**示例代码:** + +```java +@RestController +@RequestMapping("/ccdi/project") +@Api(tags = "纪检初核项目管理") +public class CcdiProjectController extends BaseController { + + @Resource + private ICcdiProjectService projectService; + + @PostMapping + @ApiOperation("创建项目") + @PreAuthorize("@ss.hasPermi('ccdi:project:add')") + public AjaxResult createProject(@Validated @RequestBody CcdiProjectSaveDTO dto) { + CcdiProjectVO vo = projectService.createProject(dto); + return AjaxResult.success("项目创建成功", vo); + } + + @GetMapping("/list") + @ApiOperation("查询项目列表") + @PreAuthorize("@ss.hasPermi('ccdi:project:list')") + public TableDataInfo listProject(CcdiProjectQueryDTO queryDTO) { + PageDomain pageDomain = TableSupport.buildPageRequest(); + Page page = new Page<>(pageDomain.getPageNum(), pageDomain.getPageSize()); + Page result = projectService.selectProjectPage(page, queryDTO); + return getDataTable(result.getRecords(), result.getTotal()); + } +} +``` + +### 3.5 Service 层 + +**接口名:** `ICcdiProjectService` +**实现类名:** `CcdiProjectServiceImpl` +**位置:** `ruoyi-info-collection/src/main/java/com/ruoyi/info/collection/service/` + +```java +public interface ICcdiProjectService { + /** + * 创建项目 + * @param dto 项目保存DTO + * @return 项目VO + */ + CcdiProjectVO createProject(CcdiProjectSaveDTO dto); + + /** + * 更新项目 + * @param dto 项目更新DTO + * @return 项目VO + */ + CcdiProjectVO updateProject(CcdiProjectSaveDTO dto); + + /** + * 删除项目 + * @param projectId 项目ID + * @return 是否成功 + */ + boolean deleteProject(Long projectId); + + /** + * 查询项目详情 + * @param projectId 项目ID + * @return 项目VO + */ + CcdiProjectVO getProjectById(Long projectId); + + /** + * 分页查询项目列表 + * @param page 分页对象 + * @param queryDTO 查询条件 + * @return 分页结果 + */ + Page selectProjectPage(Page page, CcdiProjectQueryDTO queryDTO); +} +``` + +**实现类示例:** + +```java +@Service +public class CcdiProjectServiceImpl implements ICcdiProjectService { + + @Resource + private CcdiProjectMapper projectMapper; + + @Override + public CcdiProjectVO createProject(CcdiProjectSaveDTO dto) { + CcdiProject project = new CcdiProject(); + BeanUtils.copyProperties(dto, project); + + // 设置默认值 + project.setProjectStatus("0"); // 进行中 + project.setTargetCount(0); + project.setHighRiskCount(0); + project.setMediumRiskCount(0); + project.setLowRiskCount(0); + + projectMapper.insert(project); + + CcdiProjectVO vo = new CcdiProjectVO(); + BeanUtils.copyProperties(project, vo); + return vo; + } +} +``` + +### 3.6 Mapper 层 + +**接口名:** `CcdiProjectMapper` +**位置:** `ruoyi-info-collection/src/main/java/com/ruoyi/info/collection/mapper/` + +```java +public interface CcdiProjectMapper extends BaseMapper { + /** + * 分页查询项目列表 + * @param page 分页对象 + * @param queryDTO 查询条件 + * @return 分页结果 + */ + Page selectProjectPage(Page page, @Param("queryDTO") CcdiProjectQueryDTO queryDTO); +} +``` + +**XML 文件:** `CcdiProjectMapper.xml` +**位置:** `ruoyi-info-collection/src/main/resources/mapper/info/collection/` + +```xml + + + + + + + + + + + + + + + + + + + + + +``` + +--- + +## 4. 前端架构设计 + +### 4.1 组件修改 + +**组件名称:** `AddProjectDialog.vue` +**位置:** `ruoyi-ui/src/views/ccdiProject/components/` + +**修改内容:** + +1. **简化表单字段**:只保留项目名称、项目描述、配置方式3个字段 +2. **移除字段**:目标人员、开始日期、结束日期、目标人数、高级设置 +3. **默认值**:配置方式默认为 `'default'` + +**关键代码:** + +```vue + + + + + +``` + +### 4.2 项目列表表格 + +**组件名称:** `ProjectTable.vue` +**位置:** `ruoyi-ui/src/views/ccdiProject/components/` + +**关键特性:** + +1. **项目名称和描述上下排列**:同一单元格内,项目名称加粗深色,项目描述常规浅色 +2. **预警人数悬停提示**:显示高、中、低风险人数详细分布 +3. **预警人数样式**:根据风险级别自动调整颜色 + +**表格列配置:** + +| 列名 | 宽度 | 对齐方式 | 说明 | +|------|------|---------|------| +| 项目名称 | 最小300px | 左对齐 | 包含项目名称(上)+项目描述(下),自适应 | +| 项目状态 | 100px | 居中对齐 | 固定宽度 | +| 目标人数 | 100px | 居中对齐 | 固定宽度 | +| 预警人数 | 120px | 居中对齐 | 悬停显示详细风险分布 | +| 创建人 | 120px | 居中对齐 | 固定宽度 | +| 创建时间 | 160px | 居中对齐 | 格式化显示 | +| 操作 | 280px | 居中对齐 | 固定在右侧 | + +**关键代码:** + +```vue + + + + + + + + + +``` + +**样式代码:** + +```scss +.project-info-cell { + padding: 8px 0; + line-height: 1.5; + + .project-name { + font-size: 14px; + font-weight: 600; + color: #303133; + margin-bottom: 4px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .project-desc { + font-size: 12px; + color: #909399; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } +} + +.text-danger { + color: #f56c6c; +} + +.text-warning { + color: #e6a23c; +} + +.text-info { + color: #909399; +} + +.text-bold { + font-weight: bold; +} +``` + +**预警人数样式规则:** + +- 高风险 > 0:红色加粗 +- 中风险 > 0:橙色加粗 +- 低风险 > 0:灰色 +- 无预警:普通黑色 + +### 4.3 API 接口 + +**文件名:** `ccdiProject.js` +**位置:** `ruoyi-ui/src/api/` + +```javascript +import request from '@/utils/request' + +// 创建初核项目 +export function createProject(data) { + return request({ + url: '/ccdi/project', + method: 'post', + data: data + }) +} + +// 查询初核项目列表(分页) +export function listProject(query) { + return request({ + url: '/ccdi/project/list', + method: 'get', + params: query + }) +} + +// 查询初核项目详细 +export function getProject(projectId) { + return request({ + url: '/ccdi/project/' + projectId, + method: 'get' + }) +} + +// 修改初核项目 +export function updateProject(data) { + return request({ + url: '/ccdi/project', + method: 'put', + data: data + }) +} + +// 删除初核项目 +export function delProject(projectId) { + return request({ + url: '/ccdi/project/' + projectId, + method: 'delete' + }) +} +``` + +--- + +## 5. 实施计划 + +### 5.1 实施步骤 + +#### 阶段一:数据库与后端开发(预计 2.5 小时) + +1. **创建数据库表**(15 分钟) + - 执行 `ccdi_project` 表创建脚本 + - 插入字典数据和菜单数据 + +2. **后端开发**(2 小时) + - 创建实体类 `CcdiProject` + - 创建 DTO `CcdiProjectSaveDTO` + - 创建 VO `CcdiProjectVO` + - 创建 Mapper 接口和 XML + - 创建 Service 接口和实现类 + - 创建 Controller 接口 + - 添加 Swagger 注解 + +3. **后端测试**(30 分钟) + - 使用 Swagger 测试创建项目接口 + - 使用 Swagger 测试查询项目列表接口 + - 验证数据字典显示 + +#### 阶段二:前端开发(预计 2.5 小时) + +4. **前端组件开发**(1.5 小时) + - 修改 `AddProjectDialog.vue` 组件 + - 修改 `ProjectTable.vue` 组件 + - 更新 API 接口文件 `ccdiProject.js` + - 修改父组件调用逻辑 + +5. **前端联调**(1 小时) + - 测试创建项目功能 + - 测试项目列表显示 + - 测试预警人数悬停提示 + - 测试字典数据展示 + +--- + +## 6. 注意事项 + +### 6.1 数据完整性 + +- 创建项目时,`project_status` 默认为 `'0'`(进行中) +- 创建项目时,风险计数字段默认为 `0` +- `config_type` 默认为 `'default'` +- 项目名称和描述不能为空 + +### 6.2 权限控制 + +- 创建项目需要 `ccdi:project:add` 权限 +- 编辑项目需要 `ccdi:project:edit` 权限 +- 删除项目需要 `ccdi:project:remove` 权限 +- 查询项目需要 `ccdi:project:list` 权限 + +### 6.3 前端验证 + +- 项目名称:必填,2-100字符 +- 项目描述:可选,最多500字符 +- 配置方式:必填,只能选择 `default` 或 `custom` + +### 6.4 后端验证 + +- 使用 `@Validated` 注解进行参数校验 +- 项目名称长度校验 +- 配置方式枚举值校验 + +### 6.5 性能优化 + +- 项目列表分页查询 +- 项目名称和状态字段添加索引 +- 字典数据使用缓存 + +### 6.6 用户体验 + +- 提交按钮显示 loading 状态 +- 创建成功后自动刷新列表 +- 预警人数悬停提示详细信息 +- 项目名称和描述上下排列,层次分明 + +--- + +## 7. 测试清单 + +### 7.1 后端测试 + +- [ ] 创建项目成功(必填字段) +- [ ] 创建项目失败(缺少必填字段) +- [ ] 创建项目失败(字段长度超限) +- [ ] 查询项目列表(分页) +- [ ] 查询项目详情 +- [ ] 更新项目 +- [ ] 删除项目 +- [ ] 字典数据正确返回 +- [ ] 权限验证正确 + +### 7.2 前端测试 + +- [ ] 弹窗显示正确(3个字段) +- [ ] 表单验证正常(必填项) +- [ ] 表单验证正常(长度限制) +- [ ] 项目名称和描述上下排列 +- [ ] 项目名称样式正确(加粗深色) +- [ ] 项目描述样式正确(常规浅色) +- [ ] 项目状态标签正确显示 +- [ ] 预警人数计算正确(高+中+低) +- [ ] 预警人数悬停提示显示 +- [ ] 预警人数颜色根据风险级别变化 +- [ ] 创建人正确显示 +- [ ] 创建时间格式化正确 +- [ ] 操作按钮权限控制 +- [ ] 提交按钮 loading 状态 +- [ ] 创建成功后列表刷新 + +--- + +## 8. 附录 + +### 8.1 参考文档 + +- 若依框架官方文档 +- Element UI 组件库文档 +- MyBatis Plus 官方文档 + +### 8.2 相关文件 + +- 数据库脚本:`sql/ccdi_project.sql` +- 设计截图:`doc/创建项目功能/ScreenShot_2026-02-26_153149_900.png` +- 设计截图:`doc/创建项目功能/ScreenShot_2026-02-26_162233_965.png` + +--- + +**文档结束** diff --git a/doc/创建项目功能/ScreenShot_2026-02-26_153149_900.png b/doc/创建项目功能/ScreenShot_2026-02-26_153149_900.png new file mode 100644 index 0000000000000000000000000000000000000000..d34f68b502c826def6e23c84f19703537d124040 GIT binary patch literal 22005 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 literal 0 HcmV?d00001 diff --git a/doc/创建项目功能/task.md b/doc/创建项目功能/task.md new file mode 100644 index 0000000..e69de29