diff --git a/build.bat b/build.bat index d9a20548f547efa62aef77e783b3141639e5b458..8cac5c3a283c2c99bc0366bd5aa89f0a816131b6 100755 --- a/build.bat +++ b/build.bat @@ -4,7 +4,7 @@ set dist_dir=dist set app_name=torna -set version="1.14.1" +set version="1.14.4" set build_folder=%app_name%-%version% diff --git a/build.sh b/build.sh index 5e3892c7a380f873cb4c3d81f180073063ad8911..bc1a95079b0b4108a2cb3dfeaf6b0d77c241ccb9 100644 --- a/build.sh +++ b/build.sh @@ -6,7 +6,7 @@ dist_dir="dist" # 执行文件名称 app_name="torna" -version="1.14.1" +version="1.14.4" build_folder="${app_name}-${version}" diff --git a/changelog.md b/changelog.md index 1d5c3d9548c18b59e53bc06dd33231fdc2f13604..a224cadd0202ee0a14113d1174cd46d6e2726d11 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,20 @@ # 更新日志 +## 1.14.4 + +- 【修复】修复分享整个模块只显示部分文档问题 +- 【修复】修复调试返回非200状态不显示错误信息问题 [#I4Y25X](https://gitee.com/durcframework/torna/issues/I4Y25X) + +## 1.14.3 + +- 【优化】优化消息推送 [#I4XGER](https://gitee.com/durcframework/torna/issues/I4XGER) +- 【升级】升级fastmybatis到2.1.0 + +## 1.14.2 + +- 【新增】文档浏览页新增tab标签。默认未启用,启用方式:个人中心-系统设置 +- 【优化】优化LDAP登录 + ## 1.14.1 - 【修复】推送报空指针异常问题 diff --git a/front/package.json b/front/package.json index 28539f365d1c1c53b591bfc222bbe989cc518c36..3a84fe36ffb2b979cfa6e0ac3c63c0dba864ea88 100644 --- a/front/package.json +++ b/front/package.json @@ -22,7 +22,7 @@ "js-cookie": "2.2.0", "js-md5": "^0.7.3", "jszip": "^3.5.0", - "mavon-editor": "2.7.7", + "mavon-editor": "^2.10.4", "normalize.css": "7.0.0", "nprogress": "0.2.0", "path-to-regexp": "2.4.0", @@ -34,6 +34,7 @@ "vue-i18n": "^8.24.4", "vue-router": "3.0.6", "vuex": "3.1.0", + "wangeditor": "^4.7.13", "xml-formatter": "^2.1.3" }, "devDependencies": { diff --git a/front/src/components/EditorPreview/index.vue b/front/src/components/EditorPreview/index.vue new file mode 100644 index 0000000000000000000000000000000000000000..3ce1df479c233091cd1f213fdebe002b9b2381a9 --- /dev/null +++ b/front/src/components/EditorPreview/index.vue @@ -0,0 +1,130 @@ + + + + + diff --git a/front/src/components/ProjectMenu/index.vue b/front/src/components/ProjectMenu/index.vue index 42be7ecde38d0168436a9073fa857f877e2f56b4..9695603ddb6265e9c11b7e0a706cfced8f496a24 100644 --- a/front/src/components/ProjectMenu/index.vue +++ b/front/src/components/ProjectMenu/index.vue @@ -10,6 +10,10 @@ {{ $ts('apiDoc') }} + + + {{ $ts('projectArchive') }} + {{ $ts('projectInfo') }} diff --git a/front/src/components/TreeSelect/index.vue b/front/src/components/TreeSelect/index.vue new file mode 100644 index 0000000000000000000000000000000000000000..3c8b0683e5edbc3587276664abb9725baf3fe4d5 --- /dev/null +++ b/front/src/components/TreeSelect/index.vue @@ -0,0 +1,132 @@ + + + + + diff --git a/front/src/components/editor/MdEditor/index.vue b/front/src/components/editor/MdEditor/index.vue new file mode 100644 index 0000000000000000000000000000000000000000..9d38e69605895b0d2976e8faa914a573b8441394 --- /dev/null +++ b/front/src/components/editor/MdEditor/index.vue @@ -0,0 +1,357 @@ + + + + + diff --git a/front/src/components/editor/RichTextEditor/index.vue b/front/src/components/editor/RichTextEditor/index.vue new file mode 100644 index 0000000000000000000000000000000000000000..b953f76acc5d88f6f961cb81911d376f0843b056 --- /dev/null +++ b/front/src/components/editor/RichTextEditor/index.vue @@ -0,0 +1,135 @@ + + + + + diff --git a/front/src/layout/components/AppMain.vue b/front/src/layout/components/AppMain.vue index e01ec98d3aedffb46dfc0070c4a655c5ea3eb561..69cf8ce5e6a0bfc8959ac6a3d95a265cbcb3e83f 100644 --- a/front/src/layout/components/AppMain.vue +++ b/front/src/layout/components/AppMain.vue @@ -11,6 +11,10 @@ export default { name: 'AppMain', computed: { key() { + // 项目文档页 分组不刷新 + if (this.$route.fullPath.indexOf('/project/archive') !== -1) { + return '/project/archive' + } return this.$route.fullPath } } diff --git a/front/src/router/index.js b/front/src/router/index.js index 69c2f1d6a6a9f5eb0928738db495e27d65b380f5..e78455e7e15f882203fed442eafa6da38bf1a9dc 100644 --- a/front/src/router/index.js +++ b/front/src/router/index.js @@ -138,6 +138,33 @@ export const constantRoutes = [ name: 'ProjectDoc', component: () => import('@/views/project/index_doc') }, + { + path: 'archive/:projectId(\\w+)', + name: 'ProjectArchive', + component: () => import('@/views/project/index_archive'), + children: [ + { + path: '', + name: 'ArchiveList', + component: () => import('@/views/project/ProjectArchive/ArchiveList') + }, + { + path: 'detail', + name: 'ArchiveDetail', + component: () => import('@/views/project/ProjectArchive/ArchiveDetail') + }, + { + path: 'add', + name: 'AddArchive', + component: () => import('@/views/project/ProjectArchive/AddArchive') + }, + { + path: 'edit', + name: 'EditArchive', + component: () => import('@/views/project/ProjectArchive/EditArchive') + } + ] + }, { path: 'info/:projectId(\\w+)', name: 'ProjectInfo', diff --git a/front/src/utils/enums.js b/front/src/utils/enums.js index 05c0fc9764cc1a66e2c5a8789ab6505f7b2d218c..6ea2348b7354447bb0189b9e2c9abf6dd2b70cca 100644 --- a/front/src/utils/enums.js +++ b/front/src/utils/enums.js @@ -77,5 +77,12 @@ export const Enums = { /** * 初始orderIndex */ - INIT_ORDER_INDEX: 10000 + INIT_ORDER_INDEX: 10000, + /** + * 编辑器类型 + */ + EDITOR_TYPE: { + MD: 'MD', + RICH_TEXT: 'RICH_TEXT' + } } diff --git a/front/src/utils/global.js b/front/src/utils/global.js index cfadb9de37f777d94149aaad02420388f70673ef..ed9f017d8ed3cc926472c9f8f3267b89a45877f0 100644 --- a/front/src/utils/global.js +++ b/front/src/utils/global.js @@ -18,7 +18,7 @@ import { Enums } from './enums' import { add_init } from './init' // eslint-disable-next-line -const VERSION="1.14.1" +const VERSION="1.14.4" const SPACE_ID_KEY = 'torna.spaceid' const PROJECT_ID_KEY = 'torna.projectid' const TORNA_FROM = 'torna.from' diff --git a/front/src/utils/i18n/languages/en-us.js b/front/src/utils/i18n/languages/en-us.js index 20a965b1a907a511f4a08271a87b00e217ec2d16..207f5a2199c3a310e32c166296918934251bfd05 100644 --- a/front/src/utils/i18n/languages/en-us.js +++ b/front/src/utils/i18n/languages/en-us.js @@ -34,6 +34,22 @@ const MAPPING = { 'spaceMember': 'Members', 'openUser': 'Open User', 'apiDoc': 'API Doc', + 'projectArchive': 'Project Doc', + 'projectArchiveGroup': 'Project Doc Group', + 'createArchiveGroup': 'Add Group', + 'allProjectArchive': 'All Project Doc', + 'addSubArchiveGroup': 'Add Sub Group', + 'editArchiveGroup': 'Edit', + 'deleteArchiveGroup': 'Delete', + 'projectArchiveGroupName': 'Group Name', + 'createArchive': 'Add Project Doc', + 'filterWithName': 'Filter with name', + 'backProjectArchiveList': 'Back Project Doc List', + 'inputProjectArchiveTitle': 'Please enter the correct name', + 'inputProjectArchiveGroup': 'Please enter the correct group', + 'inputProjectArchiveContent': 'Please enter the correct content', + 'switchEditorPrompt': 'Switching editor data will be lost. Are you sure?', + 'deleteArchiveGroupConfirm': 'After {0} is deleted, the documents in this group will also be deleted. Confirm deletion?', 'projectInfo': 'Project Info', 'projectMember': 'Project Member', 'createProject': 'New Project', diff --git a/front/src/utils/i18n/languages/zh-cn.js b/front/src/utils/i18n/languages/zh-cn.js index 449cacae725cd6fbf2ba16c0da2e638797a1582d..8bf21f45876e99a87100097581b928786de6e54a 100644 --- a/front/src/utils/i18n/languages/zh-cn.js +++ b/front/src/utils/i18n/languages/zh-cn.js @@ -34,6 +34,22 @@ const MAPPING = { 'spaceMember': '空间成员', 'openUser': '开放用户', 'apiDoc': '接口文档', + 'projectArchive': '项目文档', + 'projectArchiveGroup': '项目文档分组', + 'createArchiveGroup': '添加项目文档分组', + 'allProjectArchive': '所有项目文档', + 'addSubArchiveGroup': '添加子分组', + 'editArchiveGroup': '编辑', + 'deleteArchiveGroup': '删除', + 'projectArchiveGroupName': '分组名称', + 'createArchive': '添加项目文档', + 'filterWithName': '根据名称过滤', + 'backProjectArchiveList': '返回项目文档列表', + 'inputProjectArchiveTitle': '请输入项目文档标题', + 'inputProjectArchiveGroup': '请选择项目文档分组', + 'inputProjectArchiveContent': '请输入项目文档内容', + 'switchEditorPrompt': '切换编辑器数据将丢失,是否确认?', + 'deleteArchiveGroupConfirm': '删除 {0} 后,该分组内的文档也将被删除,确认删除?', 'projectInfo': '项目信息', 'projectMember': '项目成员', 'createProject': '创建项目', diff --git a/front/src/views/project/ProjectArchive/AddArchive.vue b/front/src/views/project/ProjectArchive/AddArchive.vue new file mode 100644 index 0000000000000000000000000000000000000000..d86dd41cdf41b4f54c4e25d0cae20a269be52d44 --- /dev/null +++ b/front/src/views/project/ProjectArchive/AddArchive.vue @@ -0,0 +1,16 @@ + + + + + diff --git a/front/src/views/project/ProjectArchive/ArchiveDetail.vue b/front/src/views/project/ProjectArchive/ArchiveDetail.vue new file mode 100644 index 0000000000000000000000000000000000000000..2c33b1f615ef830421583b3aec01a2230ea76090 --- /dev/null +++ b/front/src/views/project/ProjectArchive/ArchiveDetail.vue @@ -0,0 +1,169 @@ + + + + + diff --git a/front/src/views/project/ProjectArchive/ArchiveList.vue b/front/src/views/project/ProjectArchive/ArchiveList.vue new file mode 100644 index 0000000000000000000000000000000000000000..0c8a4995b2cad857bb5e4e3a64a73030afef1ac2 --- /dev/null +++ b/front/src/views/project/ProjectArchive/ArchiveList.vue @@ -0,0 +1,174 @@ + + + + + diff --git a/front/src/views/project/ProjectArchive/EditArchive.vue b/front/src/views/project/ProjectArchive/EditArchive.vue new file mode 100644 index 0000000000000000000000000000000000000000..846e1eb91d555fec6f310ffebce68382195ee5b4 --- /dev/null +++ b/front/src/views/project/ProjectArchive/EditArchive.vue @@ -0,0 +1,16 @@ + + + + + diff --git a/front/src/views/project/ProjectArchive/components/ArchiveForm/index.vue b/front/src/views/project/ProjectArchive/components/ArchiveForm/index.vue new file mode 100644 index 0000000000000000000000000000000000000000..8aead715cac02ec8352c7613d99305377c3db581 --- /dev/null +++ b/front/src/views/project/ProjectArchive/components/ArchiveForm/index.vue @@ -0,0 +1,192 @@ + + + + + + diff --git a/front/src/views/project/ProjectArchive/components/ViewMain.vue b/front/src/views/project/ProjectArchive/components/ViewMain.vue new file mode 100644 index 0000000000000000000000000000000000000000..bf22f0e91f80899341c668a9441d9d456e2a0c27 --- /dev/null +++ b/front/src/views/project/ProjectArchive/components/ViewMain.vue @@ -0,0 +1,31 @@ + + + + + diff --git a/front/src/views/project/ProjectArchive/index.vue b/front/src/views/project/ProjectArchive/index.vue new file mode 100644 index 0000000000000000000000000000000000000000..015fb83bfbc23a884c581ed1156c99a2eb7492cc --- /dev/null +++ b/front/src/views/project/ProjectArchive/index.vue @@ -0,0 +1,370 @@ + + + + + diff --git a/front/src/views/project/index_archive.vue b/front/src/views/project/index_archive.vue new file mode 100644 index 0000000000000000000000000000000000000000..efa0b5ba366d03b454d6837d784a2893ac0fe25b --- /dev/null +++ b/front/src/views/project/index_archive.vue @@ -0,0 +1,24 @@ + + + + + diff --git a/mysql-clean.sql b/mysql-clean.sql index df02fec9f5dc853861610fed6d92c416d506dd58..09a66adf57dc9831e11d434679a0378390d7a27d 100644 --- a/mysql-clean.sql +++ b/mysql-clean.sql @@ -385,6 +385,40 @@ CREATE TABLE `project` ( KEY `idx_spaceid` (`space_id`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='项目表'; +/*Table structure for table `project_archive` */ + +DROP TABLE IF EXISTS `project_archive`; + +CREATE TABLE `project_archive` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `project_id` bigint unsigned NOT NULL DEFAULT '0' COMMENT 'project.id', + `group_id` bigint unsigned NOT NULL DEFAULT '0' COMMENT 'project_archive_group.id', + `title` varchar(200) NOT NULL COMMENT '标题', + `content` longtext NOT NULL COMMENT '内容', + `content_type` tinyint NOT NULL COMMENT '内容类型', + `creator_id` bigint unsigned NOT NULL DEFAULT '0', + `modifier_id` bigint unsigned NOT NULL DEFAULT '0', + `is_deleted` tinyint NOT NULL DEFAULT '0', + `gmt_create` datetime DEFAULT CURRENT_TIMESTAMP, + `gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COMMENT='项目文档(非接口文档)表'; + +/*Table structure for table `project_archive_group` */ + +DROP TABLE IF EXISTS `project_archive_group`; + +CREATE TABLE `project_archive_group` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `group_name` varchar(255) NOT NULL COMMENT '分组名称', + `parent_id` bigint NOT NULL DEFAULT '0' COMMENT '父分组ID', + `project_id` bigint unsigned NOT NULL DEFAULT '0' COMMENT 'project.id', + `is_deleted` tinyint NOT NULL DEFAULT '0', + `gmt_create` datetime DEFAULT CURRENT_TIMESTAMP, + `gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='项目文档(非接口文档)分组表'; + /*Table structure for table `project_user` */ DROP TABLE IF EXISTS `project_user`; @@ -589,7 +623,7 @@ CREATE TABLE `user_subscribe` ( -- INSERT DATA INSERT INTO `system_config` (`config_key`, `config_value`, `remark`, `is_deleted`) -VALUES ('torna.version', '1132', '当前内部版本号。不要删除这条记录!!', 0); +VALUES ('torna.version', '1145', '当前内部版本号。不要删除这条记录!!', 0); INSERT INTO `user_info` ( `username`, `password`, `nickname`, `is_super_admin`) VALUES ('admin','f9560048604e55186198a4a02ba1b9a9','超级管理员',1); diff --git a/mysql.sql b/mysql.sql index 9a5c6431c882592256116f328e3168c622c87aa8..9ca02aba24af20975e9cd275766935da29d491cd 100644 --- a/mysql.sql +++ b/mysql.sql @@ -429,6 +429,49 @@ CREATE TABLE `project` ( insert into `project`(`id`,`name`,`description`,`space_id`,`is_private`,`creator_id`,`creator_name`,`modifier_id`,`modifier_name`,`order_index`,`is_deleted`,`gmt_create`,`gmt_modified`) values (4,'商城项目','商城项目示例',19,0,15,'超级管理员',15,'超级管理员',0,0,'2022-02-27 15:08:32','2022-02-27 15:08:32'); +/*Table structure for table `project_archive` */ + +DROP TABLE IF EXISTS `project_archive`; + +CREATE TABLE `project_archive` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `project_id` bigint unsigned NOT NULL DEFAULT '0' COMMENT 'project.id', + `group_id` bigint unsigned NOT NULL DEFAULT '0' COMMENT 'project_archive_group.id', + `title` varchar(200) NOT NULL COMMENT '标题', + `content` longtext NOT NULL COMMENT '内容', + `content_type` tinyint NOT NULL COMMENT '内容类型', + `creator_id` bigint unsigned NOT NULL DEFAULT '0', + `modifier_id` bigint unsigned NOT NULL DEFAULT '0', + `is_deleted` tinyint NOT NULL DEFAULT '0', + `gmt_create` datetime DEFAULT CURRENT_TIMESTAMP, + `gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COMMENT='项目文档(非接口文档)表'; + +/*Data for the table `project_archive` */ + +insert into `project_archive`(`id`,`project_id`,`group_id`,`title`,`content`,`content_type`,`creator_id`,`modifier_id`,`is_deleted`,`gmt_create`,`gmt_modified`) + values (1,4,1,'项目文档可以管理项目迭代过程中的设计、需求、架构等文档',' **欢迎使用Torna企业接口文档解决方案。**\n\n您可以通过富文本或者Markdown编辑器来编写文档。',1,15,15,0,'2022-03-24 04:49:44','2022-03-24 05:02:42'); + +/*Table structure for table `project_archive_group` */ + +DROP TABLE IF EXISTS `project_archive_group`; + +CREATE TABLE `project_archive_group` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `group_name` varchar(255) NOT NULL COMMENT '分组名称', + `parent_id` bigint NOT NULL DEFAULT '0' COMMENT '父分组ID', + `project_id` bigint unsigned NOT NULL DEFAULT '0' COMMENT 'project.id', + `is_deleted` tinyint NOT NULL DEFAULT '0', + `gmt_create` datetime DEFAULT CURRENT_TIMESTAMP, + `gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='项目文档(非接口文档)分组表'; + +/*Data for the table `project_archive_group` */ + +insert into `project_archive_group`(`id`,`group_name`,`parent_id`,`project_id`,`is_deleted`,`gmt_create`,`gmt_modified`) values (1,'默认分组',0,4,0,'2022-03-28 01:30:27','2022-03-28 01:30:27'); + /*Table structure for table `project_user` */ DROP TABLE IF EXISTS `project_user`; diff --git a/mysql_compat.sql b/mysql_compat.sql index 5baf4489323831f3c922a1920646a84e485aa79f..94b5b67432fcc254a1523c05c3445368fe2c7e6f 100644 --- a/mysql_compat.sql +++ b/mysql_compat.sql @@ -429,6 +429,49 @@ CREATE TABLE `project` ( insert into `project`(`id`,`name`,`description`,`space_id`,`is_private`,`creator_id`,`creator_name`,`modifier_id`,`modifier_name`,`order_index`,`is_deleted`,`gmt_create`,`gmt_modified`) values (4,'商城项目','商城项目示例',19,0,15,'超级管理员',15,'超级管理员',0,0,'2022-02-27 15:08:32','2022-02-27 15:08:32'); +/*Table structure for table `project_archive` */ + +DROP TABLE IF EXISTS `project_archive`; + +CREATE TABLE `project_archive` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `project_id` bigint unsigned NOT NULL DEFAULT '0' COMMENT 'project.id', + `group_id` bigint unsigned NOT NULL DEFAULT '0' COMMENT 'project_archive_group.id', + `title` varchar(200) NOT NULL COMMENT '标题', + `content` longtext NOT NULL COMMENT '内容', + `content_type` tinyint NOT NULL COMMENT '内容类型', + `creator_id` bigint unsigned NOT NULL DEFAULT '0', + `modifier_id` bigint unsigned NOT NULL DEFAULT '0', + `is_deleted` tinyint NOT NULL DEFAULT '0', + `gmt_create` datetime DEFAULT CURRENT_TIMESTAMP, + `gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COMMENT='项目文档(非接口文档)表'; + +/*Data for the table `project_archive` */ + +insert into `project_archive`(`id`,`project_id`,`group_id`,`title`,`content`,`content_type`,`creator_id`,`modifier_id`,`is_deleted`,`gmt_create`,`gmt_modified`) + values (1,4,1,'项目文档可以管理项目迭代过程中的设计、需求、架构等文档',' **欢迎使用Torna企业接口文档解决方案。**\n\n您可以通过富文本或者Markdown编辑器来编写文档。',1,15,15,0,'2022-03-28 04:49:44','2022-03-28 05:02:42'); + +/*Table structure for table `project_archive_group` */ + +DROP TABLE IF EXISTS `project_archive_group`; + +CREATE TABLE `project_archive_group` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `group_name` varchar(255) NOT NULL COMMENT '分组名称', + `parent_id` bigint NOT NULL DEFAULT '0' COMMENT '父分组ID', + `project_id` bigint unsigned NOT NULL DEFAULT '0' COMMENT 'project.id', + `is_deleted` tinyint NOT NULL DEFAULT '0', + `gmt_create` datetime , + `gmt_modified` datetime , + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='项目文档(非接口文档)分组表'; + +/*Data for the table `project_archive_group` */ + +insert into `project_archive_group`(`id`,`group_name`,`parent_id`,`project_id`,`is_deleted`,`gmt_create`,`gmt_modified`) values (1,'默认分组',0,4,0,'2022-03-28 01:30:27','2022-03-28 01:30:27'); + /*Table structure for table `project_user` */ DROP TABLE IF EXISTS `project_user`; diff --git a/pom.xml b/pom.xml index 61003a4d62272ae1bf81372411082ecf95ee6fa9..13be3471d7687b94d18e0b1aa9a9fb0ed18ea1bd 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ - 1.14.1 + 1.14.4 1.8 diff --git a/readme.md b/readme.md index b44636136baf2328687f43d68ec05c5b511488a0..decc83b678d137666fdcb8a6342e24cd34b51275 100644 --- a/readme.md +++ b/readme.md @@ -12,7 +12,7 @@ Torna makes up for the shortcomings of traditional document generation tools suc | Module | Version | | :----: |:-------------------------------------------------------------------------------:| -| Torna | 1.14.1 | +| Torna | 1.14.4 | | sdk-java | ![maven](https://img.shields.io/maven-central/v/cn.torna/torna-sdk) | | swagger-plugin | ![maven](https://img.shields.io/maven-central/v/cn.torna/swagger-plugin) | | smart-doc | ![maven](https://img.shields.io/maven-central/v/com.github.shalousun/smart-doc) | diff --git a/readme_CN.md b/readme_CN.md index b4eb52c70e92b95c1eb1ead8c3a1944b3ff495ac..610ef7f93d66742e1382fb9f593a0ea6290a6e08 100644 --- a/readme_CN.md +++ b/readme_CN.md @@ -12,7 +12,7 @@ Torna弥补了传统文档生成工具(如swagger)的不如之处,在保 | 模块 | 版本 | | :----: |:-------------------------------------------------------------------------------:| -| Torna | 1.14.1 | +| Torna | 1.14.4 | | sdk-java | ![maven](https://img.shields.io/maven-central/v/cn.torna/torna-sdk) | | swagger-plugin | ![maven](https://img.shields.io/maven-central/v/cn.torna/swagger-plugin) | | smart-doc | ![maven](https://img.shields.io/maven-central/v/com.github.shalousun/smart-doc) | diff --git a/release.sh b/release.sh index 14315b3ff72e9212bbf48b63e080b63a969a129f..3a9b66e1926cd581f955137b65e21040eed6750f 100644 --- a/release.sh +++ b/release.sh @@ -6,7 +6,7 @@ dist_dir="dist" # 执行文件名称 app_name="torna" -version="1.14.1" +version="1.14.4" build_folder="${app_name}-${version}" diff --git a/server/boot/src/main/resources/upgrade/1.14.5_ddl_1.txt b/server/boot/src/main/resources/upgrade/1.14.5_ddl_1.txt new file mode 100644 index 0000000000000000000000000000000000000000..b7a59c9dcf0b67449d8a31a5f3e6a85b6c9c7c3f --- /dev/null +++ b/server/boot/src/main/resources/upgrade/1.14.5_ddl_1.txt @@ -0,0 +1,10 @@ +CREATE TABLE `project_archive_group` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `group_name` varchar(255) NOT NULL COMMENT '分组名称', + `parent_id` bigint NOT NULL DEFAULT '0' COMMENT '父分组ID', + `project_id` bigint unsigned NOT NULL DEFAULT '0' COMMENT 'project.id', + `is_deleted` tinyint NOT NULL DEFAULT '0', + `gmt_create` datetime DEFAULT CURRENT_TIMESTAMP, + `gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='项目文档(非接口文档)分组表'; diff --git a/server/boot/src/main/resources/upgrade/1.14.5_ddl_2.txt b/server/boot/src/main/resources/upgrade/1.14.5_ddl_2.txt new file mode 100644 index 0000000000000000000000000000000000000000..856ae5833ac0e0d5a780904d4b13598faef0770d --- /dev/null +++ b/server/boot/src/main/resources/upgrade/1.14.5_ddl_2.txt @@ -0,0 +1,14 @@ +CREATE TABLE `project_archive` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `project_id` bigint unsigned NOT NULL DEFAULT '0' COMMENT 'project.id', + `group_id` bigint unsigned NOT NULL DEFAULT '0' COMMENT 'project_archive_group.id', + `title` varchar(200) NOT NULL COMMENT '标题', + `content` longtext NOT NULL COMMENT '内容', + `content_type` tinyint NOT NULL COMMENT '内容类型', + `creator_id` bigint unsigned NOT NULL DEFAULT '0', + `modifier_id` bigint unsigned NOT NULL DEFAULT '0', + `is_deleted` tinyint NOT NULL DEFAULT '0', + `gmt_create` datetime DEFAULT CURRENT_TIMESTAMP, + `gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='项目文档(非接口文档)表'; diff --git a/server/server-dao/src/main/java/cn/torna/dao/entity/ProjectArchive.java b/server/server-dao/src/main/java/cn/torna/dao/entity/ProjectArchive.java new file mode 100644 index 0000000000000000000000000000000000000000..fbc00446bab8471d7d4b27c159d1589cdc5a83b1 --- /dev/null +++ b/server/server-dao/src/main/java/cn/torna/dao/entity/ProjectArchive.java @@ -0,0 +1,67 @@ +package cn.torna.dao.entity; + +import cn.torna.dao.enums.ContentTypeEnum; +import com.gitee.fastmybatis.annotation.Column; +import com.gitee.fastmybatis.annotation.Pk; +import com.gitee.fastmybatis.annotation.PkStrategy; +import com.gitee.fastmybatis.annotation.Table; +import lombok.Data; + +import java.util.Date; + +/** + * 表名:project_archive + * 备注:项目文档(非接口文档) + * + * @author liu xm + * @date 2022-03-21 17:28 + */ +@Table(name = "project_archive", pk = @Pk(name = "id", strategy = PkStrategy.INCREMENT)) +@Data +public class ProjectArchive { + /** + * id + */ + private Long id; + /** + * project.id + */ + private Long projectId; + /** + * project_archive_group.id + */ + private Long groupId; + /** + * 标题 + */ + private String title; + /** + * 内容 + */ + private String content; + /** + * 内容类型 + */ + private ContentTypeEnum contentType; + /** + * 创建者userid + */ + private Long creatorId; + /** + * 修改者userid + */ + private Long modifierId; + /** + * 数据库字段:is_deleted + */ + @Column(logicDelete = true, name = "is_deleted") + private Byte deleted; + /** + * 数据库字段:gmt_create + */ + private Date gmtCreate; + /** + * 数据库字段:gmt_modified + */ + private Date gmtModified; +} diff --git a/server/server-dao/src/main/java/cn/torna/dao/entity/ProjectArchiveGroup.java b/server/server-dao/src/main/java/cn/torna/dao/entity/ProjectArchiveGroup.java new file mode 100644 index 0000000000000000000000000000000000000000..48a0ab7d7b309c5fda8416f150fa4565712f4abe --- /dev/null +++ b/server/server-dao/src/main/java/cn/torna/dao/entity/ProjectArchiveGroup.java @@ -0,0 +1,50 @@ +package cn.torna.dao.entity; + +import com.gitee.fastmybatis.annotation.Column; +import com.gitee.fastmybatis.annotation.Pk; +import com.gitee.fastmybatis.annotation.PkStrategy; +import com.gitee.fastmybatis.annotation.Table; +import lombok.Data; + +import java.util.Date; + +/** + * 表名:project_archive_group + * 备注:项目文档(非接口文档)分组表 + * + * @author liu xm + * @date 2022-03-21 13:12 + */ +@Table(name = "project_archive_group", pk = @Pk(name = "id", strategy = PkStrategy.INCREMENT)) +@Data +public class ProjectArchiveGroup { + /** + * id + */ + private Long id; + /** + * 分组名称 + */ + private String groupName; + /** + * 父分组ID + */ + private Long parentId; + /** + * project.id + */ + private Long projectId; + /** + * 数据库字段:is_deleted + */ + @Column(logicDelete = true, name = "is_deleted") + private Byte deleted; + /** + * 数据库字段:gmt_create + */ + private Date gmtCreate; + /** + * 数据库字段:gmt_modified + */ + private Date gmtModified; +} diff --git a/server/server-dao/src/main/java/cn/torna/dao/enums/ContentTypeEnum.java b/server/server-dao/src/main/java/cn/torna/dao/enums/ContentTypeEnum.java new file mode 100644 index 0000000000000000000000000000000000000000..002019bccfd41ec44724e11643c2303bc1d1f70f --- /dev/null +++ b/server/server-dao/src/main/java/cn/torna/dao/enums/ContentTypeEnum.java @@ -0,0 +1,27 @@ +package cn.torna.dao.enums; + +import com.gitee.fastmybatis.core.handler.BaseEnum; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 项目文档(非接口文档)内容类型 + * + * @author liu xm + * @date 2022-03-21 18:11 + */ +@AllArgsConstructor +@Getter +public enum ContentTypeEnum implements BaseEnum { + /** + * Markdown + */ + MD(1), + /** + * 富文本 + */ + RICH_TEXT(2); + + private final Integer code; + +} diff --git a/server/server-dao/src/main/java/cn/torna/dao/mapper/ProjectArchiveGroupMapper.java b/server/server-dao/src/main/java/cn/torna/dao/mapper/ProjectArchiveGroupMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..325b44d05ca0591775f2955e280c0d6e038ef1f6 --- /dev/null +++ b/server/server-dao/src/main/java/cn/torna/dao/mapper/ProjectArchiveGroupMapper.java @@ -0,0 +1,11 @@ +package cn.torna.dao.mapper; + +import cn.torna.dao.entity.ProjectArchiveGroup; +import com.gitee.fastmybatis.core.mapper.CrudMapper; + +/** + * @author liu xm + * @date 2022-03-21 13:28 + */ +public interface ProjectArchiveGroupMapper extends CrudMapper { +} diff --git a/server/server-dao/src/main/java/cn/torna/dao/mapper/ProjectArchiveMapper.java b/server/server-dao/src/main/java/cn/torna/dao/mapper/ProjectArchiveMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..89f2afc6b6eb45428b44c9aa158a5d9a51ba9390 --- /dev/null +++ b/server/server-dao/src/main/java/cn/torna/dao/mapper/ProjectArchiveMapper.java @@ -0,0 +1,11 @@ +package cn.torna.dao.mapper; + +import cn.torna.dao.entity.ProjectArchive; +import com.gitee.fastmybatis.core.mapper.CrudMapper; + +/** + * @author liu xm + * @date 2022-03-21 19:12 + */ +public interface ProjectArchiveMapper extends CrudMapper { +} diff --git a/server/server-service/src/main/java/cn/torna/service/ProjectArchiveGroupService.java b/server/server-service/src/main/java/cn/torna/service/ProjectArchiveGroupService.java new file mode 100644 index 0000000000000000000000000000000000000000..3f831e6c31f0f1aafcd0ade48afd3a277831612b --- /dev/null +++ b/server/server-service/src/main/java/cn/torna/service/ProjectArchiveGroupService.java @@ -0,0 +1,75 @@ +package cn.torna.service; + +import cn.torna.common.support.BaseService; +import cn.torna.dao.entity.ProjectArchiveGroup; +import cn.torna.dao.mapper.ProjectArchiveGroupMapper; +import com.gitee.fastmybatis.core.query.Query; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * 项目文档(非接口文档)分组 Service + * + * @author liu xm + * @date 2022-03-21 19:11 + */ +@Service +public class ProjectArchiveGroupService extends BaseService { + + @Resource + private ProjectArchiveService projectArchiveService; + + /** + * 根据项目ID获取项目文档(非接口文档)分组列表 + * + * @param projectId 项目ID + * @return 项目文档(非接口文档)分组列表 + */ + public List listArchiveGroups(Long projectId) { + return this.list("project_id", projectId); + } + + /** + * 获取分组名称Map信息 + * map key 为 分组ID value 为 分组名称 + * + * @param projectId 项目ID + * @return 分组名称Map信息 + */ + public Map mapGroupName(Long projectId) { + return listArchiveGroups(projectId).stream() + .collect(Collectors.toMap(ProjectArchiveGroup::getId, ProjectArchiveGroup::getGroupName)); + } + + /** + * 根据分组Id获取分组名称 + * + * @param id 分组Id + * @return 分组名称 + */ + public String getGroupNameById(Long id) { + final ProjectArchiveGroup archiveGroup = this.getById(id); + if (Objects.nonNull(archiveGroup)) { + return archiveGroup.getGroupName(); + } + return "-"; + } + + /** + * 删除项目文档(非接口文档)分组 + * + * @param id 分组ID + */ + @Transactional(rollbackFor = Exception.class) + public void deleteArchiveGroup(Long id) { + this.deleteById(id); + final Query query = new Query().eq("group_id", id); + projectArchiveService.getMapper().deleteByQuery(query); + } +} diff --git a/server/server-service/src/main/java/cn/torna/service/ProjectArchiveService.java b/server/server-service/src/main/java/cn/torna/service/ProjectArchiveService.java new file mode 100644 index 0000000000000000000000000000000000000000..c81af3875fe00b5521ccc57587dba93ea2b35556 --- /dev/null +++ b/server/server-service/src/main/java/cn/torna/service/ProjectArchiveService.java @@ -0,0 +1,33 @@ +package cn.torna.service; + +import cn.torna.common.support.BaseService; +import cn.torna.dao.entity.ProjectArchive; +import cn.torna.dao.mapper.ProjectArchiveMapper; +import org.springframework.stereotype.Service; + +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +/** + * 项目文档(非接口文档) Service + * + * @author liu xm + * @date 2022-03-21 15:18 + */ +@Service +public class ProjectArchiveService extends BaseService { + + /** + * 根据分组ID集合获取项目文档列表 + * + * @param collect 分组ID集合 + * @return 项目文档列表 + */ + public List listByGroupIdCollection(List collect) { + if (Objects.isNull(collect) || collect.isEmpty()) { + return Collections.emptyList(); + } + return this.listByCollection("group_id", collect); + } +} diff --git a/server/server-service/src/main/java/cn/torna/service/UpgradeService.java b/server/server-service/src/main/java/cn/torna/service/UpgradeService.java index b1d533ae32dd13c4196b1bf57069aca3fc6500b7..cdc1d0b5e8f9baa30c18d0355efc23282faa2510 100644 --- a/server/server-service/src/main/java/cn/torna/service/UpgradeService.java +++ b/server/server-service/src/main/java/cn/torna/service/UpgradeService.java @@ -36,7 +36,7 @@ import java.util.Optional; @Slf4j public class UpgradeService { - private static final int VERSION = 1132; + private static final int VERSION = 1145; private static final String TORNA_VERSION_KEY = "torna.version"; @@ -94,6 +94,14 @@ public class UpgradeService { v1_12_0(oldVersion); v1_13_0(oldVersion); v1_13_2(oldVersion); + v1_14_5(oldVersion); + } + + private void v1_14_5(int oldVersion) { + if (oldVersion < 1145) { + this.createTable("project_archive_group", "upgrade/1.14.5_ddl_1.txt"); + this.createTable("project_archive", "upgrade/1.14.5_ddl_2.txt"); + } } private void v1_13_2(int oldVersion) { diff --git a/server/server-web/src/main/java/cn/torna/web/controller/ExceptionHandlerController.java b/server/server-web/src/main/java/cn/torna/web/controller/ExceptionHandlerController.java index 362d461023fc2785c8697fcb36ab78a5c61faaf4..771a9d5a48b53c15b7951d9e7f7638a7cff5df75 100644 --- a/server/server-web/src/main/java/cn/torna/web/controller/ExceptionHandlerController.java +++ b/server/server-web/src/main/java/cn/torna/web/controller/ExceptionHandlerController.java @@ -13,6 +13,8 @@ import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import javax.servlet.http.HttpServletRequest; +import javax.validation.ConstraintViolation; +import javax.validation.ConstraintViolationException; import java.util.List; import java.util.stream.Collectors; @@ -46,6 +48,11 @@ public class ExceptionHandlerController { .collect(Collectors.joining(", ")); return Result.err(msg); } + if(e instanceof ConstraintViolationException){ + final ConstraintViolationException exception = (ConstraintViolationException) e; + ConstraintViolation constraintViolation = exception.getConstraintViolations().iterator().next(); + return Result.err(constraintViolation.getMessage()); + } log.error("未知错误,IP:{},URI:{},HttpMethod:{}", RequestUtil.getIP(request), request.getRequestURI(), request.getMethod(), e); return Result.err("系统错误,请查看日志"); diff --git a/server/server-web/src/main/java/cn/torna/web/controller/archive/ProjectArchiveController.java b/server/server-web/src/main/java/cn/torna/web/controller/archive/ProjectArchiveController.java new file mode 100644 index 0000000000000000000000000000000000000000..174e8d5c8591c1fd05f6eaa8a3a04b344ee81062 --- /dev/null +++ b/server/server-web/src/main/java/cn/torna/web/controller/archive/ProjectArchiveController.java @@ -0,0 +1,143 @@ +package cn.torna.web.controller.archive; + +import cn.torna.common.annotation.HashId; +import cn.torna.common.bean.Result; +import cn.torna.common.bean.User; +import cn.torna.common.context.UserContext; +import cn.torna.common.exception.BizException; +import cn.torna.common.util.CopyUtil; +import cn.torna.common.util.IdUtil; +import cn.torna.dao.entity.ProjectArchive; +import cn.torna.dao.entity.UserInfo; +import cn.torna.service.ProjectArchiveGroupService; +import cn.torna.service.ProjectArchiveService; +import cn.torna.service.UserInfoService; +import cn.torna.web.controller.archive.param.ArchiveAddParam; +import cn.torna.web.controller.archive.param.ArchiveDeleteParam; +import cn.torna.web.controller.archive.param.ArchiveUpdateParam; +import cn.torna.web.controller.archive.vo.ArchiveDetailsVO; +import cn.torna.web.controller.archive.vo.ArchiveVO; +import com.gitee.fastmybatis.core.query.Query; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 项目文档(非接口文档) Controller + * + * @author liu xm + * @date 2022-03-21 20:51 + */ +@Validated +@RestController +@RequestMapping("/project/archive") +public class ProjectArchiveController { + + @Resource + private ProjectArchiveService projectArchiveService; + @Resource + private ProjectArchiveGroupService projectArchiveGroupService; + @Resource + private UserInfoService userInfoService; + + /** + * 获取项目文档(非接口文档)列表 + * + * @param projectId 项目ID + * @param groupId 项目分组ID + * @return 项目文档(非接口文档)列表 + */ + @GetMapping("/list") + public Result> listArchive( + @NotNull(message = "project.id不能为空") @HashId Long projectId, + @HashId Long groupId) { + final Query query = new Query().eq("project_id", projectId); + if (Objects.nonNull(groupId)) { + query.eq("group_id", groupId); + } + final List archiveList = projectArchiveService.list(query); + final List groupVOList = CopyUtil.copyList(archiveList, ArchiveVO::new); + + final List list = groupVOList.stream() + .peek(item -> item.convertGroupName(projectArchiveGroupService.mapGroupName(projectId))) + .collect(Collectors.toList()); + return Result.ok(list); + } + + /** + * 获取项目文档(非接口文档)信息 + * + * @param id 项目文档(非接口文档)ID + * @return 项目文档(非接口文档)信息 + */ + @GetMapping + public Result getArchive(@HashId Long id) { + final ProjectArchive projectArchive = projectArchiveService.getById(id); + if (Objects.isNull(projectArchive)) { + throw new BizException("项目文档信息不存在"); + } + final ArchiveDetailsVO detailsVO = CopyUtil.copyBean(projectArchive, ArchiveDetailsVO::new); + detailsVO.setGroupName(projectArchiveGroupService.getGroupNameById(detailsVO.getGroupId())); + final List userInfos = userInfoService + .listByCollection("id", Arrays.asList(detailsVO.getCreatorId(), detailsVO.getModifierId())); + detailsVO.convertOperName(userInfos); + return Result.ok(detailsVO); + } + + /** + * 创建项目文档(非接口文档) + * + * @param param . + * @return result + */ + @PostMapping("/create") + public Result createArchiveGroup(@Valid @RequestBody ArchiveAddParam param) { + User user = UserContext.getUser(); + final ProjectArchive projectArchive = CopyUtil.copyBean(param, ProjectArchive::new); + projectArchive.setCreatorId(user.getUserId()); + projectArchive.setModifierId(user.getUserId()); + projectArchiveService.save(projectArchive); + return Result.ok(IdUtil.encode(projectArchive.getId())); + } + + /** + * 更新项目文档(非接口文档) + * + * @param param . + * @return result + */ + @PostMapping("/update") + public Result updateArchive(@Valid @RequestBody ArchiveUpdateParam param) { + final ProjectArchive archive = projectArchiveService.getById(param.getId()); + if (Objects.isNull(archive)) { + throw new BizException("项目文档分组不存在"); + } + User user = UserContext.getUser(); + final ProjectArchive projectArchive = CopyUtil.copyBean(param, ProjectArchive::new); + projectArchive.setModifierId(user.getUserId()); + projectArchiveService.update(projectArchive); + return Result.ok(true); + } + + + /** + * 删除项目文档(非接口文档) + * + * @param param . + * @return result + */ + @PostMapping("/delete") + public Result deleteArchive(@Valid @RequestBody ArchiveDeleteParam param) { + final ProjectArchive archive = projectArchiveService.getById(param.getId()); + if (Objects.isNull(archive)) { + throw new BizException("项目文档不存在"); + } + projectArchiveService.deleteById(param.getId()); + return Result.ok(true); + } +} diff --git a/server/server-web/src/main/java/cn/torna/web/controller/archive/ProjectArchiveGroupController.java b/server/server-web/src/main/java/cn/torna/web/controller/archive/ProjectArchiveGroupController.java new file mode 100644 index 0000000000000000000000000000000000000000..250066ea936616af28e6af73693e84f4d812a380 --- /dev/null +++ b/server/server-web/src/main/java/cn/torna/web/controller/archive/ProjectArchiveGroupController.java @@ -0,0 +1,137 @@ +package cn.torna.web.controller.archive; + +import cn.torna.common.annotation.HashId; +import cn.torna.common.bean.Result; +import cn.torna.common.exception.BizException; +import cn.torna.common.util.CopyUtil; +import cn.torna.dao.entity.ProjectArchive; +import cn.torna.dao.entity.ProjectArchiveGroup; +import cn.torna.service.ProjectArchiveGroupService; +import cn.torna.service.ProjectArchiveService; +import cn.torna.web.controller.archive.param.ArchiveGroupAddParam; +import cn.torna.web.controller.archive.param.ArchiveGroupDeleteParam; +import cn.torna.web.controller.archive.param.ArchiveGroupUpdateParam; +import cn.torna.web.controller.archive.vo.ArchiveGroupVO; +import cn.torna.web.controller.archive.vo.ArchiveTreeVO; +import com.gitee.fastmybatis.core.query.Query; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * 项目文档(非接口文档)分组 Controller + * + * @author liu xm + * @date 2022-03-20 21:01 + */ +@RestController +@RequestMapping("/project/archiveGroup") +public class ProjectArchiveGroupController { + + @Resource + private ProjectArchiveGroupService projectArchiveGroupService; + @Resource + private ProjectArchiveService projectArchiveService; + + /** + * 根据项目ID获取项目文档(非接口文档)分组tree列表 + * + * @param projectId 项目ID + * @return 项目文档(非接口文档)分组tree列表 + */ + @GetMapping("/data") + public Result> archiveGroupTree(@HashId Long projectId, Boolean hasArchive) { + final List listGroups = projectArchiveGroupService.listArchiveGroups(projectId); + final List treeList = listGroups.stream() + .map(item -> ArchiveTreeVO.builder().build().convertGroup(item)).collect(Collectors.toList()); + + if (Objects.nonNull(hasArchive) && hasArchive) { + final List collect = listGroups.stream().map(ProjectArchiveGroup::getId).collect(Collectors.toList()); + final List projectArchives = projectArchiveService.listByGroupIdCollection(collect); + final List treeListArchive = projectArchives.stream() + .map(item -> ArchiveTreeVO.builder().build().convertArchive(item)).collect(Collectors.toList()); + final List list = Stream.of(treeList, treeListArchive) + .flatMap(Collection::stream).collect(Collectors.toList()); + return Result.ok(list); + } + return Result.ok(treeList); + } + + /** + * 根据项目ID获取项目文档(非接口文档)分组列表 + * + * @param projectId 项目ID + * @return 项目文档(非接口文档)分组列表 + */ + @GetMapping("/list") + public Result> listArchiveGroups(@HashId Long projectId) { + final List listGroups = projectArchiveGroupService.listArchiveGroups(projectId); + final List groupVOList = CopyUtil.copyList(listGroups, ArchiveGroupVO::new); + return Result.ok(groupVOList); + } + + /** + * 创建项目文档(非接口文档)分组 + * + * @param param . + * @return result + */ + @PostMapping("/create") + public Result createArchiveGroup(@Valid @RequestBody ArchiveGroupAddParam param) { + final ProjectArchiveGroup group = projectArchiveGroupService.get( + new Query().eq("parent_id", param.getParentId()) + .eq("group_name", param.getGroupName())); + if (Objects.nonNull(group)) { + throw new BizException("项目文档分组名称已存在"); + } + final ProjectArchiveGroup archiveGroup = new ProjectArchiveGroup(); + archiveGroup.setGroupName(param.getGroupName()); + archiveGroup.setProjectId(param.getProjectId()); + archiveGroup.setParentId(param.getParentId()); + projectArchiveGroupService.save(archiveGroup); + final ArchiveTreeVO archiveTreeVO = ArchiveTreeVO.builder().build().convertGroup(archiveGroup); + return Result.ok(archiveTreeVO); + } + + /** + * 更新项目文档(非接口文档)分组 + * + * @param param . + * @return result + */ + @PostMapping("/update") + public Result updateArchiveGroup(@Valid @RequestBody ArchiveGroupUpdateParam param) { + final ProjectArchiveGroup archiveGroup = projectArchiveGroupService.getById(param.getId()); + if (Objects.isNull(archiveGroup)) { + throw new BizException("项目文档分组不存在"); + } + archiveGroup.setGroupName(param.getGroupName()); + archiveGroup.setParentId(param.getParentId()); + projectArchiveGroupService.update(archiveGroup); + return Result.ok(true); + } + + + /** + * 删除项目文档(非接口文档)分组 + * + * @param param . + * @return result + */ + @PostMapping("/delete") + public Result deleteArchiveGroup(@Valid @RequestBody ArchiveGroupDeleteParam param) { + final ProjectArchiveGroup archiveGroup = projectArchiveGroupService.getById(param.getId()); + if (Objects.isNull(archiveGroup)) { + throw new BizException("项目文档分组不存在"); + } + projectArchiveGroupService.deleteArchiveGroup(param.getId()); + return Result.ok(true); + } + +} diff --git a/server/server-web/src/main/java/cn/torna/web/controller/archive/param/ArchiveAddParam.java b/server/server-web/src/main/java/cn/torna/web/controller/archive/param/ArchiveAddParam.java new file mode 100644 index 0000000000000000000000000000000000000000..79cd08c0e3088181ecc5477a7be65220c1937778 --- /dev/null +++ b/server/server-web/src/main/java/cn/torna/web/controller/archive/param/ArchiveAddParam.java @@ -0,0 +1,43 @@ +package cn.torna.web.controller.archive.param; + +import cn.torna.common.support.IdCodec; +import cn.torna.dao.enums.ContentTypeEnum; +import com.alibaba.fastjson.annotation.JSONField; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * @author liu xm + * @date 2022-03-24 2:59 + */ +@Data +public class ArchiveAddParam { + /** + * project.id + */ + @NotNull(message = "project.id不能为空") + @JSONField(serializeUsing = IdCodec.class, deserializeUsing = IdCodec.class) + private Long projectId; + /** + * project_archive_group.id + */ + @NotNull(message = "group.id不能为空") + @JSONField(serializeUsing = IdCodec.class, deserializeUsing = IdCodec.class) + private Long groupId; + /** + * 标题 + */ + @NotBlank(message = "标题不能为空") + private String title; + /** + * 内容 + */ + @NotBlank(message = "内容不能为空") + private String content; + /** + * 内容类型 + */ + private ContentTypeEnum contentType; +} diff --git a/server/server-web/src/main/java/cn/torna/web/controller/archive/param/ArchiveDeleteParam.java b/server/server-web/src/main/java/cn/torna/web/controller/archive/param/ArchiveDeleteParam.java new file mode 100644 index 0000000000000000000000000000000000000000..fad253793581185464f7573ff3e3be4c5cfaab1b --- /dev/null +++ b/server/server-web/src/main/java/cn/torna/web/controller/archive/param/ArchiveDeleteParam.java @@ -0,0 +1,19 @@ +package cn.torna.web.controller.archive.param; + +import cn.torna.common.support.IdCodec; +import com.alibaba.fastjson.annotation.JSONField; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @author liu xm + * @date 2022-03-24 3:57 + */ +@Data +public class ArchiveDeleteParam { + + @NotNull(message = "项目文档id不能为空") + @JSONField(serializeUsing = IdCodec.class, deserializeUsing = IdCodec.class) + private Long id; +} diff --git a/server/server-web/src/main/java/cn/torna/web/controller/archive/param/ArchiveGroupAddParam.java b/server/server-web/src/main/java/cn/torna/web/controller/archive/param/ArchiveGroupAddParam.java new file mode 100644 index 0000000000000000000000000000000000000000..16e47217250cfa09a597fc00171fb00ded253b29 --- /dev/null +++ b/server/server-web/src/main/java/cn/torna/web/controller/archive/param/ArchiveGroupAddParam.java @@ -0,0 +1,39 @@ +package cn.torna.web.controller.archive.param; + +import cn.torna.common.support.IdCodec; +import com.alibaba.fastjson.annotation.JSONField; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.Optional; + +/** + * @author liu xm + * @date 2022-03-21 21:14 + */ +@Data +public class ArchiveGroupAddParam { + /** + * 分组名称 + */ + @NotBlank(message = "分组名称不能为空") + private String groupName; + + /** + * 父分组ID + */ + @JSONField(serializeUsing = IdCodec.class, deserializeUsing = IdCodec.class) + private Long parentId; + + /** + * project.id + */ + @NotNull(message = "project.id不能为空") + @JSONField(serializeUsing = IdCodec.class, deserializeUsing = IdCodec.class) + private Long projectId; + + public Long getParentId() { + return Optional.ofNullable(parentId).orElse(0L); + } +} diff --git a/server/server-web/src/main/java/cn/torna/web/controller/archive/param/ArchiveGroupDeleteParam.java b/server/server-web/src/main/java/cn/torna/web/controller/archive/param/ArchiveGroupDeleteParam.java new file mode 100644 index 0000000000000000000000000000000000000000..d972547508c264a110c5e87b2825b9ba0353234d --- /dev/null +++ b/server/server-web/src/main/java/cn/torna/web/controller/archive/param/ArchiveGroupDeleteParam.java @@ -0,0 +1,19 @@ +package cn.torna.web.controller.archive.param; + +import cn.torna.common.support.IdCodec; +import com.alibaba.fastjson.annotation.JSONField; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @author liu xm + * @date 2022-03-23 13:26 + */ +@Data +public class ArchiveGroupDeleteParam { + + @NotNull(message = "项目文档分组id不能为空") + @JSONField(serializeUsing = IdCodec.class, deserializeUsing = IdCodec.class) + private Long id; +} diff --git a/server/server-web/src/main/java/cn/torna/web/controller/archive/param/ArchiveGroupUpdateParam.java b/server/server-web/src/main/java/cn/torna/web/controller/archive/param/ArchiveGroupUpdateParam.java new file mode 100644 index 0000000000000000000000000000000000000000..b693cc5904adab4db35027cacec1774fdefcf20e --- /dev/null +++ b/server/server-web/src/main/java/cn/torna/web/controller/archive/param/ArchiveGroupUpdateParam.java @@ -0,0 +1,29 @@ +package cn.torna.web.controller.archive.param; + +import cn.torna.common.support.IdCodec; +import com.alibaba.fastjson.annotation.JSONField; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @author liu xm + * @date 2022-03-23 13:14 + */ +@Data +public class ArchiveGroupUpdateParam { + + @NotNull(message = "项目文档分组id不能为空") + @JSONField(serializeUsing = IdCodec.class, deserializeUsing = IdCodec.class) + private Long id; + /** + * 分组名称 + */ + private String groupName; + + /** + * 父分组ID + */ + @JSONField(serializeUsing = IdCodec.class, deserializeUsing = IdCodec.class) + private Long parentId; +} diff --git a/server/server-web/src/main/java/cn/torna/web/controller/archive/param/ArchiveUpdateParam.java b/server/server-web/src/main/java/cn/torna/web/controller/archive/param/ArchiveUpdateParam.java new file mode 100644 index 0000000000000000000000000000000000000000..260a990f154f7950a8d0ed961b90eec870f07a1e --- /dev/null +++ b/server/server-web/src/main/java/cn/torna/web/controller/archive/param/ArchiveUpdateParam.java @@ -0,0 +1,47 @@ +package cn.torna.web.controller.archive.param; + +import cn.torna.common.support.IdCodec; +import cn.torna.dao.enums.ContentTypeEnum; +import com.alibaba.fastjson.annotation.JSONField; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * @author liu xm + * @date 2022-03-24 4:01 + */ +@Data +public class ArchiveUpdateParam { + + @NotNull(message = "项目文档id不能为空") + @JSONField(serializeUsing = IdCodec.class, deserializeUsing = IdCodec.class) + private Long id; + /** + * project.id + */ + @NotNull(message = "project.id不能为空") + @JSONField(serializeUsing = IdCodec.class, deserializeUsing = IdCodec.class) + private Long projectId; + /** + * project_archive_group.id + */ + @NotNull(message = "group.id不能为空") + @JSONField(serializeUsing = IdCodec.class, deserializeUsing = IdCodec.class) + private Long groupId; + /** + * 标题 + */ + @NotBlank(message = "标题不能为空") + private String title; + /** + * 内容 + */ + @NotBlank(message = "内容不能为空") + private String content; + /** + * 内容类型 + */ + private ContentTypeEnum contentType; +} diff --git a/server/server-web/src/main/java/cn/torna/web/controller/archive/vo/ArchiveDetailsVO.java b/server/server-web/src/main/java/cn/torna/web/controller/archive/vo/ArchiveDetailsVO.java new file mode 100644 index 0000000000000000000000000000000000000000..f89ca2cdcb4dc2ac05d30dd648dde24b1023b0c3 --- /dev/null +++ b/server/server-web/src/main/java/cn/torna/web/controller/archive/vo/ArchiveDetailsVO.java @@ -0,0 +1,44 @@ +package cn.torna.web.controller.archive.vo; + +import cn.torna.dao.entity.UserInfo; +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.util.List; +import java.util.Objects; + +/** + * @author liu xm + * @date 2022-03-23 22:55 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class ArchiveDetailsVO extends ArchiveVO { + /** + * 内容 + */ + private String content; + /** + * 创建者 + */ + private String creatorName; + /** + * 修改者 + */ + private String modifierName; + + public void convertOperName(List userInfos) { + for (UserInfo userInfo : userInfos) { + if (Objects.equals(this.getCreatorId(), userInfo.getId())) { + creatorName = userInfo.getNickname(); + } + if (Objects.equals(this.getModifierId(), userInfo.getId())) { + modifierName = userInfo.getNickname(); + } + } + } +} diff --git a/server/server-web/src/main/java/cn/torna/web/controller/archive/vo/ArchiveGroupVO.java b/server/server-web/src/main/java/cn/torna/web/controller/archive/vo/ArchiveGroupVO.java new file mode 100644 index 0000000000000000000000000000000000000000..e710774b9fef693d79f70d2f7323e9d4276bac4a --- /dev/null +++ b/server/server-web/src/main/java/cn/torna/web/controller/archive/vo/ArchiveGroupVO.java @@ -0,0 +1,33 @@ +package cn.torna.web.controller.archive.vo; + +import cn.torna.common.support.IdCodec; +import com.alibaba.fastjson.annotation.JSONField; +import lombok.Data; + +/** + * 项目文档分组列表 + * + * @author liu xm + * @date 2022-03-21 12:12 + */ +@Data +public class ArchiveGroupVO { + + @JSONField(serializeUsing = IdCodec.class, deserializeUsing = IdCodec.class) + private Long id; + /** + * 分组名称 + */ + private String groupName; + /** + * 父分组ID + */ + @JSONField(serializeUsing = IdCodec.class, deserializeUsing = IdCodec.class) + private Long parentId; + /** + * project.id + */ + @JSONField(serializeUsing = IdCodec.class, deserializeUsing = IdCodec.class) + private Long projectId; + +} diff --git a/server/server-web/src/main/java/cn/torna/web/controller/archive/vo/ArchiveTreeVO.java b/server/server-web/src/main/java/cn/torna/web/controller/archive/vo/ArchiveTreeVO.java new file mode 100644 index 0000000000000000000000000000000000000000..546160b4709a857ededdd632f1729d559ffa1fb7 --- /dev/null +++ b/server/server-web/src/main/java/cn/torna/web/controller/archive/vo/ArchiveTreeVO.java @@ -0,0 +1,50 @@ +package cn.torna.web.controller.archive.vo; + +import cn.torna.common.support.IdCodec; +import cn.torna.common.util.IdGen; +import cn.torna.common.util.IdUtil; +import cn.torna.dao.entity.ProjectArchive; +import cn.torna.dao.entity.ProjectArchiveGroup; +import com.alibaba.fastjson.annotation.JSONField; +import lombok.Builder; +import lombok.Data; + +/** + * @author liu xm + * @date 2022-03-28 14:38 + */ +@Builder +@Data +public class ArchiveTreeVO { + + private String id; + + private String label; + + @JSONField(serializeUsing = IdCodec.class, deserializeUsing = IdCodec.class) + private Long parentId; + + private Byte type; + + @JSONField(serializeUsing = IdCodec.class, deserializeUsing = IdCodec.class) + private Long archiveId; + + public ArchiveTreeVO convertGroup(ProjectArchiveGroup group) { + final byte typeGroup = 0; + this.id = IdUtil.encode(group.getId()); + this.label = group.getGroupName(); + this.parentId = group.getParentId(); + this.type = typeGroup; + return this; + } + + public ArchiveTreeVO convertArchive(ProjectArchive archive) { + final byte typeDoc = 1; + this.id = IdGen.nextId(); + this.label = archive.getTitle(); + this.parentId = archive.getGroupId(); + this.type = typeDoc; + this.archiveId = archive.getId(); + return this; + } +} diff --git a/server/server-web/src/main/java/cn/torna/web/controller/archive/vo/ArchiveVO.java b/server/server-web/src/main/java/cn/torna/web/controller/archive/vo/ArchiveVO.java new file mode 100644 index 0000000000000000000000000000000000000000..36fa36e5b921b06b76430f03daacfe6a112ec146 --- /dev/null +++ b/server/server-web/src/main/java/cn/torna/web/controller/archive/vo/ArchiveVO.java @@ -0,0 +1,77 @@ +package cn.torna.web.controller.archive.vo; + +import cn.torna.common.support.IdCodec; +import cn.torna.dao.enums.ContentTypeEnum; +import com.alibaba.fastjson.annotation.JSONField; +import lombok.Data; + +import java.util.Date; +import java.util.Map; + +/** + * 项目文档列表 + * + * @author liu xm + * @date 2022-03-23 16:15 + */ +@Data +public class ArchiveVO { + /** + * id + */ + @JSONField(serializeUsing = IdCodec.class, deserializeUsing = IdCodec.class) + private Long id; + /** + * project.id + */ + @JSONField(serializeUsing = IdCodec.class, deserializeUsing = IdCodec.class) + private Long projectId; + /** + * project_archive_group.id + */ + @JSONField(serializeUsing = IdCodec.class, deserializeUsing = IdCodec.class) + private Long groupId; + /** + * 分组名称 + */ + private String groupName; + /** + * 标题 + */ + private String title; + /** + * 内容类型 + */ + private ContentTypeEnum contentType; + /** + * 创建者userid + */ + @JSONField(serializeUsing = IdCodec.class, deserializeUsing = IdCodec.class) + private Long creatorId; + /** + * 修改者userid + */ + @JSONField(serializeUsing = IdCodec.class, deserializeUsing = IdCodec.class) + private Long modifierId; + /** + * 数据库字段:is_deleted + */ + private Byte deleted; + /** + * 数据库字段:gmt_create + */ + private Date gmtCreate; + /** + * 数据库字段:gmt_modified + */ + private Date gmtModified; + + /** + * 设置分组名称 + * + * @param groupNameList key为分组ID value为分组名称 的map + */ + public void convertGroupName(Map groupNameList) { + this.groupName = groupNameList.getOrDefault(groupId, "-"); + } +}