mirror of
https://gitee.com/zhijiantianya/yudao-cloud.git
synced 2026-10-06 07:22:58 +08:00
【同步】BOOT 和 CLOUD 的功能(pms)
This commit is contained in:
@@ -31,6 +31,7 @@
|
||||
<module>yudao-module-ai</module>
|
||||
<module>yudao-module-hrm</module>
|
||||
<module>yudao-module-fms</module>
|
||||
<module>yudao-module-pms</module>
|
||||
</modules>
|
||||
|
||||
<name>${project.artifactId}</name>
|
||||
|
||||
@@ -4204,7 +4204,7 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (8052, '知识库创建', 'pms:kb:library:create', 3, 2, 8050, '', '', '', '', 0, b'1', b'1', b'1', '1', '2026-08-19 00:28:42', '1', '2026-08-23 16:21:39', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (8053, '知识库修改', 'pms:kb:library:update', 3, 3, 8050, '', '', '', '', 0, b'1', b'1', b'1', '1', '2026-08-19 00:28:42', '1', '2026-08-23 16:21:39', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (8054, '知识库删除', 'pms:kb:library:delete', 3, 4, 8050, '', '', '', '', 0, b'1', b'1', b'1', '1', '2026-08-19 00:28:42', '1', '2026-08-23 16:21:39', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (8060, '我的关注', 'pms:kb:knowledge-library:query', 2, 40, 8090, 'collection', 'ep:star', 'pms/kb/collection/index', 'PmsKnowledgeCollection', 0, b'1', b'1', b'0', '1', '2026-08-19 03:05:49', '1', '2026-08-23 16:12:56', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (8060, '我的关注', 'pms:kb:knowledge-library:query', 2, 40, 8090, 'favorite', 'ep:star', 'pms/kb/favorite/index', 'PmsKnowledgeFavorite', 0, b'1', b'1', b'0', '1', '2026-08-19 03:05:49', '1', '2026-08-23 16:12:56', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (8070, '最近使用', 'pms:kb:knowledge-library:query', 2, 50, 8090, 'recent', 'ep:clock', 'pms/kb/recent/index', 'PmsKnowledgeRecent', 0, b'1', b'1', b'0', '1', '2026-08-19 03:05:49', '1', '2026-08-23 16:12:56', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (8080, '项目中心', '', 1, 10, 8000, 'pm', 'ep:grid', NULL, NULL, 0, b'1', b'1', b'1', '1', '2026-08-19 11:42:30', '1', '2026-08-20 09:05:58', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (8081, '归档项目', 'pms:pm:project:query', 2, 30, 8080, 'project/archive', 'ep:box', 'pms/pm/project/archive/index', 'PmsProjectArchive', 0, b'1', b'0', b'0', '1', '2026-08-19 11:42:30', '1', '2026-08-27 10:01:06', b'0');
|
||||
|
||||
+6
@@ -43,6 +43,12 @@ public class BannerApplicationRunner implements ApplicationRunner {
|
||||
System.out.println("[CRM 系统 yudao-module-crm - 教程][参考 https://cloud.iocoder.cn/crm/build/ 开启]");
|
||||
// MES 系统
|
||||
System.out.println("[MES 系统 yudao-module-mes - 教程][参考 https://cloud.iocoder.cn/mes/build/ 开启]");
|
||||
// HRM 人力资源管理系统
|
||||
System.out.println("[HRM 人力资源管理系统 yudao-module-hrm - 教程][参考 https://cloud.iocoder.cn/hrm/build/ 开启]");
|
||||
// FMS 财务管理系统
|
||||
System.out.println("[FMS 财务管理系统 yudao-module-fms - 教程][参考 https://cloud.iocoder.cn/fms/build/ 开启]");
|
||||
// PMS 项目管理系统
|
||||
System.out.println("[PMS 项目管理系统 yudao-module-pms - 教程][参考 https://cloud.iocoder.cn/pms/build/ 开启]");
|
||||
// IM 即时通讯
|
||||
System.out.println("[IM 即时通讯 yudao-module-im - 教程][参考 https://cloud.iocoder.cn/im/build/ 开启]");
|
||||
// 微信公众号
|
||||
|
||||
+25
-7
@@ -430,43 +430,61 @@ public class GlobalExceptionHandler {
|
||||
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
|
||||
"[ERP 系统 yudao-module-erp - 表结构未导入][参考 https://cloud.iocoder.cn/erp/build/ 开启]");
|
||||
}
|
||||
// 6. WMS 仓库管理系统
|
||||
// 6. HRM 人力资源管理系统
|
||||
if (message.contains("hrm_")) {
|
||||
log.error("[HRM 人力资源管理系统 yudao-module-hrm - 表结构未导入][参考 https://cloud.iocoder.cn/hrm/build/ 开启]");
|
||||
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
|
||||
"[HRM 人力资源管理系统 yudao-module-hrm - 表结构未导入][参考 https://cloud.iocoder.cn/hrm/build/ 开启]");
|
||||
}
|
||||
// 7. FMS 财务管理系统
|
||||
if (message.contains("fms_")) {
|
||||
log.error("[FMS 财务管理系统 yudao-module-fms - 表结构未导入][参考 https://cloud.iocoder.cn/fms/build/ 开启]");
|
||||
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
|
||||
"[FMS 财务管理系统 yudao-module-fms - 表结构未导入][参考 https://cloud.iocoder.cn/fms/build/ 开启]");
|
||||
}
|
||||
// 8. PMS 项目管理系统
|
||||
if (message.contains("pms_")) {
|
||||
log.error("[PMS 项目管理系统 yudao-module-pms - 表结构未导入][参考 https://cloud.iocoder.cn/pms/build/ 开启]");
|
||||
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
|
||||
"[PMS 项目管理系统 yudao-module-pms - 表结构未导入][参考 https://cloud.iocoder.cn/pms/build/ 开启]");
|
||||
}
|
||||
// 9. WMS 仓库管理系统
|
||||
if (message.contains("wms_")) {
|
||||
log.error("[WMS 仓库管理系统 yudao-module-wms - 表结构未导入][参考 https://cloud.iocoder.cn/wms/build/ 开启]");
|
||||
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
|
||||
"[WMS 仓库管理系统 yudao-module-wms - 表结构未导入][参考 https://cloud.iocoder.cn/wms/build/ 开启]");
|
||||
}
|
||||
// 7. CRM 系统
|
||||
// 10. CRM 系统
|
||||
if (message.contains("crm_")) {
|
||||
log.error("[CRM 系统 yudao-module-crm - 表结构未导入][参考 https://cloud.iocoder.cn/crm/build/ 开启]");
|
||||
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
|
||||
"[CRM 系统 yudao-module-crm - 表结构未导入][参考 https://cloud.iocoder.cn/crm/build/ 开启]");
|
||||
}
|
||||
// 8. MES 系统
|
||||
// 11. MES 系统
|
||||
if (message.contains("mes_")) {
|
||||
log.error("[MES 系统 yudao-module-mes - 表结构未导入][参考 https://cloud.iocoder.cn/mes/build/ 开启]");
|
||||
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
|
||||
"[MES 系统 yudao-module-mes - 表结构未导入][参考 https://cloud.iocoder.cn/mes/build/ 开启]");
|
||||
}
|
||||
// 9. IM 即时通讯
|
||||
// 12. IM 即时通讯
|
||||
if (message.contains("im_")) {
|
||||
log.error("[IM 即时通讯 yudao-module-im - 表结构未导入][参考 https://cloud.iocoder.cn/im/build/ 开启]");
|
||||
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
|
||||
"[IM 即时通讯 yudao-module-im - 表结构未导入][参考 https://cloud.iocoder.cn/im/build/ 开启]");
|
||||
}
|
||||
// 10. 支付平台
|
||||
// 13. 支付平台
|
||||
if (message.contains("pay_")) {
|
||||
log.error("[支付模块 yudao-module-pay - 表结构未导入][参考 https://cloud.iocoder.cn/pay/build/ 开启]");
|
||||
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
|
||||
"[支付模块 yudao-module-pay - 表结构未导入][参考 https://cloud.iocoder.cn/pay/build/ 开启]");
|
||||
}
|
||||
// 11. AI 大模型
|
||||
// 14. AI 大模型
|
||||
if (message.contains("ai_")) {
|
||||
log.error("[AI 大模型 yudao-module-ai - 表结构未导入][参考 https://cloud.iocoder.cn/ai/build/ 开启]");
|
||||
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
|
||||
"[AI 大模型 yudao-module-ai - 表结构未导入][参考 https://cloud.iocoder.cn/ai/build/ 开启]");
|
||||
}
|
||||
// 12. IoT 物联网
|
||||
// 15. IoT 物联网
|
||||
if (message.contains("iot_")) {
|
||||
log.error("[IoT 物联网 yudao-module-iot - 表结构未导入][参考 https://doc.iocoder.cn/iot/build/ 开启]");
|
||||
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
|
||||
|
||||
@@ -230,6 +230,13 @@ spring:
|
||||
- Path=/admin-api/fms/**
|
||||
filters:
|
||||
- RewritePath=/admin-api/fms/v3/api-docs, /v3/api-docs # 配置,保证转发到 /v3/api-docs
|
||||
## pms-server 服务
|
||||
- id: pms-admin-api # 路由的编号
|
||||
uri: grayLb://pms-server
|
||||
predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组
|
||||
- Path=/admin-api/pms/**
|
||||
filters:
|
||||
- RewritePath=/admin-api/pms/v3/api-docs, /v3/api-docs # 配置,保证转发到 /v3/api-docs
|
||||
x-forwarded:
|
||||
prefix-enabled: false # 避免 Swagger 重复带上额外的 /admin-api/system 前缀
|
||||
default-filters:
|
||||
@@ -304,6 +311,9 @@ knife4j:
|
||||
- name: fms-server
|
||||
service-name: fms-server
|
||||
url: /admin-api/fms/v3/api-docs
|
||||
- name: pms-server
|
||||
service-name: pms-server
|
||||
url: /admin-api/pms/v3/api-docs
|
||||
|
||||
--- #################### 芋道相关配置 ####################
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao</artifactId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<modules>
|
||||
<module>yudao-module-pms-api</module>
|
||||
<module>yudao-module-pms-server</module>
|
||||
</modules>
|
||||
<artifactId>yudao-module-pms</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>${project.artifactId}</name>
|
||||
<description>
|
||||
pms 包下,项目管理(Project Management System)。
|
||||
例如说:项目、工作事项、迭代、看板、工时和知识库等等
|
||||
</description>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao-module-pms</artifactId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>yudao-module-pms-api</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>${project.artifactId}</name>
|
||||
<description>
|
||||
pms 模块 API,暴露给其它模块调用
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao-common</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 参数校验 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* pms API 包,定义暴露给其它模块的 API
|
||||
*/
|
||||
package cn.iocoder.yudao.module.pms.api;
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package cn.iocoder.yudao.module.pms.enums;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.RpcConstants;
|
||||
|
||||
/**
|
||||
* API 相关的枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public class ApiConstants {
|
||||
|
||||
/** 服务名,需要和 spring.application.name 保持一致。 */
|
||||
public static final String NAME = "pms-server";
|
||||
|
||||
public static final String PREFIX = RpcConstants.RPC_API_PREFIX + "/pms";
|
||||
|
||||
public static final String VERSION = "1.0.0";
|
||||
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package cn.iocoder.yudao.module.pms.enums;
|
||||
|
||||
/**
|
||||
* PMS 字典类型的枚举类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface DictTypeConstants {
|
||||
|
||||
String PMS_WORK_ITEM_PRIORITY = "pms_work_item_priority"; // PMS 工作项优先级
|
||||
String PMS_WORK_ITEM_DEFECT_TYPE = "pms_work_item_defect_type"; // PMS 工作项缺陷类型
|
||||
String PMS_PROJECT_TYPE = "pms_project_type"; // PMS 项目类型
|
||||
String PMS_PROJECT_STATUS = "pms_project_status"; // PMS 项目状态
|
||||
String PMS_PROJECT_LEVEL = "pms_project_level"; // PMS 项目优先级
|
||||
String PMS_PROJECT_GROUP_TYPE = "pms_project_group_type"; // PMS 项目分组类型
|
||||
String PMS_PROJECT_SCENE_TYPE = "pms_project_scene_type"; // PMS 项目列表场景
|
||||
String PMS_PROJECT_SORT_TYPE = "pms_project_sort_type"; // PMS 项目排序类型
|
||||
String PMS_PROJECT_MEMBER_LEVEL = "pms_project_member_level"; // PMS 项目成员权限级别
|
||||
String PMS_ITERATION_STATUS = "pms_iteration_status"; // PMS 迭代状态
|
||||
String PMS_WORK_ITEM_TYPE = "pms_work_item_type"; // PMS 工作项类型
|
||||
String PMS_WORK_ITEM_STATUS_TYPE = "pms_work_item_status_type"; // PMS 工作项语义状态
|
||||
String PMS_WORK_ITEM_LIFECYCLE_STATUS = "pms_work_item_lifecycle_status"; // PMS 工作项生命周期状态
|
||||
String PMS_KNOWLEDGE_DOCUMENT_STATUS = "pms_knowledge_document_status"; // PMS 知识文档状态
|
||||
String PMS_KNOWLEDGE_CONTENT_LEVEL = "pms_knowledge_content_level"; // PMS 知识内容协作等级
|
||||
String PMS_KNOWLEDGE_GROUP_TYPE = "pms_knowledge_group_type"; // PMS 知识库分组类型
|
||||
String PMS_KNOWLEDGE_LIBRARY_MEMBER_LEVEL = "pms_knowledge_library_member_level"; // PMS 知识库成员等级
|
||||
String PMS_KNOWLEDGE_OBJECT_TYPE = "pms_knowledge_object_type"; // PMS 知识对象类型
|
||||
String PMS_KNOWLEDGE_DOCUMENT_TYPE = "pms_knowledge_document_type"; // PMS 知识文档类型
|
||||
|
||||
}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
package cn.iocoder.yudao.module.pms.enums;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
|
||||
|
||||
/**
|
||||
* PMS 错误码常量
|
||||
*
|
||||
* PMS 系统,使用 1-053-000-000 段
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface ErrorCodeConstants {
|
||||
|
||||
// ========== 项目 1-053-100-000 ==========
|
||||
ErrorCode PROJECT_NOT_EXISTS = new ErrorCode(1_053_100_000, "项目不存在");
|
||||
ErrorCode PROJECT_ACCESS_DENIED = new ErrorCode(1_053_100_001, "无权访问该项目");
|
||||
ErrorCode PROJECT_ADMIN_REQUIRED = new ErrorCode(1_053_100_002, "只有项目管理员可以执行该操作");
|
||||
ErrorCode PROJECT_STATUS_INVALID = new ErrorCode(1_053_100_004, "当前项目状态不允许执行该操作");
|
||||
ErrorCode PROJECT_WRITE_ACCESS_DENIED = new ErrorCode(1_053_100_005, "当前项目角色无编辑权限");
|
||||
ErrorCode PROJECT_ANNOUNCEMENT_NOT_EXISTS = new ErrorCode(1_053_100_006, "项目公告不存在");
|
||||
ErrorCode PROJECT_OWNER_REQUIRED = new ErrorCode(1_053_100_007, "只有项目拥有者可以执行该操作");
|
||||
|
||||
// ========== 项目成员 1-053-105-000 ==========
|
||||
ErrorCode PROJECT_MEMBER_NOT_EXISTS = new ErrorCode(1_053_105_000, "项目成员不存在");
|
||||
ErrorCode PROJECT_MEMBER_CREATOR_CANNOT_REMOVE = new ErrorCode(1_053_105_001, "项目创建人不能移出项目");
|
||||
ErrorCode PROJECT_MEMBER_OWNER_LEVEL_CANNOT_ASSIGN = new ErrorCode(1_053_105_002,
|
||||
"项目拥有者级别不能直接分配");
|
||||
ErrorCode PROJECT_MEMBER_OWNER_CANNOT_EXIT = new ErrorCode(1_053_105_003, "项目拥有者不能退出项目");
|
||||
|
||||
// ========== 项目分组 1-053-110-000 ==========
|
||||
ErrorCode PROJECT_GROUP_NOT_EXISTS = new ErrorCode(1_053_110_000, "项目分组不存在");
|
||||
ErrorCode PROJECT_GROUP_NAME_DUPLICATE = new ErrorCode(1_053_110_001, "项目分组名称已存在");
|
||||
ErrorCode PROJECT_GROUP_DEFAULT_CANNOT_MODIFY = new ErrorCode(1_053_110_002, "默认项目分组不允许修改");
|
||||
ErrorCode PROJECT_GROUP_DEFAULT_CANNOT_DELETE = new ErrorCode(1_053_110_003, "默认项目分组不允许删除");
|
||||
|
||||
// ========== 项目模板 1-053-112-000 ==========
|
||||
ErrorCode PROJECT_TEMPLATE_NOT_EXISTS = new ErrorCode(1_053_112_000, "项目模板不存在");
|
||||
ErrorCode PROJECT_TEMPLATE_NAME_DUPLICATE = new ErrorCode(1_053_112_001, "同一项目类型下的模板名称已存在");
|
||||
ErrorCode PROJECT_TEMPLATE_CONFIG_INVALID = new ErrorCode(1_053_112_002, "项目模板配置无效:{}");
|
||||
|
||||
// ========== 项目迭代 1-053-115-000 ==========
|
||||
ErrorCode ITERATION_NOT_EXISTS = new ErrorCode(1_053_115_000, "项目迭代不存在");
|
||||
ErrorCode ITERATION_STATUS_INVALID = new ErrorCode(1_053_115_002, "当前迭代状态不允许执行该操作");
|
||||
|
||||
// ========== 工作项 1-053-120-000 ==========
|
||||
ErrorCode WORK_ITEM_NOT_EXISTS = new ErrorCode(1_053_120_000, "工作项不存在");
|
||||
ErrorCode WORK_ITEM_TYPE_INVALID = new ErrorCode(1_053_120_001, "当前项目不支持该工作项类型");
|
||||
ErrorCode WORK_ITEM_STATUS_NOT_EXISTS = new ErrorCode(1_053_120_002, "工作项状态不存在");
|
||||
ErrorCode WORK_ITEM_STATUS_INVALID = new ErrorCode(1_053_120_003, "工作项状态与项目或类型不匹配");
|
||||
ErrorCode WORK_ITEM_TIME_INVALID = new ErrorCode(1_053_120_004, "工作项开始时间必须早于截止时间");
|
||||
ErrorCode WORK_ITEM_ITERATION_INVALID = new ErrorCode(1_053_120_005, "所属迭代与工作项项目不匹配");
|
||||
ErrorCode WORK_ITEM_PARENT_INVALID = new ErrorCode(1_053_120_006, "父工作项与当前工作项不匹配");
|
||||
ErrorCode WORK_ITEM_RELATED_REQUIREMENT_INVALID = new ErrorCode(1_053_120_007, "关联需求与当前工作项不匹配");
|
||||
ErrorCode WORK_ITEM_DEFECT_TYPE_INVALID = new ErrorCode(1_053_120_008, "只有缺陷工作项可以设置缺陷类型");
|
||||
ErrorCode WORK_ITEM_SORT_INVALID = new ErrorCode(1_053_120_009, "工作项看板排序数据无效");
|
||||
ErrorCode WORK_ITEM_STATUS_NAME_DUPLICATE = new ErrorCode(1_053_120_010, "工作项状态名称已存在");
|
||||
ErrorCode WORK_ITEM_STATUS_DEFAULT_CANNOT_DELETE = new ErrorCode(1_053_120_011, "工作项初始状态不能删除");
|
||||
ErrorCode WORK_ITEM_STATUS_TRANSFER_INVALID = new ErrorCode(1_053_120_012, "工作项状态迁移目标无效");
|
||||
ErrorCode WORK_ITEM_STATUS_SORT_INVALID = new ErrorCode(1_053_120_013, "工作项状态排序数据无效");
|
||||
ErrorCode WORK_ITEM_WORK_LOG_NOT_EXISTS = new ErrorCode(1_053_120_014, "工作项工时记录不存在");
|
||||
ErrorCode WORK_ITEM_WORK_LOG_INVALID = new ErrorCode(1_053_120_015, "工时记录与工作项不匹配");
|
||||
ErrorCode WORK_ITEM_LABEL_NOT_EXISTS = new ErrorCode(1_053_120_016, "工作项标签不存在");
|
||||
ErrorCode WORK_ITEM_LABELS_INVALID = new ErrorCode(1_053_120_017, "工作项标签数据无效");
|
||||
ErrorCode WORK_ITEM_COMMENT_NOT_EXISTS = new ErrorCode(1_053_120_018, "工作项评论不存在");
|
||||
ErrorCode WORK_ITEM_COMMENT_REPLY_INVALID = new ErrorCode(1_053_120_019, "回复的评论与工作项不匹配");
|
||||
ErrorCode WORK_ITEM_COMMENT_ACCESS_DENIED = new ErrorCode(1_053_120_020, "只能修改或删除自己的评论");
|
||||
ErrorCode WORK_ITEM_LIFECYCLE_STATUS_INVALID = new ErrorCode(1_053_120_021, "工作项当前生命周期状态不支持该操作");
|
||||
ErrorCode WORK_ITEM_DELETE_STATUS_INVALID = new ErrorCode(1_053_120_022, "只有回收站中的工作项才能彻底删除");
|
||||
|
||||
// ========== 知识库 1-053-130-000 ==========
|
||||
ErrorCode KNOWLEDGE_LIBRARY_NOT_EXISTS = new ErrorCode(1_053_130_000, "知识库不存在");
|
||||
ErrorCode KNOWLEDGE_LIBRARY_ACCESS_DENIED = new ErrorCode(1_053_130_001, "无权访问该知识库");
|
||||
ErrorCode KNOWLEDGE_LIBRARY_WRITE_ACCESS_DENIED = new ErrorCode(1_053_130_002, "无权编辑该知识库");
|
||||
ErrorCode KNOWLEDGE_LIBRARY_ADMIN_REQUIRED = new ErrorCode(1_053_130_003, "只有知识库管理员可以执行该操作");
|
||||
ErrorCode KNOWLEDGE_LIBRARY_CREATOR_CANNOT_REMOVE = new ErrorCode(1_053_130_004, "知识库创建人不能移出知识库");
|
||||
ErrorCode KNOWLEDGE_LIBRARY_MEMBERS_INVALID = new ErrorCode(1_053_130_005, "知识库成员数据无效");
|
||||
ErrorCode KNOWLEDGE_FOLDER_NOT_EXISTS = new ErrorCode(1_053_130_006, "知识库文件夹不存在");
|
||||
ErrorCode KNOWLEDGE_FOLDER_PARENT_INVALID = new ErrorCode(1_053_130_007, "父文件夹与知识库不匹配");
|
||||
ErrorCode KNOWLEDGE_FOLDER_MOVE_INVALID = new ErrorCode(1_053_130_008, "文件夹不能移动到自身或其子文件夹中");
|
||||
ErrorCode KNOWLEDGE_DOCUMENT_NOT_EXISTS = new ErrorCode(1_053_130_009, "知识库文档不存在");
|
||||
ErrorCode KNOWLEDGE_DOCUMENT_PARENT_INVALID = new ErrorCode(1_053_130_010, "父文档与知识库不匹配");
|
||||
ErrorCode KNOWLEDGE_DOCUMENT_FOLDER_INVALID = new ErrorCode(1_053_130_011, "文档文件夹与知识库不匹配");
|
||||
ErrorCode KNOWLEDGE_DOCUMENT_MOVE_INVALID = new ErrorCode(1_053_130_012, "文档不能移动到自身或其子文档中");
|
||||
ErrorCode KNOWLEDGE_DOCUMENT_STATUS_INVALID = new ErrorCode(1_053_130_013, "文档状态无效");
|
||||
ErrorCode KNOWLEDGE_DOCUMENT_TYPE_INVALID = new ErrorCode(1_053_130_014, "文档类型无效");
|
||||
ErrorCode KNOWLEDGE_DOCUMENT_MOVE_TARGET_INVALID = new ErrorCode(1_053_130_015, "文档移动目标只能选择文件夹或父文档之一");
|
||||
ErrorCode KNOWLEDGE_GROUP_NOT_EXISTS = new ErrorCode(1_053_130_020, "知识库分组不存在");
|
||||
ErrorCode KNOWLEDGE_GROUP_NAME_DUPLICATE = new ErrorCode(1_053_130_021, "知识库分组名称已存在");
|
||||
ErrorCode KNOWLEDGE_GROUP_DEFAULT_CANNOT_MODIFY = new ErrorCode(1_053_130_022, "默认知识库分组不允许修改");
|
||||
ErrorCode KNOWLEDGE_GROUP_DEFAULT_CANNOT_DELETE = new ErrorCode(1_053_130_023, "默认知识库分组不允许删除");
|
||||
ErrorCode KNOWLEDGE_GROUP_SORT_DUPLICATE = new ErrorCode(1_053_130_024, "知识库分组排序列表存在重复分组");
|
||||
ErrorCode KNOWLEDGE_DOCUMENT_LABEL_NOT_EXISTS = new ErrorCode(1_053_130_030, "知识库文档标签不存在");
|
||||
ErrorCode KNOWLEDGE_RECYCLE_RECORD_NOT_EXISTS = new ErrorCode(1_053_130_040, "知识库回收站记录不存在");
|
||||
ErrorCode KNOWLEDGE_RECYCLE_TYPE_INVALID = new ErrorCode(1_053_130_041, "知识库回收站对象类型无效");
|
||||
ErrorCode KNOWLEDGE_INTERACTION_OBJECT_INVALID = new ErrorCode(1_053_130_050, "知识对象不存在或类型不匹配");
|
||||
ErrorCode KNOWLEDGE_FAVORITE_DUPLICATE = new ErrorCode(1_053_130_051, "该知识对象已关注");
|
||||
ErrorCode KNOWLEDGE_DOCUMENT_SHARE_ALREADY_OPEN = new ErrorCode(1_053_130_060, "该文档已开启分享");
|
||||
ErrorCode KNOWLEDGE_DOCUMENT_SHARE_INVALID = new ErrorCode(1_053_130_061, "文档分享不存在或已失效");
|
||||
ErrorCode KNOWLEDGE_CONTENT_PERMISSION_NOT_EXISTS = new ErrorCode(1_053_130_070, "知识内容协作权限不存在");
|
||||
ErrorCode KNOWLEDGE_CONTENT_ACCESS_DENIED = new ErrorCode(1_053_130_071, "无权访问该知识内容");
|
||||
ErrorCode KNOWLEDGE_CONTENT_WRITE_ACCESS_DENIED = new ErrorCode(1_053_130_072, "无权编辑该知识内容");
|
||||
ErrorCode KNOWLEDGE_CONTENT_DELETE_ACCESS_DENIED = new ErrorCode(1_053_130_073, "无权删除该知识内容");
|
||||
ErrorCode KNOWLEDGE_CONTENT_PERMISSION_MEMBERS_INVALID = new ErrorCode(1_053_130_074, "知识内容协作者数据无效");
|
||||
ErrorCode KNOWLEDGE_DOCUMENT_COMMENT_NOT_EXISTS = new ErrorCode(1_053_130_080, "知识库文档评论不存在");
|
||||
ErrorCode KNOWLEDGE_DOCUMENT_COMMENT_REPLY_INVALID = new ErrorCode(1_053_130_081, "回复的评论与文档不匹配");
|
||||
ErrorCode KNOWLEDGE_DOCUMENT_COMMENT_ACCESS_DENIED = new ErrorCode(1_053_130_082, "只能删除自己的评论");
|
||||
ErrorCode KNOWLEDGE_DOCUMENT_COMMENT_TYPE_INVALID = new ErrorCode(1_053_130_083, "只有富文本文档支持评论");
|
||||
ErrorCode KNOWLEDGE_LIBRARY_TEMPLATE_NOT_EXISTS = new ErrorCode(1_053_130_084, "知识库模板不存在");
|
||||
ErrorCode KNOWLEDGE_LIBRARY_TEMPLATE_INVALID = new ErrorCode(1_053_130_085, "知识库模板配置无效");
|
||||
ErrorCode KNOWLEDGE_LIBRARY_DIRECT_MEMBER_NOT_EXISTS = new ErrorCode(1_053_130_086,
|
||||
"当前账号不是该知识库的直接成员");
|
||||
ErrorCode KNOWLEDGE_LIBRARY_TEMPLATE_NAME_DUPLICATE = new ErrorCode(1_053_130_087, "知识库模板名称已存在");
|
||||
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package cn.iocoder.yudao.module.pms.enums;
|
||||
|
||||
/**
|
||||
* PMS 消息模板常量
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface MessageTemplateConstants {
|
||||
|
||||
// ======================= 站内信模板 =======================
|
||||
|
||||
String WORK_ITEM_ASSIGNED = "pms_work_item_assigned"; // 工作项指派通知
|
||||
String KNOWLEDGE_DOCUMENT_SHARED = "pms_knowledge_document_shared"; // 知识文档分享通知
|
||||
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package cn.iocoder.yudao.module.pms.enums.kb;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* PMS 知识对象类型枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum PmsKnowledgeObjectTypeEnum implements ArrayValuable<Integer> {
|
||||
|
||||
LIBRARY(1), // 知识库
|
||||
FOLDER(2), // 文件夹
|
||||
DOCUMENT(3), // 文档
|
||||
FILE(4); // 文件
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values())
|
||||
.map(PmsKnowledgeObjectTypeEnum::getType).toArray(Integer[]::new);
|
||||
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
private final Integer type;
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
public static PmsKnowledgeObjectTypeEnum valueOf(Integer type) {
|
||||
return ArrayUtil.firstMatch(item -> item.getType().equals(type), values());
|
||||
}
|
||||
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
package cn.iocoder.yudao.module.pms.enums.kb.content;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* PMS 知识内容协作等级枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum PmsKnowledgeContentLevelEnum implements ArrayValuable<Integer> {
|
||||
|
||||
MANAGE(1, "管理员"),
|
||||
EDIT(2, "可编辑"),
|
||||
PREVIEW(3, "仅预览"),
|
||||
DOWNLOAD(4, "可下载"),
|
||||
UPLOAD_DOWNLOAD(5, "可上传下载");
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values())
|
||||
.map(PmsKnowledgeContentLevelEnum::getLevel).toArray(Integer[]::new);
|
||||
|
||||
/**
|
||||
* 等级
|
||||
*/
|
||||
private final Integer level;
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
public static PmsKnowledgeContentLevelEnum valueOf(Integer level) {
|
||||
return ArrayUtil.firstMatch(item -> item.getLevel().equals(level), values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
public static boolean canEdit(Integer level) {
|
||||
return MANAGE.level.equals(level) || EDIT.level.equals(level) || UPLOAD_DOWNLOAD.level.equals(level);
|
||||
}
|
||||
|
||||
public static boolean canDelete(Integer level) {
|
||||
return MANAGE.level.equals(level) || EDIT.level.equals(level);
|
||||
}
|
||||
|
||||
public static boolean canDownload(Integer level) {
|
||||
return level != null && ObjectUtil.notEqual(PREVIEW.level, level);
|
||||
}
|
||||
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
package cn.iocoder.yudao.module.pms.enums.kb.content;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* PMS 知识库文档状态枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum PmsKnowledgeDocumentStatusEnum implements ArrayValuable<Integer> {
|
||||
|
||||
RECYCLED(-1, "回收站"),
|
||||
DRAFT(0, "草稿"),
|
||||
NORMAL(1, "正常"),
|
||||
TEMPLATE(2, "模板");
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values())
|
||||
.map(PmsKnowledgeDocumentStatusEnum::getStatus).toArray(Integer[]::new);
|
||||
|
||||
/**
|
||||
* 非回收站状态集合
|
||||
*/
|
||||
public static final Set<Integer> ACTIVE_STATUSES = SetUtils.asSet(
|
||||
DRAFT.getStatus(), NORMAL.getStatus(), TEMPLATE.getStatus());
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private final Integer status;
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
public static PmsKnowledgeDocumentStatusEnum valueOf(Integer status) {
|
||||
return ArrayUtil.firstMatch(item -> item.getStatus().equals(status), values());
|
||||
}
|
||||
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package cn.iocoder.yudao.module.pms.enums.kb.content;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* PMS 知识库文档类型枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum PmsKnowledgeDocumentTypeEnum implements ArrayValuable<Integer> {
|
||||
|
||||
RICH_TEXT(3, "富文本"),
|
||||
FILE(4, "文件");
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values())
|
||||
.map(PmsKnowledgeDocumentTypeEnum::getType).toArray(Integer[]::new);
|
||||
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
private final Integer type;
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
public static PmsKnowledgeDocumentTypeEnum valueOf(Integer type) {
|
||||
return ArrayUtil.firstMatch(item -> item.getType().equals(type), values());
|
||||
}
|
||||
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package cn.iocoder.yudao.module.pms.enums.kb.library;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* PMS 知识库分组类型枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum PmsKnowledgeGroupTypeEnum implements ArrayValuable<Integer> {
|
||||
|
||||
ALL(1, "全部知识库"),
|
||||
UNGROUPED(2, "未分组"),
|
||||
CUSTOM(3, "自定义分组");
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values())
|
||||
.map(PmsKnowledgeGroupTypeEnum::getType).toArray(Integer[]::new);
|
||||
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
private final Integer type;
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
public static PmsKnowledgeGroupTypeEnum valueOf(Integer type) {
|
||||
return ArrayUtil.firstMatch(item -> item.getType().equals(type), values());
|
||||
}
|
||||
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package cn.iocoder.yudao.module.pms.enums.kb.library;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* PMS 知识库成员等级枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum PmsKnowledgeLibraryMemberLevelEnum implements ArrayValuable<Integer> {
|
||||
|
||||
CREATOR(1, "创建人"),
|
||||
ADMIN(2, "管理员"),
|
||||
MEMBER(3, "成员");
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values())
|
||||
.map(PmsKnowledgeLibraryMemberLevelEnum::getLevel).toArray(Integer[]::new);
|
||||
|
||||
/**
|
||||
* 等级
|
||||
*/
|
||||
private final Integer level;
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
public static PmsKnowledgeLibraryMemberLevelEnum valueOf(Integer level) {
|
||||
return ArrayUtil.firstMatch(item -> item.getLevel().equals(level), values());
|
||||
}
|
||||
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package cn.iocoder.yudao.module.pms.enums.pm.iteration;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* PMS 迭代状态枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum PmsIterationStatusEnum implements ArrayValuable<Integer> {
|
||||
|
||||
PLANNED(1, "未开始"),
|
||||
ACTIVE(2, "进行中"),
|
||||
COMPLETED(3, "已完成");
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values())
|
||||
.map(PmsIterationStatusEnum::getStatus).toArray(Integer[]::new);
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private final Integer status;
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
public static PmsIterationStatusEnum valueOf(Integer status) {
|
||||
return ArrayUtil.firstMatch(item -> item.getStatus().equals(status), values());
|
||||
}
|
||||
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package cn.iocoder.yudao.module.pms.enums.pm.project;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* PMS 项目分组类型枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum PmsProjectGroupTypeEnum implements ArrayValuable<Integer> {
|
||||
|
||||
ALL(1, "全部项目"),
|
||||
UNGROUPED(2, "未分组"),
|
||||
CUSTOM(3, "自定义分组");
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values())
|
||||
.map(PmsProjectGroupTypeEnum::getType).toArray(Integer[]::new);
|
||||
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
private final Integer type;
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
public static PmsProjectGroupTypeEnum valueOf(Integer type) {
|
||||
return ArrayUtil.firstMatch(item -> item.getType().equals(type), values());
|
||||
}
|
||||
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
package cn.iocoder.yudao.module.pms.enums.pm.project;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* PMS 项目优先级枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum PmsProjectLevelEnum implements ArrayValuable<Integer> {
|
||||
|
||||
HIGHEST(1, "最高"),
|
||||
HIGH(2, "较高"),
|
||||
NORMAL(3, "普通"),
|
||||
LOW(4, "较低"),
|
||||
LOWEST(5, "最低");
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values()).map(PmsProjectLevelEnum::getLevel)
|
||||
.toArray(Integer[]::new);
|
||||
|
||||
/**
|
||||
* 优先级
|
||||
*/
|
||||
private final Integer level;
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
public static PmsProjectLevelEnum valueOf(Integer level) {
|
||||
return ArrayUtil.firstMatch(item -> item.getLevel().equals(level), values());
|
||||
}
|
||||
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
package cn.iocoder.yudao.module.pms.enums.pm.project;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* PMS 项目成员权限级别枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum PmsProjectMemberLevelEnum implements ArrayValuable<Integer> {
|
||||
|
||||
OWNER(1, "项目拥有者"),
|
||||
ADMIN(2, "项目管理员"),
|
||||
WRITE(3, "编辑"),
|
||||
READ(4, "只读");
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values())
|
||||
.map(PmsProjectMemberLevelEnum::getLevel).toArray(Integer[]::new);
|
||||
|
||||
/**
|
||||
* 可以管理项目的成员级别
|
||||
*/
|
||||
public static final List<Integer> MANAGER_LEVELS = Arrays.asList(OWNER.level, ADMIN.level);
|
||||
/**
|
||||
* 可以编辑项目业务数据的成员级别
|
||||
*/
|
||||
public static final List<Integer> WRITABLE_LEVELS = Arrays.asList(OWNER.level, ADMIN.level, WRITE.level);
|
||||
|
||||
/**
|
||||
* 权限级别
|
||||
*/
|
||||
private final Integer level;
|
||||
/**
|
||||
* 权限级别名称
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
public static boolean isOwner(Integer level) {
|
||||
return ObjUtil.equal(OWNER.level, level);
|
||||
}
|
||||
|
||||
public static boolean isAdmin(Integer level) {
|
||||
return ObjUtil.equal(ADMIN.level, level);
|
||||
}
|
||||
|
||||
public static boolean isManager(Integer level) {
|
||||
return isOwner(level) || isAdmin(level);
|
||||
}
|
||||
|
||||
public static boolean isWritable(Integer level) {
|
||||
return isManager(level) || ObjUtil.equal(WRITE.level, level);
|
||||
}
|
||||
|
||||
public static boolean isReadable(Integer level) {
|
||||
return valueOf(level) != null;
|
||||
}
|
||||
|
||||
public static PmsProjectMemberLevelEnum valueOf(Integer level) {
|
||||
return ArrayUtil.firstMatch(item -> ObjUtil.equal(item.level, level), values());
|
||||
}
|
||||
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package cn.iocoder.yudao.module.pms.enums.pm.project;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* PMS 项目列表场景枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum PmsProjectSceneTypeEnum implements ArrayValuable<Integer> {
|
||||
|
||||
ALL(1, "全部项目"),
|
||||
MANAGED(2, "我负责的"),
|
||||
PARTICIPATED(3, "我参与的");
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values()).map(PmsProjectSceneTypeEnum::getType)
|
||||
.toArray(Integer[]::new);
|
||||
|
||||
/**
|
||||
* 场景类型
|
||||
*/
|
||||
private final Integer type;
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
public static PmsProjectSceneTypeEnum valueOf(Integer type) {
|
||||
return ArrayUtil.firstMatch(item -> item.getType().equals(type), values());
|
||||
}
|
||||
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package cn.iocoder.yudao.module.pms.enums.pm.project;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* PMS 项目排序类型枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum PmsProjectSortTypeEnum implements ArrayValuable<Integer> {
|
||||
|
||||
ACCESS_TIME(1, "按访问时间"),
|
||||
CREATE_TIME(2, "按创建时间");
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values()).map(PmsProjectSortTypeEnum::getType)
|
||||
.toArray(Integer[]::new);
|
||||
|
||||
/**
|
||||
* 排序类型
|
||||
*/
|
||||
private final Integer type;
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
public static PmsProjectSortTypeEnum valueOf(Integer type) {
|
||||
return ArrayUtil.firstMatch(item -> item.getType().equals(type), values());
|
||||
}
|
||||
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package cn.iocoder.yudao.module.pms.enums.pm.project;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* PMS 项目状态枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum PmsProjectStatusEnum implements ArrayValuable<Integer> {
|
||||
|
||||
ACTIVE(1, "进行中"),
|
||||
ARCHIVED(2, "已归档"),
|
||||
RECYCLED(3, "回收站");
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values())
|
||||
.map(PmsProjectStatusEnum::getStatus).toArray(Integer[]::new);
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private final Integer status;
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
public static PmsProjectStatusEnum valueOf(Integer status) {
|
||||
return ArrayUtil.firstMatch(item -> item.getStatus().equals(status), values());
|
||||
}
|
||||
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package cn.iocoder.yudao.module.pms.enums.pm.project;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* PMS 项目类型枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum PmsProjectTypeEnum implements ArrayValuable<Integer> {
|
||||
|
||||
GENERAL(1, "通用项目"),
|
||||
AGILE(2, "敏捷开发项目");
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values()).map(PmsProjectTypeEnum::getType)
|
||||
.toArray(Integer[]::new);
|
||||
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
private final Integer type;
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
public static PmsProjectTypeEnum valueOf(Integer type) {
|
||||
return ArrayUtil.firstMatch(item -> item.getType().equals(type), values());
|
||||
}
|
||||
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
package cn.iocoder.yudao.module.pms.enums.pm.workitem;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* PMS 工作项动态内容枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum PmsWorkItemActivityContentEnum {
|
||||
|
||||
WORK_ITEM_CREATED("创建了工作项"),
|
||||
WORK_ITEM_FIELD_UPDATED("将{}从「{}」修改为「{}」"),
|
||||
WORK_ITEM_DESCRIPTION_UPDATED("更新了工作项描述"),
|
||||
WORK_ITEM_LABELS_UPDATED("将标签从「{}」修改为「{}」"),
|
||||
WORK_ITEM_MEMBERS_UPDATED("将参与人从「{}」修改为「{}」"),
|
||||
WORK_ITEM_ATTACHMENTS_UPDATED("将附件从「{}」修改为「{}」"),
|
||||
WORK_ITEM_PARENT_UPDATED("将父工作项从「{}」修改为「{}」"),
|
||||
WORK_ITEM_NAME_UPDATED("将工作项名称从「{}」修改为「{}」"),
|
||||
WORK_ITEM_STATUS_UPDATED("将状态从「{}」修改为「{}」"),
|
||||
WORK_ITEM_MOVED_TO_BACKLOG("将工作项移回待规划"),
|
||||
WORK_ITEM_PLANNED_TO_ITERATION("将工作项规划到迭代"),
|
||||
WORK_ITEM_ARCHIVED("归档了工作项"),
|
||||
WORK_ITEM_RECYCLED("将工作项移入回收站"),
|
||||
WORK_ITEM_RESTORED("恢复了工作项"),
|
||||
|
||||
COMMENT_CREATED("添加了评论"),
|
||||
COMMENT_REPLIED("回复了评论"),
|
||||
COMMENT_UPDATED("更新了评论"),
|
||||
COMMENT_DELETED("删除了评论"),
|
||||
|
||||
WORK_LOG_CREATED("登记了 {} 小时工时"),
|
||||
WORK_LOG_UPDATED("更新了工时记录");
|
||||
|
||||
/**
|
||||
* 动态内容模板
|
||||
*/
|
||||
private final String content;
|
||||
|
||||
/**
|
||||
* 格式化动态内容
|
||||
*
|
||||
* @param arguments 模板参数
|
||||
* @return 动态内容
|
||||
*/
|
||||
public String format(Object... arguments) {
|
||||
return StrUtil.format(content, arguments);
|
||||
}
|
||||
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
package cn.iocoder.yudao.module.pms.enums.pm.workitem;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* PMS 缺陷类型枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum PmsWorkItemDefectTypeEnum implements ArrayValuable<Integer> {
|
||||
|
||||
FUNCTION(1, "功能问题"),
|
||||
UI(2, "界面优化"),
|
||||
USABILITY(3, "易用性问题"),
|
||||
SECURITY(4, "安全问题"),
|
||||
PERFORMANCE(5, "性能问题"),
|
||||
CODE(6, "代码错误");
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values())
|
||||
.map(PmsWorkItemDefectTypeEnum::getType).toArray(Integer[]::new);
|
||||
|
||||
/**
|
||||
* 缺陷类型
|
||||
*/
|
||||
private final Integer type;
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
public static PmsWorkItemDefectTypeEnum valueOf(Integer type) {
|
||||
return ArrayUtil.firstMatch(item -> item.getType().equals(type), values());
|
||||
}
|
||||
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package cn.iocoder.yudao.module.pms.enums.pm.workitem;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* PMS 工作项生命周期状态枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum PmsWorkItemLifecycleStatusEnum implements ArrayValuable<Integer> {
|
||||
|
||||
ACTIVE(1, "正常"),
|
||||
ARCHIVED(2, "已归档"),
|
||||
RECYCLED(3, "回收站");
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values())
|
||||
.map(PmsWorkItemLifecycleStatusEnum::getStatus).toArray(Integer[]::new);
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private final Integer status;
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
public static PmsWorkItemLifecycleStatusEnum valueOf(Integer status) {
|
||||
return ArrayUtil.firstMatch(item -> item.getStatus().equals(status), values());
|
||||
}
|
||||
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package cn.iocoder.yudao.module.pms.enums.pm.workitem;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* PMS 工作项优先级枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum PmsWorkItemPriorityEnum implements ArrayValuable<Integer> {
|
||||
|
||||
NONE(0, "无"),
|
||||
LOW(1, "低"),
|
||||
MEDIUM(2, "中"),
|
||||
HIGH(3, "高");
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values())
|
||||
.map(PmsWorkItemPriorityEnum::getPriority).toArray(Integer[]::new);
|
||||
|
||||
/**
|
||||
* 优先级
|
||||
*/
|
||||
private final Integer priority;
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
public static PmsWorkItemPriorityEnum valueOf(Integer priority) {
|
||||
return ArrayUtil.firstMatch(item -> item.getPriority().equals(priority), values());
|
||||
}
|
||||
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package cn.iocoder.yudao.module.pms.enums.pm.workitem;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* PMS 工作项语义状态枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum PmsWorkItemStatusTypeEnum implements ArrayValuable<Integer> {
|
||||
|
||||
PENDING(1, "未开始"),
|
||||
PROCESSING(2, "进行中"),
|
||||
COMPLETED(3, "已完成");
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values())
|
||||
.map(PmsWorkItemStatusTypeEnum::getType).toArray(Integer[]::new);
|
||||
|
||||
/**
|
||||
* 状态类型
|
||||
*/
|
||||
private final Integer type;
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
public static PmsWorkItemStatusTypeEnum valueOf(Integer type) {
|
||||
return ArrayUtil.firstMatch(item -> item.getType().equals(type), values());
|
||||
}
|
||||
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package cn.iocoder.yudao.module.pms.enums.pm.workitem;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* PMS 工作项类型枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum PmsWorkItemTypeEnum implements ArrayValuable<Integer> {
|
||||
|
||||
REQUIREMENT(2, "需求"),
|
||||
TASK(3, "任务"),
|
||||
DEFECT(4, "缺陷");
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values())
|
||||
.map(PmsWorkItemTypeEnum::getType).toArray(Integer[]::new);
|
||||
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
private final Integer type;
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
public static PmsWorkItemTypeEnum valueOf(Integer type) {
|
||||
return ArrayUtil.firstMatch(item -> item.getType().equals(type), values());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao-module-pms</artifactId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>yudao-module-pms-server</artifactId>
|
||||
|
||||
<name>${project.artifactId}</name>
|
||||
<description>
|
||||
pms 包下,项目管理(Project Management System)。
|
||||
例如说:项目、工作事项、迭代、看板、工时和知识库等等
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
<!-- Spring Cloud 基础 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-env</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 依赖服务 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao-module-pms-api</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao-module-system-api</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao-module-infra-api</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 业务组件 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Web 相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- DB 相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-mybatis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- RPC 远程调用相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-rpc</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Registry 注册中心相关 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Config 配置中心相关 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Job 定时任务相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-job</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 工具类相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-excel</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 监控相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-monitor</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Test 测试相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<!-- 设置构建的 jar 包名 -->
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<plugins>
|
||||
<!-- 打包 -->
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal> <!-- 将引入的 jar 打入其中 -->
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package cn.iocoder.yudao.module.pms;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
/**
|
||||
* PMS 项目的启动类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@SpringBootApplication
|
||||
public class PmsServerApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(PmsServerApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.content;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.content.vo.permission.PmsKnowledgeContentPermissionRespVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.content.vo.permission.PmsKnowledgeContentPermissionUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.pms.dal.dataobject.kb.content.PmsKnowledgeContentPermissionDO;
|
||||
import cn.iocoder.yudao.module.pms.dal.dataobject.kb.content.PmsKnowledgeContentPermissionMemberDO;
|
||||
import cn.iocoder.yudao.module.pms.service.kb.content.PmsKnowledgeContentPermissionService;
|
||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Tag(name = "管理后台 - PMS 知识内容协作权限")
|
||||
@RestController
|
||||
@RequestMapping("/pms/kb/content-permission")
|
||||
@Validated
|
||||
public class PmsKnowledgeContentPermissionController {
|
||||
|
||||
@Resource
|
||||
private PmsKnowledgeContentPermissionService permissionService;
|
||||
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
@Resource
|
||||
private DeptApi deptApi;
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得知识内容协作权限")
|
||||
@Parameter(name = "id", description = "协作权限编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:query')")
|
||||
public CommonResult<PmsKnowledgeContentPermissionRespVO> getContentPermission(@RequestParam("id") Long id) {
|
||||
Long userId = getLoginUserId();
|
||||
PmsKnowledgeContentPermissionDO permission = permissionService.getContentPermission(id, userId);
|
||||
List<PmsKnowledgeContentPermissionMemberDO> members = permissionService.getContentPermissionMemberList(id, userId);
|
||||
Integer currentUserLevel = permissionService.getCurrentUserContentPermissionLevel(
|
||||
id, permission.getLibraryId(), userId);
|
||||
return success(buildPermissionRespVO(permission, members, currentUserLevel));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新知识内容协作权限")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:update')")
|
||||
public CommonResult<Boolean> updateContentPermission(@Valid @RequestBody PmsKnowledgeContentPermissionUpdateReqVO updateReqVO) {
|
||||
permissionService.updateContentPermission(updateReqVO, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
// ==================== 拼接 VO ====================
|
||||
|
||||
private PmsKnowledgeContentPermissionRespVO buildPermissionRespVO(PmsKnowledgeContentPermissionDO permission,
|
||||
List<PmsKnowledgeContentPermissionMemberDO> members,
|
||||
Integer currentUserLevel) {
|
||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
|
||||
convertSet(members, PmsKnowledgeContentPermissionMemberDO::getUserId));
|
||||
Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(
|
||||
convertSet(members, PmsKnowledgeContentPermissionMemberDO::getDeptId));
|
||||
// 拼接 VO 返回
|
||||
PmsKnowledgeContentPermissionRespVO permissionVO = BeanUtils.toBean(permission, PmsKnowledgeContentPermissionRespVO.class)
|
||||
.setCreatorUserId(NumberUtils.parseLong(permission.getCreator()))
|
||||
.setCurrentUserLevel(currentUserLevel)
|
||||
.setMembers(BeanUtils.toBean(members, PmsKnowledgeContentPermissionRespVO.Member.class));
|
||||
permissionVO.getMembers().forEach(member -> {
|
||||
findAndThen(userMap, member.getUserId(), user -> member.setUserName(user.getNickname()));
|
||||
findAndThen(deptMap, member.getDeptId(), dept -> member.setDeptName(dept.getName()));
|
||||
});
|
||||
return permissionVO;
|
||||
}
|
||||
|
||||
}
|
||||
+202
@@ -0,0 +1,202 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.content;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.content.vo.document.PmsKnowledgeDocumentCreateReqVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.content.vo.document.PmsKnowledgeDocumentMoveReqVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.content.vo.document.PmsKnowledgeDocumentRespVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.content.vo.document.PmsKnowledgeDocumentSearchPageReqVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.content.vo.document.PmsKnowledgeDocumentUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.pms.dal.dataobject.kb.content.PmsKnowledgeDocumentDO;
|
||||
import cn.iocoder.yudao.module.pms.dal.dataobject.kb.interaction.PmsKnowledgeDocumentLikeDO;
|
||||
import cn.iocoder.yudao.module.pms.dal.dataobject.kb.library.PmsKnowledgeLibraryDO;
|
||||
import cn.iocoder.yudao.module.pms.enums.kb.content.PmsKnowledgeContentLevelEnum;
|
||||
import cn.iocoder.yudao.module.pms.enums.kb.content.PmsKnowledgeDocumentTypeEnum;
|
||||
import cn.iocoder.yudao.module.pms.service.kb.content.PmsKnowledgeContentPermissionService;
|
||||
import cn.iocoder.yudao.module.pms.service.kb.content.PmsKnowledgeDocumentService;
|
||||
import cn.iocoder.yudao.module.pms.service.kb.interaction.PmsKnowledgeDocumentLikeService;
|
||||
import cn.iocoder.yudao.module.pms.service.kb.interaction.PmsKnowledgeFavoriteService;
|
||||
import cn.iocoder.yudao.module.pms.service.kb.interaction.PmsKnowledgeViewRecordService;
|
||||
import cn.iocoder.yudao.module.pms.service.kb.library.PmsKnowledgeLibraryService;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Tag(name = "管理后台 - PMS 知识库文档")
|
||||
@RestController
|
||||
@RequestMapping("/pms/kb/document")
|
||||
@Validated
|
||||
public class PmsKnowledgeDocumentController {
|
||||
|
||||
@Resource
|
||||
private PmsKnowledgeDocumentService documentService;
|
||||
@Resource
|
||||
private PmsKnowledgeContentPermissionService contentPermissionService;
|
||||
@Resource
|
||||
private PmsKnowledgeFavoriteService favoriteService;
|
||||
@Resource
|
||||
private PmsKnowledgeDocumentLikeService documentLikeService;
|
||||
@Resource
|
||||
private PmsKnowledgeViewRecordService viewRecordService;
|
||||
@Resource
|
||||
private PmsKnowledgeLibraryService libraryService;
|
||||
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建文档")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:update')")
|
||||
public CommonResult<Long> createDocument(@Valid @RequestBody PmsKnowledgeDocumentCreateReqVO createReqVO) {
|
||||
return success(documentService.createDocument(createReqVO, getLoginUserId()));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新文档内容")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:update')")
|
||||
public CommonResult<Boolean> updateDocument(@Valid @RequestBody PmsKnowledgeDocumentUpdateReqVO updateReqVO) {
|
||||
documentService.updateDocument(updateReqVO, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "将文档移入回收站")
|
||||
@Parameter(name = "id", description = "文档编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:delete')")
|
||||
public CommonResult<Boolean> deleteDocument(@RequestParam("id") Long id) {
|
||||
documentService.deleteDocument(id, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/move")
|
||||
@Operation(summary = "移动文档")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:update')")
|
||||
public CommonResult<Boolean> moveDocument(@Valid @RequestBody PmsKnowledgeDocumentMoveReqVO moveReqVO) {
|
||||
documentService.moveDocument(moveReqVO, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得文档详情")
|
||||
@Parameter(name = "id", description = "文档编号", required = true, example = "1024")
|
||||
@Parameter(name = "view", description = "是否记录本次浏览", example = "true")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:query')")
|
||||
public CommonResult<PmsKnowledgeDocumentRespVO> getDocument(
|
||||
@RequestParam("id") Long id,
|
||||
@RequestParam(value = "view", defaultValue = "false") Boolean view) {
|
||||
// 查询文档
|
||||
Long userId = getLoginUserId();
|
||||
PmsKnowledgeDocumentDO document = documentService.getDocument(id, userId);
|
||||
// 记录浏览
|
||||
if (Boolean.TRUE.equals(view)) {
|
||||
viewRecordService.createViewRecord(document.getLibraryId(), document.getType(), document.getId(), userId);
|
||||
}
|
||||
// 构建文档 VO
|
||||
return success(buildDocumentRespVO(document, userId));
|
||||
}
|
||||
|
||||
@GetMapping("/search-page")
|
||||
@Operation(summary = "使用 MySQL 全局搜索文档")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:query')")
|
||||
public CommonResult<PageResult<PmsKnowledgeDocumentRespVO>> getDocumentSearchPage(
|
||||
@Valid PmsKnowledgeDocumentSearchPageReqVO pageReqVO) {
|
||||
PageResult<PmsKnowledgeDocumentDO> pageResult = documentService.getDocumentSearchPage(
|
||||
pageReqVO, getLoginUserId());
|
||||
return success(new PageResult<>(buildDocumentRespVOList(pageResult.getList()), pageResult.getTotal()));
|
||||
}
|
||||
|
||||
// ==================== 拼接 VO ====================
|
||||
|
||||
private PmsKnowledgeDocumentRespVO buildDocumentRespVO(PmsKnowledgeDocumentDO document, Long userId) {
|
||||
// 1.1 拼接当前用户的内容权限和互动状态
|
||||
Integer currentUserLevel = contentPermissionService.getCurrentUserContentPermissionLevel(
|
||||
document.getPermissionId(), document.getLibraryId(), userId);
|
||||
Long creatorUserId = NumberUtils.parseLong(document.getCreator());
|
||||
PmsKnowledgeDocumentRespVO documentVO = BeanUtils.toBean(document, PmsKnowledgeDocumentRespVO.class)
|
||||
.setCreatorUserId(creatorUserId).setCurrentUserLevel(currentUserLevel)
|
||||
.setDownloadStatus(PmsKnowledgeContentLevelEnum.canDownload(currentUserLevel))
|
||||
.setPreviewUrl(document.getContent())
|
||||
.setFavoriteStatus(favoriteService.isFavorite(document.getType(), document.getId(), userId));
|
||||
// 1.2 文件不可下载时,隐藏实际文件地址
|
||||
if (PmsKnowledgeDocumentTypeEnum.FILE.getType().equals(document.getType())
|
||||
&& Boolean.FALSE.equals(documentVO.getDownloadStatus())) {
|
||||
documentVO.setContent(null);
|
||||
}
|
||||
|
||||
// 2. 一次查询并拼接创建人和点赞用户信息
|
||||
List<PmsKnowledgeDocumentLikeDO> likes = documentLikeService.getDocumentLikeList(document.getId());
|
||||
Set<Long> relatedUserIds = convertSet(likes, PmsKnowledgeDocumentLikeDO::getUserId);
|
||||
relatedUserIds.add(creatorUserId);
|
||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(relatedUserIds);
|
||||
findAndThen(userMap, creatorUserId, user -> documentVO.setCreatorUserName(user.getNickname()));
|
||||
documentVO.setLikeStatus(CollUtil.anyMatch(likes, like -> userId.equals(like.getUserId())))
|
||||
.setLikeUsers(convertList(likes, like -> {
|
||||
PmsKnowledgeDocumentRespVO.LikeUser likeUser = new PmsKnowledgeDocumentRespVO.LikeUser()
|
||||
.setId(like.getUserId());
|
||||
findAndThen(userMap, like.getUserId(), user ->
|
||||
likeUser.setNickname(user.getNickname()).setAvatar(user.getAvatar()));
|
||||
return likeUser;
|
||||
}));
|
||||
return documentVO;
|
||||
}
|
||||
|
||||
private List<PmsKnowledgeDocumentRespVO> buildDocumentRespVOList(List<PmsKnowledgeDocumentDO> documents) {
|
||||
if (CollUtil.isEmpty(documents)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Map<Long, PmsKnowledgeLibraryDO> libraryMap = libraryService.getLibraryMap(
|
||||
convertSet(documents, PmsKnowledgeDocumentDO::getLibraryId));
|
||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertSet(documents,
|
||||
document -> NumberUtils.parseLong(document.getCreator())));
|
||||
return convertList(documents, document -> {
|
||||
PmsKnowledgeDocumentRespVO documentVO = BeanUtils.toBean(document, PmsKnowledgeDocumentRespVO.class)
|
||||
.setContent(null).setContentSummary(buildContentSummary(document.getContent()))
|
||||
.setCreatorUserId(NumberUtils.parseLong(document.getCreator()));
|
||||
findAndThen(libraryMap, document.getLibraryId(),
|
||||
library -> documentVO.setLibraryName(library.getName()));
|
||||
findAndThen(userMap, documentVO.getCreatorUserId(),
|
||||
user -> documentVO.setCreatorUserName(user.getNickname()));
|
||||
return documentVO;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造搜索结果摘要,避免直接返回完整正文
|
||||
*/
|
||||
private String buildContentSummary(String content) {
|
||||
if (content == null || content.trim().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
String summary = content.replaceAll("<[^>]+>", " ").replaceAll("\\s+", " ").trim();
|
||||
return summary.length() > 120 ? summary.substring(0, 120) + "…" : summary;
|
||||
}
|
||||
|
||||
}
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.content;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.content.vo.document.PmsKnowledgeDocumentRespVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.content.vo.label.PmsKnowledgeDocumentLabelPageReqVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.content.vo.label.PmsKnowledgeDocumentLabelRespVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.content.vo.label.PmsKnowledgeDocumentLabelSaveReqVO;
|
||||
import cn.iocoder.yudao.module.pms.dal.dataobject.kb.content.PmsKnowledgeDocumentDO;
|
||||
import cn.iocoder.yudao.module.pms.dal.dataobject.kb.library.PmsKnowledgeLibraryDO;
|
||||
import cn.iocoder.yudao.module.pms.service.kb.content.PmsKnowledgeDocumentLabelService;
|
||||
import cn.iocoder.yudao.module.pms.service.kb.library.PmsKnowledgeLibraryService;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Tag(name = "管理后台 - PMS 知识库文档标签")
|
||||
@RestController
|
||||
@RequestMapping("/pms/kb/document-label")
|
||||
@Validated
|
||||
public class PmsKnowledgeDocumentLabelController {
|
||||
|
||||
@Resource
|
||||
private PmsKnowledgeDocumentLabelService documentLabelService;
|
||||
@Resource
|
||||
private PmsKnowledgeLibraryService libraryService;
|
||||
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建文档标签")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:update')")
|
||||
public CommonResult<Long> createDocumentLabel(
|
||||
@Valid @RequestBody PmsKnowledgeDocumentLabelSaveReqVO saveReqVO) {
|
||||
return success(documentLabelService.createDocumentLabel(saveReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "修改文档标签")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:update')")
|
||||
public CommonResult<Boolean> updateDocumentLabel(
|
||||
@Valid @RequestBody PmsKnowledgeDocumentLabelSaveReqVO saveReqVO) {
|
||||
documentLabelService.updateDocumentLabel(saveReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除文档标签")
|
||||
@Parameter(name = "id", description = "文档标签编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:delete')")
|
||||
public CommonResult<Boolean> deleteDocumentLabel(@RequestParam("id") Long id) {
|
||||
documentLabelService.deleteDocumentLabel(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得文档标签详情")
|
||||
@Parameter(name = "id", description = "文档标签编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:query')")
|
||||
public CommonResult<PmsKnowledgeDocumentLabelRespVO> getDocumentLabel(@RequestParam("id") Long id) {
|
||||
return success(BeanUtils.toBean(documentLabelService.getDocumentLabel(id),
|
||||
PmsKnowledgeDocumentLabelRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "获得文档标签列表")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:query')")
|
||||
public CommonResult<List<PmsKnowledgeDocumentLabelRespVO>> getDocumentLabelList() {
|
||||
return success(BeanUtils.toBean(documentLabelService.getDocumentLabelList(),
|
||||
PmsKnowledgeDocumentLabelRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/document-page")
|
||||
@Operation(summary = "获得指定标签的文档分页")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:query')")
|
||||
public CommonResult<PageResult<PmsKnowledgeDocumentRespVO>> getDocumentPageByLabel(
|
||||
@Valid PmsKnowledgeDocumentLabelPageReqVO pageReqVO) {
|
||||
PageResult<PmsKnowledgeDocumentDO> pageResult = documentLabelService.getDocumentPageByLabel(
|
||||
pageReqVO, getLoginUserId());
|
||||
return success(new PageResult<>(buildDocumentRespVOList(pageResult.getList()), pageResult.getTotal()));
|
||||
}
|
||||
|
||||
// ==================== 拼接 VO ====================
|
||||
|
||||
private List<PmsKnowledgeDocumentRespVO> buildDocumentRespVOList(List<PmsKnowledgeDocumentDO> documents) {
|
||||
if (CollUtil.isEmpty(documents)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Map<Long, PmsKnowledgeLibraryDO> libraryMap = libraryService.getLibraryMap(
|
||||
convertSet(documents, PmsKnowledgeDocumentDO::getLibraryId));
|
||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertSet(documents,
|
||||
document -> NumberUtils.parseLong(document.getCreator())));
|
||||
return convertList(documents, document -> {
|
||||
PmsKnowledgeDocumentRespVO documentVO = BeanUtils.toBean(document, PmsKnowledgeDocumentRespVO.class)
|
||||
.setContent(null).setCreatorUserId(NumberUtils.parseLong(document.getCreator()));
|
||||
findAndThen(libraryMap, document.getLibraryId(),
|
||||
library -> documentVO.setLibraryName(library.getName()));
|
||||
findAndThen(userMap, documentVO.getCreatorUserId(),
|
||||
user -> documentVO.setCreatorUserName(user.getNickname()));
|
||||
return documentVO;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
+189
@@ -0,0 +1,189 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.content;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.content.vo.folder.PmsKnowledgeFolderMoveReqVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.content.vo.folder.PmsKnowledgeFolderRespVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.content.vo.folder.PmsKnowledgeFolderSaveReqVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.content.vo.folder.PmsKnowledgeTreeRespVO;
|
||||
import cn.iocoder.yudao.module.pms.dal.dataobject.kb.content.PmsKnowledgeDocumentDO;
|
||||
import cn.iocoder.yudao.module.pms.dal.dataobject.kb.content.PmsKnowledgeFolderDO;
|
||||
import cn.iocoder.yudao.module.pms.enums.kb.PmsKnowledgeObjectTypeEnum;
|
||||
import cn.iocoder.yudao.module.pms.service.kb.content.PmsKnowledgeContentPermissionService;
|
||||
import cn.iocoder.yudao.module.pms.service.kb.content.PmsKnowledgeDocumentService;
|
||||
import cn.iocoder.yudao.module.pms.service.kb.content.PmsKnowledgeFolderService;
|
||||
import cn.iocoder.yudao.module.pms.service.kb.interaction.PmsKnowledgeFavoriteService;
|
||||
import cn.iocoder.yudao.module.pms.service.kb.interaction.PmsKnowledgeViewRecordService;
|
||||
import cn.iocoder.yudao.module.pms.service.kb.library.PmsKnowledgeLibraryMemberService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Tag(name = "管理后台 - PMS 知识库文件夹")
|
||||
@RestController
|
||||
@RequestMapping("/pms/kb/folder")
|
||||
@Validated
|
||||
public class PmsKnowledgeFolderController {
|
||||
|
||||
@Resource
|
||||
private PmsKnowledgeFolderService folderService;
|
||||
@Resource
|
||||
private PmsKnowledgeDocumentService documentService;
|
||||
@Resource
|
||||
private PmsKnowledgeContentPermissionService contentPermissionService;
|
||||
@Resource
|
||||
private PmsKnowledgeLibraryMemberService libraryMemberService;
|
||||
@Resource
|
||||
private PmsKnowledgeFavoriteService favoriteService;
|
||||
@Resource
|
||||
private PmsKnowledgeViewRecordService viewRecordService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建文件夹")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:update')")
|
||||
public CommonResult<Long> createFolder(@Valid @RequestBody PmsKnowledgeFolderSaveReqVO saveReqVO) {
|
||||
return success(folderService.createFolder(saveReqVO, getLoginUserId()));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新文件夹")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:update')")
|
||||
public CommonResult<Boolean> updateFolder(@Valid @RequestBody PmsKnowledgeFolderSaveReqVO saveReqVO) {
|
||||
folderService.updateFolder(saveReqVO, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "将文件夹移入回收站")
|
||||
@Parameter(name = "id", description = "文件夹编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:delete')")
|
||||
public CommonResult<Boolean> deleteFolder(@RequestParam("id") Long id) {
|
||||
folderService.deleteFolder(id, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/move")
|
||||
@Operation(summary = "移动文件夹")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:update')")
|
||||
public CommonResult<Boolean> moveFolder(@Valid @RequestBody PmsKnowledgeFolderMoveReqVO moveReqVO) {
|
||||
folderService.moveFolder(moveReqVO, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得文件夹详情")
|
||||
@Parameter(name = "id", description = "文件夹编号", required = true, example = "1024")
|
||||
@Parameter(name = "view", description = "是否记录本次浏览", example = "true")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:query')")
|
||||
public CommonResult<PmsKnowledgeFolderRespVO> getFolder(
|
||||
@RequestParam("id") Long id,
|
||||
@RequestParam(value = "view", defaultValue = "false") Boolean view) {
|
||||
Long userId = getLoginUserId();
|
||||
PmsKnowledgeFolderDO folder = folderService.getFolder(id, userId);
|
||||
if (Boolean.TRUE.equals(view)) {
|
||||
viewRecordService.createViewRecord(folder.getLibraryId(), PmsKnowledgeObjectTypeEnum.FOLDER.getType(),
|
||||
folder.getId(), userId);
|
||||
}
|
||||
return success(buildFolderRespVO(folder, userId));
|
||||
}
|
||||
|
||||
@GetMapping("/tree")
|
||||
@Operation(summary = "获得知识库目录树")
|
||||
@Parameter(name = "libraryId", description = "知识库编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:query')")
|
||||
public CommonResult<PmsKnowledgeTreeRespVO> getFolderTree(@RequestParam("libraryId") Long libraryId) {
|
||||
Long userId = getLoginUserId();
|
||||
List<PmsKnowledgeFolderDO> folders = folderService.getFolderList(libraryId, userId);
|
||||
List<PmsKnowledgeDocumentDO> documents = documentService.getDocumentList(libraryId, userId);
|
||||
return success(buildTreeRespVO(libraryId, userId,
|
||||
libraryMemberService.isLibraryWritable(libraryId, userId),
|
||||
libraryMemberService.isLibraryAdmin(libraryId, userId), folders, documents));
|
||||
}
|
||||
|
||||
// ==================== 拼接 VO ====================
|
||||
|
||||
private PmsKnowledgeFolderRespVO buildFolderRespVO(PmsKnowledgeFolderDO folder, Long userId) {
|
||||
List<PmsKnowledgeFolderDO> folders = folderService.getFolderList(folder.getLibraryId(), userId);
|
||||
List<PmsKnowledgeDocumentDO> documents = documentService.getDocumentList(folder.getLibraryId(), userId);
|
||||
int childFolderCount = CollUtil.count(folders,
|
||||
item -> folder.getId().equals(item.getParentId()));
|
||||
int documentCount = (int) CollUtil.count(documents,
|
||||
item -> folder.getId().equals(item.getFolderId())
|
||||
&& (item.getParentId() == null || item.getParentId() == 0L));
|
||||
return BeanUtils.toBean(folder, PmsKnowledgeFolderRespVO.class)
|
||||
.setChildFolderCount(childFolderCount).setDocumentCount(documentCount)
|
||||
.setCurrentUserLevel(contentPermissionService.getCurrentUserContentPermissionLevel(folder.getPermissionId(), folder.getLibraryId(), userId))
|
||||
.setFavoriteStatus(favoriteService.isFavorite(PmsKnowledgeObjectTypeEnum.FOLDER.getType(), folder.getId(), userId));
|
||||
}
|
||||
|
||||
private PmsKnowledgeTreeRespVO buildTreeRespVO(Long libraryId, Long userId, boolean writeStatus,
|
||||
boolean manageStatus,
|
||||
List<PmsKnowledgeFolderDO> folders, List<PmsKnowledgeDocumentDO> documents) {
|
||||
// 1. 批量获得当前用户的内容权限等级
|
||||
Set<Long> permissionIds = convertSet(folders, PmsKnowledgeFolderDO::getPermissionId);
|
||||
permissionIds.addAll(convertSet(documents, PmsKnowledgeDocumentDO::getPermissionId));
|
||||
Map<Long, Integer> levelMap = contentPermissionService.getCurrentUserContentPermissionLevelMap(permissionIds, libraryId, userId);
|
||||
|
||||
// 2. 批量转换文件夹和文档节点
|
||||
Map<Long, PmsKnowledgeTreeRespVO.FolderNode> folderNodeMap = convertMap(folders,
|
||||
PmsKnowledgeFolderDO::getId, folder -> BeanUtils.toBean(folder, PmsKnowledgeTreeRespVO.FolderNode.class)
|
||||
.setCurrentUserLevel(levelMap.get(folder.getPermissionId())).setChildren(new ArrayList<>()).setDocuments(new ArrayList<>()));
|
||||
Map<Long, PmsKnowledgeTreeRespVO.DocumentNode> documentNodeMap = convertMap(documents,
|
||||
PmsKnowledgeDocumentDO::getId, document -> BeanUtils.toBean(document, PmsKnowledgeTreeRespVO.DocumentNode.class)
|
||||
.setCurrentUserLevel(levelMap.get(document.getPermissionId())).setChildren(new ArrayList<>()));
|
||||
|
||||
// 3. 按父文档或所属文件夹组装文档树
|
||||
List<PmsKnowledgeTreeRespVO.DocumentNode> rootDocuments = new ArrayList<>();
|
||||
for (PmsKnowledgeDocumentDO document : documents) {
|
||||
PmsKnowledgeTreeRespVO.DocumentNode node = documentNodeMap.get(document.getId());
|
||||
PmsKnowledgeTreeRespVO.DocumentNode parentNode = documentNodeMap.get(document.getParentId());
|
||||
PmsKnowledgeTreeRespVO.FolderNode folderNode = folderNodeMap.get(document.getFolderId());
|
||||
if (parentNode != null) {
|
||||
parentNode.getChildren().add(node);
|
||||
} else if (folderNode != null) {
|
||||
folderNode.getDocuments().add(node);
|
||||
} else {
|
||||
rootDocuments.add(node);
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 按父文件夹组装文件夹树
|
||||
List<PmsKnowledgeTreeRespVO.FolderNode> rootFolders = new ArrayList<>();
|
||||
for (PmsKnowledgeFolderDO folder : folders) {
|
||||
PmsKnowledgeTreeRespVO.FolderNode node = folderNodeMap.get(folder.getId());
|
||||
PmsKnowledgeTreeRespVO.FolderNode parentNode = folderNodeMap.get(folder.getParentId());
|
||||
if (parentNode != null) {
|
||||
parentNode.getChildren().add(node);
|
||||
} else {
|
||||
rootFolders.add(node);
|
||||
}
|
||||
}
|
||||
return new PmsKnowledgeTreeRespVO().setLibraryId(libraryId).setWriteStatus(writeStatus)
|
||||
.setManageStatus(manageStatus)
|
||||
.setFolders(rootFolders).setDocuments(rootDocuments);
|
||||
}
|
||||
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.content.vo.document;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.pms.enums.kb.content.PmsKnowledgeDocumentTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库文档新增 Request VO")
|
||||
@Data
|
||||
public class PmsKnowledgeDocumentCreateReqVO {
|
||||
|
||||
@Schema(description = "知识库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "知识库编号不能为空")
|
||||
private Long libraryId;
|
||||
|
||||
@Schema(description = "文件夹编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "文件夹编号不能为空")
|
||||
private Long folderId;
|
||||
|
||||
@Schema(description = "父文档编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "父文档编号不能为空")
|
||||
private Long parentId;
|
||||
|
||||
@Schema(description = "文档标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "产品说明")
|
||||
@NotBlank(message = "文档标题不能为空")
|
||||
@Size(max = 255, message = "文档标题不能超过 255 个字符")
|
||||
private String title;
|
||||
|
||||
@Schema(description = "文档类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "3")
|
||||
@NotNull(message = "文档类型不能为空")
|
||||
@InEnum(PmsKnowledgeDocumentTypeEnum.class)
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "文档内容或文件地址")
|
||||
private String content;
|
||||
|
||||
@Schema(description = "文件类型", example = "pdf")
|
||||
@Size(max = 50, message = "文件类型不能超过 50 个字符")
|
||||
private String fileType;
|
||||
|
||||
@Schema(description = "文件大小,单位:字节", example = "102400")
|
||||
@Min(value = 0, message = "文件大小不能小于 0")
|
||||
@Max(value = 104857600, message = "文件大小不能超过 100 MB")
|
||||
private Long fileSize;
|
||||
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.content.vo.document;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库文档移动 Request VO")
|
||||
@Data
|
||||
public class PmsKnowledgeDocumentMoveReqVO {
|
||||
|
||||
@Schema(description = "文档编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "文档编号不能为空")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "目标知识库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "目标知识库编号不能为空")
|
||||
private Long targetLibraryId;
|
||||
|
||||
@Schema(description = "目标文件夹编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "目标文件夹编号不能为空")
|
||||
private Long targetFolderId;
|
||||
|
||||
@Schema(description = "目标父文档编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "目标父文档编号不能为空")
|
||||
private Long targetParentId;
|
||||
|
||||
}
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.content.vo.document;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库文档 Response VO")
|
||||
@Data
|
||||
public class PmsKnowledgeDocumentRespVO {
|
||||
|
||||
@Schema(description = "文档编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "知识库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long libraryId;
|
||||
|
||||
@Schema(description = "协作权限编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long permissionId;
|
||||
|
||||
@Schema(description = "当前用户协作等级", example = "3")
|
||||
private Integer currentUserLevel;
|
||||
|
||||
@Schema(description = "当前用户是否可下载", example = "true")
|
||||
private Boolean downloadStatus;
|
||||
|
||||
@Schema(description = "知识库名称", example = "产品知识库")
|
||||
private String libraryName;
|
||||
|
||||
@Schema(description = "文件夹编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long folderId;
|
||||
|
||||
@Schema(description = "父文档编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long parentId;
|
||||
|
||||
@Schema(description = "文档标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "产品说明")
|
||||
private String title;
|
||||
|
||||
@Schema(description = "正文摘要")
|
||||
private String contentSummary;
|
||||
|
||||
@Schema(description = "文档内容或文件地址")
|
||||
private String content;
|
||||
|
||||
@Schema(description = "文件预览地址(下载权限不足时仍可用于在线预览)")
|
||||
private String previewUrl;
|
||||
|
||||
@Schema(description = "文档类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "3")
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "文件类型", example = "pdf")
|
||||
private String fileType;
|
||||
|
||||
@Schema(description = "文件大小,单位:字节", example = "102400")
|
||||
private Long fileSize;
|
||||
|
||||
@Schema(description = "文档状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "标签编号列表", example = "[1024, 2048]")
|
||||
private List<Long> labelIds;
|
||||
|
||||
@Schema(description = "创建人用户编号", example = "1")
|
||||
private Long creatorUserId;
|
||||
|
||||
@Schema(description = "创建人姓名", example = "芋道")
|
||||
private String creatorUserName;
|
||||
|
||||
@Schema(description = "当前用户是否已关注")
|
||||
private Boolean favoriteStatus;
|
||||
|
||||
@Schema(description = "当前用户是否已点赞")
|
||||
private Boolean likeStatus;
|
||||
|
||||
@Schema(description = "点赞用户列表")
|
||||
private List<LikeUser> likeUsers;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识文档点赞用户 Response VO")
|
||||
@Data
|
||||
public static class LikeUser {
|
||||
|
||||
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "用户昵称", example = "芋道")
|
||||
private String nickname;
|
||||
|
||||
@Schema(description = "用户头像")
|
||||
private String avatar;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.content.vo.document;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库文档全局搜索分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PmsKnowledgeDocumentSearchPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "搜索关键字", example = "产品方案")
|
||||
private String keyword;
|
||||
|
||||
@Schema(description = "知识库编号", example = "1024")
|
||||
private Long libraryId;
|
||||
|
||||
@Schema(description = "创建人用户编号", example = "1")
|
||||
private Long creatorUserId;
|
||||
|
||||
@Schema(description = "更新时间范围")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] updateTime;
|
||||
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.content.vo.document;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库文档修改 Request VO")
|
||||
@Data
|
||||
public class PmsKnowledgeDocumentUpdateReqVO {
|
||||
|
||||
@Schema(description = "文档编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "文档编号不能为空")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "文档标题", example = "产品说明")
|
||||
@Size(max = 255, message = "文档标题不能超过 255 个字符")
|
||||
private String title;
|
||||
|
||||
@Schema(description = "文档内容或文件地址")
|
||||
private String content;
|
||||
|
||||
@Schema(description = "标签编号列表;传空集合表示清空标签")
|
||||
private List<Long> labelIds;
|
||||
|
||||
@Schema(description = "文件类型", example = "pdf")
|
||||
@Size(max = 50, message = "文件类型不能超过 50 个字符")
|
||||
private String fileType;
|
||||
|
||||
@Schema(description = "文件大小,单位:字节", example = "102400")
|
||||
@Min(value = 0, message = "文件大小不能小于 0")
|
||||
@Max(value = 104857600, message = "文件大小不能超过 100 MB")
|
||||
private Long fileSize;
|
||||
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.content.vo.folder;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库文件夹移动 Request VO")
|
||||
@Data
|
||||
public class PmsKnowledgeFolderMoveReqVO {
|
||||
|
||||
@Schema(description = "文件夹编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "文件夹编号不能为空")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "目标知识库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "目标知识库编号不能为空")
|
||||
private Long targetLibraryId;
|
||||
|
||||
@Schema(description = "目标父文件夹编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "目标父文件夹编号不能为空")
|
||||
private Long targetParentId;
|
||||
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.content.vo.folder;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库文件夹 Response VO")
|
||||
@Data
|
||||
public class PmsKnowledgeFolderRespVO {
|
||||
|
||||
@Schema(description = "文件夹编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "知识库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long libraryId;
|
||||
|
||||
@Schema(description = "协作权限编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long permissionId;
|
||||
|
||||
@Schema(description = "当前用户协作等级", requiredMode = Schema.RequiredMode.REQUIRED, example = "3")
|
||||
private Integer currentUserLevel;
|
||||
|
||||
@Schema(description = "父文件夹编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long parentId;
|
||||
|
||||
@Schema(description = "文件夹标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "产品文档")
|
||||
private String title;
|
||||
|
||||
@Schema(description = "直属子文件夹数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "3")
|
||||
private Integer childFolderCount;
|
||||
|
||||
@Schema(description = "直属文档数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "12")
|
||||
private Integer documentCount;
|
||||
|
||||
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "当前用户是否已关注", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Boolean favoriteStatus;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.content.vo.folder;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库文件夹新增/修改 Request VO")
|
||||
@Data
|
||||
public class PmsKnowledgeFolderSaveReqVO {
|
||||
|
||||
@Schema(description = "文件夹编号", example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "知识库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "知识库编号不能为空")
|
||||
private Long libraryId;
|
||||
|
||||
@Schema(description = "父文件夹编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "父文件夹编号不能为空")
|
||||
private Long parentId;
|
||||
|
||||
@Schema(description = "文件夹标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "产品文档")
|
||||
@NotBlank(message = "文件夹标题不能为空")
|
||||
@Size(max = 255, message = "文件夹标题不能超过 255 个字符")
|
||||
private String title;
|
||||
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.content.vo.folder;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库目录树 Response VO")
|
||||
@Data
|
||||
public class PmsKnowledgeTreeRespVO {
|
||||
|
||||
@Schema(description = "知识库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long libraryId;
|
||||
|
||||
@Schema(description = "当前用户是否可编辑", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||
private Boolean writeStatus;
|
||||
|
||||
@Schema(description = "当前用户是否可管理目录结构", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||
private Boolean manageStatus;
|
||||
|
||||
@Schema(description = "根文件夹列表", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<FolderNode> folders;
|
||||
|
||||
@Schema(description = "根文档列表", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<DocumentNode> documents;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库文件夹树节点 Response VO")
|
||||
@Data
|
||||
public static class FolderNode {
|
||||
|
||||
@Schema(description = "文件夹编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "协作权限编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long permissionId;
|
||||
|
||||
@Schema(description = "当前用户协作等级", requiredMode = Schema.RequiredMode.REQUIRED, example = "3")
|
||||
private Integer currentUserLevel;
|
||||
|
||||
@Schema(description = "父文件夹编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long parentId;
|
||||
|
||||
@Schema(description = "文件夹标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "产品文档")
|
||||
private String title;
|
||||
|
||||
@Schema(description = "子文件夹列表", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<FolderNode> children;
|
||||
|
||||
@Schema(description = "文件夹下的文档列表", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<DocumentNode> documents;
|
||||
}
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库文档树节点 Response VO")
|
||||
@Data
|
||||
public static class DocumentNode {
|
||||
|
||||
@Schema(description = "文档编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "协作权限编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long permissionId;
|
||||
|
||||
@Schema(description = "当前用户协作等级", requiredMode = Schema.RequiredMode.REQUIRED, example = "3")
|
||||
private Integer currentUserLevel;
|
||||
|
||||
@Schema(description = "父文档编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long parentId;
|
||||
|
||||
@Schema(description = "文档标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "产品说明")
|
||||
private String title;
|
||||
|
||||
@Schema(description = "文档类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "3")
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "文件类型", example = "pdf")
|
||||
private String fileType;
|
||||
|
||||
@Schema(description = "子文档列表", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<DocumentNode> children;
|
||||
}
|
||||
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.content.vo.label;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 按标签查询文档分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PmsKnowledgeDocumentLabelPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "文档标签编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "文档标签编号不能为空")
|
||||
private Long labelId;
|
||||
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.content.vo.label;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库文档标签 Response VO")
|
||||
@Data
|
||||
public class PmsKnowledgeDocumentLabelRespVO {
|
||||
|
||||
@Schema(description = "文档标签编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "标签名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "产品")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "标签颜色", requiredMode = Schema.RequiredMode.REQUIRED, example = "#409EFF")
|
||||
private String color;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.content.vo.label;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库文档标签新增/修改 Request VO")
|
||||
@Data
|
||||
public class PmsKnowledgeDocumentLabelSaveReqVO {
|
||||
|
||||
@Schema(description = "文档标签编号", example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "标签名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "产品")
|
||||
@NotBlank(message = "标签名称不能为空")
|
||||
@Size(max = 255, message = "标签名称不能超过 255 个字符")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "标签颜色", requiredMode = Schema.RequiredMode.REQUIRED, example = "#409EFF")
|
||||
@NotBlank(message = "标签颜色不能为空")
|
||||
@Size(max = 20, message = "标签颜色不能超过 20 个字符")
|
||||
private String color;
|
||||
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.content.vo.permission;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识内容协作权限 Response VO")
|
||||
@Data
|
||||
public class PmsKnowledgeContentPermissionRespVO {
|
||||
|
||||
@Schema(description = "协作权限编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "知识库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long libraryId;
|
||||
|
||||
@Schema(description = "是否公开", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||
private Boolean openStatus;
|
||||
|
||||
@Schema(description = "公开协作等级", requiredMode = Schema.RequiredMode.REQUIRED, example = "3")
|
||||
private Integer openLevel;
|
||||
|
||||
@Schema(description = "创建人用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long creatorUserId;
|
||||
|
||||
@Schema(description = "当前用户协作等级", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer currentUserLevel;
|
||||
|
||||
@Schema(description = "协作者列表", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<Member> members;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识内容协作者 Response VO")
|
||||
@Data
|
||||
public static class Member {
|
||||
|
||||
@Schema(description = "协作者编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "用户编号", example = "1")
|
||||
private Long userId;
|
||||
|
||||
@Schema(description = "用户昵称", example = "芋道")
|
||||
private String userName;
|
||||
|
||||
@Schema(description = "部门编号", example = "100")
|
||||
private Long deptId;
|
||||
|
||||
@Schema(description = "部门名称", example = "研发部")
|
||||
private String deptName;
|
||||
|
||||
@Schema(description = "协作等级", requiredMode = Schema.RequiredMode.REQUIRED, example = "3")
|
||||
private Integer level;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.content.vo.permission;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.pms.enums.kb.content.PmsKnowledgeContentLevelEnum;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.AssertTrue;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 更新知识内容协作权限 Request VO")
|
||||
@Data
|
||||
public class PmsKnowledgeContentPermissionUpdateReqVO {
|
||||
|
||||
@Schema(description = "协作权限编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "协作权限编号不能为空")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "是否公开", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||
@NotNull(message = "是否公开不能为空")
|
||||
private Boolean openStatus;
|
||||
|
||||
@Schema(description = "公开协作等级", requiredMode = Schema.RequiredMode.REQUIRED, example = "3")
|
||||
@NotNull(message = "公开协作等级不能为空")
|
||||
@InEnum(PmsKnowledgeContentLevelEnum.class)
|
||||
private Integer openLevel;
|
||||
|
||||
@Schema(description = "协作者列表", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Valid
|
||||
@NotNull(message = "协作者列表不能为空")
|
||||
private List<Member> members;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识内容协作者保存项")
|
||||
@Data
|
||||
public static class Member {
|
||||
|
||||
@Schema(description = "用户编号", example = "1")
|
||||
private Long userId;
|
||||
|
||||
@Schema(description = "部门编号", example = "100")
|
||||
private Long deptId;
|
||||
|
||||
@Schema(description = "协作等级", requiredMode = Schema.RequiredMode.REQUIRED, example = "3")
|
||||
@NotNull(message = "协作等级不能为空")
|
||||
@InEnum(PmsKnowledgeContentLevelEnum.class)
|
||||
private Integer level;
|
||||
|
||||
@AssertTrue(message = "协作者必须且只能选择用户或部门")
|
||||
@JsonIgnore
|
||||
public boolean isUserOrDeptValid() {
|
||||
return (userId != null && deptId == null) || (userId == null && deptId != null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.interaction;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.interaction.vo.comment.PmsKnowledgeDocumentCommentRespVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.interaction.vo.comment.PmsKnowledgeDocumentCommentSaveReqVO;
|
||||
import cn.iocoder.yudao.module.pms.dal.dataobject.kb.interaction.PmsKnowledgeDocumentCommentDO;
|
||||
import cn.iocoder.yudao.module.pms.service.kb.interaction.PmsKnowledgeDocumentCommentService;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSetByFlatMap;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Tag(name = "管理后台 - PMS 知识库文档评论")
|
||||
@RestController
|
||||
@RequestMapping("/pms/kb/document-comment")
|
||||
@Validated
|
||||
public class PmsKnowledgeDocumentCommentController {
|
||||
|
||||
@Resource
|
||||
private PmsKnowledgeDocumentCommentService commentService;
|
||||
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建知识库文档评论")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:query')")
|
||||
public CommonResult<Long> createDocumentComment(@Valid @RequestBody PmsKnowledgeDocumentCommentSaveReqVO saveReqVO) {
|
||||
return success(commentService.createDocumentComment(saveReqVO, getLoginUserId()));
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除知识库文档评论")
|
||||
@Parameter(name = "id", description = "评论编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:query')")
|
||||
public CommonResult<Boolean> deleteDocumentComment(@RequestParam("id") Long id) {
|
||||
commentService.deleteDocumentComment(id, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "获得知识库文档评论列表")
|
||||
@Parameter(name = "documentId", description = "文档编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:query')")
|
||||
public CommonResult<List<PmsKnowledgeDocumentCommentRespVO>> getDocumentCommentList(
|
||||
@RequestParam("documentId") Long documentId) {
|
||||
List<PmsKnowledgeDocumentCommentDO> comments = commentService.getDocumentCommentList(documentId, getLoginUserId());
|
||||
return success(buildCommentRespVOList(comments));
|
||||
}
|
||||
|
||||
// ==================== 拼接 VO ====================
|
||||
|
||||
private List<PmsKnowledgeDocumentCommentRespVO> buildCommentRespVOList(
|
||||
List<PmsKnowledgeDocumentCommentDO> comments) {
|
||||
if (CollUtil.isEmpty(comments)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
// 1. 批量查询评论人和回复对象
|
||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertSetByFlatMap(comments,
|
||||
comment -> Stream.of(comment.getUserId(), comment.getReplyUserId())));
|
||||
|
||||
// 2. 批量转换评论,避免回复组装依赖查询顺序
|
||||
Map<Long, PmsKnowledgeDocumentCommentRespVO> commentMap = convertMap(comments,
|
||||
PmsKnowledgeDocumentCommentDO::getId, comment -> {
|
||||
PmsKnowledgeDocumentCommentRespVO commentVO = BeanUtils.toBean(comment,
|
||||
PmsKnowledgeDocumentCommentRespVO.class).setChildren(new ArrayList<>());
|
||||
findAndThen(userMap, comment.getUserId(), user -> commentVO.setUserName(user.getNickname()));
|
||||
findAndThen(userMap, comment.getReplyUserId(),
|
||||
user -> commentVO.setReplyUserName(user.getNickname()));
|
||||
return commentVO;
|
||||
});
|
||||
|
||||
// 3. 按主评论组织回复列表
|
||||
List<PmsKnowledgeDocumentCommentRespVO> result = new ArrayList<>();
|
||||
for (PmsKnowledgeDocumentCommentDO comment : comments) {
|
||||
PmsKnowledgeDocumentCommentRespVO commentVO = commentMap.get(comment.getId());
|
||||
if (PmsKnowledgeDocumentCommentDO.MAIN_ID_ROOT.equals(comment.getMainId())) {
|
||||
result.add(commentVO);
|
||||
continue;
|
||||
}
|
||||
findAndThen(commentMap, comment.getMainId(), mainComment -> mainComment.getChildren().add(commentVO));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.interaction;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.pms.service.kb.interaction.PmsKnowledgeDocumentLikeService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Tag(name = "管理后台 - PMS 知识库文档点赞")
|
||||
@RestController
|
||||
@RequestMapping("/pms/kb/document-like")
|
||||
@Validated
|
||||
public class PmsKnowledgeDocumentLikeController {
|
||||
|
||||
@Resource
|
||||
private PmsKnowledgeDocumentLikeService documentLikeService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "点赞文档")
|
||||
@Parameter(name = "documentId", description = "文档编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:query')")
|
||||
public CommonResult<Boolean> createDocumentLike(@RequestParam("documentId") Long documentId) {
|
||||
documentLikeService.createDocumentLike(documentId, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "取消点赞文档")
|
||||
@Parameter(name = "documentId", description = "文档编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:query')")
|
||||
public CommonResult<Boolean> deleteDocumentLike(@RequestParam("documentId") Long documentId) {
|
||||
documentLikeService.deleteDocumentLike(documentId, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.interaction;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
|
||||
import cn.iocoder.yudao.module.infra.api.file.FileApi;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.interaction.vo.share.PmsKnowledgeDocumentSharePublicRespVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.interaction.vo.share.PmsKnowledgeDocumentShareRespVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.interaction.vo.share.PmsKnowledgeDocumentShareSaveReqVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.interaction.vo.share.PmsKnowledgeDocumentShareUpdateMemberListReqVO;
|
||||
import cn.iocoder.yudao.module.pms.dal.dataobject.kb.content.PmsKnowledgeDocumentDO;
|
||||
import cn.iocoder.yudao.module.pms.dal.dataobject.kb.interaction.PmsKnowledgeDocumentShareDO;
|
||||
import cn.iocoder.yudao.module.pms.enums.kb.content.PmsKnowledgeDocumentTypeEnum;
|
||||
import cn.iocoder.yudao.module.pms.service.kb.interaction.PmsKnowledgeDocumentShareService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.annotation.security.PermitAll;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Tag(name = "管理后台 - PMS 知识库文档分享")
|
||||
@RestController
|
||||
@RequestMapping("/pms/kb/document-share")
|
||||
@Validated
|
||||
public class PmsKnowledgeDocumentShareController {
|
||||
|
||||
@Resource
|
||||
private PmsKnowledgeDocumentShareService documentShareService;
|
||||
|
||||
@Resource
|
||||
private FileApi fileApi;
|
||||
|
||||
@PostMapping("/open")
|
||||
@Operation(summary = "开启文档分享")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:update')")
|
||||
public CommonResult<PmsKnowledgeDocumentShareRespVO> openShare(
|
||||
@Valid @RequestBody PmsKnowledgeDocumentShareSaveReqVO reqVO) {
|
||||
PmsKnowledgeDocumentShareDO share = documentShareService.openShare(reqVO.getDocumentId(),
|
||||
reqVO.getShareUserIds(), getLoginUserId());
|
||||
return success(BeanUtils.toBean(share, PmsKnowledgeDocumentShareRespVO.class));
|
||||
}
|
||||
|
||||
@PutMapping("/update-member-list")
|
||||
@Operation(summary = "更新文档内部分享成员")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:update')")
|
||||
public CommonResult<Boolean> updateShareMemberList(
|
||||
@Valid @RequestBody PmsKnowledgeDocumentShareUpdateMemberListReqVO reqVO) {
|
||||
documentShareService.updateShareMemberList(reqVO.getDocumentId(), reqVO.getShareUserIds(), getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/close")
|
||||
@Operation(summary = "关闭文档分享")
|
||||
@Parameter(name = "documentId", description = "文档编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:update')")
|
||||
public CommonResult<Boolean> closeShare(@RequestParam("documentId") Long documentId) {
|
||||
documentShareService.closeShare(documentId, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得文档分享配置")
|
||||
@Parameter(name = "documentId", description = "文档编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:query')")
|
||||
public CommonResult<PmsKnowledgeDocumentShareRespVO> getDocumentShare(@RequestParam("documentId") Long documentId) {
|
||||
PmsKnowledgeDocumentShareDO share = documentShareService.getActiveDocumentShare(documentId, getLoginUserId());
|
||||
return success(BeanUtils.toBean(share, PmsKnowledgeDocumentShareRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/get-by-token")
|
||||
@Operation(summary = "通过分享令牌获得文档")
|
||||
@Parameter(name = "token", description = "分享令牌", required = true)
|
||||
@PermitAll
|
||||
@TenantIgnore
|
||||
public CommonResult<PmsKnowledgeDocumentSharePublicRespVO> getDocumentByToken(
|
||||
@RequestParam("token") @NotBlank(message = "分享令牌不能为空") String token) {
|
||||
PmsKnowledgeDocumentDO document = documentShareService.getDocumentByShareToken(token);
|
||||
PmsKnowledgeDocumentSharePublicRespVO documentVO = BeanUtils.toBean(
|
||||
document, PmsKnowledgeDocumentSharePublicRespVO.class);
|
||||
if (PmsKnowledgeDocumentTypeEnum.FILE.getType().equals(document.getType())) {
|
||||
documentVO.setContent(null).setPreviewUrl(
|
||||
fileApi.presignGetUrl(document.getContent(), null).getCheckedData());
|
||||
}
|
||||
return success(documentVO);
|
||||
}
|
||||
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.interaction;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.interaction.vo.PmsKnowledgeInteractionItemRespVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.interaction.vo.favorite.PmsKnowledgeFavoritePageReqVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.interaction.vo.favorite.PmsKnowledgeFavoriteSaveReqVO;
|
||||
import cn.iocoder.yudao.module.pms.enums.kb.PmsKnowledgeObjectTypeEnum;
|
||||
import cn.iocoder.yudao.module.pms.service.kb.interaction.PmsKnowledgeFavoriteService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Tag(name = "管理后台 - PMS 知识关注")
|
||||
@RestController
|
||||
@RequestMapping("/pms/kb/favorite")
|
||||
@Validated
|
||||
public class PmsKnowledgeFavoriteController {
|
||||
|
||||
@Resource
|
||||
private PmsKnowledgeFavoriteService favoriteService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "关注知识对象")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:query')")
|
||||
public CommonResult<Boolean> createFavorite(@Valid @RequestBody PmsKnowledgeFavoriteSaveReqVO saveReqVO) {
|
||||
favoriteService.createFavorite(saveReqVO, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "取消关注知识对象")
|
||||
@Parameter(name = "type", description = "对象类型", required = true, example = "3")
|
||||
@Parameter(name = "entityId", description = "对象编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:query')")
|
||||
public CommonResult<Boolean> deleteFavorite(
|
||||
@RequestParam("type") @InEnum(PmsKnowledgeObjectTypeEnum.class) Integer type,
|
||||
@RequestParam("entityId") Long entityId) {
|
||||
favoriteService.deleteFavorite(type, entityId, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得我的关注分页")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:query')")
|
||||
public CommonResult<PageResult<PmsKnowledgeInteractionItemRespVO>> getFavoritePage(
|
||||
@Valid PmsKnowledgeFavoritePageReqVO pageReqVO) {
|
||||
return success(favoriteService.getFavoritePage(pageReqVO, getLoginUserId()));
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "获得知识库内我的关注列表")
|
||||
@Parameter(name = "libraryId", description = "知识库编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:query')")
|
||||
public CommonResult<List<PmsKnowledgeInteractionItemRespVO>> getFavoriteListByLibraryId(
|
||||
@RequestParam("libraryId") Long libraryId) {
|
||||
return success(favoriteService.getFavoriteListByLibraryId(libraryId, getLoginUserId()));
|
||||
}
|
||||
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.interaction;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.interaction.vo.viewrecord.PmsKnowledgeRecentListRespVO;
|
||||
import cn.iocoder.yudao.module.pms.service.kb.interaction.PmsKnowledgeViewRecordService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Tag(name = "管理后台 - PMS 知识最近浏览")
|
||||
@RestController
|
||||
@RequestMapping("/pms/kb/view-record")
|
||||
@Validated
|
||||
public class PmsKnowledgeViewRecordController {
|
||||
|
||||
@Resource
|
||||
private PmsKnowledgeViewRecordService viewRecordService;
|
||||
|
||||
@GetMapping("/recent-list")
|
||||
@Operation(summary = "获得最近浏览列表")
|
||||
@Parameter(name = "libraryId", description = "知识库编号;不传时查询全部可读知识库", example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:query')")
|
||||
public CommonResult<PmsKnowledgeRecentListRespVO> getRecentViewRecordList(
|
||||
@RequestParam(value = "libraryId", required = false) Long libraryId) {
|
||||
return success(viewRecordService.getRecentViewRecordList(libraryId, getLoginUserId()));
|
||||
}
|
||||
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.interaction.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识交互对象 Response VO")
|
||||
@Data
|
||||
public class PmsKnowledgeInteractionItemRespVO {
|
||||
|
||||
@Schema(description = "记录编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "对象类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "3")
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "对象编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long entityId;
|
||||
|
||||
@Schema(description = "知识库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long libraryId;
|
||||
|
||||
@Schema(description = "知识库名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "产品知识库")
|
||||
private String libraryName;
|
||||
|
||||
@Schema(description = "对象名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "产品说明")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "知识库简介")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "文件夹编号", example = "1024")
|
||||
private Long folderId;
|
||||
|
||||
@Schema(description = "文档编号", example = "1024")
|
||||
private Long documentId;
|
||||
|
||||
@Schema(description = "文件类型", example = "pdf")
|
||||
private String fileType;
|
||||
|
||||
@Schema(description = "文件大小,单位:字节")
|
||||
private Long fileSize;
|
||||
|
||||
@Schema(description = "对象更新时间")
|
||||
private LocalDateTime targetUpdateTime;
|
||||
|
||||
@Schema(description = "记录时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.interaction.vo.comment;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库文档评论 Response VO")
|
||||
@Data
|
||||
public class PmsKnowledgeDocumentCommentRespVO {
|
||||
|
||||
@Schema(description = "评论编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "文档编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long documentId;
|
||||
|
||||
@Schema(description = "评论人用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long userId;
|
||||
|
||||
@Schema(description = "评论人昵称", example = "芋道")
|
||||
private String userName;
|
||||
|
||||
@Schema(description = "主评论编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
|
||||
private Long mainId;
|
||||
|
||||
@Schema(description = "回复对象用户编号", example = "2")
|
||||
private Long replyUserId;
|
||||
|
||||
@Schema(description = "回复对象昵称", example = "源码")
|
||||
private String replyUserName;
|
||||
|
||||
@Schema(description = "评论内容", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String content;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "回复列表", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<PmsKnowledgeDocumentCommentRespVO> children;
|
||||
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.interaction.vo.comment;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库文档评论保存 Request VO")
|
||||
@Data
|
||||
public class PmsKnowledgeDocumentCommentSaveReqVO {
|
||||
|
||||
@Schema(description = "文档编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "文档编号不能为空")
|
||||
private Long documentId;
|
||||
|
||||
@Schema(description = "主评论编号", example = "0")
|
||||
private Long mainId;
|
||||
|
||||
@Schema(description = "回复对象用户编号", example = "1")
|
||||
private Long replyUserId;
|
||||
|
||||
@Schema(description = "评论内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "文档内容很清楚")
|
||||
@NotBlank(message = "评论内容不能为空")
|
||||
@Size(max = 2000, message = "评论内容不能超过 2000 个字符")
|
||||
private String content;
|
||||
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.interaction.vo.favorite;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.pms.enums.kb.PmsKnowledgeObjectTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识收藏(关注)分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class PmsKnowledgeFavoritePageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "对象类型", example = "3")
|
||||
@InEnum(value = PmsKnowledgeObjectTypeEnum.class, message = "对象类型必须是 {value}")
|
||||
private Integer type;
|
||||
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.interaction.vo.favorite;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.pms.enums.kb.PmsKnowledgeObjectTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识收藏(关注)保存 Request VO")
|
||||
@Data
|
||||
public class PmsKnowledgeFavoriteSaveReqVO {
|
||||
|
||||
@Schema(description = "对象类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "3")
|
||||
@NotNull(message = "对象类型不能为空")
|
||||
@InEnum(value = PmsKnowledgeObjectTypeEnum.class, message = "对象类型必须是 {value}")
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "对象编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "对象编号不能为空")
|
||||
private Long entityId;
|
||||
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.interaction.vo.share;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "PMS 知识库文档公开分享 Response VO")
|
||||
@Data
|
||||
public class PmsKnowledgeDocumentSharePublicRespVO {
|
||||
|
||||
@Schema(description = "文档编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "文档标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "产品说明")
|
||||
private String title;
|
||||
|
||||
@Schema(description = "文档内容或文件地址")
|
||||
private String content;
|
||||
|
||||
@Schema(description = "文件临时预览地址")
|
||||
private String previewUrl;
|
||||
|
||||
@Schema(description = "文档类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "3")
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "文件类型", example = "pdf")
|
||||
private String fileType;
|
||||
|
||||
@Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.interaction.vo.share;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库文档分享 Response VO")
|
||||
@Data
|
||||
public class PmsKnowledgeDocumentShareRespVO {
|
||||
|
||||
@Schema(description = "分享编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "文档编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long documentId;
|
||||
|
||||
@Schema(description = "内部分享成员用户编号列表", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<Long> shareUserIds;
|
||||
|
||||
@Schema(description = "外部查看令牌", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String token;
|
||||
|
||||
@Schema(description = "分享状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "关闭人用户编号")
|
||||
private Long closeUserId;
|
||||
|
||||
@Schema(description = "关闭时间")
|
||||
private LocalDateTime closeTime;
|
||||
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.interaction.vo.share;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库文档分享保存 Request VO")
|
||||
@Data
|
||||
public class PmsKnowledgeDocumentShareSaveReqVO {
|
||||
|
||||
@Schema(description = "文档编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "文档编号不能为空")
|
||||
private Long documentId;
|
||||
|
||||
@Schema(description = "内部分享成员用户编号列表")
|
||||
private List<@NotNull(message = "分享成员用户编号不能为空") Long> shareUserIds;
|
||||
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.interaction.vo.share;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库文档分享成员列表更新 Request VO")
|
||||
@Data
|
||||
public class PmsKnowledgeDocumentShareUpdateMemberListReqVO {
|
||||
|
||||
@Schema(description = "文档编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "文档编号不能为空")
|
||||
private Long documentId;
|
||||
|
||||
@Schema(description = "内部分享成员用户编号列表")
|
||||
private List<@NotNull(message = "分享成员用户编号不能为空") Long> shareUserIds;
|
||||
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.interaction.vo.viewrecord;
|
||||
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.interaction.vo.PmsKnowledgeInteractionItemRespVO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识最近浏览 Response VO")
|
||||
@Data
|
||||
public class PmsKnowledgeRecentListRespVO {
|
||||
|
||||
@Schema(description = "今天浏览列表", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<PmsKnowledgeInteractionItemRespVO> todayItems;
|
||||
|
||||
@Schema(description = "昨天浏览列表", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<PmsKnowledgeInteractionItemRespVO> yesterdayItems;
|
||||
|
||||
@Schema(description = "更早 30 天浏览列表", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<PmsKnowledgeInteractionItemRespVO> recent30DayItems;
|
||||
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.library;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.library.vo.group.PmsKnowledgeGroupRespVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.library.vo.group.PmsKnowledgeGroupSaveReqVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.library.vo.group.PmsKnowledgeGroupSortReqVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.library.vo.group.PmsKnowledgeLibraryMoveGroupReqVO;
|
||||
import cn.iocoder.yudao.module.pms.dal.dataobject.kb.library.PmsKnowledgeGroupDO;
|
||||
import cn.iocoder.yudao.module.pms.service.kb.library.PmsKnowledgeGroupService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Tag(name = "管理后台 - PMS 知识库分组")
|
||||
@RestController
|
||||
@RequestMapping("/pms/kb/group")
|
||||
@Validated
|
||||
public class PmsKnowledgeGroupController {
|
||||
|
||||
@Resource
|
||||
private PmsKnowledgeGroupService knowledgeGroupService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建知识库分组")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:create')")
|
||||
public CommonResult<Long> createGroup(@Valid @RequestBody PmsKnowledgeGroupSaveReqVO saveReqVO) {
|
||||
return success(knowledgeGroupService.createGroup(saveReqVO, getLoginUserId()));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "修改知识库分组")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:update')")
|
||||
public CommonResult<Boolean> updateGroup(@Valid @RequestBody PmsKnowledgeGroupSaveReqVO saveReqVO) {
|
||||
knowledgeGroupService.updateGroup(saveReqVO, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/update-sort")
|
||||
@Operation(summary = "修改知识库分组排序")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:update')")
|
||||
public CommonResult<Boolean> updateGroupSort(
|
||||
@Valid @RequestBody PmsKnowledgeGroupSortReqVO sortReqVO) {
|
||||
knowledgeGroupService.updateGroupSort(sortReqVO, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除知识库分组")
|
||||
@Parameter(name = "id", description = "知识库分组编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:delete')")
|
||||
public CommonResult<Boolean> deleteGroup(@RequestParam("id") Long id) {
|
||||
knowledgeGroupService.deleteGroup(id, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "获得知识库分组列表")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:query')")
|
||||
public CommonResult<List<PmsKnowledgeGroupRespVO>> getGroupList() {
|
||||
Long userId = getLoginUserId();
|
||||
List<PmsKnowledgeGroupDO> groups = knowledgeGroupService.getGroupList(userId);
|
||||
Map<Long, Integer> groupCountMap = knowledgeGroupService.getGroupLibraryCountMap(userId,
|
||||
convertSet(groups, PmsKnowledgeGroupDO::getId));
|
||||
return success(convertList(groups, group -> BeanUtils.toBean(group, PmsKnowledgeGroupRespVO.class)
|
||||
.setLibraryCount(groupCountMap.getOrDefault(group.getId(), 0))));
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得知识库分组")
|
||||
@Parameter(name = "id", description = "知识库分组编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:query')")
|
||||
public CommonResult<PmsKnowledgeGroupRespVO> getGroup(@RequestParam("id") Long id) {
|
||||
return success(BeanUtils.toBean(knowledgeGroupService.getGroup(id, getLoginUserId()),
|
||||
PmsKnowledgeGroupRespVO.class));
|
||||
}
|
||||
|
||||
@PutMapping("/move")
|
||||
@Operation(summary = "移动知识库到个人分组")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:update')")
|
||||
public CommonResult<Boolean> moveLibraryToGroup(
|
||||
@Valid @RequestBody PmsKnowledgeLibraryMoveGroupReqVO moveReqVO) {
|
||||
knowledgeGroupService.moveLibraryToGroup(moveReqVO, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
}
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.library;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.library.vo.library.PmsKnowledgeLibraryPageReqVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.library.vo.library.PmsKnowledgeLibraryRespVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.library.vo.library.PmsKnowledgeLibrarySaveReqVO;
|
||||
import cn.iocoder.yudao.module.pms.dal.dataobject.kb.library.PmsKnowledgeLibraryDO;
|
||||
import cn.iocoder.yudao.module.pms.dal.dataobject.kb.library.PmsKnowledgeLibraryMemberDO;
|
||||
import cn.iocoder.yudao.module.pms.enums.kb.PmsKnowledgeObjectTypeEnum;
|
||||
import cn.iocoder.yudao.module.pms.enums.kb.content.PmsKnowledgeDocumentTypeEnum;
|
||||
import cn.iocoder.yudao.module.pms.enums.kb.library.PmsKnowledgeLibraryMemberLevelEnum;
|
||||
import cn.iocoder.yudao.module.pms.service.kb.content.PmsKnowledgeDocumentService;
|
||||
import cn.iocoder.yudao.module.pms.service.kb.interaction.PmsKnowledgeFavoriteService;
|
||||
import cn.iocoder.yudao.module.pms.service.kb.library.PmsKnowledgeLibraryMemberService;
|
||||
import cn.iocoder.yudao.module.pms.service.kb.library.PmsKnowledgeLibraryService;
|
||||
import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import cn.iocoder.yudao.module.system.enums.permission.RoleCodeEnum;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Tag(name = "管理后台 - PMS 知识库")
|
||||
@RestController
|
||||
@RequestMapping("/pms/kb/library")
|
||||
@Validated
|
||||
public class PmsKnowledgeLibraryController {
|
||||
|
||||
@Resource
|
||||
private PmsKnowledgeLibraryService libraryService;
|
||||
@Resource
|
||||
private PmsKnowledgeLibraryMemberService memberService;
|
||||
@Resource
|
||||
private PmsKnowledgeDocumentService documentService;
|
||||
@Resource
|
||||
private PmsKnowledgeFavoriteService favoriteService;
|
||||
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
@Resource
|
||||
private PermissionApi permissionApi;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建知识库")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:create')")
|
||||
public CommonResult<Long> createLibrary(@Valid @RequestBody PmsKnowledgeLibrarySaveReqVO saveReqVO) {
|
||||
return success(libraryService.createLibrary(saveReqVO, getLoginUserId()));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新知识库")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:update')")
|
||||
public CommonResult<Boolean> updateLibrary(@Valid @RequestBody PmsKnowledgeLibrarySaveReqVO saveReqVO) {
|
||||
libraryService.updateLibrary(saveReqVO, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除知识库")
|
||||
@Parameter(name = "id", description = "知识库编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:delete')")
|
||||
public CommonResult<Boolean> deleteLibrary(@RequestParam("id") Long id) {
|
||||
libraryService.deleteLibrary(id, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得知识库详情")
|
||||
@Parameter(name = "id", description = "知识库编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:query')")
|
||||
public CommonResult<PmsKnowledgeLibraryRespVO> getLibrary(@RequestParam("id") Long id) {
|
||||
Long userId = getLoginUserId();
|
||||
PmsKnowledgeLibraryDO library = memberService.validateLibraryReadable(id, userId);
|
||||
return success(CollUtil.getFirst(buildLibraryRespVOList(Collections.singletonList(library), userId)));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得知识库分页")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:query')")
|
||||
public CommonResult<PageResult<PmsKnowledgeLibraryRespVO>> getLibraryPage(
|
||||
@Valid PmsKnowledgeLibraryPageReqVO pageReqVO) {
|
||||
Long userId = getLoginUserId();
|
||||
PageResult<PmsKnowledgeLibraryDO> pageResult = libraryService.getLibraryPage(pageReqVO, userId);
|
||||
return success(new PageResult<>(buildLibraryRespVOList(pageResult.getList(), userId), pageResult.getTotal()));
|
||||
}
|
||||
|
||||
// ==================== 拼接 VO ====================
|
||||
|
||||
private List<PmsKnowledgeLibraryRespVO> buildLibraryRespVOList(
|
||||
List<PmsKnowledgeLibraryDO> libraries, Long userId) {
|
||||
if (CollUtil.isEmpty(libraries)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// 1. 批量查询知识库成员、内容数量、创建人和当前用户权限信息
|
||||
Set<Long> libraryIds = convertSet(libraries, PmsKnowledgeLibraryDO::getId);
|
||||
Map<Long, List<PmsKnowledgeLibraryMemberDO>> memberListMap = memberService.getLibraryMemberListMap(libraryIds);
|
||||
Map<Long, Map<Integer, Long>> documentTypeCountMap = documentService.getDocumentTypeCountMap(libraryIds);
|
||||
Set<Long> userIds = convertSet(libraries, library -> NumberUtils.parseLong(library.getCreator()));
|
||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);
|
||||
AdminUserRespDTO currentUser = adminUserApi.getUser(userId).getCheckedData();
|
||||
Long deptId = currentUser != null ? currentUser.getDeptId() : null;
|
||||
boolean superAdmin = permissionApi.hasAnyRoles(userId, RoleCodeEnum.SUPER_ADMIN.getCode()).getCheckedData();
|
||||
Set<Long> favoriteLibraryIds = favoriteService.getFavoriteEntityIdSet(
|
||||
PmsKnowledgeObjectTypeEnum.LIBRARY.getType(), libraryIds, userId);
|
||||
|
||||
// 2. 拼接每个知识库的成员权限、统计数量、收藏状态和创建人名称
|
||||
return convertList(libraries, library -> {
|
||||
List<PmsKnowledgeLibraryMemberDO> members = memberListMap.getOrDefault(library.getId(), Collections.emptyList());
|
||||
PmsKnowledgeLibraryMemberDO directMember = CollUtil.findOne(members, member -> userId.equals(member.getUserId()));
|
||||
PmsKnowledgeLibraryMemberDO currentMember = directMember;
|
||||
if (currentMember == null && deptId != null) {
|
||||
currentMember = CollUtil.findOne(members, member -> deptId.equals(member.getDeptId()));
|
||||
}
|
||||
boolean adminStatus = superAdmin || currentMember != null
|
||||
&& (PmsKnowledgeLibraryMemberLevelEnum.CREATOR.getLevel().equals(currentMember.getLevel())
|
||||
|| PmsKnowledgeLibraryMemberLevelEnum.ADMIN.getLevel().equals(currentMember.getLevel()));
|
||||
PmsKnowledgeLibraryRespVO libraryVO = BeanUtils.toBean(library, PmsKnowledgeLibraryRespVO.class)
|
||||
.setCreatorUserId(NumberUtils.parseLong(library.getCreator())).setMemberCount(members.size())
|
||||
.setWriteStatus(superAdmin || currentMember != null).setAdminStatus(adminStatus)
|
||||
.setExitStatus(directMember != null && !PmsKnowledgeLibraryMemberLevelEnum.CREATOR.getLevel().equals(directMember.getLevel()))
|
||||
.setFavoriteStatus(favoriteLibraryIds.contains(library.getId()));
|
||||
Map<Integer, Long> typeCountMap = documentTypeCountMap.getOrDefault(library.getId(), Collections.emptyMap());
|
||||
libraryVO.setDocumentCount(typeCountMap.getOrDefault(PmsKnowledgeDocumentTypeEnum.RICH_TEXT.getType(), 0L))
|
||||
.setFileCount(typeCountMap.getOrDefault(PmsKnowledgeDocumentTypeEnum.FILE.getType(), 0L));
|
||||
findAndThen(userMap, libraryVO.getCreatorUserId(), user -> libraryVO.setCreatorUserName(user.getNickname()));
|
||||
return libraryVO;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.library;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.library.vo.member.PmsKnowledgeLibraryMemberRespVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.library.vo.member.PmsKnowledgeLibraryUpdateMemberListReqVO;
|
||||
import cn.iocoder.yudao.module.pms.dal.dataobject.kb.library.PmsKnowledgeLibraryMemberDO;
|
||||
import cn.iocoder.yudao.module.pms.service.kb.library.PmsKnowledgeLibraryMemberService;
|
||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Tag(name = "管理后台 - PMS 知识库成员")
|
||||
@RestController
|
||||
@RequestMapping("/pms/kb/library-member")
|
||||
@Validated
|
||||
public class PmsKnowledgeLibraryMemberController {
|
||||
|
||||
@Resource
|
||||
private PmsKnowledgeLibraryMemberService memberService;
|
||||
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
@Resource
|
||||
private DeptApi deptApi;
|
||||
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "获得知识库成员列表")
|
||||
@Parameter(name = "libraryId", description = "知识库编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:query')")
|
||||
public CommonResult<List<PmsKnowledgeLibraryMemberRespVO>> getLibraryMemberList(@RequestParam("libraryId") Long libraryId) {
|
||||
List<PmsKnowledgeLibraryMemberDO> members = memberService.getLibraryMemberList(libraryId, getLoginUserId());
|
||||
return success(buildLibraryMemberRespVOList(members));
|
||||
}
|
||||
|
||||
@PutMapping("/update-list")
|
||||
@Operation(summary = "更新知识库成员")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:update')")
|
||||
public CommonResult<Boolean> updateLibraryMemberList(@Valid @RequestBody PmsKnowledgeLibraryUpdateMemberListReqVO updateReqVO) {
|
||||
memberService.updateLibraryMemberList(updateReqVO, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/exit")
|
||||
@Operation(summary = "主动退出知识库")
|
||||
@Parameter(name = "libraryId", description = "知识库编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:query')")
|
||||
public CommonResult<Boolean> exitLibrary(@RequestParam("libraryId") Long libraryId) {
|
||||
memberService.exitLibrary(libraryId, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
// ==================== 拼接 VO ====================
|
||||
|
||||
private List<PmsKnowledgeLibraryMemberRespVO> buildLibraryMemberRespVOList(
|
||||
List<PmsKnowledgeLibraryMemberDO> members) {
|
||||
if (CollUtil.isEmpty(members)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// 1. 批量查询用户和部门
|
||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
|
||||
convertSet(members, PmsKnowledgeLibraryMemberDO::getUserId));
|
||||
Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(
|
||||
convertSet(members, PmsKnowledgeLibraryMemberDO::getDeptId));
|
||||
Map<Long, DeptRespDTO> parentDeptMap = deptApi.getDeptMap(convertSet(deptMap.values(), DeptRespDTO::getParentId));
|
||||
// 2. 转换成员响应,并拼接用户和部门名称
|
||||
return convertList(members, member -> {
|
||||
PmsKnowledgeLibraryMemberRespVO memberVO = BeanUtils.toBean(member, PmsKnowledgeLibraryMemberRespVO.class);
|
||||
findAndThen(userMap, member.getUserId(), user ->
|
||||
memberVO.setNickname(user.getNickname()).setAvatar(user.getAvatar()));
|
||||
findAndThen(deptMap, member.getDeptId(), dept -> {
|
||||
memberVO.setDeptName(dept.getName()).setParentDeptId(dept.getParentId());
|
||||
findAndThen(parentDeptMap, dept.getParentId(), parent -> memberVO.setParentDeptName(parent.getName()));
|
||||
});
|
||||
return memberVO;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.library;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.library.vo.template.PmsKnowledgeLibraryTemplatePageReqVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.library.vo.template.PmsKnowledgeLibraryTemplateRespVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.library.vo.template.PmsKnowledgeLibraryTemplateSaveReqVO;
|
||||
import cn.iocoder.yudao.module.pms.dal.dataobject.kb.library.PmsKnowledgeLibraryTemplateDO;
|
||||
import cn.iocoder.yudao.module.pms.service.kb.library.PmsKnowledgeLibraryTemplateService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
|
||||
/**
|
||||
* 管理后台 - PMS 知识库模板 Controller
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Tag(name = "管理后台 - PMS 知识库模板")
|
||||
@RestController
|
||||
@RequestMapping("/pms/kb/library-template")
|
||||
@Validated
|
||||
public class PmsKnowledgeLibraryTemplateController {
|
||||
|
||||
@Resource
|
||||
private PmsKnowledgeLibraryTemplateService libraryTemplateService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建知识库模板")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library-template:create')")
|
||||
public CommonResult<Long> createLibraryTemplate(
|
||||
@Valid @RequestBody PmsKnowledgeLibraryTemplateSaveReqVO createReqVO) {
|
||||
return success(libraryTemplateService.createLibraryTemplate(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新知识库模板")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library-template:update')")
|
||||
public CommonResult<Boolean> updateLibraryTemplate(
|
||||
@Valid @RequestBody PmsKnowledgeLibraryTemplateSaveReqVO updateReqVO) {
|
||||
libraryTemplateService.updateLibraryTemplate(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除知识库模板")
|
||||
@Parameter(name = "id", description = "模板编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library-template:delete')")
|
||||
public CommonResult<Boolean> deleteLibraryTemplate(@RequestParam("id") Long id) {
|
||||
libraryTemplateService.deleteLibraryTemplate(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得知识库模板")
|
||||
@Parameter(name = "id", description = "模板编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library-template:query')")
|
||||
public CommonResult<PmsKnowledgeLibraryTemplateRespVO> getLibraryTemplate(@RequestParam("id") Long id) {
|
||||
PmsKnowledgeLibraryTemplateDO template = libraryTemplateService.getLibraryTemplate(id);
|
||||
return success(BeanUtils.toBean(template, PmsKnowledgeLibraryTemplateRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/simple-list")
|
||||
@Operation(summary = "获取知识库模板全列表", description = "只包含开启状态模板,返回模板选择所需的基本信息和文档标题")
|
||||
public CommonResult<List<PmsKnowledgeLibraryTemplateRespVO>> getSimpleLibraryTemplateList() {
|
||||
return success(convertList(libraryTemplateService.getLibraryTemplateList(CommonStatusEnum.ENABLE.getStatus()),
|
||||
template -> new PmsKnowledgeLibraryTemplateRespVO().setId(template.getId())
|
||||
.setName(template.getName()).setCoverUrl(template.getCoverUrl()).setDescription(template.getDescription())
|
||||
.setDocuments(convertList(template.getDocuments(), document ->
|
||||
new PmsKnowledgeLibraryTemplateSaveReqVO.Document().setTitle(document.getTitle())))));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得知识库模板分页")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library-template:query')")
|
||||
public CommonResult<PageResult<PmsKnowledgeLibraryTemplateRespVO>> getLibraryTemplatePage(
|
||||
@Valid PmsKnowledgeLibraryTemplatePageReqVO pageReqVO) {
|
||||
PageResult<PmsKnowledgeLibraryTemplateDO> pageResult = libraryTemplateService
|
||||
.getLibraryTemplatePage(pageReqVO);
|
||||
return success(new PageResult<>(BeanUtils.toBean(pageResult.getList(), PmsKnowledgeLibraryTemplateRespVO.class),
|
||||
pageResult.getTotal()));
|
||||
}
|
||||
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.library.vo.group;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库分组 Response VO")
|
||||
@Data
|
||||
public class PmsKnowledgeGroupRespVO {
|
||||
|
||||
@Schema(description = "知识库分组编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "分组名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "产品知识库")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "显示顺序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer sort;
|
||||
|
||||
@Schema(description = "分组类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "3")
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "分组内知识库数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
|
||||
private Integer libraryCount;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.library.vo.group;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库分组新增/修改 Request VO")
|
||||
@Data
|
||||
public class PmsKnowledgeGroupSaveReqVO {
|
||||
|
||||
@Schema(description = "知识库分组编号", example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "分组名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "产品知识库")
|
||||
@NotBlank(message = "分组名称不能为空")
|
||||
@Size(max = 100, message = "分组名称不能超过 100 个字符")
|
||||
private String name;
|
||||
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.library.vo.group;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库分组排序 Request VO")
|
||||
@Data
|
||||
public class PmsKnowledgeGroupSortReqVO {
|
||||
|
||||
@Schema(description = "知识库分组排序项", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotEmpty(message = "知识库分组排序项不能为空")
|
||||
private List<@Valid Item> items;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库分组排序项 Request VO")
|
||||
@Data
|
||||
public static class Item {
|
||||
|
||||
@Schema(description = "知识库分组编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "知识库分组编号不能为空")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "显示顺序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "显示顺序不能为空")
|
||||
@Min(value = 0, message = "显示顺序不能小于 0")
|
||||
private Integer sort;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.library.vo.group;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库移动分组 Request VO")
|
||||
@Data
|
||||
public class PmsKnowledgeLibraryMoveGroupReqVO {
|
||||
|
||||
@Schema(description = "知识库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "知识库编号不能为空")
|
||||
private Long libraryId;
|
||||
|
||||
@Schema(description = "目标分组编号;为空表示移出分组", example = "2048")
|
||||
private Long groupId;
|
||||
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.library.vo.library;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PmsKnowledgeLibraryPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "知识库名称", example = "产品")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "个人知识库分组编号", example = "1024")
|
||||
private Long groupId;
|
||||
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.library.vo.library;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库 Response VO")
|
||||
@Data
|
||||
public class PmsKnowledgeLibraryRespVO {
|
||||
|
||||
@Schema(description = "知识库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "知识库名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "产品知识库")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "知识库简介")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "是否公开", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Boolean openStatus;
|
||||
|
||||
@Schema(description = "知识库封面")
|
||||
private String coverUrl;
|
||||
|
||||
@Schema(description = "创建人用户编号", example = "1")
|
||||
private Long creatorUserId;
|
||||
|
||||
@Schema(description = "创建人姓名", example = "芋道源码")
|
||||
private String creatorUserName;
|
||||
|
||||
@Schema(description = "成员数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
|
||||
private Integer memberCount;
|
||||
|
||||
@Schema(description = "文档数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "12")
|
||||
private Long documentCount;
|
||||
|
||||
@Schema(description = "文件数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "4")
|
||||
private Long fileCount;
|
||||
|
||||
@Schema(description = "当前用户是否可以编辑内容", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Boolean writeStatus;
|
||||
|
||||
@Schema(description = "当前用户是否为知识库管理员", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Boolean adminStatus;
|
||||
|
||||
@Schema(description = "当前用户是否可以主动退出知识库", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Boolean exitStatus;
|
||||
|
||||
@Schema(description = "当前用户是否已关注", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Boolean favoriteStatus;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.library.vo.library;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Positive;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库新增/修改 Request VO")
|
||||
@Data
|
||||
public class PmsKnowledgeLibrarySaveReqVO {
|
||||
|
||||
@Schema(description = "知识库编号", example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "知识库名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "产品知识库")
|
||||
@NotBlank(message = "知识库名称不能为空")
|
||||
@Size(max = 50, message = "知识库名称不能超过 50 个字符")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "知识库简介", example = "沉淀产品文档")
|
||||
@Size(max = 300, message = "知识库简介不能超过 300 个字符")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "是否公开", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
|
||||
@NotNull(message = "知识库可见范围不能为空")
|
||||
private Boolean openStatus;
|
||||
|
||||
@Schema(description = "知识库封面")
|
||||
@Size(max = 255, message = "知识库封面地址不能超过 255 个字符")
|
||||
private String coverUrl;
|
||||
|
||||
@Schema(description = "创建时的初始管理员用户编号列表", example = "[1, 2]")
|
||||
private List<Long> adminUserIds;
|
||||
|
||||
@Schema(description = "创建时的初始普通成员用户编号列表", example = "[3, 4]")
|
||||
private List<Long> memberUserIds;
|
||||
|
||||
@Schema(description = "模板编号,仅创建时有效", example = "1")
|
||||
@Positive(message = "模板编号必须大于 0")
|
||||
private Long templateId;
|
||||
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.library.vo.member;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库成员 Response VO")
|
||||
@Data
|
||||
public class PmsKnowledgeLibraryMemberRespVO {
|
||||
|
||||
@Schema(description = "成员编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "用户编号", example = "1")
|
||||
private Long userId;
|
||||
|
||||
@Schema(description = "用户姓名", example = "芋道源码")
|
||||
private String nickname;
|
||||
|
||||
@Schema(description = "用户头像")
|
||||
private String avatar;
|
||||
|
||||
@Schema(description = "部门编号", example = "100")
|
||||
private Long deptId;
|
||||
|
||||
@Schema(description = "部门名称", example = "研发部")
|
||||
private String deptName;
|
||||
|
||||
@Schema(description = "父部门编号")
|
||||
private Long parentDeptId;
|
||||
|
||||
@Schema(description = "父部门名称")
|
||||
private String parentDeptName;
|
||||
|
||||
@Schema(description = "成员等级", requiredMode = Schema.RequiredMode.REQUIRED, example = "3")
|
||||
private Integer level;
|
||||
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.library.vo.member;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.pms.enums.kb.library.PmsKnowledgeLibraryMemberLevelEnum;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.AssertTrue;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 更新知识库成员列表 Request VO")
|
||||
@Data
|
||||
public class PmsKnowledgeLibraryUpdateMemberListReqVO {
|
||||
|
||||
@Schema(description = "知识库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "知识库编号不能为空")
|
||||
private Long libraryId;
|
||||
|
||||
@Schema(description = "成员列表", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Valid
|
||||
@NotNull(message = "成员列表不能为空")
|
||||
private List<Member> members;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库成员更新项")
|
||||
@Data
|
||||
public static class Member {
|
||||
|
||||
@Schema(description = "用户编号", example = "1")
|
||||
private Long userId;
|
||||
|
||||
@Schema(description = "部门编号", example = "100")
|
||||
private Long deptId;
|
||||
|
||||
@Schema(description = "成员等级", requiredMode = Schema.RequiredMode.REQUIRED, example = "3")
|
||||
@NotNull(message = "成员等级不能为空")
|
||||
@InEnum(PmsKnowledgeLibraryMemberLevelEnum.class)
|
||||
private Integer level;
|
||||
|
||||
@AssertTrue(message = "知识库成员必须且只能选择用户或部门")
|
||||
@JsonIgnore
|
||||
public boolean isUserOrDeptValid() {
|
||||
return (userId != null && deptId == null) || (userId == null && deptId != null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.library.vo.template;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库模板分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class PmsKnowledgeLibraryTemplatePageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "模板名称,模糊匹配", example = "产品研发")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "模板状态", example = "0")
|
||||
@InEnum(CommonStatusEnum.class)
|
||||
private Integer status;
|
||||
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.library.vo.template;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库模板 Response VO")
|
||||
@Data
|
||||
public class PmsKnowledgeLibraryTemplateRespVO {
|
||||
|
||||
@Schema(description = "模板编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "模板名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "产品研发")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "模板简介", example = "提供完善的产品流程文档")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "模板封面地址", example = "/static/pms/kb/template/product.png")
|
||||
private String coverUrl;
|
||||
|
||||
@Schema(description = "模板状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "显示顺序", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
|
||||
private Integer sort;
|
||||
|
||||
@Schema(description = "模板文档列表", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<PmsKnowledgeLibraryTemplateSaveReqVO.Document> documents;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.library.vo.template;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.PositiveOrZero;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库模板新增/修改 Request VO")
|
||||
@Data
|
||||
public class PmsKnowledgeLibraryTemplateSaveReqVO {
|
||||
|
||||
@Schema(description = "模板编号", example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "模板名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "产品研发")
|
||||
@NotBlank(message = "模板名称不能为空")
|
||||
@Size(max = 100, message = "模板名称不能超过 100 个字符")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "模板简介", example = "提供完善的产品流程文档")
|
||||
@Size(max = 500, message = "模板简介不能超过 500 个字符")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "模板封面地址", example = "/static/pms/kb/template/product.png")
|
||||
@Size(max = 255, message = "模板封面地址不能超过 255 个字符")
|
||||
private String coverUrl;
|
||||
|
||||
@Schema(description = "模板状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
|
||||
@NotNull(message = "模板状态不能为空")
|
||||
@InEnum(CommonStatusEnum.class)
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "显示顺序", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
|
||||
@NotNull(message = "显示顺序不能为空")
|
||||
@PositiveOrZero(message = "显示顺序不能小于 0")
|
||||
private Integer sort;
|
||||
|
||||
@Schema(description = "模板文档列表", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotEmpty(message = "模板文档不能为空")
|
||||
@Valid
|
||||
private List<Document> documents;
|
||||
|
||||
@Schema(description = "模板文档")
|
||||
@Data
|
||||
public static class Document {
|
||||
|
||||
@Schema(description = "文档标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "产品需求文档")
|
||||
@NotBlank(message = "文档标题不能为空")
|
||||
@Size(max = 255, message = "文档标题不能超过 255 个字符")
|
||||
private String title;
|
||||
|
||||
@Schema(description = "文档内容", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "文档内容不能为空")
|
||||
private String content;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.recycle;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.recycle.vo.PmsKnowledgeRecycleDetailRespVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.recycle.vo.PmsKnowledgeRecyclePreviewRespVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.kb.recycle.vo.PmsKnowledgeRecycleRespVO;
|
||||
import cn.iocoder.yudao.module.pms.dal.dataobject.kb.content.PmsKnowledgeDocumentDO;
|
||||
import cn.iocoder.yudao.module.pms.dal.dataobject.kb.recycle.PmsKnowledgeRecycleRecordDO;
|
||||
import cn.iocoder.yudao.module.pms.enums.kb.PmsKnowledgeObjectTypeEnum;
|
||||
import cn.iocoder.yudao.module.pms.service.kb.content.PmsKnowledgeDocumentService;
|
||||
import cn.iocoder.yudao.module.pms.service.kb.recycle.PmsKnowledgeRecycleService;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Tag(name = "管理后台 - PMS 知识库回收站")
|
||||
@RestController
|
||||
@RequestMapping("/pms/kb/recycle")
|
||||
@Validated
|
||||
public class PmsKnowledgeRecycleController {
|
||||
|
||||
@Resource
|
||||
private PmsKnowledgeRecycleService recycleService;
|
||||
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
|
||||
@Resource
|
||||
private PmsKnowledgeDocumentService documentService;
|
||||
|
||||
@GetMapping("/library-list")
|
||||
@Operation(summary = "获得已删除知识库列表")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:delete')")
|
||||
public CommonResult<List<PmsKnowledgeRecycleRespVO>> getLibraryRecycleList() {
|
||||
List<PmsKnowledgeRecycleRecordDO> records = recycleService.getLibraryRecycleList(getLoginUserId());
|
||||
return success(buildRecycleRespVOList(records));
|
||||
}
|
||||
|
||||
@GetMapping("/content-list")
|
||||
@Operation(summary = "获得知识库最近删除内容")
|
||||
@Parameter(name = "libraryId", description = "知识库编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:delete')")
|
||||
public CommonResult<List<PmsKnowledgeRecycleRespVO>> getContentRecycleList(
|
||||
@RequestParam("libraryId") Long libraryId) {
|
||||
List<PmsKnowledgeRecycleRecordDO> records = recycleService.getContentRecycleList(
|
||||
libraryId, getLoginUserId());
|
||||
return success(buildRecycleRespVOList(records));
|
||||
}
|
||||
|
||||
@GetMapping("/content-detail")
|
||||
@Operation(summary = "获得知识库最近删除详情")
|
||||
@Parameter(name = "id", description = "回收站记录编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:delete')")
|
||||
public CommonResult<PmsKnowledgeRecycleDetailRespVO> getContentRecycleDetail(
|
||||
@RequestParam("id") Long id) {
|
||||
return success(recycleService.getContentRecycleDetail(id, getLoginUserId()));
|
||||
}
|
||||
|
||||
@GetMapping("/content-preview")
|
||||
@Operation(summary = "预览知识库最近删除内容")
|
||||
@Parameter(name = "id", description = "回收站记录编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:delete')")
|
||||
public CommonResult<PmsKnowledgeRecyclePreviewRespVO> getContentRecyclePreview(
|
||||
@RequestParam("id") Long id,
|
||||
@RequestParam(value = "entityId", required = false) Long entityId) {
|
||||
PmsKnowledgeDocumentDO document = recycleService.getContentRecyclePreview(id, entityId, getLoginUserId());
|
||||
return success(BeanUtils.toBean(document, PmsKnowledgeRecyclePreviewRespVO.class,
|
||||
o -> o.setName(document.getTitle())));
|
||||
}
|
||||
|
||||
@PutMapping("/restore")
|
||||
@Operation(summary = "恢复回收站对象")
|
||||
@Parameter(name = "id", description = "回收站记录编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:delete')")
|
||||
public CommonResult<Boolean> restoreContentRecycle(@RequestParam("id") Long id) {
|
||||
recycleService.restoreContentRecycle(id, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/permanent-delete")
|
||||
@Operation(summary = "彻底删除回收站对象")
|
||||
@Parameter(name = "id", description = "回收站记录编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:kb:library:delete')")
|
||||
public CommonResult<Boolean> deleteContentRecycle(@RequestParam("id") Long id) {
|
||||
recycleService.deleteContentRecycle(id, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
// ==================== 拼接 VO ====================
|
||||
|
||||
private List<PmsKnowledgeRecycleRespVO> buildRecycleRespVOList(List<PmsKnowledgeRecycleRecordDO> records) {
|
||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
|
||||
convertSet(records, PmsKnowledgeRecycleRecordDO::getDeleteUserId));
|
||||
Map<Long, PmsKnowledgeDocumentDO> documentMap = documentService.getDocumentMap(convertSet(records, record ->
|
||||
PmsKnowledgeObjectTypeEnum.FILE.getType().equals(record.getType()) ? record.getEntityId() : null));
|
||||
return convertList(records, record -> {
|
||||
PmsKnowledgeRecycleRespVO recordVO = BeanUtils.toBean(record, PmsKnowledgeRecycleRespVO.class);
|
||||
findAndThen(documentMap, record.getEntityId(), document -> recordVO.setFileSize(document.getFileSize()));
|
||||
findAndThen(userMap, record.getDeleteUserId(), user -> recordVO.setDeleteUserName(user.getNickname()));
|
||||
return recordVO;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.recycle.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库回收站详情 Response VO")
|
||||
@Data
|
||||
public class PmsKnowledgeRecycleDetailRespVO {
|
||||
|
||||
@Schema(description = "根回收站记录")
|
||||
private PmsKnowledgeRecycleRespVO root;
|
||||
|
||||
@Schema(description = "级联删除内容")
|
||||
private List<Item> children;
|
||||
|
||||
@Data
|
||||
public static class Item {
|
||||
|
||||
@Schema(description = "内容编号", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "内容类型", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "内容名称", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String name;
|
||||
|
||||
@Schema(description = "父文档或父文件夹编号")
|
||||
private Long parentId;
|
||||
|
||||
@Schema(description = "所属文件夹编号")
|
||||
private Long folderId;
|
||||
|
||||
@Schema(description = "删除时间")
|
||||
private LocalDateTime deleteTime;
|
||||
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.recycle.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库回收站内容预览 Response VO")
|
||||
@Data
|
||||
public class PmsKnowledgeRecyclePreviewRespVO {
|
||||
|
||||
@Schema(description = "内容编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "内容类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "3")
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "内容名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "产品说明")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "文档正文或文件地址")
|
||||
private String content;
|
||||
|
||||
@Schema(description = "文件类型", example = "pdf")
|
||||
private String fileType;
|
||||
|
||||
@Schema(description = "文件大小,单位:字节", example = "102400")
|
||||
private Long fileSize;
|
||||
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.kb.recycle.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 知识库回收站记录 Response VO")
|
||||
@Data
|
||||
public class PmsKnowledgeRecycleRespVO {
|
||||
|
||||
@Schema(description = "回收站记录编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "知识库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long libraryId;
|
||||
|
||||
@Schema(description = "对象类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "3")
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "对象编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048")
|
||||
private Long entityId;
|
||||
|
||||
@Schema(description = "对象名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "产品说明")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "文件大小,单位:字节")
|
||||
private Long fileSize;
|
||||
|
||||
@Schema(description = "删除人用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long deleteUserId;
|
||||
|
||||
@Schema(description = "删除人姓名", example = "芋道")
|
||||
private String deleteUserName;
|
||||
|
||||
@Schema(description = "删除时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime deleteTime;
|
||||
|
||||
@Schema(description = "父对象编号,回收站详情中用于组装层级", example = "2048")
|
||||
private Long parentId;
|
||||
|
||||
@Schema(description = "所属文件夹编号,回收站详情中用于组装层级", example = "2048")
|
||||
private Long folderId;
|
||||
|
||||
}
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.pm.iteration;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.pm.iteration.vo.PmsIterationOverviewRespVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.pm.iteration.vo.PmsIterationPageReqVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.pm.iteration.vo.PmsIterationRespVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.pm.iteration.vo.PmsIterationSaveReqVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.pm.iteration.vo.PmsIterationStartReqVO;
|
||||
import cn.iocoder.yudao.module.pms.dal.dataobject.pm.iteration.PmsIterationDO;
|
||||
import cn.iocoder.yudao.module.pms.service.pm.iteration.PmsIterationService;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Tag(name = "管理后台 - PMS 项目迭代")
|
||||
@RestController
|
||||
@RequestMapping("/pms/pm/iteration")
|
||||
@Validated
|
||||
public class PmsIterationController {
|
||||
|
||||
@Resource
|
||||
private PmsIterationService iterationService;
|
||||
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建项目迭代")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:iteration:create')")
|
||||
public CommonResult<Long> createIteration(@Valid @RequestBody PmsIterationSaveReqVO saveReqVO) {
|
||||
return success(iterationService.createIteration(saveReqVO, getLoginUserId()));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新项目迭代")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:iteration:update')")
|
||||
public CommonResult<Boolean> updateIteration(@Valid @RequestBody PmsIterationSaveReqVO saveReqVO) {
|
||||
iterationService.updateIteration(saveReqVO, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/start")
|
||||
@Operation(summary = "开始项目迭代")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:iteration:update')")
|
||||
public CommonResult<Boolean> startIteration(@Valid @RequestBody PmsIterationStartReqVO startReqVO) {
|
||||
iterationService.startIteration(startReqVO, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/complete")
|
||||
@Operation(summary = "完成项目迭代")
|
||||
@Parameter(name = "id", description = "迭代编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:iteration:update')")
|
||||
public CommonResult<Boolean> completeIteration(@RequestParam("id") Long id) {
|
||||
iterationService.completeIteration(id, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除项目迭代")
|
||||
@Parameter(name = "id", description = "迭代编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:iteration:delete')")
|
||||
public CommonResult<Boolean> deleteIteration(@RequestParam("id") Long id) {
|
||||
iterationService.deleteIteration(id, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得项目迭代详情")
|
||||
@Parameter(name = "id", description = "迭代编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:iteration:query')")
|
||||
public CommonResult<PmsIterationRespVO> getIteration(@RequestParam("id") Long id) {
|
||||
PmsIterationDO iteration = iterationService.getIteration(id, getLoginUserId());
|
||||
PmsIterationRespVO iterationVO = buildIterationRespVO(iteration);
|
||||
return success(iterationVO);
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得项目迭代分页")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:iteration:query')")
|
||||
public CommonResult<PageResult<PmsIterationRespVO>> getIterationPage(
|
||||
@Valid PmsIterationPageReqVO pageReqVO) {
|
||||
PageResult<PmsIterationDO> pageResult = iterationService.getIterationPage(pageReqVO, getLoginUserId());
|
||||
List<PmsIterationRespVO> iterationVOList = buildIterationRespVOList(pageResult.getList());
|
||||
Map<Long, Integer> progressMap = iterationService.getIterationProgressMap(
|
||||
convertSet(pageResult.getList(), PmsIterationDO::getId));
|
||||
iterationVOList.forEach(iteration -> iteration.setProgress(progressMap.getOrDefault(iteration.getId(), 0)));
|
||||
return success(new PageResult<>(iterationVOList, pageResult.getTotal()));
|
||||
}
|
||||
|
||||
@GetMapping("/overview")
|
||||
@Operation(summary = "获得迭代概览统计")
|
||||
@Parameter(name = "id", description = "迭代编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:iteration:query')")
|
||||
public CommonResult<PmsIterationOverviewRespVO> getIterationOverview(@RequestParam("id") Long id) {
|
||||
PmsIterationOverviewRespVO overview = iterationService.getIterationOverview(id, getLoginUserId());
|
||||
List<PmsIterationOverviewRespVO.ActivityItem> activities = overview.getRecentActivities();
|
||||
Map<Long, AdminUserRespDTO> activityUserMap = adminUserApi.getUserMap(
|
||||
convertSet(activities, PmsIterationOverviewRespVO.ActivityItem::getOperatorUserId));
|
||||
activities.forEach(activity -> findAndThen(activityUserMap, activity.getOperatorUserId(),
|
||||
user -> activity.setOperatorUserName(user.getNickname())));
|
||||
return success(overview.setRecentActivities(activities));
|
||||
}
|
||||
|
||||
// ==================== 拼接 VO ====================
|
||||
|
||||
private PmsIterationRespVO buildIterationRespVO(PmsIterationDO iteration) {
|
||||
return CollUtil.getFirst(buildIterationRespVOList(Collections.singletonList(iteration)));
|
||||
}
|
||||
|
||||
private List<PmsIterationRespVO> buildIterationRespVOList(List<PmsIterationDO> iterations) {
|
||||
if (CollUtil.isEmpty(iterations)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// 1. 批量查询负责人
|
||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
|
||||
convertSet(iterations, PmsIterationDO::getOwnerUserId));
|
||||
|
||||
// 2. 转换迭代响应,并拼接负责人姓名
|
||||
return BeanUtils.toBean(iterations, PmsIterationRespVO.class, iterationVO ->
|
||||
findAndThen(userMap, iterationVO.getOwnerUserId(),
|
||||
user -> iterationVO.setOwnerUserName(user.getNickname())));
|
||||
}
|
||||
|
||||
}
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.pm.iteration.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 迭代概览 Response VO")
|
||||
@Data
|
||||
public class PmsIterationOverviewRespVO {
|
||||
|
||||
@Schema(description = "工作项总数", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
|
||||
private Integer totalCount;
|
||||
|
||||
@Schema(description = "未开始工作项数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "20")
|
||||
private Integer pendingCount;
|
||||
|
||||
@Schema(description = "进行中工作项数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "30")
|
||||
private Integer processingCount;
|
||||
|
||||
@Schema(description = "已完成工作项数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "50")
|
||||
private Integer completedCount;
|
||||
|
||||
@Schema(description = "完成进度百分比", requiredMode = Schema.RequiredMode.REQUIRED, example = "50")
|
||||
private Integer progress;
|
||||
|
||||
@Schema(description = "工作项类型数量统计", requiredMode = Schema.RequiredMode.REQUIRED, example = "{\"1\": 60, \"2\": 40}")
|
||||
private Map<Integer, Integer> typeCountMap;
|
||||
|
||||
@Schema(description = "工作项类型和状态数量统计", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Map<Integer, Map<Integer, Integer>> typeStatusCountMap;
|
||||
|
||||
@Schema(description = "状态趋势", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<TrendItem> statusTrends;
|
||||
|
||||
@Schema(description = "燃尽图数据", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<BurnDownItem> burnDowns;
|
||||
|
||||
@Schema(description = "最近动态列表", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<ActivityItem> recentActivities;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 迭代概览状态趋势项 VO")
|
||||
@Data
|
||||
public static class TrendItem {
|
||||
|
||||
@Schema(description = "日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2026-01-01")
|
||||
private String date;
|
||||
|
||||
@Schema(description = "当日未开始工作项数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
|
||||
private Integer pendingCount;
|
||||
|
||||
@Schema(description = "当日进行中工作项数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "3")
|
||||
private Integer processingCount;
|
||||
|
||||
@Schema(description = "当日已完成工作项数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
private Integer completedCount;
|
||||
|
||||
}
|
||||
|
||||
@Schema(description = "管理后台 - PMS 迭代概览燃尽图项 VO")
|
||||
@Data
|
||||
public static class BurnDownItem {
|
||||
|
||||
@Schema(description = "日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2026-01-01")
|
||||
private String date;
|
||||
|
||||
@Schema(description = "理想剩余工时,单位:小时", requiredMode = Schema.RequiredMode.REQUIRED, example = "40")
|
||||
private Integer idealRemaining;
|
||||
|
||||
@Schema(description = "实际剩余工时,单位:小时", requiredMode = Schema.RequiredMode.REQUIRED, example = "38")
|
||||
private Integer actualRemaining;
|
||||
|
||||
}
|
||||
|
||||
@Schema(description = "管理后台 - PMS 迭代概览动态项 VO")
|
||||
@Data
|
||||
public static class ActivityItem {
|
||||
|
||||
@Schema(description = "动态编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "工作项编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long workItemId;
|
||||
|
||||
@Schema(description = "工作项序号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3")
|
||||
private Integer workItemSerialNumber;
|
||||
|
||||
@Schema(description = "工作项名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "优化登录页")
|
||||
private String workItemName;
|
||||
|
||||
@Schema(description = "操作人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long operatorUserId;
|
||||
|
||||
@Schema(description = "操作人昵称", example = "芋道")
|
||||
private String operatorUserName;
|
||||
|
||||
@Schema(description = "动态内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "将状态更新为「已完成」")
|
||||
private String content;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.pm.iteration.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.pms.enums.pm.iteration.PmsIterationStatusEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 项目迭代分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PmsIterationPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "项目编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "项目编号不能为空")
|
||||
private Long projectId;
|
||||
|
||||
@Schema(description = "迭代名称", example = "第一期")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "迭代状态", example = "1")
|
||||
@InEnum(PmsIterationStatusEnum.class)
|
||||
private Integer status;
|
||||
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.pm.iteration.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 项目迭代 Response VO")
|
||||
@Data
|
||||
public class PmsIterationRespVO {
|
||||
|
||||
@Schema(description = "迭代编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "项目编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long projectId;
|
||||
|
||||
@Schema(description = "迭代名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "第一期")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "负责人用户编号", example = "1")
|
||||
private Long ownerUserId;
|
||||
|
||||
@Schema(description = "迭代状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "负责人姓名", example = "芋道源码")
|
||||
private String ownerUserName;
|
||||
|
||||
@Schema(description = "开始时间")
|
||||
private LocalDateTime startTime;
|
||||
|
||||
@Schema(description = "结束时间")
|
||||
private LocalDateTime endTime;
|
||||
|
||||
@Schema(description = "迭代目标", example = "完成核心流程")
|
||||
private String target;
|
||||
|
||||
@Schema(description = "迭代描述")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "完成时间")
|
||||
private LocalDateTime finishTime;
|
||||
|
||||
@Schema(description = "显示顺序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer sort;
|
||||
|
||||
@Schema(description = "完成进度百分比", requiredMode = Schema.RequiredMode.REQUIRED, example = "50")
|
||||
private Integer progress;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.pm.iteration.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.AssertTrue;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 项目迭代新增/修改 Request VO")
|
||||
@Data
|
||||
public class PmsIterationSaveReqVO {
|
||||
|
||||
@Schema(description = "迭代编号", example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "项目编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "项目编号不能为空")
|
||||
private Long projectId;
|
||||
|
||||
@Schema(description = "迭代名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "第一期")
|
||||
@NotBlank(message = "迭代名称不能为空")
|
||||
@Size(max = 100, message = "迭代名称长度不能超过 100 个字符")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "负责人用户编号", example = "1")
|
||||
private Long ownerUserId;
|
||||
|
||||
@Schema(description = "开始时间")
|
||||
private LocalDateTime startTime;
|
||||
|
||||
@Schema(description = "结束时间")
|
||||
private LocalDateTime endTime;
|
||||
|
||||
@Schema(description = "迭代目标", example = "完成核心流程")
|
||||
@Size(max = 255, message = "迭代目标长度不能超过 255 个字符")
|
||||
private String target;
|
||||
|
||||
@Schema(description = "迭代描述")
|
||||
private String description;
|
||||
|
||||
@Schema(hidden = true)
|
||||
@AssertTrue(message = "迭代结束时间必须晚于开始时间,且开始、结束时间需要同时填写")
|
||||
@JsonIgnore
|
||||
public boolean isTimeRangeValid() {
|
||||
return startTime == null && endTime == null
|
||||
|| startTime != null && endTime != null && endTime.isAfter(startTime);
|
||||
}
|
||||
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.pm.iteration.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.AssertTrue;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 项目迭代开始 Request VO")
|
||||
@Data
|
||||
public class PmsIterationStartReqVO {
|
||||
|
||||
@Schema(description = "迭代编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "迭代编号不能为空")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "迭代开始时间不能为空")
|
||||
private LocalDateTime startTime;
|
||||
|
||||
@Schema(description = "结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "迭代结束时间不能为空")
|
||||
private LocalDateTime endTime;
|
||||
|
||||
@Schema(hidden = true)
|
||||
@AssertTrue(message = "迭代结束时间必须晚于开始时间")
|
||||
@JsonIgnore
|
||||
public boolean isTimeRangeValid() {
|
||||
return startTime == null || endTime == null || endTime.isAfter(startTime);
|
||||
}
|
||||
|
||||
}
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.pm.project;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.pm.project.vo.announcement.PmsProjectAnnouncementRespVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.pm.project.vo.announcement.PmsProjectAnnouncementSaveReqVO;
|
||||
import cn.iocoder.yudao.module.pms.dal.dataobject.pm.project.PmsProjectAnnouncementDO;
|
||||
import cn.iocoder.yudao.module.pms.service.pm.project.PmsProjectAnnouncementService;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Tag(name = "管理后台 - PMS 项目公告")
|
||||
@RestController
|
||||
@RequestMapping("/pms/pm/project-announcement")
|
||||
@Validated
|
||||
public class PmsProjectAnnouncementController {
|
||||
|
||||
@Resource
|
||||
private PmsProjectAnnouncementService projectAnnouncementService;
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建项目公告")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:project:update')")
|
||||
public CommonResult<Long> createProjectAnnouncement(@Valid @RequestBody PmsProjectAnnouncementSaveReqVO saveReqVO) {
|
||||
return success(projectAnnouncementService.createProjectAnnouncement(saveReqVO, getLoginUserId()));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新项目公告")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:project:update')")
|
||||
public CommonResult<Boolean> updateProjectAnnouncement(
|
||||
@Valid @RequestBody PmsProjectAnnouncementSaveReqVO saveReqVO) {
|
||||
projectAnnouncementService.updateProjectAnnouncement(saveReqVO, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除项目公告")
|
||||
@Parameter(name = "id", description = "公告编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:project:update')")
|
||||
public CommonResult<Boolean> deleteProjectAnnouncement(@RequestParam("id") Long id) {
|
||||
projectAnnouncementService.deleteProjectAnnouncement(id, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得项目公告详情")
|
||||
@Parameter(name = "id", description = "公告编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:project:query')")
|
||||
public CommonResult<PmsProjectAnnouncementRespVO> getProjectAnnouncement(@RequestParam("id") Long id) {
|
||||
PmsProjectAnnouncementDO announcement = projectAnnouncementService
|
||||
.getProjectAnnouncement(id, getLoginUserId());
|
||||
return success(buildProjectAnnouncementRespVO(announcement));
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "获得项目公告列表")
|
||||
@Parameter(name = "projectId", description = "项目编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:project:query')")
|
||||
public CommonResult<List<PmsProjectAnnouncementRespVO>> getProjectAnnouncementList(
|
||||
@RequestParam("projectId") Long projectId) {
|
||||
List<PmsProjectAnnouncementDO> announcements = projectAnnouncementService
|
||||
.getProjectAnnouncementList(projectId, getLoginUserId());
|
||||
List<PmsProjectAnnouncementRespVO> announcementVOList = buildProjectAnnouncementRespVOList(announcements);
|
||||
return success(announcementVOList);
|
||||
}
|
||||
|
||||
// ==================== 拼接 VO ====================
|
||||
|
||||
/**
|
||||
* 构建项目公告响应
|
||||
*
|
||||
* @param announcement 项目公告
|
||||
* @return 项目公告响应
|
||||
*/
|
||||
private PmsProjectAnnouncementRespVO buildProjectAnnouncementRespVO(PmsProjectAnnouncementDO announcement) {
|
||||
return CollUtil.getFirst(buildProjectAnnouncementRespVOList(Collections.singletonList(announcement)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建项目公告响应列表
|
||||
*
|
||||
* @param announcements 项目公告列表
|
||||
* @return 项目公告响应列表
|
||||
*/
|
||||
private List<PmsProjectAnnouncementRespVO> buildProjectAnnouncementRespVOList(
|
||||
List<PmsProjectAnnouncementDO> announcements) {
|
||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertSet(announcements,
|
||||
announcement -> NumberUtils.parseLong(announcement.getCreator())));
|
||||
return convertList(announcements, announcement -> {
|
||||
PmsProjectAnnouncementRespVO announcementVO = BeanUtils.toBean(
|
||||
announcement, PmsProjectAnnouncementRespVO.class)
|
||||
.setCreatorUserId(NumberUtils.parseLong(announcement.getCreator()));
|
||||
findAndThen(userMap, announcementVO.getCreatorUserId(),
|
||||
user -> announcementVO.setCreatorUserName(user.getNickname()));
|
||||
return announcementVO;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
+207
@@ -0,0 +1,207 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.pm.project;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.pm.project.vo.project.PmsProjectOverviewRespVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.pm.project.vo.project.PmsProjectPageReqVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.pm.project.vo.project.PmsProjectRespVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.pm.project.vo.project.PmsProjectSaveReqVO;
|
||||
import cn.iocoder.yudao.module.pms.dal.dataobject.pm.project.PmsProjectDO;
|
||||
import cn.iocoder.yudao.module.pms.enums.pm.workitem.PmsWorkItemStatusTypeEnum;
|
||||
import cn.iocoder.yudao.module.pms.service.pm.project.PmsProjectFavoriteService;
|
||||
import cn.iocoder.yudao.module.pms.service.pm.project.PmsProjectMemberService;
|
||||
import cn.iocoder.yudao.module.pms.service.pm.project.PmsProjectService;
|
||||
import cn.iocoder.yudao.module.pms.service.pm.workitem.PmsWorkItemService;
|
||||
import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import cn.iocoder.yudao.module.system.enums.permission.RoleCodeEnum;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Tag(name = "管理后台 - PMS 项目")
|
||||
@RestController
|
||||
@RequestMapping("/pms/pm/project")
|
||||
@Validated
|
||||
public class PmsProjectController {
|
||||
|
||||
@Resource
|
||||
private PmsProjectService projectService;
|
||||
@Resource
|
||||
private PmsProjectMemberService projectMemberService;
|
||||
@Resource
|
||||
private PmsProjectFavoriteService projectFavoriteService;
|
||||
@Resource
|
||||
private PmsWorkItemService workItemService;
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
@Resource
|
||||
private PermissionApi permissionApi;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建项目")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:project:create')")
|
||||
public CommonResult<Long> createProject(@Valid @RequestBody PmsProjectSaveReqVO saveReqVO) {
|
||||
return success(projectService.createProject(saveReqVO, getLoginUserId()));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新项目")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:project:update')")
|
||||
public CommonResult<Boolean> updateProject(@Valid @RequestBody PmsProjectSaveReqVO saveReqVO) {
|
||||
projectService.updateProject(saveReqVO, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得项目详情")
|
||||
@Parameter(name = "id", description = "项目编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:project:query')")
|
||||
public CommonResult<PmsProjectRespVO> getProject(@RequestParam("id") Long id) {
|
||||
Long userId = getLoginUserId();
|
||||
PmsProjectDO project = projectService.getProjectAndUpdateVisitTime(id, userId);
|
||||
return success(buildProjectRespVO(project, userId));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得项目分页")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:project:query')")
|
||||
public CommonResult<PageResult<PmsProjectRespVO>> getProjectPage(@Valid PmsProjectPageReqVO pageReqVO) {
|
||||
Long userId = getLoginUserId();
|
||||
PageResult<PmsProjectDO> pageResult = projectService.getProjectPage(pageReqVO, userId);
|
||||
return success(new PageResult<>(buildProjectRespVOList(pageResult.getList(), userId), pageResult.getTotal()));
|
||||
}
|
||||
|
||||
@GetMapping("/favorite-list")
|
||||
@Operation(summary = "获得星标项目列表")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:project:query')")
|
||||
public CommonResult<List<PmsProjectRespVO>> getFavoriteProjectList() {
|
||||
Long userId = getLoginUserId();
|
||||
return success(buildProjectRespVOList(projectService.getFavoriteProjectList(userId), userId));
|
||||
}
|
||||
|
||||
@GetMapping("/overview")
|
||||
@Operation(summary = "获得项目概况")
|
||||
@Parameter(name = "projectId", description = "项目编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:project:query')")
|
||||
public CommonResult<PmsProjectOverviewRespVO> getProjectOverview(@RequestParam("projectId") Long projectId) {
|
||||
return success(projectService.getProjectOverview(projectId, getLoginUserId()));
|
||||
}
|
||||
|
||||
@PutMapping("/archive")
|
||||
@Operation(summary = "归档项目")
|
||||
@Parameter(name = "id", description = "项目编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:project:update')")
|
||||
public CommonResult<Boolean> archiveProject(@RequestParam("id") Long id) {
|
||||
projectService.archiveProject(id, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/recycle")
|
||||
@Operation(summary = "将项目移入回收站")
|
||||
@Parameter(name = "id", description = "项目编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:project:update')")
|
||||
public CommonResult<Boolean> recycleProject(@RequestParam("id") Long id) {
|
||||
projectService.recycleProject(id, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/restore")
|
||||
@Operation(summary = "恢复项目")
|
||||
@Parameter(name = "id", description = "项目编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:project:update')")
|
||||
public CommonResult<Boolean> restoreProject(@RequestParam("id") Long id) {
|
||||
projectService.restoreProject(id, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "彻底删除回收站项目")
|
||||
@Parameter(name = "id", description = "项目编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:project:delete')")
|
||||
public CommonResult<Boolean> deleteProject(@RequestParam("id") Long id) {
|
||||
projectService.deleteProject(id, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
// ==================== 拼接 VO ====================
|
||||
|
||||
private PmsProjectRespVO buildProjectRespVO(PmsProjectDO project, Long userId) {
|
||||
if (project == null) {
|
||||
return null;
|
||||
}
|
||||
return CollUtil.getFirst(buildProjectRespVOList(Collections.singletonList(project), userId));
|
||||
}
|
||||
|
||||
private List<PmsProjectRespVO> buildProjectRespVOList(List<PmsProjectDO> projects, Long userId) {
|
||||
if (CollUtil.isEmpty(projects)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
// 1. 批量查询创建人、项目管理员、成员数量和工作项完成度
|
||||
Set<Long> projectIds = convertSet(projects, PmsProjectDO::getId);
|
||||
Map<Long, List<Long>> managerUserIdListMap = projectMemberService.getProjectManagerUserIdListMap(projectIds);
|
||||
Map<Long, Integer> memberCountMap = projectMemberService.getProjectMemberCountMap(projectIds);
|
||||
Map<Long, Map<Integer, Long>> projectStatusCountMap = workItemService
|
||||
.getProjectWorkItemStatusCountMap(projectIds);
|
||||
Set<Long> userIds = convertSet(projects, project ->
|
||||
NumberUtils.parseLong(project.getCreator()));
|
||||
managerUserIdListMap.values().forEach(userIds::addAll);
|
||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);
|
||||
Set<Long> ownerProjectIds = convertSet(projectMemberService.getOwnerProjectIdListByUserId(userId));
|
||||
Set<Long> managedProjectIds = convertSet(projectMemberService.getManagedProjectIdListByUserId(userId));
|
||||
Set<Long> memberProjectIds = convertSet(projectMemberService.getProjectIdListByUserId(userId));
|
||||
Set<Long> writableProjectIds = convertSet(projectMemberService.getWritableProjectIdListByUserId(userId));
|
||||
Set<Long> favoriteProjectIds = convertSet(projectFavoriteService.getFavoriteProjectIdListByUserId(userId));
|
||||
favoriteProjectIds.retainAll(projectIds);
|
||||
boolean superAdmin = permissionApi.hasAnyRoles(userId, RoleCodeEnum.SUPER_ADMIN.getCode()).getCheckedData();
|
||||
// 2. 转换项目响应,并拼接展示字段
|
||||
return BeanUtils.toBean(projects, PmsProjectRespVO.class, projectVO -> {
|
||||
findAndThen(userMap, NumberUtils.parseLong(projectVO.getCreator()),
|
||||
creator -> projectVO.setCreatorName(creator.getNickname()));
|
||||
List<String> adminNames = new ArrayList<>();
|
||||
for (Long adminUserId : managerUserIdListMap.getOrDefault(projectVO.getId(), Collections.emptyList())) {
|
||||
findAndThen(userMap, adminUserId, admin -> adminNames.add(admin.getNickname()));
|
||||
}
|
||||
Map<Integer, Long> statusCountMap = projectStatusCountMap.getOrDefault(
|
||||
projectVO.getId(), Collections.emptyMap());
|
||||
projectVO.setAdminNames(adminNames).setMemberCount(memberCountMap.getOrDefault(projectVO.getId(), 0))
|
||||
.setPendingWorkItemCount(statusCountMap.getOrDefault(PmsWorkItemStatusTypeEnum.PENDING.getType(), 0L))
|
||||
.setProcessingWorkItemCount(statusCountMap.getOrDefault(PmsWorkItemStatusTypeEnum.PROCESSING.getType(), 0L))
|
||||
.setCompletedWorkItemCount(statusCountMap.getOrDefault(PmsWorkItemStatusTypeEnum.COMPLETED.getType(), 0L))
|
||||
.setOwnerStatus(superAdmin || ownerProjectIds.contains(projectVO.getId()))
|
||||
.setAdminStatus(superAdmin || managedProjectIds.contains(projectVO.getId()))
|
||||
.setMemberStatus(memberProjectIds.contains(projectVO.getId()))
|
||||
.setExitStatus(memberProjectIds.contains(projectVO.getId()) && !ownerProjectIds.contains(projectVO.getId()))
|
||||
.setWriteStatus(superAdmin || writableProjectIds.contains(projectVO.getId()))
|
||||
.setFavoriteStatus(favoriteProjectIds.contains(projectVO.getId()));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.pm.project;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.pms.service.pm.project.PmsProjectFavoriteService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Tag(name = "管理后台 - PMS 项目收藏")
|
||||
@RestController
|
||||
@RequestMapping("/pms/pm/project-favorite")
|
||||
@Validated
|
||||
public class PmsProjectFavoriteController {
|
||||
|
||||
@Resource
|
||||
private PmsProjectFavoriteService projectFavoriteService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "收藏项目")
|
||||
@Parameter(name = "projectId", description = "项目编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:project:query')")
|
||||
public CommonResult<Boolean> createProjectFavorite(@RequestParam("projectId") Long projectId) {
|
||||
projectFavoriteService.createProjectFavorite(projectId, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "取消收藏项目")
|
||||
@Parameter(name = "projectId", description = "项目编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:project:query')")
|
||||
public CommonResult<Boolean> deleteProjectFavorite(@RequestParam("projectId") Long projectId) {
|
||||
projectFavoriteService.deleteProjectFavorite(projectId, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.pm.project;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.pm.project.vo.group.PmsProjectGroupMoveReqVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.pm.project.vo.group.PmsProjectGroupRespVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.pm.project.vo.group.PmsProjectGroupSaveReqVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.pm.project.vo.group.PmsProjectGroupSortReqVO;
|
||||
import cn.iocoder.yudao.module.pms.dal.dataobject.pm.project.PmsProjectGroupDO;
|
||||
import cn.iocoder.yudao.module.pms.service.pm.project.PmsProjectGroupService;
|
||||
import cn.iocoder.yudao.module.pms.service.pm.project.PmsProjectMemberService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Tag(name = "管理后台 - PMS 项目分组")
|
||||
@RestController
|
||||
@RequestMapping("/pms/pm/project-group")
|
||||
@Validated
|
||||
public class PmsProjectGroupController {
|
||||
|
||||
@Resource
|
||||
private PmsProjectGroupService projectGroupService;
|
||||
@Resource
|
||||
private PmsProjectMemberService projectMemberService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建项目分组")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:project-group:create')")
|
||||
public CommonResult<Long> createProjectGroup(@Valid @RequestBody PmsProjectGroupSaveReqVO createReqVO) {
|
||||
return success(projectGroupService.createProjectGroup(createReqVO, getLoginUserId()));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "修改项目分组")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:project-group:update')")
|
||||
public CommonResult<Boolean> updateProjectGroup(@Valid @RequestBody PmsProjectGroupSaveReqVO updateReqVO) {
|
||||
projectGroupService.updateProjectGroup(updateReqVO, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/update-sort")
|
||||
@Operation(summary = "修改项目分组排序")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:project-group:update')")
|
||||
public CommonResult<Boolean> updateProjectGroupSort(@Valid @RequestBody PmsProjectGroupSortReqVO sortReqVO) {
|
||||
projectGroupService.updateProjectGroupSort(sortReqVO, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除项目分组")
|
||||
@Parameter(name = "id", description = "项目分组编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:project-group:delete')")
|
||||
public CommonResult<Boolean> deleteProjectGroup(@RequestParam("id") Long id) {
|
||||
projectGroupService.deleteProjectGroup(id, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "获得项目分组列表")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:project-group:query')")
|
||||
public CommonResult<List<PmsProjectGroupRespVO>> getProjectGroupList() {
|
||||
Long userId = getLoginUserId();
|
||||
List<PmsProjectGroupDO> groups = projectGroupService.getProjectGroupList(userId);
|
||||
List<Long> projectIds = projectMemberService.getActiveProjectIdListByUserId(userId);
|
||||
Map<Long, Integer> groupCountMap = projectGroupService.getProjectGroupCountMap(userId, groups, projectIds);
|
||||
return success(BeanUtils.toBean(groups, PmsProjectGroupRespVO.class,
|
||||
group -> group.setProjectCount(groupCountMap.getOrDefault(group.getId(), 0))));
|
||||
}
|
||||
|
||||
@PutMapping("/move-project")
|
||||
@Operation(summary = "移动项目到个人分组")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:project-group:update')")
|
||||
public CommonResult<Boolean> moveProjectToGroup(@Valid @RequestBody PmsProjectGroupMoveReqVO moveReqVO) {
|
||||
projectGroupService.moveProjectToGroup(moveReqVO, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.pm.project;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.pm.project.vo.member.PmsProjectMemberRespVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.pm.project.vo.member.PmsProjectMemberSaveReqVO;
|
||||
import cn.iocoder.yudao.module.pms.service.pm.project.PmsProjectMemberService;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Tag(name = "管理后台 - PMS 项目成员")
|
||||
@RestController
|
||||
@RequestMapping("/pms/pm/project-member")
|
||||
@Validated
|
||||
public class PmsProjectMemberController {
|
||||
|
||||
@Resource
|
||||
private PmsProjectMemberService projectMemberService;
|
||||
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "获得项目成员列表")
|
||||
@Parameter(name = "projectId", description = "项目编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:project-member:query')")
|
||||
public CommonResult<List<PmsProjectMemberRespVO>> getProjectMemberList(
|
||||
@RequestParam("projectId") Long projectId) {
|
||||
List<PmsProjectMemberRespVO> members = projectMemberService.getProjectMemberList(projectId, getLoginUserId());
|
||||
return success(fillProjectMemberRespVOList(members));
|
||||
}
|
||||
|
||||
@PutMapping("/update-list")
|
||||
@Operation(summary = "保存项目成员及其权限级别")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:project-member:update')")
|
||||
public CommonResult<Boolean> updateProjectMemberList(@Valid @RequestBody PmsProjectMemberSaveReqVO saveReqVO) {
|
||||
projectMemberService.updateProjectMemberList(saveReqVO, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "移除项目成员")
|
||||
@Parameters({
|
||||
@Parameter(name = "projectId", description = "项目编号", required = true, example = "1024"),
|
||||
@Parameter(name = "userId", description = "后台用户编号", required = true, example = "1")
|
||||
})
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:project-member:update')")
|
||||
public CommonResult<Boolean> deleteProjectMember(@RequestParam("projectId") Long projectId,
|
||||
@RequestParam("userId") Long userId) {
|
||||
projectMemberService.deleteProjectMember(projectId, userId, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/exit")
|
||||
@Operation(summary = "主动退出项目")
|
||||
@Parameter(name = "projectId", description = "项目编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:project-member:query')")
|
||||
public CommonResult<Boolean> exitProject(@RequestParam("projectId") Long projectId) {
|
||||
projectMemberService.exitProject(projectId, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
// ==================== 拼接 VO ====================
|
||||
|
||||
private List<PmsProjectMemberRespVO> fillProjectMemberRespVOList(List<PmsProjectMemberRespVO> members) {
|
||||
if (CollUtil.isEmpty(members)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
// 1. 批量查询用户
|
||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
|
||||
convertSet(members, PmsProjectMemberRespVO::getUserId));
|
||||
// 2. 拼接用户信息
|
||||
for (PmsProjectMemberRespVO memberVO : members) {
|
||||
MapUtils.findAndThen(userMap, memberVO.getUserId(),
|
||||
user -> memberVO.setNickname(user.getNickname()).setAvatar(user.getAvatar()));
|
||||
}
|
||||
return members;
|
||||
}
|
||||
|
||||
}
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.pm.project;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.pm.project.vo.template.PmsProjectTemplatePageReqVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.pm.project.vo.template.PmsProjectTemplateRespVO;
|
||||
import cn.iocoder.yudao.module.pms.controller.admin.pm.project.vo.template.PmsProjectTemplateSaveReqVO;
|
||||
import cn.iocoder.yudao.module.pms.dal.dataobject.pm.project.PmsProjectTemplateDO;
|
||||
import cn.iocoder.yudao.module.pms.service.pm.project.PmsProjectTemplateService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
|
||||
@Tag(name = "管理后台 - PMS 项目模板")
|
||||
@RestController
|
||||
@RequestMapping("/pms/pm/project-template")
|
||||
@Validated
|
||||
public class PmsProjectTemplateController {
|
||||
|
||||
@Resource
|
||||
private PmsProjectTemplateService projectTemplateService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建项目模板")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:project-template:create')")
|
||||
public CommonResult<Long> createProjectTemplate(@Valid @RequestBody PmsProjectTemplateSaveReqVO createReqVO) {
|
||||
return success(projectTemplateService.createProjectTemplate(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新项目模板")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:project-template:update')")
|
||||
public CommonResult<Boolean> updateProjectTemplate(@Valid @RequestBody PmsProjectTemplateSaveReqVO updateReqVO) {
|
||||
projectTemplateService.updateProjectTemplate(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除项目模板")
|
||||
@Parameter(name = "id", description = "模板编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:project-template:delete')")
|
||||
public CommonResult<Boolean> deleteProjectTemplate(@RequestParam("id") Long id) {
|
||||
projectTemplateService.deleteProjectTemplate(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得项目模板")
|
||||
@Parameter(name = "id", description = "模板编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:project-template:query')")
|
||||
public CommonResult<PmsProjectTemplateRespVO> getProjectTemplate(@RequestParam("id") Long id) {
|
||||
PmsProjectTemplateDO template = projectTemplateService.getProjectTemplate(id);
|
||||
return success(BeanUtils.toBean(template, PmsProjectTemplateRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得项目模板分页")
|
||||
@PreAuthorize("@ss.hasPermission('pms:pm:project-template:query')")
|
||||
public CommonResult<PageResult<PmsProjectTemplateRespVO>> getProjectTemplatePage(
|
||||
@Valid PmsProjectTemplatePageReqVO pageReqVO) {
|
||||
PageResult<PmsProjectTemplateDO> pageResult = projectTemplateService.getProjectTemplatePage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, PmsProjectTemplateRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package cn.iocoder.yudao.module.pms.controller.admin.pm.project.vo.announcement;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - PMS 项目公告 Response VO")
|
||||
@Data
|
||||
public class PmsProjectAnnouncementRespVO {
|
||||
|
||||
@Schema(description = "公告编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "项目编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048")
|
||||
private Long projectId;
|
||||
|
||||
@Schema(description = "公告内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "项目启动")
|
||||
private String content;
|
||||
|
||||
@Schema(description = "附件地址列表", example = "[\"https://example.com/a.pdf\"]")
|
||||
private List<String> fileUrls;
|
||||
|
||||
@Schema(description = "创建者用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long creatorUserId;
|
||||
|
||||
@Schema(description = "创建者用户昵称", example = "芋道")
|
||||
private String creatorUserName;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user