commit ec222db6f0b23593000a0000d5a196d3b7367b46 Author: 小诺 <15099670051> Date: Tue Dec 1 20:53:52 2020 +0800 初始化项目 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..53e0ee69 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,4 @@ +*.js linguist-language=java +*.css linguist-language=java +*.html linguist-language=java +*.btl linguist-language=java \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..ee86264c --- /dev/null +++ b/.gitignore @@ -0,0 +1,45 @@ +# Compiled class file +*.class +*.iml +*.idea +target/ +logs/ + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +*velocity.log* + +# Eclipse # +.classpath +.project +.settings/ + +.DS_Store + +_dockerCerts/ + +.factorypath + +node_modules/ +dist/ +package-lock.json +yarn.lock + +rebel.xml \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..d6aac6c3 --- /dev/null +++ b/LICENSE @@ -0,0 +1,53 @@ +Apache License + +Version 2.0, January 2004 + +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of this License; and +You must cause any modified files to carry prominent notices stating that You changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + +You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. +5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 00000000..0917eba5 --- /dev/null +++ b/README.md @@ -0,0 +1,72 @@ +

+

+ xiaonuo-vue为xiaonuo生态技术框架环境中的vue分离版本
+ 前后端分离架构,开箱即用,紧随前沿技术
+
+ + bootstrap + + + + + spring-boot + + + mybatis-plus + +

+

+ +#框架说明 + +#### 利用空闲时间纯手研发搭建框架脚手架,在自己用的时候,也为各位小伙伴打下坚固的接私活利器。后续我们会发多个版本,并且根据多年经验会出相关系统中用到的案例,提供给大家使用! +#### 当然、如需了解我们更多,请移步官网:https://xiaonuo.vip + +### 在线演示 +* 账号密码:superAdmin/123456,地址:https://www.xiaonuo.vip:81 +* 注意:因服务器数量暂少,演示环境必须加端口访问 +### 框架优势 + +1. 模块化架构设计,层次清晰,业务层推荐写到单独模块,方便升级。 +2. 前后端分离架构,分离开发,分离部署,前后端互不影响。 +3. 前端技术采用vue + antdvPro + axios。 +3. 后端采用spring boot + mybatis-plus + hutool等,开源可靠。 +4. 基于spring security(jwt) + 用户UUID双重认证。 +5. 基于AOP实现的接口粒度的鉴权,最细粒度过滤权限资源。 +6. 基于hibernate validator实现的校验框架,支持自定义校验注解。 +7. 提供Request-No的响应header快速定位线上异常问题。 +8. 在线用户可查,可在线踢人,同账号登录可同时在线,可单独在线(通过系统参数配置)。 +9. 支持前端 + 后端在线代码生成(后续开放)。 +10. 支持jenkins一键部署,另自带docker maven插件,支持docker部署。 +11. 文件,短信,缓存,邮件等,利用接口封装,方便拓展。 +12. 文件默认使用本地文件,短信默认使用阿里云sms,缓存默认使用内存缓存。 + +### 功能介绍 + +1. 主控面板。控制台页面,可进行工作台,分析页,统计等功能的展示。 +2. 用户管理。对企业用户和系统管理员用户的维护,可绑定用户职务,机构,角色,数据权限等。 +3. 应用管理。通过应用来控制不同维度的菜单展示。 +4. 机构管理。公司组织架构维护,支持多层级结构的树形结构。 +5. 职位管理。用户职务管理,职务可作为用户的一个标签,职务目前没有和权限等其他功能挂钩。 +6. 菜单管理。菜单目录,菜单,和按钮的维护是权限控制的基本单位。 +7. 角色管理。角色绑定菜单后,可限制相关角色的人员登录系统的功能范围。角色也可以绑定数据授权范围。 +8. 字典管理。系统内各种枚举类型的维护。 +9. 访问日志。用户的登录和退出日志的查看和管理。 +10. 操作日志。用户的操作业务的日志的查看和管理。 +11. 服务监控。服务器的运行状态,Java虚拟机信息,jvm等数据的查看。 +12. 在线用户。当前系统在线用户的查看。 +13. 数据监控。druid控制台功能,可查看sql的运行信息。 +14. 公告管理。系统的公告的管理。 +15. 文件管理。文件的上传下载查看等操作,文件可使用本地存储,阿里云oss,腾讯cos接入,支持拓展。 +16. 定时任务。定时任务的维护,通过cron表达式控制任务的执行频率。 +17. 系统配置。系统运行的参数的维护,参数的配置与系统运行机制息息相关。 +18. 邮件发送。发送邮件功能。 +19. 短信发送。短信发送功能,可使用阿里云sms,腾讯云sms,支持拓展。 + + +### XiaoNuo技术团队荣誉作品 + +| 成员组成 | 负责内容 | +| :---: | :---: | +| 俞宝山 | 全栈 | +| 徐玉祥 | 全栈 | + diff --git a/_sql/xiaonuo-vue-pub.sql b/_sql/xiaonuo-vue-pub.sql new file mode 100644 index 00000000..7afedd2f --- /dev/null +++ b/_sql/xiaonuo-vue-pub.sql @@ -0,0 +1,1296 @@ +/* +Navicat MySQL Data Transfer + +Source Server : 俞宝山 +Source Server Version : 50710 +Source Host : 127.0.0.1:3306 +Source Database : xiaonuo-vue-pub + +Target Server Type : MYSQL +Target Server Version : 50710 +File Encoding : 65001 + +Date: 2020-12-01 20:09:40 +*/ + +SET FOREIGN_KEY_CHECKS=0; + +-- ---------------------------- +-- Table structure for `sys_app` +-- ---------------------------- +DROP TABLE IF EXISTS `sys_app`; +CREATE TABLE `sys_app` ( + `id` bigint(20) NOT NULL COMMENT '主键id', + `name` varchar(100) NOT NULL COMMENT '应用名称', + `code` varchar(50) NOT NULL COMMENT '编码', + `active` varchar(1) DEFAULT NULL COMMENT '是否默认激活(Y-是,N-否)', + `status` tinyint(4) NOT NULL COMMENT '状态(字典 0正常 1停用 2删除)', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `create_user` bigint(20) DEFAULT NULL COMMENT '创建人', + `update_time` datetime DEFAULT NULL COMMENT '修改时间', + `update_user` bigint(20) DEFAULT NULL COMMENT '修改人', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='系统应用表'; + +-- ---------------------------- +-- Records of sys_app +-- ---------------------------- +INSERT INTO `sys_app` VALUES ('1265476890672672821', '系统应用', 'system', 'Y', '0', '2020-03-25 19:07:00', '1265476890672672808', '2020-08-15 15:23:05', '1280709549107552257'); +INSERT INTO `sys_app` VALUES ('1265476890672672822', '业务应用', 'business', 'N', '2', '2020-03-26 08:40:33', '1265476890672672808', '2020-09-23 22:00:01', '1265476890672672808'); +INSERT INTO `sys_app` VALUES ('1265476890672672823', '在线办公', 'office', 'N', '2', '2020-04-02 15:48:43', '1265476890672672808', '2020-12-01 19:22:50', '1265476890672672808'); +INSERT INTO `sys_app` VALUES ('1290262474351808514', '高级体验', 'experience', 'N', '2', '2020-08-03 20:25:20', '1265476890672672808', '2020-12-01 19:22:53', '1265476890672672808'); + +-- ---------------------------- +-- Table structure for `sys_config` +-- ---------------------------- +DROP TABLE IF EXISTS `sys_config`; +CREATE TABLE `sys_config` ( + `id` bigint(20) NOT NULL COMMENT '主键', + `name` varchar(100) NOT NULL COMMENT '名称', + `code` varchar(50) NOT NULL COMMENT '编码', + `value` varchar(255) NOT NULL COMMENT '值', + `sys_flag` char(1) NOT NULL COMMENT '是否是系统参数(Y-是,N-否)', + `remark` varchar(255) DEFAULT NULL COMMENT '备注', + `status` tinyint(4) NOT NULL COMMENT '状态(字典 0正常 1停用 2删除)', + `group_code` varchar(255) NOT NULL DEFAULT 'DEFAULT' COMMENT '常量所属分类的编码,来自于“常量的分类”字典', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `create_user` bigint(20) DEFAULT NULL COMMENT '创建人', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `update_user` bigint(20) DEFAULT NULL COMMENT '更新人', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='系统参数配置表'; + +-- ---------------------------- +-- Records of sys_config +-- ---------------------------- +INSERT INTO `sys_config` VALUES ('1265117443880853504', '验证码开关', 'XIAONUO_KAPTCHA_OPEN', 'N', 'Y', '登录验证码开关 N关闭 Y打开', '0', 'DEFAULT', '2020-04-14 23:30:14', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1265117443880853506', 'jwt密钥', 'XIAONUO_JWT_SECRET', 'xiaonuo', 'Y', '(重要)jwt密钥,默认为空,自行设置', '0', 'DEFAULT', '2020-05-26 06:35:19', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1265117443880853507', '默认密码', 'XIAONUO_DEFAULT_PASSWORD', '123456', 'Y', '默认密码', '0', 'DEFAULT', '2020-05-26 06:37:56', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1265117443880853508', 'token过期时间', 'XIAONUO_TOKEN_EXPIRE', '86400', 'Y', 'token过期时间(单位:秒)', '0', 'DEFAULT', '2020-05-27 11:54:49', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1265117443880853509', 'session会话过期时间', 'XIAONUO_SESSION_EXPIRE', '7200', 'Y', 'session会话过期时间(单位:秒)', '0', 'DEFAULT', '2020-05-27 11:54:49', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1265117443880853519', '阿里云短信keyId', 'XIAONUO_ALIYUN_SMS_ACCESSKEY_ID', '你的keyId', 'Y', '阿里云短信keyId', '0', 'ALIYUN_SMS', '2020-06-07 16:27:11', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1269547042242371585', '阿里云短信secret', 'XIAONUO_ALIYUN_SMS_ACCESSKEY_SECRET', '你的secret', 'Y', '阿里云短信secret', '0', 'ALIYUN_SMS', '2020-06-07 16:29:37', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1269547130041737217', '阿里云短信签名', 'XIAONUO_ALIYUN_SMS_SIGN_NAME', 'XiaoNuo快速开发平台', 'Y', '阿里云短信签名', '0', 'ALIYUN_SMS', '2020-06-07 16:29:58', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1269547279530926081', '阿里云短信-登录模板号', 'XIAONUO_ALIYUN_SMS_LOGIN_TEMPLATE_CODE', 'SMS_1877123456', 'Y', '阿里云短信-登录模板号', '0', 'ALIYUN_SMS', '2020-06-07 16:30:33', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1269547410879750145', '阿里云短信默认失效时间', 'XIAONUO_ALIYUN_SMS_INVALIDATE_MINUTES', '5', 'Y', '阿里云短信默认失效时间(单位:分钟)', '0', 'ALIYUN_SMS', '2020-06-07 16:31:04', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1269575927357071361', '腾讯云短信secretId', 'XIAONUO_TENCENT_SMS_SECRET_ID', '你的secretId', 'Y', '腾讯云短信secretId', '0', 'TENCENT_SMS', '2020-06-07 18:24:23', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1269575991693500418', '腾讯云短信secretKey', 'XIAONUO_TENCENT_SMS_SECRET_KEY', '你的secretkey', 'Y', '腾讯云短信secretKey', '0', 'TENCENT_SMS', '2020-06-07 18:24:39', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1269576044084551682', '腾讯云短信sdkAppId', 'XIAONUO_TENCENT_SMS_SDK_APP_ID', '1400375123', 'Y', '腾讯云短信sdkAppId', '0', 'TENCENT_SMS', '2020-06-07 18:24:51', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1269576089294954497', '腾讯云短信签名', 'XIAONUO_TENCENT_SMS_SIGN', 'XiaoNuo快速开发平台', 'Y', '腾讯云短信签名', '0', 'TENCENT_SMS', '2020-06-07 18:25:02', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1270378172860403713', '邮箱host', 'XIAONUO_EMAIL_HOST', 'smtp.126.com', 'Y', '邮箱host', '0', 'EMAIL', '2020-06-09 23:32:14', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1270378295543795714', '邮箱用户名', 'XIAONUO_EMAIL_USERNAME', 'test@126.com', 'Y', '邮箱用户名', '0', 'EMAIL', '2020-06-09 23:32:43', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1270378340510928897', '邮箱密码', 'XIAONUO_EMAIL_PASSWORD', '你的邮箱密码', 'Y', '邮箱密码', '0', 'EMAIL', '2020-06-09 23:32:54', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1270378527358783489', '邮箱端口', 'XIAONUO_EMAIL_PORT', '465', 'Y', '邮箱端口', '0', 'EMAIL', '2020-06-09 23:33:38', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1270378790035460097', '邮箱是否开启ssl', 'XIAONUO_EMAIL_FROM', 'true', 'Y', '邮箱是否开启ssl', '0', 'EMAIL', '2020-06-09 23:34:41', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1270380786649972737', '邮箱发件人', 'XIAONUO_EMAIL_SSL', 'test@126.com', 'Y', '邮箱发件人', '0', 'EMAIL', '2020-06-09 23:42:37', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1270380786649972738', 'win本地上传文件路径', 'XIAONUO_FILE_UPLOAD_PATH_FOR_WINDOWS', 'C:\\XNXX\\PROJECT\\XiaoNuo\\img', 'Y', 'win本地上传文件路径', '0', 'FILE_PATH', '2020-06-09 23:42:37', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1270380786649972739', 'linux/mac本地上传文件路径', 'XIAONUO_FILE_UPLOAD_PATH_FOR_LINUX', 'C:\\XNXX\\PROJECT\\XiaoNuo\\img', 'Y', 'linux/mac本地上传文件路径', '0', 'FILE_PATH', '2020-06-09 23:42:37', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1270380786649982740', 'XiaoNuo演示环境', 'XIAONUO_DEMO_ENV_FLAG', 'false', 'Y', 'XiaoNuo演示环境的开关,true-打开,false-关闭,如果演示环境开启,则只能读数据不能写数据', '0', 'DEFAULT', '2020-06-09 23:42:37', '1265476890672672808', '2020-09-03 14:38:17', '1265476890672672808'); +INSERT INTO `sys_config` VALUES ('1270380786649982741', 'XiaoNuo放开XSS过滤的接口', 'XIAONUO_UN_XSS_FILTER_URL', '/demo/xssfilter,/demo/unxss', 'Y', '多个url可以用英文逗号隔开', '0', 'DEFAULT', '2020-06-09 23:42:37', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1270380786649982742', '单用户登陆的开关', 'XIAONUO_ENABLE_SINGLE_LOGIN', 'false', 'Y', '单用户登陆的开关,true-打开,false-关闭,如果一个人登录两次,就会将上一次登陆挤下去', '0', 'DEFAULT', '2020-06-09 23:42:37', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1280694183769792514', 'druid监控登录账号', 'XIAONUO_DRUID_USERNAME', '', 'Y', 'druid监控登录账号', '0', 'DEFAULT', '2020-07-08 10:44:22', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1280694281648070658', 'druid监控界面登录密码', 'XIAONUO_DRUID_PASSWORD', '', 'Y', 'druid监控登录密码', '0', 'DEFAULT', '2020-07-08 10:44:46', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1280694281648070659', '阿里云定位api接口地址', 'XIAONUO_IP_GEO_API', 'http://api01.aliyun.venuscn.com/ip?ip=%s', 'Y', '阿里云定位api接口地址', '0', 'DEFAULT', '2020-07-20 10:44:46', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1280694281648070660', '阿里云定位appCode', 'XIAONUO_IP_GEO_APP_CODE', '461535aabeae4f34861884d392f5d452', 'Y', '阿里云定位appCode', '0', 'DEFAULT', '2020-07-20 10:44:46', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1288309751255412737', 'Oauth用户登录的开关', 'XIAONUO_ENABLE_OAUTH_LOGIN', 'true', 'Y', 'Oauth用户登录的开关', '0', 'OAUTH', '2020-07-29 11:05:55', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1288310043346743297', 'Oauth码云登录ClientId', 'XIAONUO_OAUTH_GITEE_CLIENT_ID', '你的clientId', 'Y', 'Oauth码云登录ClientId', '0', 'OAUTH', '2020-07-29 11:07:05', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1288310157876408321', 'Oauth码云登录ClientSecret', 'XIAONUO_OAUTH_GITEE_CLIENT_SECRET', '你的clientSecret', 'Y', 'Oauth码云登录ClientSecret', '0', 'OAUTH', '2020-07-29 11:07:32', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1288310280056483841', 'Oauth码云登录回调地址', 'XIAONUO_OAUTH_GITEE_REDIRECT_URI', 'http://localhost:82/oauth/callback/gitee', 'Y', 'Oauth码云登录回调地址', '0', 'OAUTH', '2020-07-29 11:08:01', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1288358228593221633', '前端项目地址', 'XIAONUO_WEB_URL', 'http://localhost:82', 'Y', '前端项目地址', '0', 'DEFAULT', '2020-07-29 14:18:33', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1288358228593221634', '支付宝支付跳转地址', 'XIAONUO_ALIPAY_RETURN_URL', 'http://localhost:82/pay/index', 'Y', '支付宝支付跳转地址', '0', 'DEFAULT', '2020-07-29 14:18:33', '1265476890672672808', null, null); +INSERT INTO `sys_config` VALUES ('1288358228593221635', '是否开启多租户', 'XIAONUO_TENANT_OPEN', 'false', 'Y', '是否开启多租户', '0', 'DEFAULT', '2020-09-03 17:45:58', '1265476890672672808', '2020-09-23 22:23:38', '1265476890672672808'); + +-- ---------------------------- +-- Table structure for `sys_database_info` +-- ---------------------------- +DROP TABLE IF EXISTS `sys_database_info`; +CREATE TABLE `sys_database_info` ( + `id` bigint(20) NOT NULL COMMENT '主键id', + `db_name` varchar(255) NOT NULL COMMENT '数据库名称(英文名称)', + `jdbc_driver` varchar(255) NOT NULL COMMENT 'jdbc的驱动类型', + `user_name` varchar(255) NOT NULL COMMENT '数据库连接的账号', + `password` varchar(255) NOT NULL COMMENT '数据库连接密码', + `jdbc_url` varchar(2000) NOT NULL COMMENT 'jdbc的url', + `remarks` varchar(255) DEFAULT NULL COMMENT '备注,摘要', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE KEY `NAME_UNIQUE` (`db_name`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='数据库信息表'; + +-- ---------------------------- +-- Records of sys_database_info +-- ---------------------------- +INSERT INTO `sys_database_info` VALUES ('1298984760954310657', 'backup', 'com.mysql.cj.jdbc.Driver', 'root', 'ybs1003', 'jdbc:mysql://49.232.20.132:3306/xiaonuo-vue-backup?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=CTT&nullCatalogMeansCurrent=true', '备份数据源', '2020-08-27 22:04:36'); +INSERT INTO `sys_database_info` VALUES ('1304687049021960193', 'xiaonuo_tenant_db_beijing', 'com.mysql.cj.jdbc.Driver', 'root', 'ybs1003', 'jdbc:mysql://49.232.20.132:3306/xiaonuo_tenant_db_beijing?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=CTT&nullCatalogMeansCurrent=true', '北京客户数据源', '2020-09-12 15:43:27'); +INSERT INTO `sys_database_info` VALUES ('1304687901644279809', 'xiaonuo_tenant_db_guangzhou', 'com.mysql.cj.jdbc.Driver', 'root', 'ybs1003', 'jdbc:mysql://49.232.20.132:3306/xiaonuo_tenant_db_guangzhou?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=CTT&nullCatalogMeansCurrent=true', '广州客户数据源', '2020-09-12 15:46:50'); +INSERT INTO `sys_database_info` VALUES ('1324647725275611138', 'master', 'com.mysql.cj.jdbc.Driver', 'root', 'ybs1003', 'jdbc:mysql://49.232.20.132:3306/xiaonuo-vue?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=CTT&nullCatalogMeansCurrent=true', '主数据源,项目启动数据源!', '2020-11-06 17:40:03'); + +-- ---------------------------- +-- Table structure for `sys_demo_leave` +-- ---------------------------- +DROP TABLE IF EXISTS `sys_demo_leave`; +CREATE TABLE `sys_demo_leave` ( + `id` bigint(20) NOT NULL COMMENT '主键', + `name` varchar(50) NOT NULL COMMENT '姓名', + `org_name` varchar(50) NOT NULL COMMENT '部门名', + `type` tinyint(4) NOT NULL COMMENT '请假类型(字典 1事假 2病假 3婚假 4丧假 5产假 6其他)', + `begin_time` datetime NOT NULL COMMENT '请假开始时间', + `end_time` datetime NOT NULL COMMENT '请假结束时间', + `days` tinyint(4) NOT NULL COMMENT '请假天数', + `status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '状态(字典 0正常 1停用 2删除)', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `create_user` bigint(20) DEFAULT NULL COMMENT '创建人', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `update_user` bigint(20) DEFAULT NULL COMMENT '更新人', + `flw_process_status` tinyint(4) DEFAULT NULL COMMENT '流程状态(字典 0草稿 1审核中 2已退回 3已完成)', + `flw_start_user_id` bigint(20) DEFAULT NULL COMMENT '发起人id', + `flw_start_user_name` varchar(100) DEFAULT NULL COMMENT '发起人姓名', + `flw_start_org_id` bigint(20) DEFAULT NULL COMMENT '发起人所属机构id', + `flw_start_org_name` varchar(100) DEFAULT NULL COMMENT '发起人所属机构名称', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +-- ---------------------------- +-- Records of sys_demo_leave +-- ---------------------------- + +-- ---------------------------- +-- Table structure for `sys_dict_data` +-- ---------------------------- +DROP TABLE IF EXISTS `sys_dict_data`; +CREATE TABLE `sys_dict_data` ( + `id` bigint(20) NOT NULL COMMENT '主键', + `type_id` bigint(20) NOT NULL COMMENT '字典类型id', + `value` text NOT NULL COMMENT '值', + `code` varchar(50) NOT NULL COMMENT '编码', + `sort` int(11) NOT NULL COMMENT '排序', + `remark` varchar(255) DEFAULT NULL COMMENT '备注', + `status` tinyint(4) NOT NULL COMMENT '状态(字典 0正常 1停用 2删除)', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `create_user` bigint(20) DEFAULT NULL COMMENT '创建人', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `update_user` bigint(20) DEFAULT NULL COMMENT '更新人', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='系统字典值表'; + +-- ---------------------------- +-- Records of sys_dict_data +-- ---------------------------- +INSERT INTO `sys_dict_data` VALUES ('1265216536659087357', '1265216211667636234', '男', '1', '100', '男性', '0', '2020-04-01 10:23:29', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265216536659087358', '1265216211667636234', '女', '2', '100', '女性', '0', '2020-04-01 10:23:49', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265216536659087359', '1265216211667636234', '未知', '3', '100', '未知性别', '0', '2020-04-01 10:24:01', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265216536659087361', '1265216211667636235', '默认常量', 'DEFAULT', '100', '默认常量,都以GUNS_开头的', '0', '2020-04-14 23:25:45', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265216536659087363', '1265216211667636235', '阿里云短信', 'ALIYUN_SMS', '100', '阿里云短信配置', '0', '2020-04-14 23:25:45', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265216536659087364', '1265216211667636235', '腾讯云短信', 'TENCENT_SMS', '100', '腾讯云短信', '0', '2020-04-14 23:25:45', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265216536659087365', '1265216211667636235', '邮件配置', 'EMAIL', '100', '邮箱配置', '0', '2020-04-14 23:25:45', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265216536659087366', '1265216211667636235', '文件上传路径', 'FILE_PATH', '100', '文件上传路径', '0', '2020-04-14 23:25:45', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265216536659087367', '1265216211667636235', 'Oauth配置', 'OAUTH', '100', 'Oauth配置', '0', '2020-04-14 23:25:45', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265216617500102656', '1265216211667636226', '正常', '0', '100', '正常', '0', '2020-05-26 17:41:44', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265216617500102657', '1265216211667636226', '停用', '1', '100', '停用', '0', '2020-05-26 17:42:03', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265216938389524482', '1265216211667636226', '删除', '2', '100', '删除', '0', '2020-05-26 17:43:19', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265217669028892673', '1265217074079453185', '否', 'N', '100', '否', '0', '2020-05-26 17:46:14', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265217706584690689', '1265217074079453185', '是', 'Y', '100', '是', '0', '2020-05-26 17:46:23', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265220776437731330', '1265217846770913282', '登录', '1', '100', '登录', '0', '2020-05-26 17:58:34', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265220806070489090', '1265217846770913282', '登出', '2', '100', '登出', '0', '2020-05-26 17:58:41', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265221129564573697', '1265221049302372354', '目录', '0', '100', '目录', '0', '2020-05-26 17:59:59', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265221163119005697', '1265221049302372354', '菜单', '1', '100', '菜单', '0', '2020-05-26 18:00:07', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265221188091891713', '1265221049302372354', '按钮', '2', '100', '按钮', '0', '2020-05-26 18:00:13', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265466389204967426', '1265466149622128641', '未发送', '0', '100', '未发送', '0', '2020-05-27 10:14:33', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265466432670539778', '1265466149622128641', '发送成功', '1', '100', '发送成功', '0', '2020-05-27 10:14:43', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265466486097584130', '1265466149622128641', '发送失败', '2', '100', '发送失败', '0', '2020-05-27 10:14:56', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265466530477514754', '1265466149622128641', '失效', '3', '100', '失效', '0', '2020-05-27 10:15:07', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265466835009150978', '1265466752209395713', '无', '0', '100', '无', '0', '2020-05-27 10:16:19', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265466874758569986', '1265466752209395713', '组件', '1', '100', '组件', '0', '2020-05-27 10:16:29', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265466925476093953', '1265466752209395713', '内链', '2', '100', '内链', '0', '2020-05-27 10:16:41', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265466962209808385', '1265466752209395713', '外链', '3', '100', '外链', '0', '2020-05-27 10:16:50', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265467428423475202', '1265467337566461954', '系统权重', '1', '100', '系统权重', '0', '2020-05-27 10:18:41', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265467503090475009', '1265467337566461954', '业务权重', '2', '100', '业务权重', '0', '2020-05-27 10:18:59', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265467709110493186', '1265467629167058946', '事假', '1', '100', '事假', '0', '2020-05-27 10:19:48', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265467745013735426', '1265467629167058946', '病假', '2', '100', '病假', '0', '2020-05-27 10:19:56', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265467785253888001', '1265467629167058946', '婚假', '3', '100', '婚假', '0', '2020-05-27 10:20:06', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265467823426248706', '1265467629167058946', '丧假', '4', '100', '丧假', '0', '2020-05-27 10:20:15', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265467855781109762', '1265467629167058946', '产假', '5', '100', '产假', '0', '2020-05-27 10:20:23', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265467895782187010', '1265467629167058946', '其他', '6', '100', '其他', '0', '2020-05-27 10:20:32', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265468138431062018', '1265468028632571905', '全部数据', '1', '100', '全部数据', '0', '2020-05-27 10:21:30', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265468194928336897', '1265468028632571905', '本部门及以下数据', '2', '100', '本部门及以下数据', '0', '2020-05-27 10:21:44', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265468241992622082', '1265468028632571905', '本部门数据', '3', '100', '本部门数据', '0', '2020-05-27 10:21:55', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265468273634451457', '1265468028632571905', '仅本人数据', '4', '100', '仅本人数据', '0', '2020-05-27 10:22:02', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265468302046666753', '1265468028632571905', '自定义数据', '5', '100', '自定义数据', '0', '2020-05-27 10:22:09', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265468508100239362', '1265468437904367618', 'app', '1', '100', 'app', '0', '2020-05-27 10:22:58', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265468543433056258', '1265468437904367618', 'pc', '2', '100', 'pc', '0', '2020-05-27 10:23:07', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265468576874242050', '1265468437904367618', '其他', '3', '100', '其他', '0', '2020-05-27 10:23:15', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265468839764828161', '1265468761230680066', 'Integer', '1', '100', 'Integer', '0', '2020-05-27 10:24:17', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265468871641538562', '1265468761230680066', 'String', '2', '100', 'String', '0', '2020-05-27 10:24:25', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265468898896125954', '1265468761230680066', 'Long', '3', '100', 'Long', '0', '2020-05-27 10:24:31', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265468922275176450', '1265468761230680066', 'Double', '4', '100', 'Double', '0', '2020-05-27 10:24:37', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265468946648276993', '1265468761230680066', 'Boolean', '5', '100', 'Boolean', '0', '2020-05-27 10:24:43', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265468970450952193', '1265468761230680066', 'Date', '6', '100', 'Date', '0', '2020-05-27 10:24:48', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265468970450952194', '1265468761230680066', 'List', '7', '100', 'List', '0', '2020-05-27 10:24:48', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265469305756196865', '1265469198583341057', '流程脚本', '1', '100', '流程脚本', '0', '2020-05-27 10:26:08', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265469330859106306', '1265469198583341057', '系统脚本', '2', '100', '系统脚本', '0', '2020-05-27 10:26:14', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265469526330449922', '1265469441454514178', 'groovy', '1', '100', 'groovy', '0', '2020-05-27 10:27:01', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265469753078718464', '1265469702042427393', '启动', '1', '100', '启动', '0', '2020-05-27 10:30:05', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265469753078718465', '1265469702042427393', '全局', '2', '100', '全局', '0', '2020-05-27 10:27:55', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265469779460890626', '1265469702042427393', '节点', '3', '100', '节点', '0', '2020-05-27 10:28:01', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265470046877130753', '1265469962873610241', '流程启动', 'PROCESS_STARTED', '100', '流程启动', '0', '2020-05-27 10:29:05', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265470074517594113', '1265469962873610241', '流程完成', 'PROCESS_COMPLETED', '100', '流程完成', '0', '2020-05-27 10:29:12', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265470103152107521', '1265469962873610241', '流程取消', 'PROCESS_CANCELLED', '100', '流程取消', '0', '2020-05-27 10:29:19', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265470125725851649', '1265469962873610241', '活动开始', 'ACTIVITY_STARTED', '100', '活动开始', '0', '2020-05-27 10:29:24', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265470153416646657', '1265469962873610241', '活动完成', 'ACTIVITY_COMPLETED', '100', '活动完成', '0', '2020-05-27 10:29:31', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265470179165478913', '1265469962873610241', '活动取消', 'ACTIVITY_CANCELLED', '100', '活动取消', '0', '2020-05-27 10:29:37', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265470207363784705', '1265469962873610241', '任务分配', 'TASK_ASSIGNED', '100', '任务分配', '0', '2020-05-27 10:29:43', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265470236853936130', '1265469962873610241', '任务创建', 'TASK_CREATED', '100', '任务创建', '0', '2020-05-27 10:29:50', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265470266780295170', '1265469962873610241', '任务完成', 'TASK_COMPLETED', '100', '任务完成', '0', '2020-05-27 10:29:58', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265470296446607361', '1265469962873610241', '连接线', 'SEQUENCEFLOW_TAKEN', '100', '连接线', '0', '2020-05-27 10:30:05', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265470296446607362', '1265469962873610242', '全局', '1', '100', '全局', '0', '2020-05-27 10:30:05', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265470296446607363', '1265469962873610242', '节点', '2', '100', '节点', '0', '2020-05-27 10:30:05', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265470526197997569', '1265470456631271426', '草稿', '0', '100', '草稿', '0', '2020-05-27 10:30:59', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265470552823439361', '1265470456631271426', '审核中', '1', '100', '审核中', '0', '2020-05-27 10:31:06', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265470575615287297', '1265470456631271426', '已退回', '2', '100', '已退回', '0', '2020-05-27 10:31:11', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1265470607588466690', '1265470456631271426', '已完成', '3', '100', '已完成', '0', '2020-05-27 10:31:19', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1275617233011335170', '1275617093517172738', '其它', '0', '100', '其它', '0', '2020-06-24 10:30:23', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1275617295355469826', '1275617093517172738', '增加', '1', '100', '增加', '0', '2020-06-24 10:30:38', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1275617348610547714', '1275617093517172738', '删除', '2', '100', '删除', '0', '2020-06-24 10:30:50', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1275617395515449346', '1275617093517172738', '编辑', '3', '100', '编辑', '0', '2020-06-24 10:31:02', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1275617433612312577', '1275617093517172738', '更新', '4', '100', '更新', '0', '2020-06-24 10:31:11', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1275617472707420161', '1275617093517172738', '查询', '5', '100', '查询', '0', '2020-06-24 10:31:20', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1275617502973517826', '1275617093517172738', '详情', '6', '100', '详情', '0', '2020-06-24 10:31:27', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1275617536959963137', '1275617093517172738', '树', '7', '100', '树', '0', '2020-06-24 10:31:35', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1275617619524837377', '1275617093517172738', '导入', '8', '100', '导入', '0', '2020-06-24 10:31:55', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1275617651816783873', '1275617093517172738', '导出', '9', '100', '导出', '0', '2020-06-24 10:32:03', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1275617683475390465', '1275617093517172738', '授权', '10', '100', '授权', '0', '2020-06-24 10:32:10', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1275617709928865793', '1275617093517172738', '强退', '11', '100', '强退', '0', '2020-06-24 10:32:17', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1275617739091861505', '1275617093517172738', '清空', '12', '100', '清空', '0', '2020-06-24 10:32:23', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1275617788601425921', '1275617093517172738', '修改状态', '13', '100', '修改状态', '0', '2020-06-24 10:32:35', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1277774590944317441', '1277774529430654977', '阿里云', '1', '100', '阿里云', '0', '2020-06-30 09:22:57', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1277774666055913474', '1277774529430654977', '腾讯云', '2', '100', '腾讯云', '0', '2020-06-30 09:23:15', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1277774695168577538', '1277774529430654977', 'minio', '3', '100', 'minio', '0', '2020-06-30 09:23:22', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1277774726835572737', '1277774529430654977', '本地', '4', '100', '本地', '0', '2020-06-30 09:23:29', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1278607123583868929', '1278606951432855553', '运行', '1', '100', '运行', '0', '2020-07-02 16:31:08', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1278607162943217666', '1278606951432855553', '停止', '2', '100', '停止', '0', '2020-07-02 16:31:18', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1278939265862004738', '1278911800547147777', '通知', '1', '100', '通知', '0', '2020-07-03 14:30:57', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1278939319922388994', '1278911800547147777', '公告', '2', '100', '公告', '0', '2020-07-03 14:31:10', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1278939399001796609', '1278911952657776642', '草稿', '0', '100', '草稿', '0', '2020-07-03 14:31:29', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1278939432686252034', '1278911952657776642', '发布', '1', '100', '发布', '0', '2020-07-03 14:31:37', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1278939458804183041', '1278911952657776642', '撤回', '2', '100', '撤回', '0', '2020-07-03 14:31:43', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1278939485878415362', '1278911952657776642', '删除', '3', '100', '删除', '0', '2020-07-03 14:31:50', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1278992343223025665', '1278992276965605377', '委托中', '0', '90', '委托中', '0', '2020-07-03 18:01:52', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1278992370066571266', '1278992276965605377', '委托结束', '1', '100', '委托结束', '0', '2020-07-03 18:01:58', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1278992396788482050', '1278992276965605377', '未委托', '2', '100', '未委托', '0', '2020-07-03 18:02:05', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1291390260160299009', '1291390159941599233', '是', 'true', '100', '是', '2', '2020-08-06 23:06:46', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1291390315437031426', '1291390159941599233', '否', 'false', '100', '否', '2', '2020-08-06 23:06:59', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1291391148769738754', '1291391077990858754', '是', 'true', '100', '是', '0', '2020-08-06 23:10:17', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1291391205719998465', '1291391077990858754', '否', 'false', '100', '否', '0', '2020-08-06 23:10:31', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1291393684314587138', '1291393441594408961', '是', 'true', '100', '已结束', '0', '2020-08-06 23:20:22', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1291393766048989186', '1291393441594408961', '否', 'false', '100', '未结束', '0', '2020-08-06 23:20:41', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1300767954291433474', '1300767512828354562', 'Mysql', 'com.mysql.cj.jdbc.Driver', '100', 'Mysql数据库驱动', '0', '2020-09-01 20:10:22', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1300768214854180866', '1300767512828354562', 'Oracle', 'oracle.jdbc.OracleDriver', '100', 'Oracle数据库驱动', '0', '2020-09-01 20:11:24', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1300768392747196417', '1300767512828354562', 'Sqlserver', 'com.microsoft.jdbc.sqlserver.SQLServerDriver', '100', 'Sqlserver数据库', '0', '2020-09-01 20:12:07', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1300768392747196418', '1300767512828354563', '未支付', '0', '100', '未支付', '0', '2020-09-01 20:12:07', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1300768392747196419', '1300767512828354563', '已支付', '1', '100', '已支付', '0', '2020-09-01 20:12:07', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1300768392747196420', '1300767512828354563', '已退款', '2', '100', '已退款', '0', '2020-09-01 20:12:07', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1300768392747196421', '1300767512828354563', '已关闭', '3', '100', '已关闭', '0', '2020-09-01 20:12:07', '1265476890672672808', null, null); +INSERT INTO `sys_dict_data` VALUES ('1300768392747196422', '1300767512828354563', '已关闭有退款', '4', '100', '已关闭有退款', '0', '2020-09-01 20:12:07', '1265476890672672808', null, null); + +-- ---------------------------- +-- Table structure for `sys_dict_type` +-- ---------------------------- +DROP TABLE IF EXISTS `sys_dict_type`; +CREATE TABLE `sys_dict_type` ( + `id` bigint(20) NOT NULL COMMENT '主键', + `name` varchar(100) NOT NULL COMMENT '名称', + `code` varchar(50) NOT NULL COMMENT '编码', + `sort` int(11) NOT NULL COMMENT '排序', + `remark` varchar(255) DEFAULT NULL COMMENT '备注', + `status` tinyint(4) NOT NULL COMMENT '状态(字典 0正常 1停用 2删除)', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `create_user` bigint(20) DEFAULT NULL COMMENT '创建人', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `update_user` bigint(20) DEFAULT NULL COMMENT '更新人', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='系统字典类型表'; + +-- ---------------------------- +-- Records of sys_dict_type +-- ---------------------------- +INSERT INTO `sys_dict_type` VALUES ('1265216211667636226', '通用状态', 'common_status', '100', '通用状态', '0', '2020-05-26 17:40:26', '1265476890672672808', '2020-06-08 11:31:47', '1265476890672672808'); +INSERT INTO `sys_dict_type` VALUES ('1265216211667636234', '性别', 'sex', '100', '性别字典', '0', '2020-04-01 10:12:30', '1265476890672672808', null, null); +INSERT INTO `sys_dict_type` VALUES ('1265216211667636235', '常量的分类', 'consts_type', '100', '常量的分类,用于区别一组配置', '0', '2020-04-14 23:24:13', '1265476890672672808', null, null); +INSERT INTO `sys_dict_type` VALUES ('1265217074079453185', '是否', 'yes_or_no', '100', '是否', '0', '2020-05-26 17:43:52', '1265476890672672808', null, null); +INSERT INTO `sys_dict_type` VALUES ('1265217846770913282', '访问类型', 'vis_type', '100', '访问类型', '0', '2020-05-26 17:46:56', '1265476890672672808', null, null); +INSERT INTO `sys_dict_type` VALUES ('1265221049302372354', '菜单类型', 'menu_type', '100', '菜单类型', '0', '2020-05-26 17:59:39', '1265476890672672808', null, null); +INSERT INTO `sys_dict_type` VALUES ('1265466149622128641', '发送类型', 'send_type', '100', '发送类型', '0', '2020-05-27 10:13:36', '1265476890672672808', null, null); +INSERT INTO `sys_dict_type` VALUES ('1265466752209395713', '打开方式', 'open_type', '100', '打开方式', '0', '2020-05-27 10:16:00', '1265476890672672808', null, null); +INSERT INTO `sys_dict_type` VALUES ('1265467337566461954', '菜单权重', 'menu_weight', '100', '菜单权重', '0', '2020-05-27 10:18:19', '1265476890672672808', null, null); +INSERT INTO `sys_dict_type` VALUES ('1265467629167058946', '请假类型', 'leave_type', '100', '请假类型', '0', '2020-05-27 10:19:29', '1265476890672672808', null, null); +INSERT INTO `sys_dict_type` VALUES ('1265468028632571905', '数据范围类型', 'data_scope_type', '100', '数据范围类型', '0', '2020-05-27 10:21:04', '1265476890672672808', null, null); +INSERT INTO `sys_dict_type` VALUES ('1265468437904367618', '短信发送来源', 'sms_send_source', '100', '短信发送来源', '0', '2020-05-27 10:22:42', '1265476890672672808', null, null); +INSERT INTO `sys_dict_type` VALUES ('1265468761230680066', '字段类型', 'filed_type', '100', '字段类型', '0', '2020-05-27 10:23:59', '1265476890672672808', null, null); +INSERT INTO `sys_dict_type` VALUES ('1265469198583341057', '脚本类型', 'script_type', '100', '脚本类型', '0', '2020-05-27 10:25:43', '1265476890672672808', null, null); +INSERT INTO `sys_dict_type` VALUES ('1265469441454514178', '脚本语言类型', 'script_language_type', '100', '脚本语言类型', '0', '2020-05-27 10:26:41', '1265476890672672808', null, null); +INSERT INTO `sys_dict_type` VALUES ('1265469702042427393', '表单类型', 'form_type', '100', '表单类型', '0', '2020-05-27 10:27:43', '1265476890672672808', null, null); +INSERT INTO `sys_dict_type` VALUES ('1265469962873610241', '事件类型', 'event_type', '100', '事件类型', '0', '2020-05-27 10:28:45', '1265476890672672808', null, null); +INSERT INTO `sys_dict_type` VALUES ('1265469962873610242', '事件节点类型', 'event_node_type', '100', '事件节点类型', '0', '2020-05-27 10:28:45', '1265476890672672808', null, null); +INSERT INTO `sys_dict_type` VALUES ('1265470456631271426', '流程状态', 'process_status', '100', '流程状态', '0', '2020-05-27 10:30:43', '1265476890672672808', null, null); +INSERT INTO `sys_dict_type` VALUES ('1275617093517172738', '操作类型', 'op_type', '100', '操作类型', '0', '2020-06-24 10:29:50', '1265476890672672808', null, null); +INSERT INTO `sys_dict_type` VALUES ('1277774529430654977', '文件存储位置', 'file_storage_location', '100', '文件存储位置', '0', '2020-06-30 09:22:42', '1265476890672672808', null, null); +INSERT INTO `sys_dict_type` VALUES ('1278606951432855553', '运行状态', 'run_status', '100', '定时任务运行状态', '0', '2020-07-02 16:30:27', '1265476890672672808', null, null); +INSERT INTO `sys_dict_type` VALUES ('1278911800547147777', '通知公告类型', 'notice_type', '100', '通知公告类型', '0', '2020-07-03 12:41:49', '1265476890672672808', null, null); +INSERT INTO `sys_dict_type` VALUES ('1278911952657776642', '通知公告状态', 'notice_status', '100', '通知公告状态', '0', '2020-07-03 12:42:25', '1265476890672672808', null, null); +INSERT INTO `sys_dict_type` VALUES ('1278992276965605377', '委托状态', 'delegate_status', '100', '委托状态', '0', '2020-07-03 18:01:36', '1265476890672672808', null, null); +INSERT INTO `sys_dict_type` VALUES ('1291390159941599233', '是否boolean', 'yes_true_false', '100', '是否boolean', '2', '2020-08-06 23:06:22', '1265476890672672808', null, null); +INSERT INTO `sys_dict_type` VALUES ('1291391077990858754', '流程是否挂起', 'suspended_status', '100', '流程是否挂起', '0', '2020-08-06 23:10:01', '1265476890672672808', null, null); +INSERT INTO `sys_dict_type` VALUES ('1291393441594408961', '是否结束', 'ended_status', '100', '是否结束', '0', '2020-08-06 23:19:24', '1265476890672672808', null, null); +INSERT INTO `sys_dict_type` VALUES ('1300767512828354562', 'JDBC驱动类型', 'jdbc_driver', '100', 'JDBC驱动类型', '0', '2020-09-01 20:08:37', '1265476890672672808', null, null); +INSERT INTO `sys_dict_type` VALUES ('1300767512828354563', '支付宝交易状态', 'alipay_trade_status', '100', '支付宝交易状态', '0', '2020-09-23 10:36:53', '1265476890672672808', null, null); + +-- ---------------------------- +-- Table structure for `sys_emp` +-- ---------------------------- +DROP TABLE IF EXISTS `sys_emp`; +CREATE TABLE `sys_emp` ( + `id` bigint(20) NOT NULL COMMENT '主键', + `job_num` varchar(100) DEFAULT NULL COMMENT '工号', + `org_id` bigint(20) NOT NULL COMMENT '所属机构id', + `org_name` varchar(100) NOT NULL COMMENT '所属机构名称', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='员工表'; + +-- ---------------------------- +-- Records of sys_emp +-- ---------------------------- +INSERT INTO `sys_emp` VALUES ('1275735541155614721', '102', '1265476890672672769', '华夏集团北京分公司'); +INSERT INTO `sys_emp` VALUES ('1280700700074041345', '110', '1265476890672672771', '研发部'); +INSERT INTO `sys_emp` VALUES ('1280709549107552257', '100', '1265476890672672770', '华夏集团成都分公司'); + +-- ---------------------------- +-- Table structure for `sys_emp_ext_org_pos` +-- ---------------------------- +DROP TABLE IF EXISTS `sys_emp_ext_org_pos`; +CREATE TABLE `sys_emp_ext_org_pos` ( + `id` bigint(20) NOT NULL COMMENT '主键', + `emp_id` bigint(20) NOT NULL COMMENT '员工id', + `org_id` bigint(20) NOT NULL COMMENT '机构id', + `pos_id` bigint(20) NOT NULL COMMENT '岗位id', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='员工附属机构岗位表'; + +-- ---------------------------- +-- Records of sys_emp_ext_org_pos +-- ---------------------------- + +-- ---------------------------- +-- Table structure for `sys_emp_pos` +-- ---------------------------- +DROP TABLE IF EXISTS `sys_emp_pos`; +CREATE TABLE `sys_emp_pos` ( + `id` bigint(20) NOT NULL COMMENT '主键', + `emp_id` bigint(20) NOT NULL COMMENT '员工id', + `pos_id` bigint(20) NOT NULL COMMENT '职位id', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='员工职位关联表'; + +-- ---------------------------- +-- Records of sys_emp_pos +-- ---------------------------- +INSERT INTO `sys_emp_pos` VALUES ('1280710811995709441', '1275735541155614721', '1265476890672672787'); +INSERT INTO `sys_emp_pos` VALUES ('1280710828479324161', '1280700700074041345', '1265476890672672790'); +INSERT INTO `sys_emp_pos` VALUES ('1281042262003867649', '1280709549107552257', '1265476890672672787'); + +-- ---------------------------- +-- Table structure for `sys_file_info` +-- ---------------------------- +DROP TABLE IF EXISTS `sys_file_info`; +CREATE TABLE `sys_file_info` ( + `id` bigint(20) NOT NULL COMMENT '主键id', + `file_location` tinyint(4) NOT NULL COMMENT '文件存储位置(1:阿里云,2:腾讯云,3:minio,4:本地)', + `file_bucket` varchar(1000) DEFAULT NULL COMMENT '文件仓库', + `file_origin_name` varchar(100) NOT NULL COMMENT '文件名称(上传时候的文件名)', + `file_suffix` varchar(50) DEFAULT NULL COMMENT '文件后缀', + `file_size_kb` bigint(20) DEFAULT NULL COMMENT '文件大小kb', + `file_size_info` varchar(100) DEFAULT NULL COMMENT '文件大小信息,计算后的', + `file_object_name` varchar(100) NOT NULL COMMENT '存储到bucket的名称(文件唯一标识id)', + `file_path` varchar(1000) DEFAULT NULL COMMENT '存储路径', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `create_user` bigint(20) DEFAULT NULL COMMENT '创建用户', + `update_time` datetime DEFAULT NULL COMMENT '修改时间', + `update_user` bigint(20) DEFAULT NULL COMMENT '修改用户', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='文件信息表'; + +-- ---------------------------- +-- Records of sys_file_info +-- ---------------------------- +INSERT INTO `sys_file_info` VALUES ('1323533270338170882', '4', 'defaultBucket', 'xiaonuo_logo.png', 'png', '30', '30.23 kB', '1323533270338170882.png', null, '2020-11-03 15:51:36', '1265476890672672808', null, null); +INSERT INTO `sys_file_info` VALUES ('1323547434033016833', '4', 'defaultBucket', 'xiaonuo_logo_b.png', 'png', '30', '30.03 kB', '1323547434033016833.png', null, '2020-11-03 16:47:53', '1265476890672672808', null, null); +INSERT INTO `sys_file_info` VALUES ('1323586730685218817', '4', 'defaultBucket', 'xiaonuo_logo_b.png', 'png', '30', '30.4 kB', '1323586730685218817.png', null, '2020-11-03 19:24:02', '1265476890672672808', null, null); +INSERT INTO `sys_file_info` VALUES ('1324609505700892673', '4', 'defaultBucket', 'xiaonuo_logo_pt_wz.png', 'png', '29', '29.23 kB', '1324609505700892673.png', null, '2020-11-06 15:08:11', '1265476890672672808', null, null); +INSERT INTO `sys_file_info` VALUES ('1333734209900740609', '4', 'defaultBucket', 'await_logo.jpg', 'jpg', '6', '6.4 kB', '1333734209900740609.jpg', null, '2020-12-01 19:26:30', '1265476890672672808', null, null); + +-- ---------------------------- +-- Table structure for `sys_menu` +-- ---------------------------- +DROP TABLE IF EXISTS `sys_menu`; +CREATE TABLE `sys_menu` ( + `id` bigint(20) NOT NULL COMMENT '主键', + `pid` bigint(20) NOT NULL COMMENT '父id', + `pids` text NOT NULL COMMENT '父ids', + `name` varchar(100) NOT NULL COMMENT '名称', + `code` varchar(50) NOT NULL COMMENT '编码', + `type` tinyint(4) NOT NULL DEFAULT '1' COMMENT '菜单类型(字典 0目录 1菜单 2按钮)', + `icon` varchar(255) DEFAULT NULL COMMENT '图标', + `router` varchar(255) DEFAULT NULL COMMENT '路由地址', + `component` varchar(255) DEFAULT NULL COMMENT '组件地址', + `permission` varchar(255) DEFAULT NULL COMMENT '权限标识', + `application` varchar(50) NOT NULL COMMENT '应用分类(应用编码)', + `open_type` tinyint(4) NOT NULL COMMENT '打开方式(字典 0无 1组件 2内链 3外链)', + `visible` char(1) NOT NULL COMMENT '是否可见(Y-是,N-否)', + `link` varchar(255) DEFAULT NULL COMMENT '链接地址', + `redirect` varchar(255) DEFAULT NULL COMMENT '重定向地址', + `weight` tinyint(4) DEFAULT NULL COMMENT '权重(字典 1系统权重 2业务权重)', + `sort` int(11) NOT NULL COMMENT '排序', + `remark` varchar(255) DEFAULT NULL COMMENT '备注', + `status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '状态(字典 0正常 1停用 2删除)', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `create_user` bigint(20) DEFAULT NULL COMMENT '创建人', + `update_time` datetime DEFAULT NULL COMMENT '修改时间', + `update_user` bigint(20) DEFAULT NULL COMMENT '修改人', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='系统菜单表'; + +-- ---------------------------- +-- Records of sys_menu +-- ---------------------------- +INSERT INTO `sys_menu` VALUES ('1264622039642255311', '0', '[0],', '主控面板', 'system_index', '0', 'home', '/', 'RouteView', null, 'system', '0', 'Y', null, '/analysis', '1', '1', null, '0', '2020-05-25 02:19:24', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255321', '1264622039642255311', '[0],[1264622039642255311],', '分析页', 'system_index_dashboard', '1', null, 'analysis', 'system/dashboard/Analysis', null, 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-05-25 02:21:55', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255331', '1264622039642255311', '[0],[1264622039642255311],', '工作台', 'system_index_workplace', '1', null, 'workplace', 'system/dashboard/Workplace', null, 'system', '0', 'Y', null, null, '1', '2', null, '0', '2020-05-25 02:23:48', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255341', '0', '[0],', '组织架构', 'sys_mgr', '0', 'team', '/sys', 'PageView', null, 'system', '0', 'Y', null, null, '1', '2', null, '0', '2020-03-27 15:58:16', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255351', '1264622039642255341', '[0],[1264622039642255341],', '用户管理', 'sys_user_mgr', '1', null, '/mgr_user', 'system/user/index', null, 'system', '1', 'Y', null, null, '1', '3', null, '0', '2020-03-27 16:10:21', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255361', '1264622039642255351', '[0],[1264622039642255341],[1264622039642255351],', '用户查询', 'sys_user_mgr_page', '2', null, null, null, 'sysUser:page', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-03-27 16:36:49', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255371', '1264622039642255351', '[0],[1264622039642255341],[1264622039642255351],', '用户编辑', 'sys_user_mgr_edit', '2', null, null, null, 'sysUser:edit', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-07-02 12:20:23', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255381', '1264622039642255351', '[0],[1264622039642255341],[1264622039642255351],', '用户增加', 'sys_user_mgr_add', '2', null, null, null, 'sysUser:add', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-03-27 16:37:35', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255391', '1264622039642255351', '[0],[1264622039642255341],[1264622039642255351],', '用户删除', 'sys_user_mgr_delete', '2', null, null, null, 'sysUser:delete', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-03-27 16:37:58', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255401', '1264622039642255351', '[0],[1264622039642255341],[1264622039642255351],', '用户详情', 'sys_user_mgr_detail', '2', null, null, null, 'sysUser:detail', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-03-27 16:38:25', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255411', '1264622039642255351', '[0],[1264622039642255341],[1264622039642255351],', '用户导出', 'sys_user_mgr_export', '2', null, null, null, 'sysUser:export', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-07-02 12:21:59', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255421', '1264622039642255351', '[0],[1264622039642255341],[1264622039642255351],', '用户选择器', 'sys_user_mgr_selector', '2', null, null, null, 'sysUser:selector', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-07-03 13:30:14', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255431', '1264622039642255351', '[0],[1264622039642255341],[1264622039642255351],', '用户授权角色', 'sys_user_mgr_grant_role', '2', null, null, null, 'sysUser:grantRole', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-04-01 09:22:01', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255441', '1264622039642255351', '[0],[1264622039642255341],[1264622039642255351],', '用户拥有角色', 'sys_user_mgr_own_role', '2', null, null, null, 'sysUser:ownRole', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-05-29 14:27:22', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255451', '1264622039642255351', '[0],[1264622039642255341],[1264622039642255351],', '用户授权数据', 'sys_user_mgr_grant_data', '2', null, null, null, 'sysUser:grantData', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-04-01 09:22:13', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255461', '1264622039642255351', '[0],[1264622039642255341],[1264622039642255351],', '用户拥有数据', 'sys_user_mgr_own_data', '2', null, null, null, 'sysUser:ownData', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-05-29 14:27:41', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255471', '1264622039642255351', '[0],[1264622039642255341],[1264622039642255351],', '用户更新信息', 'sys_user_mgr_update_info', '2', null, null, null, 'sysUser:updateInfo', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-04-01 16:19:32', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255481', '1264622039642255351', '[0],[1264622039642255341],[1264622039642255351],', '用户修改密码', 'sys_user_mgr_update_pwd', '2', null, null, null, 'sysUser:updatePwd', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-04-01 16:20:25', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255491', '1264622039642255351', '[0],[1264622039642255341],[1264622039642255351],', '用户修改状态', 'sys_user_mgr_change_status', '2', null, null, null, 'sysUser:changeStatus', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-06-23 11:13:14', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255501', '1264622039642255351', '[0],[1264622039642255341],[1264622039642255351],', '用户修改头像', 'sys_user_mgr_update_avatar', '2', null, null, null, 'sysUser:updateAvatar', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-07-02 12:21:42', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255511', '1264622039642255351', '[0],[1264622039642255341],[1264622039642255351],', '用户重置密码', 'sys_user_mgr_reset_pwd', '2', null, null, null, 'sysUser:resetPwd', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-05-29 15:01:51', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255521', '1264622039642255341', '[0],[1264622039642255341],', '机构管理', 'sys_org_mgr', '1', null, '/org', 'system/org/index', null, 'system', '1', 'Y', null, null, '1', '4', null, '0', '2020-03-27 17:15:39', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255531', '1264622039642255521', '[0],[1264622039642255341],[1264622039642255521]', '机构查询', 'sys_org_mgr_page', '2', null, null, null, 'sysOrg:page', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-03-27 17:17:37', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255541', '1264622039642255521', '[0],[1264622039642255341],[1264622039642255521]', '机构列表', 'sys_org_mgr_list', '2', null, null, null, 'sysOrg:list', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-07-02 11:54:26', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255551', '1264622039642255521', '[0],[1264622039642255341],[1264622039642255521]', '机构增加', 'sys_org_mgr_add', '2', null, null, null, 'sysOrg:add', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-03-27 17:19:53', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255561', '1264622039642255521', '[0],[1264622039642255341],[1264622039642255521]', '机构编辑', 'sys_org_mgr_edit', '2', null, null, null, 'sysOrg:edit', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-07-02 11:54:37', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255571', '1264622039642255521', '[0],[1264622039642255341],[1264622039642255521]', '机构删除', 'sys_org_mgr_delete', '2', null, null, null, 'sysOrg:delete', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-03-27 17:20:48', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255581', '1264622039642255521', '[0],[1264622039642255341],[1264622039642255521]', '机构详情', 'sys_org_mgr_detail', '2', null, null, null, 'sysOrg:detail', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-03-27 17:21:15', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255591', '1264622039642255521', '[0],[1264622039642255341],[1264622039642255521]', '机构树', 'sys_org_mgr_tree', '2', null, null, null, 'sysOrg:tree', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-03-27 17:21:58', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255601', '1264622039642255341', '[0],[1264622039642255341],', '职位管理', 'sys_pos_mgr', '1', null, '/pos', 'system/pos/index', null, 'system', '1', 'Y', null, null, '1', '5', null, '0', '2020-03-27 18:38:31', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255611', '1264622039642255601', '[0],[1264622039642255341],[1264622039642255601],', '职位查询', 'sys_pos_mgr_page', '2', null, null, null, 'sysPos:page', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-03-27 18:41:48', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255621', '1264622039642255601', '[0],[1264622039642255341],[1264622039642255601],', '职位列表', 'sys_pos_mgr_list', '2', null, null, null, 'sysPos:list', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-07-02 11:55:57', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255631', '1264622039642255601', '[0],[1264622039642255341],[1264622039642255601],', '职位增加', 'sys_pos_mgr_add', '2', null, null, null, 'sysPos:add', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-03-27 18:42:20', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255641', '1264622039642255601', '[0],[1264622039642255341],[1264622039642255601],', '职位编辑', 'sys_pos_mgr_edit', '2', null, null, null, 'sysPos:edit', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-07-02 11:56:08', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255651', '1264622039642255601', '[0],[1264622039642255341],[1264622039642255601],', '职位删除', 'sys_pos_mgr_delete', '2', null, null, null, 'sysPos:delete', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-03-27 18:42:39', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255661', '1264622039642255601', '[0],[1264622039642255341],[1264622039642255601],', '职位详情', 'sys_pos_mgr_detail', '2', null, null, null, 'sysPos:detail', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-03-27 18:43:00', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255671', '0', '[0],', '权限管理', 'auth_manager', '0', 'safety-certificate', '/auth', 'PageView', null, 'system', '0', 'Y', null, null, '1', '3', null, '0', '2020-07-15 15:51:57', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255681', '1264622039642255671', '[0],[1264622039642255671],', '应用管理', 'sys_app_mgr', '1', null, '/app', 'system/app/index', null, 'system', '1', 'Y', null, null, '1', '6', null, '0', '2020-03-27 16:40:21', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255691', '1264622039642255681', '[0],[1264622039642255671],[1264622039642255681],', '应用查询', 'sys_app_mgr_page', '2', null, null, null, 'sysApp:page', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-03-27 16:41:58', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255701', '1264622039642255681', '[0],[1264622039642255671],[1264622039642255681],', '应用列表', 'sys_app_mgr_list', '2', null, null, null, 'sysApp:list', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-07-02 10:04:59', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255711', '1264622039642255681', '[0],[1264622039642255671],[1264622039642255681],', '应用增加', 'sys_app_mgr_add', '2', null, null, null, 'sysApp:add', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-03-27 16:44:10', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255721', '1264622039642255681', '[0],[1264622039642255671],[1264622039642255681],', '应用编辑', 'sys_app_mgr_edit', '2', null, null, null, 'sysApp:edit', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-07-02 10:04:34', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255731', '1264622039642255681', '[0],[1264622039642255671],[1264622039642255681],', '应用删除', 'sys_app_mgr_delete', '2', null, null, null, 'sysApp:delete', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-03-27 17:14:29', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255741', '1264622039642255681', '[0],[1264622039642255671],[1264622039642255681],', '应用详情', 'sys_app_mgr_detail', '2', null, null, null, 'sysApp:detail', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-03-27 17:14:56', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255751', '1264622039642255681', '[0],[1264622039642255671],[1264622039642255681],', '设为默认应用', 'sys_app_mgr_set_as_default', '2', null, null, null, 'sysApp:setAsDefault', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-03-27 17:14:56', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255761', '1264622039642255671', '[0],[1264622039642255671],', '菜单管理', 'sys_menu_mgr', '1', null, '/menu', 'system/menu/index', null, 'system', '1', 'Y', null, null, '1', '7', null, '0', '2020-03-27 18:44:35', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255771', '1264622039642255761', '[0],[1264622039642255671],[1264622039642255761],', '菜单列表', 'sys_menu_mgr_list', '2', null, null, null, 'sysMenu:list', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-03-27 18:45:20', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255781', '1264622039642255761', '[0],[1264622039642255671],[1264622039642255761],', '菜单增加', 'sys_menu_mgr_add', '2', null, null, null, 'sysMenu:add', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-03-27 18:45:37', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255791', '1264622039642255761', '[0],[1264622039642255671],[1264622039642255761],', '菜单编辑', 'sys_menu_mgr_edit', '2', null, null, null, 'sysMenu:edit', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-07-02 11:52:00', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255801', '1264622039642255761', '[0],[1264622039642255671],[1264622039642255761],', '菜单删除', 'sys_menu_mgr_delete', '2', null, null, null, 'sysMenu:delete', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-03-27 18:46:01', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255811', '1264622039642255761', '[0],[1264622039642255671],[1264622039642255761],', '菜单详情', 'sys_menu_mgr_detail', '2', null, null, null, 'sysMenu:detail', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-03-27 18:46:22', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255821', '1264622039642255761', '[0],[1264622039642255671],[1264622039642255761],', '菜单授权树', 'sys_menu_mgr_grant_tree', '2', null, null, null, 'sysMenu:treeForGrant', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-06-03 09:50:31', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255831', '1264622039642255761', '[0],[1264622039642255671],[1264622039642255761],', '菜单树', 'sys_menu_mgr_tree', '2', null, null, null, 'sysMenu:tree', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-03-27 18:47:50', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255841', '1264622039642255761', '[0],[1264622039642255671],[1264622039642255761],', '菜单切换', 'sys_menu_mgr_change', '2', null, null, null, 'sysMenu:change', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-06-03 09:51:43', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255851', '1264622039642255671', '[0],[1264622039642255671],', '角色管理', 'sys_role_mgr', '1', null, '/role', 'system/role/index', null, 'system', '1', 'Y', null, null, '1', '8', null, '0', '2020-03-28 16:01:09', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255861', '1264622039642255851', '[0],[1264622039642255671],[1264622039642255851],', '角色查询', 'sys_role_mgr_page', '2', null, null, null, 'sysRole:page', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-03-28 16:02:09', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255871', '1264622039642255851', '[0],[1264622039642255671],[1264622039642255851],', '角色增加', 'sys_role_mgr_add', '2', null, null, null, 'sysRole:add', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-03-28 16:02:27', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255881', '1264622039642255851', '[0],[1264622039642255671],[1264622039642255851],', '角色编辑', 'sys_role_mgr_edit', '2', null, null, null, 'sysRole:edit', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-07-02 11:57:27', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255891', '1264622039642255851', '[0],[1264622039642255671],[1264622039642255851],', '角色删除', 'sys_role_mgr_delete', '2', null, null, null, 'sysRole:delete', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-03-28 16:02:46', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255901', '1264622039642255851', '[0],[1264622039642255671],[1264622039642255851],', '角色详情', 'sys_role_mgr_detail', '2', null, null, null, 'sysRole:detail', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-03-28 16:03:01', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255911', '1264622039642255851', '[0],[1264622039642255671],[1264622039642255851],', '角色下拉', 'sys_role_mgr_drop_down', '2', null, null, null, 'sysRole:dropDown', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-05-29 15:45:39', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255921', '1264622039642255851', '[0],[1264622039642255671],[1264622039642255851],', '角色授权菜单', 'sys_role_mgr_grant_menu', '2', null, null, null, 'sysRole:grantMenu', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-04-01 09:16:27', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255931', '1264622039642255851', '[0],[1264622039642255671],[1264622039642255851],', '角色拥有菜单', 'sys_role_mgr_own_menu', '2', null, null, null, 'sysRole:ownMenu', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-05-29 14:21:54', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255941', '1264622039642255851', '[0],[1264622039642255671],[1264622039642255851],', '角色授权数据', 'sys_role_mgr_grant_data', '2', null, null, null, 'sysRole:grantData', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-04-01 09:16:56', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255951', '1264622039642255851', '[0],[1264622039642255671],[1264622039642255851],', '角色拥有数据', 'sys_role_mgr_own_data', '2', null, null, null, 'sysRole:ownData', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-05-29 14:23:08', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255961', '0', '[0],', '开发管理', 'system_tools', '0', 'euro', '/tools', 'PageView', null, 'system', '1', 'Y', null, null, '1', '4', null, '0', '2020-05-25 02:10:55', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255971', '1264622039642255961', '[0],[1264622039642255961],', '系统配置', 'system_tools_config', '1', null, '/config', 'system/config/index', null, 'system', '1', 'Y', null, null, '1', '9', null, '0', '2020-05-25 02:12:56', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255981', '1264622039642255971', '[0],[1264622039642255961],[1264622039642255971],', '配置查询', 'system_tools_config_page', '2', null, null, null, 'sysConfig:page', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-05-27 17:02:22', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642255991', '1264622039642255971', '[0],[1264622039642255961],[1264622039642255971],', '配置列表', 'system_tools_config_list', '2', null, null, null, 'sysConfig:list', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-05-27 17:02:42', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256001', '1264622039642255971', '[0],[1264622039642255961],[1264622039642255971],', '配置增加', 'system_tools_config_add', '2', null, null, null, 'sysConfig:add', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-05-27 17:03:31', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256011', '1264622039642255971', '[0],[1264622039642255961],[1264622039642255971],', '配置编辑', 'system_tools_config_edit', '2', null, null, null, 'sysConfig:edit', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-05-27 17:03:55', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256021', '1264622039642255971', '[0],[1264622039642255961],[1264622039642255971],', '配置删除', 'system_tools_config_delete', '2', null, null, null, 'sysConfig:delete', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-05-27 17:03:44', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256031', '1264622039642255971', '[0],[1264622039642255961],[1264622039642255971],', '配置详情', 'system_tools_config_detail', '2', null, null, null, 'sysConfig:detail', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-05-27 17:02:59', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256041', '1264622039642255961', '[0],[1264622039642255961],', '邮件发送', 'sys_email_mgr', '1', null, '/email', 'system/email/index', null, 'system', '1', 'Y', null, null, '1', '10', null, '0', '2020-07-02 11:44:21', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256051', '1264622039642256041', '[0],[1264622039642255961],[1264622039642256041],', '发送文本邮件', 'sys_email_mgr_send_email', '2', null, null, null, 'email:sendEmail', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-07-02 11:45:39', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256061', '1264622039642256041', '[0],[1264622039642255961],[1264622039642256041],', '发送html邮件', 'sys_email_mgr_send_email_html', '2', null, null, null, 'email:sendEmailHtml', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-07-02 11:45:57', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256071', '1264622039642255961', '[0],[1264622039642255961],', '短信管理', 'sys_sms_mgr', '1', null, '/sms', 'system/sms/index', null, 'system', '1', 'Y', null, null, '1', '11', null, '0', '2020-07-02 12:00:12', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256081', '1264622039642256071', '[0],[1264622039642255961],[1264622039642256071],', '短信发送查询', 'sys_sms_mgr_page', '2', null, null, null, 'sms:page', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-07-02 12:16:56', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256091', '1264622039642256071', '[0],[1264622039642255961],[1264622039642256071],', '发送验证码短信', 'sys_sms_mgr_send_login_message', '2', null, null, null, 'sms:sendLoginMessage', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-07-02 12:02:31', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256101', '1264622039642256071', '[0],[1264622039642255961],[1264622039642256071],', '验证短信验证码', 'sys_sms_mgr_validate_message', '2', null, null, null, 'sms:validateMessage', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-07-02 12:02:50', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256111', '1264622039642255961', '[0],[1264622039642255961],', '字典管理', 'sys_dict_mgr', '1', null, '/dict', 'system/dict/index', null, 'system', '1', 'Y', null, null, '1', '12', null, '0', '2020-04-01 11:17:26', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256121', '1264622039642256111', '[0],[1264622039642255961],[1264622039642256111],', '字典类型查询', 'sys_dict_mgr_dict_type_page', '2', null, null, null, 'sysDictType:page', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-04-01 11:20:22', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256131', '1264622039642256111', '[0],[1264622039642255961],[1264622039642256111],', '字典类型列表', 'sys_dict_mgr_dict_type_list', '2', null, null, null, 'sysDictType:list', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-05-29 15:12:35', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256141', '1264622039642256111', '[0],[1264622039642255961],[1264622039642256111],', '字典类型增加', 'sys_dict_mgr_dict_type_add', '2', null, null, null, 'sysDictType:add', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-04-01 11:19:58', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256151', '1264622039642256111', '[0],[1264622039642255961],[1264622039642256111],', '字典类型删除', 'sys_dict_mgr_dict_type_delete', '2', null, null, null, 'sysDictType:delete', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-04-01 11:21:30', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256161', '1264622039642256111', '[0],[1264622039642255961],[1264622039642256111],', '字典类型编辑', 'sys_dict_mgr_dict_type_edit', '2', null, null, null, 'sysDictType:edit', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-04-01 11:21:42', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256171', '1264622039642256111', '[0],[1264622039642255961],[1264622039642256111],', '字典类型详情', 'sys_dict_mgr_dict_type_detail', '2', null, null, null, 'sysDictType:detail', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-04-01 11:22:06', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256181', '1264622039642256111', '[0],[1264622039642255961],[1264622039642256111],', '字典类型下拉', 'sys_dict_mgr_dict_type_drop_down', '2', null, null, null, 'sysDictType:dropDown', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-04-01 11:22:23', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256191', '1264622039642256111', '[0],[1264622039642255961],[1264622039642256111],', '字典类型修改状态', 'sys_dict_mgr_dict_type_change_status', '2', null, null, null, 'sysDictType:changeStatus', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-06-23 11:15:50', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256201', '1264622039642256111', '[0],[1264622039642255961],[1264622039642256111],', '字典值查询', 'sys_dict_mgr_dict_page', '2', null, null, null, 'sysDictData:page', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-04-01 11:23:11', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256211', '1264622039642256111', '[0],[1264622039642255961],[1264622039642256111],', '字典值列表', 'sys_dict_mgr_dict_list', '2', null, null, null, 'sysDictData:list', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-04-01 11:24:58', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256221', '1264622039642256111', '[0],[1264622039642255961],[1264622039642256111],', '字典值增加', 'sys_dict_mgr_dict_add', '2', null, null, null, 'sysDictData:add', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-04-01 11:22:51', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256231', '1264622039642256111', '[0],[1264622039642255961],[1264622039642256111],', '字典值删除', 'sys_dict_mgr_dict_delete', '2', null, null, null, 'sysDictData:delete', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-04-01 11:23:26', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256241', '1264622039642256111', '[0],[1264622039642255961],[1264622039642256111],', '字典值编辑', 'sys_dict_mgr_dict_edit', '2', null, null, null, 'sysDictData:edit', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-04-01 11:24:21', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256251', '1264622039642256111', '[0],[1264622039642255961],[1264622039642256111],', '字典值详情', 'sys_dict_mgr_dict_detail', '2', null, null, null, 'sysDictData:detail', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-04-01 11:24:42', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256261', '1264622039642256111', '[0],[1264622039642255961],[1264622039642256111],', '字典值修改状态', 'sys_dict_mgr_dict_change_status', '2', null, null, null, 'sysDictData:changeStatus', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-06-23 11:17:53', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256271', '1264622039642255961', '[0],[1264622039642255961],', '接口文档', 'sys_swagger_mgr', '1', null, '/swagger', 'Iframe', null, 'system', '2', 'Y', 'http://localhost:82/doc.html', null, '1', '13', null, '0', '2020-07-02 12:16:56', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256281', '0', '[0],', '日志管理', 'sys_log_mgr', '0', 'read', '/log', 'PageView', null, 'system', '1', 'Y', null, null, '1', '5', null, '0', '2020-04-01 09:25:01', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256291', '1264622039642256281', '[0],[1264622039642256281],', '访问日志', 'sys_log_mgr_vis_log', '1', null, '/vislog', 'system/log/vislog/index', null, 'system', '0', 'Y', null, null, '1', '14', null, '0', '2020-04-01 09:26:40', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256301', '1264622039642256291', '[0],[1264622039642256281],[1264622039642256291],', '访问日志查询', 'sys_log_mgr_vis_log_page', '2', null, null, null, 'sysVisLog:page', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-07-02 09:55:51', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256311', '1264622039642256291', '[0],[1264622039642256281],[1264622039642256291],', '访问日志清空', 'sys_log_mgr_vis_log_delete', '2', null, null, null, 'sysVisLog:delete', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-07-02 09:56:57', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256321', '1264622039642256281', '[0],[1264622039642256281],', '操作日志', 'sys_log_mgr_op_log', '1', null, '/oplog', 'system/log/oplog/index', null, 'system', '0', 'Y', null, null, '1', '15', null, '0', '2020-04-01 09:26:59', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256331', '1264622039642256321', '[0],[1264622039642256281],[1264622039642256321],', '操作日志查询', 'sys_log_mgr_op_log_page', '2', null, null, null, 'sysOpLog:page', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-07-02 09:57:39', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256341', '1264622039642256321', '[0],[1264622039642256281],[1264622039642256321],', '操作日志清空', 'sys_log_mgr_op_log_delete', '2', null, null, null, 'sysOpLog:delete', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-07-02 09:58:13', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256351', '0', '[0],', '系统监控', 'sys_monitor_mgr', '0', 'deployment-unit', '/monitor', 'PageView', null, 'system', '1', 'Y', null, null, '1', '6', null, '0', '2020-06-05 16:00:50', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256361', '1264622039642256351', '[0],[1264622039642256351],', '服务监控', 'sys_monitor_mgr_machine_monitor', '1', null, '/machine', 'system/machine/index', null, 'system', '1', 'Y', null, null, '1', '16', null, '0', '2020-06-05 16:02:38', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256371', '1264622039642256361', '[0],[1264622039642256351],[1264622039642256361],', '服务监控查询', 'sys_monitor_mgr_machine_monitor_query', '2', null, null, null, 'sysMachine:query', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-06-05 16:05:33', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256381', '1264622039642256351', '[0],[1264622039642256351],', '在线用户', 'sys_monitor_mgr_online_user', '1', null, '/onlineUser', 'system/onlineUser/index', null, 'system', '1', 'Y', null, null, '1', '17', null, '0', '2020-06-05 16:01:55', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256391', '1264622039642256381', '[0],[1264622039642256351],[1264622039642256381],', '在线用户列表', 'sys_monitor_mgr_online_user_list', '2', null, null, null, 'sysOnlineUser:list', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-06-05 16:03:46', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256401', '1264622039642256381', '[0],[1264622039642256351],[1264622039642256381],', '在线用户强退', 'sys_monitor_mgr_online_user_force_exist', '2', null, null, null, 'sysOnlineUser:forceExist', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-06-05 16:04:16', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256411', '1264622039642256351', '[0],[1264622039642256351],', '数据监控', 'sys_monitor_mgr_druid', '1', null, '/druid', 'Iframe', null, 'system', '2', 'Y', 'http://localhost:82/druid/login.html', null, '1', '18', null, '0', '2020-06-28 16:15:07', '1265476890672672808', '2020-09-13 09:39:10', '1265476890672672808'); +INSERT INTO `sys_menu` VALUES ('1264622039642256421', '0', '[0],', '通知公告', 'sys_notice', '0', 'sound', '/notice', 'PageView', null, 'system', '1', 'Y', null, null, '1', '7', null, '0', '2020-06-29 15:41:53', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256431', '1264622039642256421', '[0],[1264622039642256421],', '公告管理', 'sys_notice_mgr', '1', null, '/notice', 'system/notice/index', null, 'system', '1', 'Y', null, null, '1', '19', null, '0', '2020-06-29 15:44:24', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256441', '1264622039642256431', '[0],[1264622039642256421],[1264622039642256431],', '公告查询', 'sys_notice_mgr_page', '2', null, null, null, 'sysNotice:page', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-06-29 15:45:30', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256451', '1264622039642256431', '[0],[1264622039642256421],[1264622039642256431],', '公告增加', 'sys_notice_mgr_add', '2', null, null, null, 'sysNotice:add', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-06-29 15:45:57', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256461', '1264622039642256431', '[0],[1264622039642256421],[1264622039642256431],', '公告编辑', 'sys_notice_mgr_edit', '2', null, null, null, 'sysNotice:edit', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-06-29 15:46:22', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256471', '1264622039642256431', '[0],[1264622039642256421],[1264622039642256431],', '公告删除', 'sys_notice_mgr_delete', '2', null, null, null, 'sysNotice:delete', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-06-29 15:46:11', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256481', '1264622039642256431', '[0],[1264622039642256421],[1264622039642256431],', '公告查看', 'sys_notice_mgr_detail', '2', null, null, null, 'sysNotice:detail', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-06-29 15:46:33', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256491', '1264622039642256431', '[0],[1264622039642256421],[1264622039642256431],', '公告修改状态', 'sys_notice_mgr_changeStatus', '2', null, null, null, 'sysNotice:changeStatus', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-06-29 15:46:50', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256501', '1264622039642256421', '[0],[1264622039642256421],', '已收公告', 'sys_notice_mgr_received', '1', null, '/noticeReceived', 'system/noticeReceived/index', null, 'system', '1', 'Y', null, null, '1', '20', null, '0', '2020-06-29 16:32:53', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256511', '1264622039642256501', '[0],[1264622039642256421],[1264622039642256501],', '已收公告查询', 'sys_notice_mgr_received_page', '2', null, null, null, 'sysNotice:received', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-06-29 16:33:43', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256521', '0', '[0],', '文件管理', 'sys_file_mgr', '0', 'file', '/file', 'PageView', null, 'system', '1', 'Y', null, null, '1', '8', null, '0', '2020-06-24 17:31:10', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256531', '1264622039642256521', '[0],[1264622039642256521],', '系统文件', 'sys_file_mgr_sys_file', '1', null, '/file', 'system/file/index', null, 'system', '1', 'Y', null, null, '1', '21', null, '0', '2020-06-24 17:32:57', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256541', '1264622039642256531', '[0],[1264622039642256521],[1264622039642256531],', '文件查询', 'sys_file_mgr_sys_file_page', '2', null, null, null, 'sysFileInfo:page', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-06-24 17:35:38', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256551', '1264622039642256531', '[0],[1264622039642256521],[1264622039642256531],', '文件列表', 'sys_file_mgr_sys_file_list', '2', null, null, null, 'sysFileInfo:list', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-06-24 17:35:49', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256561', '1264622039642256531', '[0],[1264622039642256521],[1264622039642256531],', '文件删除', 'sys_file_mgr_sys_file_delete', '2', null, null, null, 'sysFileInfo:delete', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-06-24 17:36:11', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256571', '1264622039642256531', '[0],[1264622039642256521],[1264622039642256531],', '文件详情', 'sys_file_mgr_sys_file_detail', '2', null, null, null, 'sysFileInfo:detail', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-06-24 17:36:01', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256581', '1264622039642256531', '[0],[1264622039642256521],[1264622039642256531],', '文件上传', 'sys_file_mgr_sys_file_upload', '2', null, null, null, 'sysFileInfo:upload', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-06-24 17:34:29', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256591', '1264622039642256531', '[0],[1264622039642256521],[1264622039642256531],', '文件下载', 'sys_file_mgr_sys_file_download', '2', null, null, null, 'sysFileInfo:download', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-06-24 17:34:55', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256601', '1264622039642256531', '[0],[1264622039642256521],[1264622039642256531],', '图片预览', 'sys_file_mgr_sys_file_preview', '2', null, null, null, 'sysFileInfo:preview', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-06-24 17:35:19', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256611', '0', '[0],', '定时任务', 'sys_timers', '0', 'dashboard', '/timers', 'PageView', null, 'system', '1', 'Y', null, null, '1', '100', null, '0', '2020-07-01 17:17:20', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256621', '1264622039642256611', '[0],[1264622039642256611],', '任务管理', 'sys_timers_mgr', '1', null, '/timers', 'system/timers/index', null, 'system', '1', 'Y', null, null, '1', '22', null, '0', '2020-07-01 17:18:53', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256631', '1264622039642256621', '[0],[1264622039642256611],[1264622039642256621],', '定时任务查询', 'sys_timers_mgr_page', '2', null, null, null, 'sysTimers:page', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-07-01 17:19:43', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256641', '1264622039642256621', '[0],[1264622039642256611],[1264622039642256621],', '定时任务列表', 'sys_timers_mgr_list', '2', null, null, null, 'sysTimers:list', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-07-01 17:19:56', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256651', '1264622039642256621', '[0],[1264622039642256611],[1264622039642256621],', '定时任务详情', 'sys_timers_mgr_detail', '2', null, null, null, 'sysTimers:detail', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-07-01 17:20:10', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256661', '1264622039642256621', '[0],[1264622039642256611],[1264622039642256621],', '定时任务增加', 'sys_timers_mgr_add', '2', null, null, null, 'sysTimers:add', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-07-01 17:20:23', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256671', '1264622039642256621', '[0],[1264622039642256611],[1264622039642256621],', '定时任务删除', 'sys_timers_mgr_delete', '2', null, null, null, 'sysTimers:delete', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-07-01 17:20:33', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256681', '1264622039642256621', '[0],[1264622039642256611],[1264622039642256621],', '定时任务编辑', 'sys_timers_mgr_edit', '2', null, null, null, 'sysTimers:edit', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-07-01 17:20:43', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256691', '1264622039642256621', '[0],[1264622039642256611],[1264622039642256621],', '定时任务可执行列表', 'sys_timers_mgr_get_action_classes', '2', null, null, null, 'sysTimers:getActionClasses', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-07-01 17:22:16', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256701', '1264622039642256621', '[0],[1264622039642256611],[1264622039642256621],', '定时任务启动', 'sys_timers_mgr_start', '2', null, null, null, 'sysTimers:start', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-07-01 17:22:32', '1265476890672672808', null, null); +INSERT INTO `sys_menu` VALUES ('1264622039642256711', '1264622039642256621', '[0],[1264622039642256611],[1264622039642256621],', '定时任务关闭', 'sys_timers_mgr_stop', '2', null, null, null, 'sysTimers:stop', 'system', '0', 'Y', null, null, '1', '100', null, '0', '2020-07-01 17:22:43', '1265476890672672808', null, null); + +-- ---------------------------- +-- Table structure for `sys_notice` +-- ---------------------------- +DROP TABLE IF EXISTS `sys_notice`; +CREATE TABLE `sys_notice` ( + `id` bigint(20) NOT NULL COMMENT '主键', + `title` varchar(1000) DEFAULT NULL COMMENT '标题', + `content` text CHARACTER SET utf8 COLLATE utf8_bin COMMENT '内容', + `type` tinyint(4) NOT NULL COMMENT '类型(字典 1通知 2公告)', + `public_user_id` bigint(20) NOT NULL COMMENT '发布人id', + `public_user_name` varchar(100) NOT NULL COMMENT '发布人姓名', + `public_org_id` bigint(20) DEFAULT NULL COMMENT '发布机构id', + `public_org_name` varchar(50) DEFAULT NULL COMMENT '发布机构名称', + `public_time` datetime DEFAULT NULL COMMENT '发布时间', + `cancel_time` datetime DEFAULT NULL COMMENT '撤回时间', + `status` tinyint(4) NOT NULL COMMENT '状态(字典 0草稿 1发布 2撤回 3删除)', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `create_user` bigint(20) DEFAULT NULL COMMENT '创建人', + `update_time` datetime DEFAULT NULL COMMENT '修改时间', + `update_user` bigint(20) DEFAULT NULL COMMENT '修改人', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='通知表'; + +-- ---------------------------- +-- Records of sys_notice +-- ---------------------------- +INSERT INTO `sys_notice` VALUES ('1304960081456066561', 'qqqq', 0x7171717171713C703E3C2F703E, '1', '1265476890672672808', '超级管理员', null, null, '2020-09-13 09:48:23', '2020-09-13 09:52:26', '3', '2020-09-13 09:48:23', '1265476890672672808', '2020-09-13 09:52:27', '1280700700074041345'); +INSERT INTO `sys_notice` VALUES ('1304960124862918657', '123123123', 0x3C703E32333132333132333132333132333C2F703E, '2', '1265476890672672808', '超级管理员', null, null, '2020-09-13 09:48:33', '2020-09-13 09:52:28', '3', '2020-09-13 09:48:33', '1265476890672672808', '2020-09-13 09:52:40', '1280700700074041345'); +INSERT INTO `sys_notice` VALUES ('1304961721068220417', '北京的秋天', 0x3C703E3C696D67207372633D2268747470733A2F2F74696D6773612E62616964752E636F6D2F74696D673F696D61676526616D703B7175616C6974793D383026616D703B73697A653D62393939395F313030303026616D703B7365633D3135393939373230373136383826616D703B64693D396436393238303737313730313865396633366463323039623866326132393026616D703B696D67747970653D3026616D703B7372633D68747470253341253246253246696D67312E696D67746E2E6264696D672E636F6D2532466974253246752533443331373838363937333625324331343330323430373631253236666D2533443231342532366770253344302E6A7067223E266E6273703B266E6273703B3C62723E3C2F703E, '1', '1280700700074041345', '老俞', '1265476890672672771', '研发部', '2020-09-13 09:54:54', null, '1', '2020-09-13 09:54:54', '1280700700074041345', null, null); +INSERT INTO `sys_notice` VALUES ('1304964964817104898', '北京的秋天', 0x3C646976207374796C653D22746578742D616C69676E3A2063656E7465723B223E3C696D67207372633D2268747470733A2F2F74696D6773612E62616964752E636F6D2F74696D673F696D61676526616D703B7175616C6974793D383026616D703B73697A653D62393939395F313030303026616D703B7365633D3135393939373239333632343026616D703B64693D306336353631306137306137663864653236653834663531646137373630346626616D703B696D67747970653D3026616D703B7372633D68747470253341253246253246696D67312E696D67746E2E6264696D672E636F6D2532466974253246752533443331373838363937333625324331343330323430373631253236666D2533443231342532366770253344302E6A7067223E266E6273703B266E6273703B3C62723E3C2F6469763E3C703E3C2F703E, '1', '1265476890672672808', '超级管理员', null, null, '2020-09-13 10:07:47', null, '1', '2020-09-13 10:07:47', '1265476890672672808', null, null); + +-- ---------------------------- +-- Table structure for `sys_notice_user` +-- ---------------------------- +DROP TABLE IF EXISTS `sys_notice_user`; +CREATE TABLE `sys_notice_user` ( + `id` bigint(20) NOT NULL COMMENT '主键', + `notice_id` bigint(20) NOT NULL COMMENT '通知公告id', + `user_id` bigint(20) NOT NULL COMMENT '用户id', + `status` tinyint(4) NOT NULL COMMENT '状态(字典 0未读 1已读)', + `read_time` datetime DEFAULT NULL COMMENT '阅读时间', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='系统用户数据范围表'; + +-- ---------------------------- +-- Records of sys_notice_user +-- ---------------------------- +INSERT INTO `sys_notice_user` VALUES ('1304960081539952642', '1304960081456066561', '1280700700074041345', '0', null); +INSERT INTO `sys_notice_user` VALUES ('1304960124934221825', '1304960124862918657', '1280700700074041345', '1', '2020-09-13 09:49:02'); +INSERT INTO `sys_notice_user` VALUES ('1304961721131134977', '1304961721068220417', '1280700700074041345', '1', '2020-09-13 09:54:56'); +INSERT INTO `sys_notice_user` VALUES ('1304964964875825153', '1304964964817104898', '1280700700074041345', '0', null); + +-- ---------------------------- +-- Table structure for `sys_oauth_user` +-- ---------------------------- +DROP TABLE IF EXISTS `sys_oauth_user`; +CREATE TABLE `sys_oauth_user` ( + `id` bigint(20) NOT NULL COMMENT '主键', + `uuid` varchar(255) NOT NULL COMMENT '第三方平台的用户唯一id', + `access_token` varchar(255) DEFAULT NULL COMMENT '用户授权的token', + `nick_name` varchar(255) DEFAULT NULL COMMENT '昵称', + `avatar` varchar(500) DEFAULT NULL COMMENT '头像', + `blog` varchar(255) DEFAULT NULL COMMENT '用户网址', + `company` varchar(255) DEFAULT NULL COMMENT '所在公司', + `location` varchar(255) DEFAULT NULL COMMENT '位置', + `email` varchar(255) DEFAULT NULL COMMENT '邮箱', + `gender` varchar(50) DEFAULT NULL COMMENT '性别', + `source` varchar(255) DEFAULT NULL COMMENT '用户来源', + `remark` varchar(255) DEFAULT NULL COMMENT '用户备注(各平台中的用户个人介绍)', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `create_user` bigint(20) DEFAULT NULL COMMENT '创建用户', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `update_user` bigint(20) DEFAULT NULL COMMENT '更新用户', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='第三方认证用户信息表'; + +-- ---------------------------- +-- Records of sys_oauth_user +-- ---------------------------- + +-- ---------------------------- +-- Table structure for `sys_op_log` +-- ---------------------------- +DROP TABLE IF EXISTS `sys_op_log`; +CREATE TABLE `sys_op_log` ( + `id` bigint(20) NOT NULL COMMENT '主键', + `name` varchar(50) DEFAULT NULL COMMENT '名称', + `op_type` tinyint(4) DEFAULT NULL COMMENT '操作类型', + `success` char(1) DEFAULT NULL COMMENT '是否执行成功(Y-是,N-否)', + `message` text CHARACTER SET utf8 COLLATE utf8_bin COMMENT '具体消息', + `ip` varchar(255) DEFAULT NULL COMMENT 'ip', + `location` varchar(255) DEFAULT NULL COMMENT '地址', + `browser` varchar(255) DEFAULT NULL COMMENT '浏览器', + `os` varchar(255) DEFAULT NULL COMMENT '操作系统', + `url` varchar(500) DEFAULT NULL COMMENT '请求地址', + `class_name` varchar(500) DEFAULT NULL COMMENT '类名称', + `method_name` varchar(500) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '方法名称', + `req_method` varchar(255) DEFAULT NULL COMMENT '请求方式(GET POST PUT DELETE)', + `param` text COMMENT '请求参数', + `result` longtext COMMENT '返回结果', + `op_time` datetime DEFAULT NULL COMMENT '操作时间', + `account` varchar(50) DEFAULT NULL COMMENT '操作账号', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='系统操作日志表'; + +-- ---------------------------- +-- Records of sys_op_log +-- ---------------------------- +INSERT INTO `sys_op_log` VALUES ('1333732924677914626', '系统字典类型_树', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysDictType/tree', 'com.cn.xiaonuo.sys.modular.dict.controller.SysDictTypeController', 'tree', 'GET', '', '{\"code\":200,\"data\":[{\"children\":[{\"children\":[],\"code\":\"0\",\"id\":1265216617500102656,\"name\":\"正常\",\"pid\":1265216211667636226},{\"children\":[],\"code\":\"1\",\"id\":1265216617500102657,\"name\":\"停用\",\"pid\":1265216211667636226},{\"children\":[],\"code\":\"2\",\"id\":1265216938389524482,\"name\":\"删除\",\"pid\":1265216211667636226}],\"code\":\"common_status\",\"id\":1265216211667636226,\"name\":\"通用状态\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"1\",\"id\":1265216536659087357,\"name\":\"男\",\"pid\":1265216211667636234},{\"children\":[],\"code\":\"2\",\"id\":1265216536659087358,\"name\":\"女\",\"pid\":1265216211667636234},{\"children\":[],\"code\":\"3\",\"id\":1265216536659087359,\"name\":\"未知\",\"pid\":1265216211667636234}],\"code\":\"sex\",\"id\":1265216211667636234,\"name\":\"性别\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"DEFAULT\",\"id\":1265216536659087361,\"name\":\"默认常量\",\"pid\":1265216211667636235},{\"children\":[],\"code\":\"ALIYUN_SMS\",\"id\":1265216536659087363,\"name\":\"阿里云短信\",\"pid\":1265216211667636235},{\"children\":[],\"code\":\"TENCENT_SMS\",\"id\":1265216536659087364,\"name\":\"腾讯云短信\",\"pid\":1265216211667636235},{\"children\":[],\"code\":\"EMAIL\",\"id\":1265216536659087365,\"name\":\"邮件配置\",\"pid\":1265216211667636235},{\"children\":[],\"code\":\"FILE_PATH\",\"id\":1265216536659087366,\"name\":\"文件上传路径\",\"pid\":1265216211667636235},{\"children\":[],\"code\":\"OAUTH\",\"id\":1265216536659087367,\"name\":\"Oauth配置\",\"pid\":1265216211667636235}],\"code\":\"consts_type\",\"id\":1265216211667636235,\"name\":\"常量的分类\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"N\",\"id\":1265217669028892673,\"name\":\"否\",\"pid\":1265217074079453185},{\"children\":[],\"code\":\"Y\",\"id\":1265217706584690689,\"name\":\"是\",\"pid\":1265217074079453185}],\"code\":\"yes_or_no\",\"id\":1265217074079453185,\"name\":\"是否\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"1\",\"id\":1265220776437731330,\"name\":\"登录\",\"pid\":1265217846770913282},{\"children\":[],\"code\":\"2\",\"id\":1265220806070489090,\"name\":\"登出\",\"pid\":1265217846770913282}],\"code\":\"vis_type\",\"id\":1265217846770913282,\"name\":\"访问类型\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"0\",\"id\":1265221129564573697,\"name\":\"目录\",\"pid\":1265221049302372354},{\"children\":[],\"code\":\"1\",\"id\":1265221163119005697,\"name\":\"菜单\",\"pid\":1265221049302372354},{\"children\":[],\"code\":\"2\",\"id\":1265221188091891713,\"name\":\"按钮\",\"pid\":1265221049302372354}],\"code\":\"menu_type\",\"id\":1265221049302372354,\"name\":\"菜单类型\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"0\",\"id\":1265466389204967426,\"name\":\"未发送\",\"pid\":1265466149622128641},{\"children\":[],\"code\":\"1\",\"id\":1265466432670539778,\"name\":\"发送成功\",\"pid\":1265466149622128641},{\"children\":[],\"code\":\"2\",\"id\":1265466486097584130,\"name\":\"发送失败\",\"pid\":1265466149622128641},{\"children\":[],\"code\":\"3\",\"id\":1265466530477514754,\"name\":\"失效\",\"pid\":1265466149622128641}],\"code\":\"send_type\",\"id\":1265466149622128641,\"name\":\"发送类型\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"0\",\"id\":1265466835009150978,\"name\":\"无\",\"pid\":1265466752209395713},{\"children\":[],\"code\":\"1\",\"id\":1265466874758569986,\"name\":\"组件\",\"pid\":1265466752209395713},{\"children\":[],\"code\":\"2\",\"id\":1265466925476093953,\"name\":\"内链\",\"pid\":1265466752209395713},{\"children\":[],\"code\":\"3\",\"id\":1265466962209808385,\"name\":\"外链\",\"pid\":1265466752209395713}],\"code\":\"open_type\",\"id\":1265466752209395713,\"name\":\"打开方式\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"1\",\"id\":1265467428423475202,\"name\":\"系统权重\",\"pid\":1265467337566461954},{\"children\":[],\"code\":\"2\",\"id\":1265467503090475009,\"name\":\"业务权重\",\"pid\":1265467337566461954}],\"code\":\"menu_weight\",\"id\":1265467337566461954,\"name\":\"菜单权重\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"1\",\"id\":1265467709110493186,\"name\":\"事假\",\"pid\":1265467629167058946},{\"children\":[],\"code\":\"2\",\"id\":1265467745013735426,\"name\":\"病假\",\"pid\":1265467629167058946},{\"children\":[],\"code\":\"3\",\"id\":1265467785253888001,\"name\":\"婚假\",\"pid\":1265467629167058946},{\"children\":[],\"code\":\"4\",\"id\":1265467823426248706,\"name\":\"丧假\",\"pid\":1265467629167058946},{\"children\":[],\"code\":\"5\",\"id\":1265467855781109762,\"name\":\"产假\",\"pid\":1265467629167058946},{\"children\":[],\"code\":\"6\",\"id\":1265467895782187010,\"name\":\"其他\",\"pid\":1265467629167058946}],\"code\":\"leave_type\",\"id\":1265467629167058946,\"name\":\"请假类型\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"1\",\"id\":1265468138431062018,\"name\":\"全部数据\",\"pid\":1265468028632571905},{\"children\":[],\"code\":\"2\",\"id\":1265468194928336897,\"name\":\"本部门及以下数据\",\"pid\":1265468028632571905},{\"children\":[],\"code\":\"3\",\"id\":1265468241992622082,\"name\":\"本部门数据\",\"pid\":1265468028632571905},{\"children\":[],\"code\":\"4\",\"id\":1265468273634451457,\"name\":\"仅本人数据\",\"pid\":1265468028632571905},{\"children\":[],\"code\":\"5\",\"id\":1265468302046666753,\"name\":\"自定义数据\",\"pid\":1265468028632571905}],\"code\":\"data_scope_type\",\"id\":1265468028632571905,\"name\":\"数据范围类型\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"1\",\"id\":1265468508100239362,\"name\":\"app\",\"pid\":1265468437904367618},{\"children\":[],\"code\":\"2\",\"id\":1265468543433056258,\"name\":\"pc\",\"pid\":1265468437904367618},{\"children\":[],\"code\":\"3\",\"id\":1265468576874242050,\"name\":\"其他\",\"pid\":1265468437904367618}],\"code\":\"sms_send_source\",\"id\":1265468437904367618,\"name\":\"短信发送来源\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"1\",\"id\":1265468839764828161,\"name\":\"Integer\",\"pid\":1265468761230680066},{\"children\":[],\"code\":\"2\",\"id\":1265468871641538562,\"name\":\"String\",\"pid\":1265468761230680066},{\"children\":[],\"code\":\"3\",\"id\":1265468898896125954,\"name\":\"Long\",\"pid\":1265468761230680066},{\"children\":[],\"code\":\"4\",\"id\":1265468922275176450,\"name\":\"Double\",\"pid\":1265468761230680066},{\"children\":[],\"code\":\"5\",\"id\":1265468946648276993,\"name\":\"Boolean\",\"pid\":1265468761230680066},{\"children\":[],\"code\":\"6\",\"id\":1265468970450952193,\"name\":\"Date\",\"pid\":1265468761230680066},{\"children\":[],\"code\":\"7\",\"id\":1265468970450952194,\"name\":\"List\",\"pid\":1265468761230680066}],\"code\":\"filed_type\",\"id\":1265468761230680066,\"name\":\"字段类型\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"1\",\"id\":1265469305756196865,\"name\":\"流程脚本\",\"pid\":1265469198583341057},{\"children\":[],\"code\":\"2\",\"id\":1265469330859106306,\"name\":\"系统脚本\",\"pid\":1265469198583341057}],\"code\":\"script_type\",\"id\":1265469198583341057,\"name\":\"脚本类型\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"1\",\"id\":1265469526330449922,\"name\":\"groovy\",\"pid\":1265469441454514178}],\"code\":\"script_language_type\",\"id\":1265469441454514178,\"name\":\"脚本语言类型\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"1\",\"id\":1265469753078718464,\"name\":\"启动\",\"pid\":1265469702042427393},{\"children\":[],\"code\":\"2\",\"id\":1265469753078718465,\"name\":\"全局\",\"pid\":1265469702042427393},{\"children\":[],\"code\":\"3\",\"id\":1265469779460890626,\"name\":\"节点\",\"pid\":1265469702042427393}],\"code\":\"form_type\",\"id\":1265469702042427393,\"name\":\"表单类型\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"PROCESS_STARTED\",\"id\":1265470046877130753,\"name\":\"流程启动\",\"pid\":1265469962873610241},{\"children\":[],\"code\":\"PROCESS_COMPLETED\",\"id\":1265470074517594113,\"name\":\"流程完成\",\"pid\":1265469962873610241},{\"children\":[],\"code\":\"PROCESS_CANCELLED\",\"id\":1265470103152107521,\"name\":\"流程取消\",\"pid\":1265469962873610241},{\"children\":[],\"code\":\"ACTIVITY_STARTED\",\"id\":1265470125725851649,\"name\":\"活动开始\",\"pid\":1265469962873610241},{\"children\":[],\"code\":\"ACTIVITY_COMPLETED\",\"id\":1265470153416646657,\"name\":\"活动完成\",\"pid\":1265469962873610241},{\"children\":[],\"code\":\"ACTIVITY_CANCELLED\",\"id\":1265470179165478913,\"name\":\"活动取消\",\"pid\":1265469962873610241},{\"children\":[],\"code\":\"TASK_ASSIGNED\",\"id\":1265470207363784705,\"name\":\"任务分配\",\"pid\":1265469962873610241},{\"children\":[],\"code\":\"TASK_CREATED\",\"id\":1265470236853936130,\"name\":\"任务创建\",\"pid\":1265469962873610241},{\"children\":[],\"code\":\"TASK_COMPLETED\",\"id\":1265470266780295170,\"name\":\"任务完成\",\"pid\":1265469962873610241},{\"children\":[],\"code\":\"SEQUENCEFLOW_TAKEN\",\"id\":1265470296446607361,\"name\":\"连接线\",\"pid\":1265469962873610241}],\"code\":\"event_type\",\"id\":1265469962873610241,\"name\":\"事件类型\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"1\",\"id\":1265470296446607362,\"name\":\"全局\",\"pid\":1265469962873610242},{\"children\":[],\"code\":\"2\",\"id\":1265470296446607363,\"name\":\"节点\",\"pid\":1265469962873610242}],\"code\":\"event_node_type\",\"id\":1265469962873610242,\"name\":\"事件节点类型\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"0\",\"id\":1265470526197997569,\"name\":\"草稿\",\"pid\":1265470456631271426},{\"children\":[],\"code\":\"1\",\"id\":1265470552823439361,\"name\":\"审核中\",\"pid\":1265470456631271426},{\"children\":[],\"code\":\"2\",\"id\":1265470575615287297,\"name\":\"已退回\",\"pid\":1265470456631271426},{\"children\":[],\"code\":\"3\",\"id\":1265470607588466690,\"name\":\"已完成\",\"pid\":1265470456631271426}],\"code\":\"process_status\",\"id\":1265470456631271426,\"name\":\"流程状态\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"0\",\"id\":1275617233011335170,\"name\":\"其它\",\"pid\":1275617093517172738},{\"children\":[],\"code\":\"1\",\"id\":1275617295355469826,\"name\":\"增加\",\"pid\":1275617093517172738},{\"children\":[],\"code\":\"2\",\"id\":1275617348610547714,\"name\":\"删除\",\"pid\":1275617093517172738},{\"children\":[],\"code\":\"3\",\"id\":1275617395515449346,\"name\":\"编辑\",\"pid\":1275617093517172738},{\"children\":[],\"code\":\"4\",\"id\":1275617433612312577,\"name\":\"更新\",\"pid\":1275617093517172738},{\"children\":[],\"code\":\"5\",\"id\":1275617472707420161,\"name\":\"查询\",\"pid\":1275617093517172738},{\"children\":[],\"code\":\"6\",\"id\":1275617502973517826,\"name\":\"详情\",\"pid\":1275617093517172738},{\"children\":[],\"code\":\"7\",\"id\":1275617536959963137,\"name\":\"树\",\"pid\":1275617093517172738},{\"children\":[],\"code\":\"8\",\"id\":1275617619524837377,\"name\":\"导入\",\"pid\":1275617093517172738},{\"children\":[],\"code\":\"9\",\"id\":1275617651816783873,\"name\":\"导出\",\"pid\":1275617093517172738},{\"children\":[],\"code\":\"10\",\"id\":1275617683475390465,\"name\":\"授权\",\"pid\":1275617093517172738},{\"children\":[],\"code\":\"11\",\"id\":1275617709928865793,\"name\":\"强退\",\"pid\":1275617093517172738},{\"children\":[],\"code\":\"12\",\"id\":1275617739091861505,\"name\":\"清空\",\"pid\":1275617093517172738},{\"children\":[],\"code\":\"13\",\"id\":1275617788601425921,\"name\":\"修改状态\",\"pid\":1275617093517172738}],\"code\":\"op_type\",\"id\":1275617093517172738,\"name\":\"操作类型\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"1\",\"id\":1277774590944317441,\"name\":\"阿里云\",\"pid\":1277774529430654977},{\"children\":[],\"code\":\"2\",\"id\":1277774666055913474,\"name\":\"腾讯云\",\"pid\":1277774529430654977},{\"children\":[],\"code\":\"3\",\"id\":1277774695168577538,\"name\":\"minio\",\"pid\":1277774529430654977},{\"children\":[],\"code\":\"4\",\"id\":1277774726835572737,\"name\":\"本地\",\"pid\":1277774529430654977}],\"code\":\"file_storage_location\",\"id\":1277774529430654977,\"name\":\"文件存储位置\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"1\",\"id\":1278607123583868929,\"name\":\"运行\",\"pid\":1278606951432855553},{\"children\":[],\"code\":\"2\",\"id\":1278607162943217666,\"name\":\"停止\",\"pid\":1278606951432855553}],\"code\":\"run_status\",\"id\":1278606951432855553,\"name\":\"运行状态\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"1\",\"id\":1278939265862004738,\"name\":\"通知\",\"pid\":1278911800547147777},{\"children\":[],\"code\":\"2\",\"id\":1278939319922388994,\"name\":\"公告\",\"pid\":1278911800547147777}],\"code\":\"notice_type\",\"id\":1278911800547147777,\"name\":\"通知公告类型\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"0\",\"id\":1278939399001796609,\"name\":\"草稿\",\"pid\":1278911952657776642},{\"children\":[],\"code\":\"1\",\"id\":1278939432686252034,\"name\":\"发布\",\"pid\":1278911952657776642},{\"children\":[],\"code\":\"2\",\"id\":1278939458804183041,\"name\":\"撤回\",\"pid\":1278911952657776642},{\"children\":[],\"code\":\"3\",\"id\":1278939485878415362,\"name\":\"删除\",\"pid\":1278911952657776642}],\"code\":\"notice_status\",\"id\":1278911952657776642,\"name\":\"通知公告状态\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"0\",\"id\":1278992343223025665,\"name\":\"委托中\",\"pid\":1278992276965605377},{\"children\":[],\"code\":\"1\",\"id\":1278992370066571266,\"name\":\"委托结束\",\"pid\":1278992276965605377},{\"children\":[],\"code\":\"2\",\"id\":1278992396788482050,\"name\":\"未委托\",\"pid\":1278992276965605377}],\"code\":\"delegate_status\",\"id\":1278992276965605377,\"name\":\"委托状态\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"true\",\"id\":1291391148769738754,\"name\":\"是\",\"pid\":1291391077990858754},{\"children\":[],\"code\":\"false\",\"id\":1291391205719998465,\"name\":\"否\",\"pid\":1291391077990858754}],\"code\":\"suspended_status\",\"id\":1291391077990858754,\"name\":\"流程是否挂起\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"true\",\"id\":1291393684314587138,\"name\":\"是\",\"pid\":1291393441594408961},{\"children\":[],\"code\":\"false\",\"id\":1291393766048989186,\"name\":\"否\",\"pid\":1291393441594408961}],\"code\":\"ended_status\",\"id\":1291393441594408961,\"name\":\"是否结束\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"com.mysql.cj.jdbc.Driver\",\"id\":1300767954291433474,\"name\":\"Mysql\",\"pid\":1300767512828354562},{\"children\":[],\"code\":\"oracle.jdbc.OracleDriver\",\"id\":1300768214854180866,\"name\":\"Oracle\",\"pid\":1300767512828354562},{\"children\":[],\"code\":\"com.microsoft.jdbc.sqlserver.SQLServerDriver\",\"id\":1300768392747196417,\"name\":\"Sqlserver\",\"pid\":1300767512828354562}],\"code\":\"jdbc_driver\",\"id\":1300767512828354562,\"name\":\"JDBC驱动类型\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"0\",\"id\":1300768392747196418,\"name\":\"未支付\",\"pid\":1300767512828354563},{\"children\":[],\"code\":\"1\",\"id\":1300768392747196419,\"name\":\"已支付\",\"pid\":1300767512828354563},{\"children\":[],\"code\":\"2\",\"id\":1300768392747196420,\"name\":\"已退款\",\"pid\":1300767512828354563},{\"children\":[],\"code\":\"3\",\"id\":1300768392747196421,\"name\":\"已关闭\",\"pid\":1300767512828354563},{\"children\":[],\"code\":\"4\",\"id\":1300768392747196422,\"name\":\"已关闭有退款\",\"pid\":1300767512828354563}],\"code\":\"alipay_trade_status\",\"id\":1300767512828354563,\"name\":\"支付宝交易状态\",\"pid\":0}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:21:23', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333732949696937986', '系统菜单_切换', '7', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysMenu/change', 'com.cn.xiaonuo.sys.modular.menu.controller.SysMenuController', 'change', 'POST', '{\"application\":\"office\"}', '{\"code\":200,\"data\":[],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:21:29', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333732955497660417', '系统菜单_切换', '7', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysMenu/change', 'com.cn.xiaonuo.sys.modular.menu.controller.SysMenuController', 'change', 'POST', '{\"application\":\"experience\"}', '{\"code\":200,\"data\":[],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:21:31', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333732959817793537', '系统菜单_切换', '7', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysMenu/change', 'com.cn.xiaonuo.sys.modular.menu.controller.SysMenuController', 'change', 'POST', '{\"application\":\"system\"}', '{\"code\":200,\"data\":[{\"component\":\"RouteView\",\"hidden\":false,\"id\":1264622039642255311,\"meta\":{\"icon\":\"home\",\"show\":true,\"title\":\"主控面板\"},\"name\":\"system_index\",\"path\":\"/\",\"pid\":0,\"redirect\":\"/analysis\"},{\"component\":\"system/dashboard/Workplace\",\"hidden\":false,\"id\":1264622039642255331,\"meta\":{\"show\":true,\"title\":\"工作台\"},\"name\":\"system_index_workplace\",\"path\":\"workplace\",\"pid\":1264622039642255311},{\"component\":\"PageView\",\"hidden\":false,\"id\":1264622039642255341,\"meta\":{\"icon\":\"team\",\"show\":true,\"title\":\"组织架构\"},\"name\":\"sys_mgr\",\"path\":\"/sys\",\"pid\":0},{\"component\":\"PageView\",\"hidden\":false,\"id\":1264622039642255671,\"meta\":{\"icon\":\"safety-certificate\",\"show\":true,\"title\":\"权限管理\"},\"name\":\"auth_manager\",\"path\":\"/auth\",\"pid\":0},{\"component\":\"system/user/index\",\"hidden\":false,\"id\":1264622039642255351,\"meta\":{\"show\":true,\"title\":\"用户管理\"},\"name\":\"sys_user_mgr\",\"path\":\"/mgr_user\",\"pid\":1264622039642255341},{\"component\":\"PageView\",\"hidden\":false,\"id\":1264622039642255961,\"meta\":{\"icon\":\"euro\",\"show\":true,\"title\":\"开发管理\"},\"name\":\"system_tools\",\"path\":\"/tools\",\"pid\":0},{\"component\":\"system/org/index\",\"hidden\":false,\"id\":1264622039642255521,\"meta\":{\"show\":true,\"title\":\"机构管理\"},\"name\":\"sys_org_mgr\",\"path\":\"/org\",\"pid\":1264622039642255341},{\"component\":\"PageView\",\"hidden\":false,\"id\":1264622039642256281,\"meta\":{\"icon\":\"read\",\"show\":true,\"title\":\"日志管理\"},\"name\":\"sys_log_mgr\",\"path\":\"/log\",\"pid\":0},{\"component\":\"system/pos/index\",\"hidden\":false,\"id\":1264622039642255601,\"meta\":{\"show\":true,\"title\":\"职位管理\"},\"name\":\"sys_pos_mgr\",\"path\":\"/pos\",\"pid\":1264622039642255341},{\"component\":\"system/app/index\",\"hidden\":false,\"id\":1264622039642255681,\"meta\":{\"show\":true,\"title\":\"应用管理\"},\"name\":\"sys_app_mgr\",\"path\":\"/app\",\"pid\":1264622039642255671},{\"component\":\"PageView\",\"hidden\":false,\"id\":1264622039642256351,\"meta\":{\"icon\":\"deployment-unit\",\"show\":true,\"title\":\"系统监控\"},\"name\":\"sys_monitor_mgr\",\"path\":\"/monitor\",\"pid\":0},{\"component\":\"PageView\",\"hidden\":false,\"id\":1264622039642256421,\"meta\":{\"icon\":\"sound\",\"show\":true,\"title\":\"通知公告\"},\"name\":\"sys_notice\",\"path\":\"/notice\",\"pid\":0},{\"component\":\"system/menu/index\",\"hidden\":false,\"id\":1264622039642255761,\"meta\":{\"show\":true,\"title\":\"菜单管理\"},\"name\":\"sys_menu_mgr\",\"path\":\"/menu\",\"pid\":1264622039642255671},{\"component\":\"PageView\",\"hidden\":false,\"id\":1264622039642256521,\"meta\":{\"icon\":\"file\",\"show\":true,\"title\":\"文件管理\"},\"name\":\"sys_file_mgr\",\"path\":\"/file\",\"pid\":0},{\"component\":\"system/role/index\",\"hidden\":false,\"id\":1264622039642255851,\"meta\":{\"show\":true,\"title\":\"角色管理\"},\"name\":\"sys_role_mgr\",\"path\":\"/role\",\"pid\":1264622039642255671},{\"component\":\"system/config/index\",\"hidden\":false,\"id\":1264622039642255971,\"meta\":{\"show\":true,\"title\":\"系统配置\"},\"name\":\"system_tools_config\",\"path\":\"/config\",\"pid\":1264622039642255961},{\"component\":\"system/email/index\",\"hidden\":false,\"id\":1264622039642256041,\"meta\":{\"show\":true,\"title\":\"邮件发送\"},\"name\":\"sys_email_mgr\",\"path\":\"/email\",\"pid\":1264622039642255961},{\"component\":\"system/sms/index\",\"hidden\":false,\"id\":1264622039642256071,\"meta\":{\"show\":true,\"title\":\"短信管理\"},\"name\":\"sys_sms_mgr\",\"path\":\"/sms\",\"pid\":1264622039642255961},{\"component\":\"system/dict/index\",\"hidden\":false,\"id\":1264622039642256111,\"meta\":{\"show\":true,\"title\":\"字典管理\"},\"name\":\"sys_dict_mgr\",\"path\":\"/dict\",\"pid\":1264622039642255961},{\"component\":\"Iframe\",\"hidden\":false,\"id\":1264622039642256271,\"meta\":{\"link\":\"http://localhost:82/doc.html\",\"show\":true,\"title\":\"接口文档\"},\"name\":\"sys_swagger_mgr\",\"path\":\"/swagger\",\"pid\":1264622039642255961},{\"component\":\"system/log/vislog/index\",\"hidden\":false,\"id\":1264622039642256291,\"meta\":{\"show\":true,\"title\":\"访问日志\"},\"name\":\"sys_log_mgr_vis_log\",\"path\":\"/vislog\",\"pid\":1264622039642256281},{\"component\":\"system/log/oplog/index\",\"hidden\":false,\"id\":1264622039642256321,\"meta\":{\"show\":true,\"title\":\"操作日志\"},\"name\":\"sys_log_mgr_op_log\",\"path\":\"/oplog\",\"pid\":1264622039642256281},{\"component\":\"system/machine/index\",\"hidden\":false,\"id\":1264622039642256361,\"meta\":{\"show\":true,\"title\":\"服务监控\"},\"name\":\"sys_monitor_mgr_machine_monitor\",\"path\":\"/machine\",\"pid\":1264622039642256351},{\"component\":\"system/onlineUser/index\",\"hidden\":false,\"id\":1264622039642256381,\"meta\":{\"show\":true,\"title\":\"在线用户\"},\"name\":\"sys_monitor_mgr_online_user\",\"path\":\"/onlineUser\",\"pid\":1264622039642256351},{\"component\":\"Iframe\",\"hidden\":false,\"id\":1264622039642256411,\"meta\":{\"link\":\"http://localhost:82/druid/login.html\",\"show\":true,\"title\":\"数据监控\"},\"name\":\"sys_monitor_mgr_druid\",\"path\":\"/druid\",\"pid\":1264622039642256351},{\"component\":\"system/notice/index\",\"hidden\":false,\"id\":1264622039642256431,\"meta\":{\"show\":true,\"title\":\"公告管理\"},\"name\":\"sys_notice_mgr\",\"path\":\"/notice\",\"pid\":1264622039642256421},{\"component\":\"system/noticeReceived/index\",\"hidden\":false,\"id\":1264622039642256501,\"meta\":{\"show\":true,\"title\":\"已收公告\"},\"name\":\"sys_notice_mgr_received\",\"path\":\"/noticeReceived\",\"pid\":1264622039642256421},{\"component\":\"system/file/index\",\"hidden\":false,\"id\":1264622039642256531,\"meta\":{\"show\":true,\"title\":\"系统文件\"},\"name\":\"sys_file_mgr_sys_file\",\"path\":\"/file\",\"pid\":1264622039642256521},{\"component\":\"system/timers/index\",\"hidden\":false,\"id\":1264622039642256621,\"meta\":{\"show\":true,\"title\":\"任务管理\"},\"name\":\"sys_timers_mgr\",\"path\":\"/timers\",\"pid\":1264622039642256611},{\"component\":\"system/dashboard/Analysis\",\"hidden\":false,\"id\":1264622039642255321,\"meta\":{\"show\":true,\"title\":\"分析页\"},\"name\":\"system_index_dashboard\",\"path\":\"analysis\",\"pid\":1264622039642255311},{\"component\":\"PageView\",\"hidden\":false,\"id\":1264622039642256611,\"meta\":{\"icon\":\"dashboard\",\"show\":true,\"title\":\"定时任务\"},\"name\":\"sys_timers\",\"path\":\"/timers\",\"pid\":0}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:21:32', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333732971951915010', '系统组织机构_树', '7', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysOrg/tree', 'com.cn.xiaonuo.sys.modular.org.controller.SysOrgController', 'tree', 'GET', '{}', '{\"code\":200,\"data\":[{\"children\":[{\"children\":[{\"children\":[],\"id\":1265476890672672771,\"parentId\":1265476890672672769,\"pid\":1265476890672672769,\"title\":\"研发部\",\"value\":\"1265476890672672771\",\"weight\":100},{\"children\":[],\"id\":1265476890672672772,\"parentId\":1265476890672672769,\"pid\":1265476890672672769,\"title\":\"企划部\",\"value\":\"1265476890672672772\",\"weight\":100}],\"id\":1265476890672672769,\"parentId\":1265476890651701250,\"pid\":1265476890651701250,\"title\":\"华夏集团北京分公司\",\"value\":\"1265476890672672769\",\"weight\":100},{\"children\":[{\"children\":[{\"children\":[],\"id\":1265476890672672775,\"parentId\":1265476890672672773,\"pid\":1265476890672672773,\"title\":\"市场部二部\",\"value\":\"1265476890672672775\",\"weight\":100}],\"id\":1265476890672672773,\"parentId\":1265476890672672770,\"pid\":1265476890672672770,\"title\":\"市场部\",\"value\":\"1265476890672672773\",\"weight\":100},{\"children\":[],\"id\":1265476890672672774,\"parentId\":1265476890672672770,\"pid\":1265476890672672770,\"title\":\"财务部\",\"value\":\"1265476890672672774\",\"weight\":100}],\"id\":1265476890672672770,\"parentId\":1265476890651701250,\"pid\":1265476890651701250,\"title\":\"华夏集团成都分公司\",\"value\":\"1265476890672672770\",\"weight\":100}],\"id\":1265476890651701250,\"parentId\":0,\"pid\":0,\"title\":\"华夏集团\",\"value\":\"1265476890651701250\",\"weight\":100}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:21:35', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333732972128075778', '系统字典类型_下拉', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysDictType/dropDown', 'com.cn.xiaonuo.sys.modular.dict.controller.SysDictTypeController', 'dropDown', 'GET', '{\"code\":\"sex\"}', '{\"code\":200,\"data\":[{\"code\":\"1\",\"value\":\"男\"},{\"code\":\"2\",\"value\":\"女\"},{\"code\":\"3\",\"value\":\"未知\"}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:21:35', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333732972186796034', '系统字典类型_下拉', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysDictType/dropDown', 'com.cn.xiaonuo.sys.modular.dict.controller.SysDictTypeController', 'dropDown', 'GET', '{\"code\":\"common_status\"}', '{\"code\":200,\"data\":[{\"code\":\"0\",\"value\":\"正常\"},{\"code\":\"1\",\"value\":\"停用\"},{\"code\":\"2\",\"value\":\"删除\"}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:21:35', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333732972371345410', '系统用户_查询', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysUser/page', 'com.cn.xiaonuo.sys.modular.user.controller.SysUserController', 'page', 'GET', '{}', '{\"code\":200,\"data\":{\"pageNo\":1,\"pageSize\":10,\"rainbow\":[1],\"rows\":[{\"account\":\"yubaoshan\",\"avatar\":1307866860842360834,\"birthday\":718041600000,\"email\":\"await183@qq.com\",\"id\":1275735541155614721,\"name\":\"俞宝山\",\"nickName\":\"Await\",\"phone\":\"18200001102\",\"sex\":1,\"status\":0,\"sysEmpInfo\":{\"jobNum\":\"102\",\"orgId\":1265476890672672769,\"orgName\":\"华夏集团北京分公司\"},\"tel\":\"\"},{\"account\":\"xuyuxiang\",\"avatar\":1307863777357832194,\"birthday\":1593532800000,\"id\":1280709549107552257,\"name\":\"徐玉祥\",\"nickName\":\"就是那个锅\",\"phone\":\"18200001100\",\"sex\":1,\"status\":0,\"sysEmpInfo\":{\"jobNum\":\"100\",\"orgId\":1265476890672672770,\"orgName\":\"华夏集团成都分公司\"}}],\"totalPage\":1,\"totalRows\":2},\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:21:35', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333732976813113346', '系统组织机构_树', '7', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysOrg/tree', 'com.cn.xiaonuo.sys.modular.org.controller.SysOrgController', 'tree', 'GET', '{}', '{\"code\":200,\"data\":[{\"children\":[{\"children\":[{\"children\":[],\"id\":1265476890672672771,\"parentId\":1265476890672672769,\"pid\":1265476890672672769,\"title\":\"研发部\",\"value\":\"1265476890672672771\",\"weight\":100},{\"children\":[],\"id\":1265476890672672772,\"parentId\":1265476890672672769,\"pid\":1265476890672672769,\"title\":\"企划部\",\"value\":\"1265476890672672772\",\"weight\":100}],\"id\":1265476890672672769,\"parentId\":1265476890651701250,\"pid\":1265476890651701250,\"title\":\"华夏集团北京分公司\",\"value\":\"1265476890672672769\",\"weight\":100},{\"children\":[{\"children\":[{\"children\":[],\"id\":1265476890672672775,\"parentId\":1265476890672672773,\"pid\":1265476890672672773,\"title\":\"市场部二部\",\"value\":\"1265476890672672775\",\"weight\":100}],\"id\":1265476890672672773,\"parentId\":1265476890672672770,\"pid\":1265476890672672770,\"title\":\"市场部\",\"value\":\"1265476890672672773\",\"weight\":100},{\"children\":[],\"id\":1265476890672672774,\"parentId\":1265476890672672770,\"pid\":1265476890672672770,\"title\":\"财务部\",\"value\":\"1265476890672672774\",\"weight\":100}],\"id\":1265476890672672770,\"parentId\":1265476890651701250,\"pid\":1265476890651701250,\"title\":\"华夏集团成都分公司\",\"value\":\"1265476890672672770\",\"weight\":100}],\"id\":1265476890651701250,\"parentId\":0,\"pid\":0,\"title\":\"华夏集团\",\"value\":\"1265476890651701250\",\"weight\":100}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:21:36', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333732978415337473', '系统机构_查询', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysOrg/page', 'com.cn.xiaonuo.sys.modular.org.controller.SysOrgController', 'page', 'GET', '{}', '{\"code\":200,\"data\":{\"pageNo\":1,\"pageSize\":10,\"rainbow\":[1],\"rows\":[{\"code\":\"hxjt_bj\",\"createTime\":1585212942000,\"createUser\":1265476890672672808,\"id\":1265476890672672769,\"name\":\"华夏集团北京分公司\",\"pid\":1265476890651701250,\"pids\":\"[0],[1265476890651701250],\",\"remark\":\"华夏集团北京分公司\",\"sort\":100,\"status\":0},{\"code\":\"hxjt_cd\",\"createTime\":1585212962000,\"createUser\":1265476890672672808,\"id\":1265476890672672770,\"name\":\"华夏集团成都分公司\",\"pid\":1265476890651701250,\"pids\":\"[0],[1265476890651701250],\",\"remark\":\"华夏集团成都分公司\",\"sort\":100,\"status\":0},{\"code\":\"hxjt\",\"createTime\":1585212653000,\"createUser\":1265476890672672808,\"id\":1265476890651701250,\"name\":\"华夏集团\",\"pid\":0,\"pids\":\"[0],\",\"remark\":\"华夏集团总公司\",\"sort\":100,\"status\":0},{\"code\":\"hxjt_bj_yfb\",\"createTime\":1585212996000,\"createUser\":1265476890672672808,\"id\":1265476890672672771,\"name\":\"研发部\",\"pid\":1265476890672672769,\"pids\":\"[0],[1265476890651701250],[1265476890672672769],\",\"remark\":\"华夏集团北京分公司研发部\",\"sort\":100,\"status\":0},{\"code\":\"hxjt_bj_qhb\",\"createTime\":1585213026000,\"createUser\":1265476890672672808,\"id\":1265476890672672772,\"name\":\"企划部\",\"pid\":1265476890672672769,\"pids\":\"[0],[1265476890651701250],[1265476890672672769],\",\"remark\":\"华夏集团北京分公司企划部\",\"sort\":100,\"status\":0},{\"code\":\"hxjt_cd_scb\",\"createTime\":1585213055000,\"createUser\":1265476890672672808,\"id\":1265476890672672773,\"name\":\"市场部\",\"pid\":1265476890672672770,\"pids\":\"[0],[1265476890651701250],[1265476890672672770],\",\"remark\":\"华夏集团成都分公司市场部\",\"sort\":100,\"status\":0},{\"code\":\"hxjt_cd_cwb\",\"createTime\":1585213081000,\"createUser\":1265476890672672808,\"id\":1265476890672672774,\"name\":\"财务部\",\"pid\":1265476890672672770,\"pids\":\"[0],[1265476890651701250],[1265476890672672770],\",\"remark\":\"华夏集团成都分公司财务部\",\"sort\":100,\"status\":0},{\"code\":\"hxjt_cd_scb_2b\",\"createTime\":1586158610000,\"createUser\":1265476890672672808,\"id\":1265476890672672775,\"name\":\"市场部二部\",\"pid\":1265476890672672773,\"pids\":\"[0],[1265476890651701250],[1265476890672672770],[1265476890672672773],\",\"remark\":\"华夏集团成都分公司市场部二部\",\"sort\":100,\"status\":0}],\"totalPage\":1,\"totalRows\":8},\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:21:36', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333732978662801409', '系统机构_查询', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysOrg/page', 'com.cn.xiaonuo.sys.modular.org.controller.SysOrgController', 'page', 'GET', '{}', '{\"code\":200,\"data\":{\"pageNo\":1,\"pageSize\":10,\"rainbow\":[1],\"rows\":[{\"code\":\"hxjt_bj\",\"createTime\":1585212942000,\"createUser\":1265476890672672808,\"id\":1265476890672672769,\"name\":\"华夏集团北京分公司\",\"pid\":1265476890651701250,\"pids\":\"[0],[1265476890651701250],\",\"remark\":\"华夏集团北京分公司\",\"sort\":100,\"status\":0},{\"code\":\"hxjt_cd\",\"createTime\":1585212962000,\"createUser\":1265476890672672808,\"id\":1265476890672672770,\"name\":\"华夏集团成都分公司\",\"pid\":1265476890651701250,\"pids\":\"[0],[1265476890651701250],\",\"remark\":\"华夏集团成都分公司\",\"sort\":100,\"status\":0},{\"code\":\"hxjt\",\"createTime\":1585212653000,\"createUser\":1265476890672672808,\"id\":1265476890651701250,\"name\":\"华夏集团\",\"pid\":0,\"pids\":\"[0],\",\"remark\":\"华夏集团总公司\",\"sort\":100,\"status\":0},{\"code\":\"hxjt_bj_yfb\",\"createTime\":1585212996000,\"createUser\":1265476890672672808,\"id\":1265476890672672771,\"name\":\"研发部\",\"pid\":1265476890672672769,\"pids\":\"[0],[1265476890651701250],[1265476890672672769],\",\"remark\":\"华夏集团北京分公司研发部\",\"sort\":100,\"status\":0},{\"code\":\"hxjt_bj_qhb\",\"createTime\":1585213026000,\"createUser\":1265476890672672808,\"id\":1265476890672672772,\"name\":\"企划部\",\"pid\":1265476890672672769,\"pids\":\"[0],[1265476890651701250],[1265476890672672769],\",\"remark\":\"华夏集团北京分公司企划部\",\"sort\":100,\"status\":0},{\"code\":\"hxjt_cd_scb\",\"createTime\":1585213055000,\"createUser\":1265476890672672808,\"id\":1265476890672672773,\"name\":\"市场部\",\"pid\":1265476890672672770,\"pids\":\"[0],[1265476890651701250],[1265476890672672770],\",\"remark\":\"华夏集团成都分公司市场部\",\"sort\":100,\"status\":0},{\"code\":\"hxjt_cd_cwb\",\"createTime\":1585213081000,\"createUser\":1265476890672672808,\"id\":1265476890672672774,\"name\":\"财务部\",\"pid\":1265476890672672770,\"pids\":\"[0],[1265476890651701250],[1265476890672672770],\",\"remark\":\"华夏集团成都分公司财务部\",\"sort\":100,\"status\":0},{\"code\":\"hxjt_cd_scb_2b\",\"createTime\":1586158610000,\"createUser\":1265476890672672808,\"id\":1265476890672672775,\"name\":\"市场部二部\",\"pid\":1265476890672672773,\"pids\":\"[0],[1265476890651701250],[1265476890672672770],[1265476890672672773],\",\"remark\":\"华夏集团成都分公司市场部二部\",\"sort\":100,\"status\":0}],\"totalPage\":1,\"totalRows\":8},\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:21:36', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333732982429286401', '系统职位_查询', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysPos/page', 'com.cn.xiaonuo.sys.modular.pos.controller.SysPosController', 'page', 'GET', '{}', '{\"code\":200,\"data\":{\"pageNo\":1,\"pageSize\":10,\"rainbow\":[1],\"rows\":[{\"code\":\"zjl\",\"createTime\":1585222134000,\"createUser\":1265476890672672808,\"id\":1265476890672672787,\"name\":\"总经理\",\"remark\":\"总经理职位\",\"sort\":100,\"status\":0,\"updateTime\":1591102864000,\"updateUser\":1265476890672672808},{\"code\":\"fzjl\",\"createTime\":1585222197000,\"createUser\":1265476890672672808,\"id\":1265476890672672788,\"name\":\"副总经理\",\"remark\":\"副总经理职位\",\"sort\":100,\"status\":0},{\"code\":\"bmjl\",\"createTime\":1585222309000,\"createUser\":1265476890672672808,\"id\":1265476890672672789,\"name\":\"部门经理\",\"remark\":\"部门经理职位\",\"sort\":100,\"status\":0},{\"code\":\"gzry\",\"createTime\":1590550320000,\"createUser\":1265476890672672808,\"id\":1265476890672672790,\"name\":\"工作人员\",\"remark\":\"工作人员职位\",\"sort\":100,\"status\":0,\"updateTime\":1590979895000,\"updateUser\":1265476890672672808}],\"totalPage\":1,\"totalRows\":4},\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:21:37', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733263078555649', '系统应用_查询', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysApp/page', 'com.cn.xiaonuo.sys.modular.app.controller.SysAppController', 'page', 'GET', '{}', '{\"code\":200,\"data\":{\"pageNo\":1,\"pageSize\":10,\"rainbow\":[1],\"rows\":[{\"active\":\"Y\",\"code\":\"system\",\"createTime\":1585134420000,\"createUser\":1265476890672672808,\"id\":1265476890672672821,\"name\":\"系统应用\",\"status\":0,\"updateTime\":1597476185000,\"updateUser\":1280709549107552257},{\"active\":\"N\",\"code\":\"office\",\"createTime\":1585813723000,\"createUser\":1265476890672672808,\"id\":1265476890672672823,\"name\":\"在线办公\",\"status\":0,\"updateTime\":1600869615000,\"updateUser\":1265476890672672808},{\"active\":\"N\",\"code\":\"experience\",\"createTime\":1596457520000,\"createUser\":1265476890672672808,\"id\":1290262474351808514,\"name\":\"高级体验\",\"status\":0,\"updateTime\":1597477572000,\"updateUser\":1265476890672672808}],\"totalPage\":1,\"totalRows\":3},\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:22:44', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733263128887297', '系统字典类型_下拉', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysDictType/dropDown', 'com.cn.xiaonuo.sys.modular.dict.controller.SysDictTypeController', 'dropDown', 'GET', '{\"code\":\"common_status\"}', '{\"code\":200,\"data\":[{\"code\":\"0\",\"value\":\"正常\"},{\"code\":\"1\",\"value\":\"停用\"},{\"code\":\"2\",\"value\":\"删除\"}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:22:44', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733263179218945', '系统字典类型_下拉', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysDictType/dropDown', 'com.cn.xiaonuo.sys.modular.dict.controller.SysDictTypeController', 'dropDown', 'GET', '{\"code\":\"yes_or_no\"}', '{\"code\":200,\"data\":[{\"code\":\"N\",\"value\":\"否\"},{\"code\":\"Y\",\"value\":\"是\"}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:22:44', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733286235308033', '系统应用_删除', '2', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysApp/delete', 'com.cn.xiaonuo.sys.modular.app.controller.SysAppController', 'delete', 'POST', '{\"active\":\"N\",\"code\":\"office\",\"id\":1265476890672672823,\"name\":\"在线办公\"}', '{\"code\":200,\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:22:50', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733288328265730', '系统应用_查询', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysApp/page', 'com.cn.xiaonuo.sys.modular.app.controller.SysAppController', 'page', 'GET', '{}', '{\"code\":200,\"data\":{\"pageNo\":1,\"pageSize\":10,\"rainbow\":[1],\"rows\":[{\"active\":\"Y\",\"code\":\"system\",\"createTime\":1585134420000,\"createUser\":1265476890672672808,\"id\":1265476890672672821,\"name\":\"系统应用\",\"status\":0,\"updateTime\":1597476185000,\"updateUser\":1280709549107552257},{\"active\":\"N\",\"code\":\"experience\",\"createTime\":1596457520000,\"createUser\":1265476890672672808,\"id\":1290262474351808514,\"name\":\"高级体验\",\"status\":0,\"updateTime\":1597477572000,\"updateUser\":1265476890672672808}],\"totalPage\":1,\"totalRows\":2},\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:22:50', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733299103432705', '系统应用_删除', '2', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysApp/delete', 'com.cn.xiaonuo.sys.modular.app.controller.SysAppController', 'delete', 'POST', '{\"active\":\"N\",\"code\":\"experience\",\"id\":1290262474351808514,\"name\":\"高级体验\"}', '{\"code\":200,\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:22:53', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733301188001794', '系统应用_查询', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysApp/page', 'com.cn.xiaonuo.sys.modular.app.controller.SysAppController', 'page', 'GET', '{}', '{\"code\":200,\"data\":{\"pageNo\":1,\"pageSize\":10,\"rainbow\":[1],\"rows\":[{\"active\":\"Y\",\"code\":\"system\",\"createTime\":1585134420000,\"createUser\":1265476890672672808,\"id\":1265476890672672821,\"name\":\"系统应用\",\"status\":0,\"updateTime\":1597476185000,\"updateUser\":1280709549107552257}],\"totalPage\":1,\"totalRows\":1},\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:22:53', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733501617012737', '系统菜单_列表', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysMenu/list', 'com.cn.xiaonuo.sys.modular.menu.controller.SysMenuController', 'list', 'GET', '{}', '{\"code\":200,\"data\":[{\"application\":\"system\",\"children\":[{\"application\":\"system\",\"children\":[],\"code\":\"system_index_workplace\",\"component\":\"system/dashboard/Workplace\",\"createTime\":1590344628000,\"createUser\":1265476890672672808,\"id\":1264622039642255331,\"name\":\"工作台\",\"openType\":0,\"pid\":1264622039642255311,\"pids\":\"[0],[1264622039642255311],\",\"router\":\"workplace\",\"sort\":2,\"status\":0,\"type\":1,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"system_index_dashboard\",\"component\":\"system/dashboard/Analysis\",\"createTime\":1590344515000,\"createUser\":1265476890672672808,\"id\":1264622039642255321,\"name\":\"分析页\",\"openType\":0,\"pid\":1264622039642255311,\"pids\":\"[0],[1264622039642255311],\",\"router\":\"analysis\",\"sort\":100,\"status\":0,\"type\":1,\"visible\":\"Y\",\"weight\":1}],\"code\":\"system_index\",\"component\":\"RouteView\",\"createTime\":1590344364000,\"createUser\":1265476890672672808,\"icon\":\"home\",\"id\":1264622039642255311,\"name\":\"主控面板\",\"openType\":0,\"pid\":0,\"pids\":\"[0],\",\"redirect\":\"/analysis\",\"router\":\"/\",\"sort\":1,\"status\":0,\"type\":0,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[{\"application\":\"system\",\"children\":[{\"application\":\"system\",\"children\":[],\"code\":\"sys_user_mgr_page\",\"createTime\":1585298209000,\"createUser\":1265476890672672808,\"id\":1264622039642255361,\"name\":\"用户查询\",\"openType\":0,\"permission\":\"sysUser:page\",\"pid\":1264622039642255351,\"pids\":\"[0],[1264622039642255341],[1264622039642255351],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_user_mgr_edit\",\"createTime\":1593663623000,\"createUser\":1265476890672672808,\"id\":1264622039642255371,\"name\":\"用户编辑\",\"openType\":0,\"permission\":\"sysUser:edit\",\"pid\":1264622039642255351,\"pids\":\"[0],[1264622039642255341],[1264622039642255351],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_user_mgr_add\",\"createTime\":1585298255000,\"createUser\":1265476890672672808,\"id\":1264622039642255381,\"name\":\"用户增加\",\"openType\":0,\"permission\":\"sysUser:add\",\"pid\":1264622039642255351,\"pids\":\"[0],[1264622039642255341],[1264622039642255351],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_user_mgr_delete\",\"createTime\":1585298278000,\"createUser\":1265476890672672808,\"id\":1264622039642255391,\"name\":\"用户删除\",\"openType\":0,\"permission\":\"sysUser:delete\",\"pid\":1264622039642255351,\"pids\":\"[0],[1264622039642255341],[1264622039642255351],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_user_mgr_detail\",\"createTime\":1585298305000,\"createUser\":1265476890672672808,\"id\":1264622039642255401,\"name\":\"用户详情\",\"openType\":0,\"permission\":\"sysUser:detail\",\"pid\":1264622039642255351,\"pids\":\"[0],[1264622039642255341],[1264622039642255351],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_user_mgr_export\",\"createTime\":1593663719000,\"createUser\":1265476890672672808,\"id\":1264622039642255411,\"name\":\"用户导出\",\"openType\":0,\"permission\":\"sysUser:export\",\"pid\":1264622039642255351,\"pids\":\"[0],[1264622039642255341],[1264622039642255351],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_user_mgr_selector\",\"createTime\":1593754214000,\"createUser\":1265476890672672808,\"id\":1264622039642255421,\"name\":\"用户选择器\",\"openType\":0,\"permission\":\"sysUser:selector\",\"pid\":1264622039642255351,\"pids\":\"[0],[1264622039642255341],[1264622039642255351],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_user_mgr_grant_role\",\"createTime\":1585704121000,\"createUser\":1265476890672672808,\"id\":1264622039642255431,\"name\":\"用户授权角色\",\"openType\":0,\"permission\":\"sysUser:grantRole\",\"pid\":1264622039642255351,\"pids\":\"[0],[1264622039642255341],[1264622039642255351],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_user_mgr_own_role\",\"createTime\":1590733642000,\"createUser\":1265476890672672808,\"id\":1264622039642255441,\"name\":\"用户拥有角色\",\"openType\":0,\"permission\":\"sysUser:ownRole\",\"pid\":1264622039642255351,\"pids\":\"[0],[1264622039642255341],[1264622039642255351],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_user_mgr_grant_data\",\"createTime\":1585704133000,\"createUser\":1265476890672672808,\"id\":1264622039642255451,\"name\":\"用户授权数据\",\"openType\":0,\"permission\":\"sysUser:grantData\",\"pid\":1264622039642255351,\"pids\":\"[0],[1264622039642255341],[1264622039642255351],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_user_mgr_own_data\",\"createTime\":1590733661000,\"createUser\":1265476890672672808,\"id\":1264622039642255461,\"name\":\"用户拥有数据\",\"openType\":0,\"permission\":\"sysUser:ownData\",\"pid\":1264622039642255351,\"pids\":\"[0],[1264622039642255341],[1264622039642255351],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_user_mgr_update_info\",\"createTime\":1585729172000,\"createUser\":1265476890672672808,\"id\":1264622039642255471,\"name\":\"用户更新信息\",\"openType\":0,\"permission\":\"sysUser:updateInfo\",\"pid\":1264622039642255351,\"pids\":\"[0],[1264622039642255341],[1264622039642255351],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_user_mgr_update_pwd\",\"createTime\":1585729225000,\"createUser\":1265476890672672808,\"id\":1264622039642255481,\"name\":\"用户修改密码\",\"openType\":0,\"permission\":\"sysUser:updatePwd\",\"pid\":1264622039642255351,\"pids\":\"[0],[1264622039642255341],[1264622039642255351],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_user_mgr_change_status\",\"createTime\":1592881994000,\"createUser\":1265476890672672808,\"id\":1264622039642255491,\"name\":\"用户修改状态\",\"openType\":0,\"permission\":\"sysUser:changeStatus\",\"pid\":1264622039642255351,\"pids\":\"[0],[1264622039642255341],[1264622039642255351],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_user_mgr_update_avatar\",\"createTime\":1593663702000,\"createUser\":1265476890672672808,\"id\":1264622039642255501,\"name\":\"用户修改头像\",\"openType\":0,\"permission\":\"sysUser:updateAvatar\",\"pid\":1264622039642255351,\"pids\":\"[0],[1264622039642255341],[1264622039642255351],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_user_mgr_reset_pwd\",\"createTime\":1590735711000,\"createUser\":1265476890672672808,\"id\":1264622039642255511,\"name\":\"用户重置密码\",\"openType\":0,\"permission\":\"sysUser:resetPwd\",\"pid\":1264622039642255351,\"pids\":\"[0],[1264622039642255341],[1264622039642255351],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1}],\"code\":\"sys_user_mgr\",\"component\":\"system/user/index\",\"createTime\":1585296621000,\"createUser\":1265476890672672808,\"id\":1264622039642255351,\"name\":\"用户管理\",\"openType\":1,\"pid\":1264622039642255341,\"pids\":\"[0],[1264622039642255341],\",\"router\":\"/mgr_user\",\"sort\":3,\"status\":0,\"type\":1,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[{\"application\":\"system\",\"children\":[],\"code\":\"sys_org_mgr_page\",\"createTime\":1585300657000,\"createUser\":1265476890672672808,\"id\":1264622039642255531,\"name\":\"机构查询\",\"openType\":0,\"permission\":\"sysOrg:page\",\"pid\":1264622039642255521,\"pids\":\"[0],[1264622039642255341],[1264622039642255521]\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_org_mgr_list\",\"createTime\":1593662066000,\"createUser\":1265476890672672808,\"id\":1264622039642255541,\"name\":\"机构列表\",\"openType\":0,\"permission\":\"sysOrg:list\",\"pid\":1264622039642255521,\"pids\":\"[0],[1264622039642255341],[1264622039642255521]\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_org_mgr_add\",\"createTime\":1585300793000,\"createUser\":1265476890672672808,\"id\":1264622039642255551,\"name\":\"机构增加\",\"openType\":0,\"permission\":\"sysOrg:add\",\"pid\":1264622039642255521,\"pids\":\"[0],[1264622039642255341],[1264622039642255521]\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_org_mgr_edit\",\"createTime\":1593662077000,\"createUser\":1265476890672672808,\"id\":1264622039642255561,\"name\":\"机构编辑\",\"openType\":0,\"permission\":\"sysOrg:edit\",\"pid\":1264622039642255521,\"pids\":\"[0],[1264622039642255341],[1264622039642255521]\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_org_mgr_delete\",\"createTime\":1585300848000,\"createUser\":1265476890672672808,\"id\":1264622039642255571,\"name\":\"机构删除\",\"openType\":0,\"permission\":\"sysOrg:delete\",\"pid\":1264622039642255521,\"pids\":\"[0],[1264622039642255341],[1264622039642255521]\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_org_mgr_detail\",\"createTime\":1585300875000,\"createUser\":1265476890672672808,\"id\":1264622039642255581,\"name\":\"机构详情\",\"openType\":0,\"permission\":\"sysOrg:detail\",\"pid\":1264622039642255521,\"pids\":\"[0],[1264622039642255341],[1264622039642255521]\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_org_mgr_tree\",\"createTime\":1585300918000,\"createUser\":1265476890672672808,\"id\":1264622039642255591,\"name\":\"机构树\",\"openType\":0,\"permission\":\"sysOrg:tree\",\"pid\":1264622039642255521,\"pids\":\"[0],[1264622039642255341],[1264622039642255521]\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1}],\"code\":\"sys_org_mgr\",\"component\":\"system/org/index\",\"createTime\":1585300539000,\"createUser\":1265476890672672808,\"id\":1264622039642255521,\"name\":\"机构管理\",\"openType\":1,\"pid\":1264622039642255341,\"pids\":\"[0],[1264622039642255341],\",\"router\":\"/org\",\"sort\":4,\"status\":0,\"type\":1,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[{\"application\":\"system\",\"children\":[],\"code\":\"sys_pos_mgr_list\",\"createTime\":1593662157000,\"createUser\":1265476890672672808,\"id\":1264622039642255621,\"name\":\"职位列表\",\"openType\":0,\"permission\":\"sysPos:list\",\"pid\":1264622039642255601,\"pids\":\"[0],[1264622039642255341],[1264622039642255601],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_pos_mgr_add\",\"createTime\":1585305740000,\"createUser\":1265476890672672808,\"id\":1264622039642255631,\"name\":\"职位增加\",\"openType\":0,\"permission\":\"sysPos:add\",\"pid\":1264622039642255601,\"pids\":\"[0],[1264622039642255341],[1264622039642255601],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_pos_mgr_edit\",\"createTime\":1593662168000,\"createUser\":1265476890672672808,\"id\":1264622039642255641,\"name\":\"职位编辑\",\"openType\":0,\"permission\":\"sysPos:edit\",\"pid\":1264622039642255601,\"pids\":\"[0],[1264622039642255341],[1264622039642255601],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_pos_mgr_delete\",\"createTime\":1585305759000,\"createUser\":1265476890672672808,\"id\":1264622039642255651,\"name\":\"职位删除\",\"openType\":0,\"permission\":\"sysPos:delete\",\"pid\":1264622039642255601,\"pids\":\"[0],[1264622039642255341],[1264622039642255601],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_pos_mgr_detail\",\"createTime\":1585305780000,\"createUser\":1265476890672672808,\"id\":1264622039642255661,\"name\":\"职位详情\",\"openType\":0,\"permission\":\"sysPos:detail\",\"pid\":1264622039642255601,\"pids\":\"[0],[1264622039642255341],[1264622039642255601],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_pos_mgr_page\",\"createTime\":1585305708000,\"createUser\":1265476890672672808,\"id\":1264622039642255611,\"name\":\"职位查询\",\"openType\":0,\"permission\":\"sysPos:page\",\"pid\":1264622039642255601,\"pids\":\"[0],[1264622039642255341],[1264622039642255601],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1}],\"code\":\"sys_pos_mgr\",\"component\":\"system/pos/index\",\"createTime\":1585305511000,\"createUser\":1265476890672672808,\"id\":1264622039642255601,\"name\":\"职位管理\",\"openType\":1,\"pid\":1264622039642255341,\"pids\":\"[0],[1264622039642255341],\",\"router\":\"/pos\",\"sort\":5,\"status\":0,\"type\":1,\"visible\":\"Y\",\"weight\":1}],\"code\":\"sys_mgr\",\"component\":\"PageView\",\"createTime\":1585295896000,\"createUser\":1265476890672672808,\"icon\":\"team\",\"id\":1264622039642255341,\"name\":\"组织架构\",\"openType\":0,\"pid\":0,\"pids\":\"[0],\",\"router\":\"/sys\",\"sort\":2,\"status\":0,\"type\":0,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[{\"application\":\"system\",\"children\":[{\"application\":\"system\",\"children\":[],\"code\":\"sys_app_mgr_page\",\"createTime\":1585298518000,\"createUser\":1265476890672672808,\"id\":1264622039642255691,\"name\":\"应用查询\",\"openType\":0,\"permission\":\"sysApp:page\",\"pid\":1264622039642255681,\"pids\":\"[0],[1264622039642255671],[1264622039642255681],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_app_mgr_list\",\"createTime\":1593655499000,\"createUser\":1265476890672672808,\"id\":1264622039642255701,\"name\":\"应用列表\",\"openType\":0,\"permission\":\"sysApp:list\",\"pid\":1264622039642255681,\"pids\":\"[0],[1264622039642255671],[1264622039642255681],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_app_mgr_add\",\"createTime\":1585298650000,\"createUser\":1265476890672672808,\"id\":1264622039642255711,\"name\":\"应用增加\",\"openType\":0,\"permission\":\"sysApp:add\",\"pid\":1264622039642255681,\"pids\":\"[0],[1264622039642255671],[1264622039642255681],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_app_mgr_edit\",\"createTime\":1593655474000,\"createUser\":1265476890672672808,\"id\":1264622039642255721,\"name\":\"应用编辑\",\"openType\":0,\"permission\":\"sysApp:edit\",\"pid\":1264622039642255681,\"pids\":\"[0],[1264622039642255671],[1264622039642255681],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_app_mgr_delete\",\"createTime\":1585300469000,\"createUser\":1265476890672672808,\"id\":1264622039642255731,\"name\":\"应用删除\",\"openType\":0,\"permission\":\"sysApp:delete\",\"pid\":1264622039642255681,\"pids\":\"[0],[1264622039642255671],[1264622039642255681],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_app_mgr_detail\",\"createTime\":1585300496000,\"createUser\":1265476890672672808,\"id\":1264622039642255741,\"name\":\"应用详情\",\"openType\":0,\"permission\":\"sysApp:detail\",\"pid\":1264622039642255681,\"pids\":\"[0],[1264622039642255671],[1264622039642255681],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_app_mgr_set_as_default\",\"createTime\":1585300496000,\"createUser\":1265476890672672808,\"id\":1264622039642255751,\"name\":\"设为默认应用\",\"openType\":0,\"permission\":\"sysApp:setAsDefault\",\"pid\":1264622039642255681,\"pids\":\"[0],[1264622039642255671],[1264622039642255681],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1}],\"code\":\"sys_app_mgr\",\"component\":\"system/app/index\",\"createTime\":1585298421000,\"createUser\":1265476890672672808,\"id\":1264622039642255681,\"name\":\"应用管理\",\"openType\":1,\"pid\":1264622039642255671,\"pids\":\"[0],[1264622039642255671],\",\"router\":\"/app\",\"sort\":6,\"status\":0,\"type\":1,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[{\"application\":\"system\",\"children\":[],\"code\":\"sys_menu_mgr_list\",\"createTime\":1585305920000,\"createUser\":1265476890672672808,\"id\":1264622039642255771,\"name\":\"菜单列表\",\"openType\":0,\"permission\":\"sysMenu:list\",\"pid\":1264622039642255761,\"pids\":\"[0],[1264622039642255671],[1264622039642255761],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_menu_mgr_add\",\"createTime\":1585305937000,\"createUser\":1265476890672672808,\"id\":1264622039642255781,\"name\":\"菜单增加\",\"openType\":0,\"permission\":\"sysMenu:add\",\"pid\":1264622039642255761,\"pids\":\"[0],[1264622039642255671],[1264622039642255761],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_menu_mgr_edit\",\"createTime\":1593661920000,\"createUser\":1265476890672672808,\"id\":1264622039642255791,\"name\":\"菜单编辑\",\"openType\":0,\"permission\":\"sysMenu:edit\",\"pid\":1264622039642255761,\"pids\":\"[0],[1264622039642255671],[1264622039642255761],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_menu_mgr_delete\",\"createTime\":1585305961000,\"createUser\":1265476890672672808,\"id\":1264622039642255801,\"name\":\"菜单删除\",\"openType\":0,\"permission\":\"sysMenu:delete\",\"pid\":1264622039642255761,\"pids\":\"[0],[1264622039642255671],[1264622039642255761],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_menu_mgr_detail\",\"createTime\":1585305982000,\"createUser\":1265476890672672808,\"id\":1264622039642255811,\"name\":\"菜单详情\",\"openType\":0,\"permission\":\"sysMenu:detail\",\"pid\":1264622039642255761,\"pids\":\"[0],[1264622039642255671],[1264622039642255761],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_menu_mgr_grant_tree\",\"createTime\":1591149031000,\"createUser\":1265476890672672808,\"id\":1264622039642255821,\"name\":\"菜单授权树\",\"openType\":0,\"permission\":\"sysMenu:treeForGrant\",\"pid\":1264622039642255761,\"pids\":\"[0],[1264622039642255671],[1264622039642255761],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_menu_mgr_tree\",\"createTime\":1585306070000,\"createUser\":1265476890672672808,\"id\":1264622039642255831,\"name\":\"菜单树\",\"openType\":0,\"permission\":\"sysMenu:tree\",\"pid\":1264622039642255761,\"pids\":\"[0],[1264622039642255671],[1264622039642255761],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_menu_mgr_change\",\"createTime\":1591149103000,\"createUser\":1265476890672672808,\"id\":1264622039642255841,\"name\":\"菜单切换\",\"openType\":0,\"permission\":\"sysMenu:change\",\"pid\":1264622039642255761,\"pids\":\"[0],[1264622039642255671],[1264622039642255761],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1}],\"code\":\"sys_menu_mgr\",\"component\":\"system/menu/index\",\"createTime\":1585305875000,\"createUser\":1265476890672672808,\"id\":1264622039642255761,\"name\":\"菜单管理\",\"openType\":1,\"pid\":1264622039642255671,\"pids\":\"[0],[1264622039642255671],\",\"router\":\"/menu\",\"sort\":7,\"status\":0,\"type\":1,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[{\"application\":\"system\",\"children\":[],\"code\":\"sys_role_mgr_edit\",\"createTime\":1593662247000,\"createUser\":1265476890672672808,\"id\":1264622039642255881,\"name\":\"角色编辑\",\"openType\":0,\"permission\":\"sysRole:edit\",\"pid\":1264622039642255851,\"pids\":\"[0],[1264622039642255671],[1264622039642255851],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_role_mgr_delete\",\"createTime\":1585382566000,\"createUser\":1265476890672672808,\"id\":1264622039642255891,\"name\":\"角色删除\",\"openType\":0,\"permission\":\"sysRole:delete\",\"pid\":1264622039642255851,\"pids\":\"[0],[1264622039642255671],[1264622039642255851],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_role_mgr_detail\",\"createTime\":1585382581000,\"createUser\":1265476890672672808,\"id\":1264622039642255901,\"name\":\"角色详情\",\"openType\":0,\"permission\":\"sysRole:detail\",\"pid\":1264622039642255851,\"pids\":\"[0],[1264622039642255671],[1264622039642255851],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_role_mgr_drop_down\",\"createTime\":1590738339000,\"createUser\":1265476890672672808,\"id\":1264622039642255911,\"name\":\"角色下拉\",\"openType\":0,\"permission\":\"sysRole:dropDown\",\"pid\":1264622039642255851,\"pids\":\"[0],[1264622039642255671],[1264622039642255851],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_role_mgr_grant_menu\",\"createTime\":1585703787000,\"createUser\":1265476890672672808,\"id\":1264622039642255921,\"name\":\"角色授权菜单\",\"openType\":0,\"permission\":\"sysRole:grantMenu\",\"pid\":1264622039642255851,\"pids\":\"[0],[1264622039642255671],[1264622039642255851],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_role_mgr_own_menu\",\"createTime\":1590733314000,\"createUser\":1265476890672672808,\"id\":1264622039642255931,\"name\":\"角色拥有菜单\",\"openType\":0,\"permission\":\"sysRole:ownMenu\",\"pid\":1264622039642255851,\"pids\":\"[0],[1264622039642255671],[1264622039642255851],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_role_mgr_grant_data\",\"createTime\":1585703816000,\"createUser\":1265476890672672808,\"id\":1264622039642255941,\"name\":\"角色授权数据\",\"openType\":0,\"permission\":\"sysRole:grantData\",\"pid\":1264622039642255851,\"pids\":\"[0],[1264622039642255671],[1264622039642255851],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_role_mgr_own_data\",\"createTime\":1590733388000,\"createUser\":1265476890672672808,\"id\":1264622039642255951,\"name\":\"角色拥有数据\",\"openType\":0,\"permission\":\"sysRole:ownData\",\"pid\":1264622039642255851,\"pids\":\"[0],[1264622039642255671],[1264622039642255851],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_role_mgr_page\",\"createTime\":1585382529000,\"createUser\":1265476890672672808,\"id\":1264622039642255861,\"name\":\"角色查询\",\"openType\":0,\"permission\":\"sysRole:page\",\"pid\":1264622039642255851,\"pids\":\"[0],[1264622039642255671],[1264622039642255851],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_role_mgr_add\",\"createTime\":1585382547000,\"createUser\":1265476890672672808,\"id\":1264622039642255871,\"name\":\"角色增加\",\"openType\":0,\"permission\":\"sysRole:add\",\"pid\":1264622039642255851,\"pids\":\"[0],[1264622039642255671],[1264622039642255851],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1}],\"code\":\"sys_role_mgr\",\"component\":\"system/role/index\",\"createTime\":1585382469000,\"createUser\":1265476890672672808,\"id\":1264622039642255851,\"name\":\"角色管理\",\"openType\":1,\"pid\":1264622039642255671,\"pids\":\"[0],[1264622039642255671],\",\"router\":\"/role\",\"sort\":8,\"status\":0,\"type\":1,\"visible\":\"Y\",\"weight\":1}],\"code\":\"auth_manager\",\"component\":\"PageView\",\"createTime\":1594799517000,\"createUser\":1265476890672672808,\"icon\":\"safety-certificate\",\"id\":1264622039642255671,\"name\":\"权限管理\",\"openType\":0,\"pid\":0,\"pids\":\"[0],\",\"router\":\"/auth\",\"sort\":3,\"status\":0,\"type\":0,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[{\"application\":\"system\",\"children\":[{\"application\":\"system\",\"children\":[],\"code\":\"system_tools_config_page\",\"createTime\":1590570142000,\"createUser\":1265476890672672808,\"id\":1264622039642255981,\"name\":\"配置查询\",\"openType\":0,\"permission\":\"sysConfig:page\",\"pid\":1264622039642255971,\"pids\":\"[0],[1264622039642255961],[1264622039642255971],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"system_tools_config_list\",\"createTime\":1590570162000,\"createUser\":1265476890672672808,\"id\":1264622039642255991,\"name\":\"配置列表\",\"openType\":0,\"permission\":\"sysConfig:list\",\"pid\":1264622039642255971,\"pids\":\"[0],[1264622039642255961],[1264622039642255971],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"system_tools_config_add\",\"createTime\":1590570211000,\"createUser\":1265476890672672808,\"id\":1264622039642256001,\"name\":\"配置增加\",\"openType\":0,\"permission\":\"sysConfig:add\",\"pid\":1264622039642255971,\"pids\":\"[0],[1264622039642255961],[1264622039642255971],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"system_tools_config_edit\",\"createTime\":1590570235000,\"createUser\":1265476890672672808,\"id\":1264622039642256011,\"name\":\"配置编辑\",\"openType\":0,\"permission\":\"sysConfig:edit\",\"pid\":1264622039642255971,\"pids\":\"[0],[1264622039642255961],[1264622039642255971],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"system_tools_config_delete\",\"createTime\":1590570224000,\"createUser\":1265476890672672808,\"id\":1264622039642256021,\"name\":\"配置删除\",\"openType\":0,\"permission\":\"sysConfig:delete\",\"pid\":1264622039642255971,\"pids\":\"[0],[1264622039642255961],[1264622039642255971],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"system_tools_config_detail\",\"createTime\":1590570179000,\"createUser\":1265476890672672808,\"id\":1264622039642256031,\"name\":\"配置详情\",\"openType\":0,\"permission\":\"sysConfig:detail\",\"pid\":1264622039642255971,\"pids\":\"[0],[1264622039642255961],[1264622039642255971],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1}],\"code\":\"system_tools_config\",\"component\":\"system/config/index\",\"createTime\":1590343976000,\"createUser\":1265476890672672808,\"id\":1264622039642255971,\"name\":\"系统配置\",\"openType\":1,\"pid\":1264622039642255961,\"pids\":\"[0],[1264622039642255961],\",\"router\":\"/config\",\"sort\":9,\"status\":0,\"type\":1,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[{\"application\":\"system\",\"children\":[],\"code\":\"sys_email_mgr_send_email\",\"createTime\":1593661539000,\"createUser\":1265476890672672808,\"id\":1264622039642256051,\"name\":\"发送文本邮件\",\"openType\":0,\"permission\":\"email:sendEmail\",\"pid\":1264622039642256041,\"pids\":\"[0],[1264622039642255961],[1264622039642256041],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_email_mgr_send_email_html\",\"createTime\":1593661557000,\"createUser\":1265476890672672808,\"id\":1264622039642256061,\"name\":\"发送html邮件\",\"openType\":0,\"permission\":\"email:sendEmailHtml\",\"pid\":1264622039642256041,\"pids\":\"[0],[1264622039642255961],[1264622039642256041],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1}],\"code\":\"sys_email_mgr\",\"component\":\"system/email/index\",\"createTime\":1593661461000,\"createUser\":1265476890672672808,\"id\":1264622039642256041,\"name\":\"邮件发送\",\"openType\":1,\"pid\":1264622039642255961,\"pids\":\"[0],[1264622039642255961],\",\"router\":\"/email\",\"sort\":10,\"status\":0,\"type\":1,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[{\"application\":\"system\",\"children\":[],\"code\":\"sys_sms_mgr_page\",\"createTime\":1593663416000,\"createUser\":1265476890672672808,\"id\":1264622039642256081,\"name\":\"短信发送查询\",\"openType\":0,\"permission\":\"sms:page\",\"pid\":1264622039642256071,\"pids\":\"[0],[1264622039642255961],[1264622039642256071],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_sms_mgr_send_login_message\",\"createTime\":1593662551000,\"createUser\":1265476890672672808,\"id\":1264622039642256091,\"name\":\"发送验证码短信\",\"openType\":0,\"permission\":\"sms:sendLoginMessage\",\"pid\":1264622039642256071,\"pids\":\"[0],[1264622039642255961],[1264622039642256071],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_sms_mgr_validate_message\",\"createTime\":1593662570000,\"createUser\":1265476890672672808,\"id\":1264622039642256101,\"name\":\"验证短信验证码\",\"openType\":0,\"permission\":\"sms:validateMessage\",\"pid\":1264622039642256071,\"pids\":\"[0],[1264622039642255961],[1264622039642256071],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1}],\"code\":\"sys_sms_mgr\",\"component\":\"system/sms/index\",\"createTime\":1593662412000,\"createUser\":1265476890672672808,\"id\":1264622039642256071,\"name\":\"短信管理\",\"openType\":1,\"pid\":1264622039642255961,\"pids\":\"[0],[1264622039642255961],\",\"router\":\"/sms\",\"sort\":11,\"status\":0,\"type\":1,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[{\"application\":\"system\",\"children\":[],\"code\":\"sys_dict_mgr_dict_type_list\",\"createTime\":1590736355000,\"createUser\":1265476890672672808,\"id\":1264622039642256131,\"name\":\"字典类型列表\",\"openType\":0,\"permission\":\"sysDictType:list\",\"pid\":1264622039642256111,\"pids\":\"[0],[1264622039642255961],[1264622039642256111],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_dict_mgr_dict_type_add\",\"createTime\":1585711198000,\"createUser\":1265476890672672808,\"id\":1264622039642256141,\"name\":\"字典类型增加\",\"openType\":0,\"permission\":\"sysDictType:add\",\"pid\":1264622039642256111,\"pids\":\"[0],[1264622039642255961],[1264622039642256111],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_dict_mgr_dict_type_delete\",\"createTime\":1585711290000,\"createUser\":1265476890672672808,\"id\":1264622039642256151,\"name\":\"字典类型删除\",\"openType\":0,\"permission\":\"sysDictType:delete\",\"pid\":1264622039642256111,\"pids\":\"[0],[1264622039642255961],[1264622039642256111],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_dict_mgr_dict_type_edit\",\"createTime\":1585711302000,\"createUser\":1265476890672672808,\"id\":1264622039642256161,\"name\":\"字典类型编辑\",\"openType\":0,\"permission\":\"sysDictType:edit\",\"pid\":1264622039642256111,\"pids\":\"[0],[1264622039642255961],[1264622039642256111],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_dict_mgr_dict_type_detail\",\"createTime\":1585711326000,\"createUser\":1265476890672672808,\"id\":1264622039642256171,\"name\":\"字典类型详情\",\"openType\":0,\"permission\":\"sysDictType:detail\",\"pid\":1264622039642256111,\"pids\":\"[0],[1264622039642255961],[1264622039642256111],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_dict_mgr_dict_type_drop_down\",\"createTime\":1585711343000,\"createUser\":1265476890672672808,\"id\":1264622039642256181,\"name\":\"字典类型下拉\",\"openType\":0,\"permission\":\"sysDictType:dropDown\",\"pid\":1264622039642256111,\"pids\":\"[0],[1264622039642255961],[1264622039642256111],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_dict_mgr_dict_type_change_status\",\"createTime\":1592882150000,\"createUser\":1265476890672672808,\"id\":1264622039642256191,\"name\":\"字典类型修改状态\",\"openType\":0,\"permission\":\"sysDictType:changeStatus\",\"pid\":1264622039642256111,\"pids\":\"[0],[1264622039642255961],[1264622039642256111],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_dict_mgr_dict_page\",\"createTime\":1585711391000,\"createUser\":1265476890672672808,\"id\":1264622039642256201,\"name\":\"字典值查询\",\"openType\":0,\"permission\":\"sysDictData:page\",\"pid\":1264622039642256111,\"pids\":\"[0],[1264622039642255961],[1264622039642256111],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_dict_mgr_dict_list\",\"createTime\":1585711498000,\"createUser\":1265476890672672808,\"id\":1264622039642256211,\"name\":\"字典值列表\",\"openType\":0,\"permission\":\"sysDictData:list\",\"pid\":1264622039642256111,\"pids\":\"[0],[1264622039642255961],[1264622039642256111],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_dict_mgr_dict_add\",\"createTime\":1585711371000,\"createUser\":1265476890672672808,\"id\":1264622039642256221,\"name\":\"字典值增加\",\"openType\":0,\"permission\":\"sysDictData:add\",\"pid\":1264622039642256111,\"pids\":\"[0],[1264622039642255961],[1264622039642256111],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_dict_mgr_dict_delete\",\"createTime\":1585711406000,\"createUser\":1265476890672672808,\"id\":1264622039642256231,\"name\":\"字典值删除\",\"openType\":0,\"permission\":\"sysDictData:delete\",\"pid\":1264622039642256111,\"pids\":\"[0],[1264622039642255961],[1264622039642256111],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_dict_mgr_dict_edit\",\"createTime\":1585711461000,\"createUser\":1265476890672672808,\"id\":1264622039642256241,\"name\":\"字典值编辑\",\"openType\":0,\"permission\":\"sysDictData:edit\",\"pid\":1264622039642256111,\"pids\":\"[0],[1264622039642255961],[1264622039642256111],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_dict_mgr_dict_detail\",\"createTime\":1585711482000,\"createUser\":1265476890672672808,\"id\":1264622039642256251,\"name\":\"字典值详情\",\"openType\":0,\"permission\":\"sysDictData:detail\",\"pid\":1264622039642256111,\"pids\":\"[0],[1264622039642255961],[1264622039642256111],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_dict_mgr_dict_change_status\",\"createTime\":1592882273000,\"createUser\":1265476890672672808,\"id\":1264622039642256261,\"name\":\"字典值修改状态\",\"openType\":0,\"permission\":\"sysDictData:changeStatus\",\"pid\":1264622039642256111,\"pids\":\"[0],[1264622039642255961],[1264622039642256111],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_dict_mgr_dict_type_page\",\"createTime\":1585711222000,\"createUser\":1265476890672672808,\"id\":1264622039642256121,\"name\":\"字典类型查询\",\"openType\":0,\"permission\":\"sysDictType:page\",\"pid\":1264622039642256111,\"pids\":\"[0],[1264622039642255961],[1264622039642256111],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1}],\"code\":\"sys_dict_mgr\",\"component\":\"system/dict/index\",\"createTime\":1585711046000,\"createUser\":1265476890672672808,\"id\":1264622039642256111,\"name\":\"字典管理\",\"openType\":1,\"pid\":1264622039642255961,\"pids\":\"[0],[1264622039642255961],\",\"router\":\"/dict\",\"sort\":12,\"status\":0,\"type\":1,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_swagger_mgr\",\"component\":\"Iframe\",\"createTime\":1593663416000,\"createUser\":1265476890672672808,\"id\":1264622039642256271,\"link\":\"http://localhost:82/doc.html\",\"name\":\"接口文档\",\"openType\":2,\"pid\":1264622039642255961,\"pids\":\"[0],[1264622039642255961],\",\"router\":\"/swagger\",\"sort\":13,\"status\":0,\"type\":1,\"visible\":\"Y\",\"weight\":1}],\"code\":\"system_tools\",\"component\":\"PageView\",\"createTime\":1590343855000,\"createUser\":1265476890672672808,\"icon\":\"euro\",\"id\":1264622039642255961,\"name\":\"开发管理\",\"openType\":1,\"pid\":0,\"pids\":\"[0],\",\"router\":\"/tools\",\"sort\":4,\"status\":0,\"type\":0,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[{\"application\":\"system\",\"children\":[{\"application\":\"system\",\"children\":[],\"code\":\"sys_log_mgr_vis_log_page\",\"createTime\":1593654951000,\"createUser\":1265476890672672808,\"id\":1264622039642256301,\"name\":\"访问日志查询\",\"openType\":0,\"permission\":\"sysVisLog:page\",\"pid\":1264622039642256291,\"pids\":\"[0],[1264622039642256281],[1264622039642256291],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_log_mgr_vis_log_delete\",\"createTime\":1593655017000,\"createUser\":1265476890672672808,\"id\":1264622039642256311,\"name\":\"访问日志清空\",\"openType\":0,\"permission\":\"sysVisLog:delete\",\"pid\":1264622039642256291,\"pids\":\"[0],[1264622039642256281],[1264622039642256291],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1}],\"code\":\"sys_log_mgr_vis_log\",\"component\":\"system/log/vislog/index\",\"createTime\":1585704400000,\"createUser\":1265476890672672808,\"id\":1264622039642256291,\"name\":\"访问日志\",\"openType\":0,\"pid\":1264622039642256281,\"pids\":\"[0],[1264622039642256281],\",\"router\":\"/vislog\",\"sort\":14,\"status\":0,\"type\":1,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[{\"application\":\"system\",\"children\":[],\"code\":\"sys_log_mgr_op_log_page\",\"createTime\":1593655059000,\"createUser\":1265476890672672808,\"id\":1264622039642256331,\"name\":\"操作日志查询\",\"openType\":0,\"permission\":\"sysOpLog:page\",\"pid\":1264622039642256321,\"pids\":\"[0],[1264622039642256281],[1264622039642256321],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_log_mgr_op_log_delete\",\"createTime\":1593655093000,\"createUser\":1265476890672672808,\"id\":1264622039642256341,\"name\":\"操作日志清空\",\"openType\":0,\"permission\":\"sysOpLog:delete\",\"pid\":1264622039642256321,\"pids\":\"[0],[1264622039642256281],[1264622039642256321],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1}],\"code\":\"sys_log_mgr_op_log\",\"component\":\"system/log/oplog/index\",\"createTime\":1585704419000,\"createUser\":1265476890672672808,\"id\":1264622039642256321,\"name\":\"操作日志\",\"openType\":0,\"pid\":1264622039642256281,\"pids\":\"[0],[1264622039642256281],\",\"router\":\"/oplog\",\"sort\":15,\"status\":0,\"type\":1,\"visible\":\"Y\",\"weight\":1}],\"code\":\"sys_log_mgr\",\"component\":\"PageView\",\"createTime\":1585704301000,\"createUser\":1265476890672672808,\"icon\":\"read\",\"id\":1264622039642256281,\"name\":\"日志管理\",\"openType\":1,\"pid\":0,\"pids\":\"[0],\",\"router\":\"/log\",\"sort\":5,\"status\":0,\"type\":0,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[{\"application\":\"system\",\"children\":[{\"application\":\"system\",\"children\":[],\"code\":\"sys_monitor_mgr_machine_monitor_query\",\"createTime\":1591344333000,\"createUser\":1265476890672672808,\"id\":1264622039642256371,\"name\":\"服务监控查询\",\"openType\":0,\"permission\":\"sysMachine:query\",\"pid\":1264622039642256361,\"pids\":\"[0],[1264622039642256351],[1264622039642256361],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1}],\"code\":\"sys_monitor_mgr_machine_monitor\",\"component\":\"system/machine/index\",\"createTime\":1591344158000,\"createUser\":1265476890672672808,\"id\":1264622039642256361,\"name\":\"服务监控\",\"openType\":1,\"pid\":1264622039642256351,\"pids\":\"[0],[1264622039642256351],\",\"router\":\"/machine\",\"sort\":16,\"status\":0,\"type\":1,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[{\"application\":\"system\",\"children\":[],\"code\":\"sys_monitor_mgr_online_user_list\",\"createTime\":1591344226000,\"createUser\":1265476890672672808,\"id\":1264622039642256391,\"name\":\"在线用户列表\",\"openType\":0,\"permission\":\"sysOnlineUser:list\",\"pid\":1264622039642256381,\"pids\":\"[0],[1264622039642256351],[1264622039642256381],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_monitor_mgr_online_user_force_exist\",\"createTime\":1591344256000,\"createUser\":1265476890672672808,\"id\":1264622039642256401,\"name\":\"在线用户强退\",\"openType\":0,\"permission\":\"sysOnlineUser:forceExist\",\"pid\":1264622039642256381,\"pids\":\"[0],[1264622039642256351],[1264622039642256381],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1}],\"code\":\"sys_monitor_mgr_online_user\",\"component\":\"system/onlineUser/index\",\"createTime\":1591344115000,\"createUser\":1265476890672672808,\"id\":1264622039642256381,\"name\":\"在线用户\",\"openType\":1,\"pid\":1264622039642256351,\"pids\":\"[0],[1264622039642256351],\",\"router\":\"/onlineUser\",\"sort\":17,\"status\":0,\"type\":1,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_monitor_mgr_druid\",\"component\":\"Iframe\",\"createTime\":1593332107000,\"createUser\":1265476890672672808,\"id\":1264622039642256411,\"link\":\"http://localhost:82/druid/login.html\",\"name\":\"数据监控\",\"openType\":2,\"pid\":1264622039642256351,\"pids\":\"[0],[1264622039642256351],\",\"router\":\"/druid\",\"sort\":18,\"status\":0,\"type\":1,\"updateTime\":1599961150000,\"updateUser\":1265476890672672808,\"visible\":\"Y\",\"weight\":1}],\"code\":\"sys_monitor_mgr\",\"component\":\"PageView\",\"createTime\":1591344050000,\"createUser\":1265476890672672808,\"icon\":\"deployment-unit\",\"id\":1264622039642256351,\"name\":\"系统监控\",\"openType\":1,\"pid\":0,\"pids\":\"[0],\",\"router\":\"/monitor\",\"sort\":6,\"status\":0,\"type\":0,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[{\"application\":\"system\",\"children\":[{\"application\":\"system\",\"children\":[],\"code\":\"sys_notice_mgr_page\",\"createTime\":1593416730000,\"createUser\":1265476890672672808,\"id\":1264622039642256441,\"name\":\"公告查询\",\"openType\":0,\"permission\":\"sysNotice:page\",\"pid\":1264622039642256431,\"pids\":\"[0],[1264622039642256421],[1264622039642256431],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_notice_mgr_add\",\"createTime\":1593416757000,\"createUser\":1265476890672672808,\"id\":1264622039642256451,\"name\":\"公告增加\",\"openType\":0,\"permission\":\"sysNotice:add\",\"pid\":1264622039642256431,\"pids\":\"[0],[1264622039642256421],[1264622039642256431],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_notice_mgr_edit\",\"createTime\":1593416782000,\"createUser\":1265476890672672808,\"id\":1264622039642256461,\"name\":\"公告编辑\",\"openType\":0,\"permission\":\"sysNotice:edit\",\"pid\":1264622039642256431,\"pids\":\"[0],[1264622039642256421],[1264622039642256431],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_notice_mgr_delete\",\"createTime\":1593416771000,\"createUser\":1265476890672672808,\"id\":1264622039642256471,\"name\":\"公告删除\",\"openType\":0,\"permission\":\"sysNotice:delete\",\"pid\":1264622039642256431,\"pids\":\"[0],[1264622039642256421],[1264622039642256431],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_notice_mgr_detail\",\"createTime\":1593416793000,\"createUser\":1265476890672672808,\"id\":1264622039642256481,\"name\":\"公告查看\",\"openType\":0,\"permission\":\"sysNotice:detail\",\"pid\":1264622039642256431,\"pids\":\"[0],[1264622039642256421],[1264622039642256431],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_notice_mgr_changeStatus\",\"createTime\":1593416810000,\"createUser\":1265476890672672808,\"id\":1264622039642256491,\"name\":\"公告修改状态\",\"openType\":0,\"permission\":\"sysNotice:changeStatus\",\"pid\":1264622039642256431,\"pids\":\"[0],[1264622039642256421],[1264622039642256431],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1}],\"code\":\"sys_notice_mgr\",\"component\":\"system/notice/index\",\"createTime\":1593416664000,\"createUser\":1265476890672672808,\"id\":1264622039642256431,\"name\":\"公告管理\",\"openType\":1,\"pid\":1264622039642256421,\"pids\":\"[0],[1264622039642256421],\",\"router\":\"/notice\",\"sort\":19,\"status\":0,\"type\":1,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[{\"application\":\"system\",\"children\":[],\"code\":\"sys_notice_mgr_received_page\",\"createTime\":1593419623000,\"createUser\":1265476890672672808,\"id\":1264622039642256511,\"name\":\"已收公告查询\",\"openType\":0,\"permission\":\"sysNotice:received\",\"pid\":1264622039642256501,\"pids\":\"[0],[1264622039642256421],[1264622039642256501],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1}],\"code\":\"sys_notice_mgr_received\",\"component\":\"system/noticeReceived/index\",\"createTime\":1593419573000,\"createUser\":1265476890672672808,\"id\":1264622039642256501,\"name\":\"已收公告\",\"openType\":1,\"pid\":1264622039642256421,\"pids\":\"[0],[1264622039642256421],\",\"router\":\"/noticeReceived\",\"sort\":20,\"status\":0,\"type\":1,\"visible\":\"Y\",\"weight\":1}],\"code\":\"sys_notice\",\"component\":\"PageView\",\"createTime\":1593416513000,\"createUser\":1265476890672672808,\"icon\":\"sound\",\"id\":1264622039642256421,\"name\":\"通知公告\",\"openType\":1,\"pid\":0,\"pids\":\"[0],\",\"router\":\"/notice\",\"sort\":7,\"status\":0,\"type\":0,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[{\"application\":\"system\",\"children\":[{\"application\":\"system\",\"children\":[],\"code\":\"sys_file_mgr_sys_file_page\",\"createTime\":1592991338000,\"createUser\":1265476890672672808,\"id\":1264622039642256541,\"name\":\"文件查询\",\"openType\":0,\"permission\":\"sysFileInfo:page\",\"pid\":1264622039642256531,\"pids\":\"[0],[1264622039642256521],[1264622039642256531],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_file_mgr_sys_file_list\",\"createTime\":1592991349000,\"createUser\":1265476890672672808,\"id\":1264622039642256551,\"name\":\"文件列表\",\"openType\":0,\"permission\":\"sysFileInfo:list\",\"pid\":1264622039642256531,\"pids\":\"[0],[1264622039642256521],[1264622039642256531],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_file_mgr_sys_file_delete\",\"createTime\":1592991371000,\"createUser\":1265476890672672808,\"id\":1264622039642256561,\"name\":\"文件删除\",\"openType\":0,\"permission\":\"sysFileInfo:delete\",\"pid\":1264622039642256531,\"pids\":\"[0],[1264622039642256521],[1264622039642256531],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_file_mgr_sys_file_detail\",\"createTime\":1592991361000,\"createUser\":1265476890672672808,\"id\":1264622039642256571,\"name\":\"文件详情\",\"openType\":0,\"permission\":\"sysFileInfo:detail\",\"pid\":1264622039642256531,\"pids\":\"[0],[1264622039642256521],[1264622039642256531],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_file_mgr_sys_file_upload\",\"createTime\":1592991269000,\"createUser\":1265476890672672808,\"id\":1264622039642256581,\"name\":\"文件上传\",\"openType\":0,\"permission\":\"sysFileInfo:upload\",\"pid\":1264622039642256531,\"pids\":\"[0],[1264622039642256521],[1264622039642256531],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_file_mgr_sys_file_download\",\"createTime\":1592991295000,\"createUser\":1265476890672672808,\"id\":1264622039642256591,\"name\":\"文件下载\",\"openType\":0,\"permission\":\"sysFileInfo:download\",\"pid\":1264622039642256531,\"pids\":\"[0],[1264622039642256521],[1264622039642256531],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_file_mgr_sys_file_preview\",\"createTime\":1592991319000,\"createUser\":1265476890672672808,\"id\":1264622039642256601,\"name\":\"图片预览\",\"openType\":0,\"permission\":\"sysFileInfo:preview\",\"pid\":1264622039642256531,\"pids\":\"[0],[1264622039642256521],[1264622039642256531],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1}],\"code\":\"sys_file_mgr_sys_file\",\"component\":\"system/file/index\",\"createTime\":1592991177000,\"createUser\":1265476890672672808,\"id\":1264622039642256531,\"name\":\"系统文件\",\"openType\":1,\"pid\":1264622039642256521,\"pids\":\"[0],[1264622039642256521],\",\"router\":\"/file\",\"sort\":21,\"status\":0,\"type\":1,\"visible\":\"Y\",\"weight\":1}],\"code\":\"sys_file_mgr\",\"component\":\"PageView\",\"createTime\":1592991070000,\"createUser\":1265476890672672808,\"icon\":\"file\",\"id\":1264622039642256521,\"name\":\"文件管理\",\"openType\":1,\"pid\":0,\"pids\":\"[0],\",\"router\":\"/file\",\"sort\":8,\"status\":0,\"type\":0,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[{\"application\":\"system\",\"children\":[{\"application\":\"system\",\"children\":[],\"code\":\"sys_timers_mgr_list\",\"createTime\":1593595196000,\"createUser\":1265476890672672808,\"id\":1264622039642256641,\"name\":\"定时任务列表\",\"openType\":0,\"permission\":\"sysTimers:list\",\"pid\":1264622039642256621,\"pids\":\"[0],[1264622039642256611],[1264622039642256621],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_timers_mgr_detail\",\"createTime\":1593595210000,\"createUser\":1265476890672672808,\"id\":1264622039642256651,\"name\":\"定时任务详情\",\"openType\":0,\"permission\":\"sysTimers:detail\",\"pid\":1264622039642256621,\"pids\":\"[0],[1264622039642256611],[1264622039642256621],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_timers_mgr_add\",\"createTime\":1593595223000,\"createUser\":1265476890672672808,\"id\":1264622039642256661,\"name\":\"定时任务增加\",\"openType\":0,\"permission\":\"sysTimers:add\",\"pid\":1264622039642256621,\"pids\":\"[0],[1264622039642256611],[1264622039642256621],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_timers_mgr_delete\",\"createTime\":1593595233000,\"createUser\":1265476890672672808,\"id\":1264622039642256671,\"name\":\"定时任务删除\",\"openType\":0,\"permission\":\"sysTimers:delete\",\"pid\":1264622039642256621,\"pids\":\"[0],[1264622039642256611],[1264622039642256621],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_timers_mgr_edit\",\"createTime\":1593595243000,\"createUser\":1265476890672672808,\"id\":1264622039642256681,\"name\":\"定时任务编辑\",\"openType\":0,\"permission\":\"sysTimers:edit\",\"pid\":1264622039642256621,\"pids\":\"[0],[1264622039642256611],[1264622039642256621],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_timers_mgr_get_action_classes\",\"createTime\":1593595336000,\"createUser\":1265476890672672808,\"id\":1264622039642256691,\"name\":\"定时任务可执行列表\",\"openType\":0,\"permission\":\"sysTimers:getActionClasses\",\"pid\":1264622039642256621,\"pids\":\"[0],[1264622039642256611],[1264622039642256621],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_timers_mgr_start\",\"createTime\":1593595352000,\"createUser\":1265476890672672808,\"id\":1264622039642256701,\"name\":\"定时任务启动\",\"openType\":0,\"permission\":\"sysTimers:start\",\"pid\":1264622039642256621,\"pids\":\"[0],[1264622039642256611],[1264622039642256621],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_timers_mgr_stop\",\"createTime\":1593595363000,\"createUser\":1265476890672672808,\"id\":1264622039642256711,\"name\":\"定时任务关闭\",\"openType\":0,\"permission\":\"sysTimers:stop\",\"pid\":1264622039642256621,\"pids\":\"[0],[1264622039642256611],[1264622039642256621],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1},{\"application\":\"system\",\"children\":[],\"code\":\"sys_timers_mgr_page\",\"createTime\":1593595183000,\"createUser\":1265476890672672808,\"id\":1264622039642256631,\"name\":\"定时任务查询\",\"openType\":0,\"permission\":\"sysTimers:page\",\"pid\":1264622039642256621,\"pids\":\"[0],[1264622039642256611],[1264622039642256621],\",\"sort\":100,\"status\":0,\"type\":2,\"visible\":\"Y\",\"weight\":1}],\"code\":\"sys_timers_mgr\",\"component\":\"system/timers/index\",\"createTime\":1593595133000,\"createUser\":1265476890672672808,\"id\":1264622039642256621,\"name\":\"任务管理\",\"openType\":1,\"pid\":1264622039642256611,\"pids\":\"[0],[1264622039642256611],\",\"router\":\"/timers\",\"sort\":22,\"status\":0,\"type\":1,\"visible\":\"Y\",\"weight\":1}],\"code\":\"sys_timers\",\"component\":\"PageView\",\"createTime\":1593595040000,\"createUser\":1265476890672672808,\"icon\":\"dashboard\",\"id\":1264622039642256611,\"name\":\"定时任务\",\"openType\":1,\"pid\":0,\"pids\":\"[0],\",\"router\":\"/timers\",\"sort\":100,\"status\":0,\"type\":0,\"visible\":\"Y\",\"weight\":1}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:23:41', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733502753669122', '系统字典类型_下拉', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysDictType/dropDown', 'com.cn.xiaonuo.sys.modular.dict.controller.SysDictTypeController', 'dropDown', 'GET', '{\"code\":\"menu_type\"}', '{\"code\":200,\"data\":[{\"code\":\"1\",\"value\":\"菜单\"},{\"code\":\"0\",\"value\":\"目录\"},{\"code\":\"2\",\"value\":\"按钮\"}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:23:41', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733614846443522', '系统角色_查询', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysRole/page', 'com.cn.xiaonuo.sys.modular.role.controller.SysRoleController', 'page', 'GET', '{}', '{\"code\":200,\"data\":{\"pageNo\":1,\"pageSize\":10,\"rainbow\":[1],\"rows\":[{\"code\":\"ent_manager_role\",\"createTime\":1585826846000,\"createUser\":1265476890672672808,\"dataScopeType\":1,\"id\":1265476890672672817,\"name\":\"组织架构管理员\",\"remark\":\"组织架构管理员\",\"sort\":100,\"status\":0,\"updateTime\":1599897247000,\"updateUser\":1265476890672672808},{\"code\":\"auth_role\",\"createTime\":1585826920000,\"createUser\":1265476890672672808,\"dataScopeType\":5,\"id\":1265476890672672818,\"name\":\"权限管理员\",\"remark\":\"权限管理员\",\"sort\":101,\"status\":0,\"updateTime\":1594867941000,\"updateUser\":1265476890672672808},{\"code\":\"notice_produce_role\",\"createTime\":1590738491000,\"createUser\":1265476890672672808,\"dataScopeType\":5,\"id\":1265476890672672819,\"name\":\"公告发布员\",\"remark\":\"公告发布员\",\"sort\":102,\"status\":0,\"updateTime\":1596886114000,\"updateUser\":1265476890672672808}],\"totalPage\":1,\"totalRows\":3},\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:24:08', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733628691841025', '系统菜单_授权树', '7', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysMenu/treeForGrant', 'com.cn.xiaonuo.sys.modular.menu.controller.SysMenuController', 'treeForGrant', 'GET', '{}', '{\"code\":200,\"data\":[{\"children\":[{\"children\":[],\"id\":1264622039642255331,\"parentId\":1264622039642255311,\"pid\":1264622039642255311,\"title\":\"工作台\",\"value\":\"1264622039642255331\",\"weight\":2},{\"children\":[],\"id\":1264622039642255321,\"parentId\":1264622039642255311,\"pid\":1264622039642255311,\"title\":\"分析页\",\"value\":\"1264622039642255321\",\"weight\":100}],\"id\":1264622039642255311,\"parentId\":0,\"pid\":0,\"title\":\"主控面板\",\"value\":\"1264622039642255311\",\"weight\":1},{\"children\":[{\"children\":[{\"children\":[],\"id\":1264622039642255361,\"parentId\":1264622039642255351,\"pid\":1264622039642255351,\"title\":\"用户查询\",\"value\":\"1264622039642255361\",\"weight\":100},{\"children\":[],\"id\":1264622039642255371,\"parentId\":1264622039642255351,\"pid\":1264622039642255351,\"title\":\"用户编辑\",\"value\":\"1264622039642255371\",\"weight\":100},{\"children\":[],\"id\":1264622039642255381,\"parentId\":1264622039642255351,\"pid\":1264622039642255351,\"title\":\"用户增加\",\"value\":\"1264622039642255381\",\"weight\":100},{\"children\":[],\"id\":1264622039642255391,\"parentId\":1264622039642255351,\"pid\":1264622039642255351,\"title\":\"用户删除\",\"value\":\"1264622039642255391\",\"weight\":100},{\"children\":[],\"id\":1264622039642255401,\"parentId\":1264622039642255351,\"pid\":1264622039642255351,\"title\":\"用户详情\",\"value\":\"1264622039642255401\",\"weight\":100},{\"children\":[],\"id\":1264622039642255411,\"parentId\":1264622039642255351,\"pid\":1264622039642255351,\"title\":\"用户导出\",\"value\":\"1264622039642255411\",\"weight\":100},{\"children\":[],\"id\":1264622039642255421,\"parentId\":1264622039642255351,\"pid\":1264622039642255351,\"title\":\"用户选择器\",\"value\":\"1264622039642255421\",\"weight\":100},{\"children\":[],\"id\":1264622039642255431,\"parentId\":1264622039642255351,\"pid\":1264622039642255351,\"title\":\"用户授权角色\",\"value\":\"1264622039642255431\",\"weight\":100},{\"children\":[],\"id\":1264622039642255441,\"parentId\":1264622039642255351,\"pid\":1264622039642255351,\"title\":\"用户拥有角色\",\"value\":\"1264622039642255441\",\"weight\":100},{\"children\":[],\"id\":1264622039642255451,\"parentId\":1264622039642255351,\"pid\":1264622039642255351,\"title\":\"用户授权数据\",\"value\":\"1264622039642255451\",\"weight\":100},{\"children\":[],\"id\":1264622039642255461,\"parentId\":1264622039642255351,\"pid\":1264622039642255351,\"title\":\"用户拥有数据\",\"value\":\"1264622039642255461\",\"weight\":100},{\"children\":[],\"id\":1264622039642255471,\"parentId\":1264622039642255351,\"pid\":1264622039642255351,\"title\":\"用户更新信息\",\"value\":\"1264622039642255471\",\"weight\":100},{\"children\":[],\"id\":1264622039642255481,\"parentId\":1264622039642255351,\"pid\":1264622039642255351,\"title\":\"用户修改密码\",\"value\":\"1264622039642255481\",\"weight\":100},{\"children\":[],\"id\":1264622039642255491,\"parentId\":1264622039642255351,\"pid\":1264622039642255351,\"title\":\"用户修改状态\",\"value\":\"1264622039642255491\",\"weight\":100},{\"children\":[],\"id\":1264622039642255501,\"parentId\":1264622039642255351,\"pid\":1264622039642255351,\"title\":\"用户修改头像\",\"value\":\"1264622039642255501\",\"weight\":100},{\"children\":[],\"id\":1264622039642255511,\"parentId\":1264622039642255351,\"pid\":1264622039642255351,\"title\":\"用户重置密码\",\"value\":\"1264622039642255511\",\"weight\":100}],\"id\":1264622039642255351,\"parentId\":1264622039642255341,\"pid\":1264622039642255341,\"title\":\"用户管理\",\"value\":\"1264622039642255351\",\"weight\":3},{\"children\":[{\"children\":[],\"id\":1264622039642255531,\"parentId\":1264622039642255521,\"pid\":1264622039642255521,\"title\":\"机构查询\",\"value\":\"1264622039642255531\",\"weight\":100},{\"children\":[],\"id\":1264622039642255541,\"parentId\":1264622039642255521,\"pid\":1264622039642255521,\"title\":\"机构列表\",\"value\":\"1264622039642255541\",\"weight\":100},{\"children\":[],\"id\":1264622039642255551,\"parentId\":1264622039642255521,\"pid\":1264622039642255521,\"title\":\"机构增加\",\"value\":\"1264622039642255551\",\"weight\":100},{\"children\":[],\"id\":1264622039642255561,\"parentId\":1264622039642255521,\"pid\":1264622039642255521,\"title\":\"机构编辑\",\"value\":\"1264622039642255561\",\"weight\":100},{\"children\":[],\"id\":1264622039642255571,\"parentId\":1264622039642255521,\"pid\":1264622039642255521,\"title\":\"机构删除\",\"value\":\"1264622039642255571\",\"weight\":100},{\"children\":[],\"id\":1264622039642255581,\"parentId\":1264622039642255521,\"pid\":1264622039642255521,\"title\":\"机构详情\",\"value\":\"1264622039642255581\",\"weight\":100},{\"children\":[],\"id\":1264622039642255591,\"parentId\":1264622039642255521,\"pid\":1264622039642255521,\"title\":\"机构树\",\"value\":\"1264622039642255591\",\"weight\":100}],\"id\":1264622039642255521,\"parentId\":1264622039642255341,\"pid\":1264622039642255341,\"title\":\"机构管理\",\"value\":\"1264622039642255521\",\"weight\":4},{\"children\":[{\"children\":[],\"id\":1264622039642255621,\"parentId\":1264622039642255601,\"pid\":1264622039642255601,\"title\":\"职位列表\",\"value\":\"1264622039642255621\",\"weight\":100},{\"children\":[],\"id\":1264622039642255631,\"parentId\":1264622039642255601,\"pid\":1264622039642255601,\"title\":\"职位增加\",\"value\":\"1264622039642255631\",\"weight\":100},{\"children\":[],\"id\":1264622039642255641,\"parentId\":1264622039642255601,\"pid\":1264622039642255601,\"title\":\"职位编辑\",\"value\":\"1264622039642255641\",\"weight\":100},{\"children\":[],\"id\":1264622039642255651,\"parentId\":1264622039642255601,\"pid\":1264622039642255601,\"title\":\"职位删除\",\"value\":\"1264622039642255651\",\"weight\":100},{\"children\":[],\"id\":1264622039642255661,\"parentId\":1264622039642255601,\"pid\":1264622039642255601,\"title\":\"职位详情\",\"value\":\"1264622039642255661\",\"weight\":100},{\"children\":[],\"id\":1264622039642255611,\"parentId\":1264622039642255601,\"pid\":1264622039642255601,\"title\":\"职位查询\",\"value\":\"1264622039642255611\",\"weight\":100}],\"id\":1264622039642255601,\"parentId\":1264622039642255341,\"pid\":1264622039642255341,\"title\":\"职位管理\",\"value\":\"1264622039642255601\",\"weight\":5}],\"id\":1264622039642255341,\"parentId\":0,\"pid\":0,\"title\":\"组织架构\",\"value\":\"1264622039642255341\",\"weight\":2},{\"children\":[{\"children\":[{\"children\":[],\"id\":1264622039642255691,\"parentId\":1264622039642255681,\"pid\":1264622039642255681,\"title\":\"应用查询\",\"value\":\"1264622039642255691\",\"weight\":100},{\"children\":[],\"id\":1264622039642255701,\"parentId\":1264622039642255681,\"pid\":1264622039642255681,\"title\":\"应用列表\",\"value\":\"1264622039642255701\",\"weight\":100},{\"children\":[],\"id\":1264622039642255711,\"parentId\":1264622039642255681,\"pid\":1264622039642255681,\"title\":\"应用增加\",\"value\":\"1264622039642255711\",\"weight\":100},{\"children\":[],\"id\":1264622039642255721,\"parentId\":1264622039642255681,\"pid\":1264622039642255681,\"title\":\"应用编辑\",\"value\":\"1264622039642255721\",\"weight\":100},{\"children\":[],\"id\":1264622039642255731,\"parentId\":1264622039642255681,\"pid\":1264622039642255681,\"title\":\"应用删除\",\"value\":\"1264622039642255731\",\"weight\":100},{\"children\":[],\"id\":1264622039642255741,\"parentId\":1264622039642255681,\"pid\":1264622039642255681,\"title\":\"应用详情\",\"value\":\"1264622039642255741\",\"weight\":100},{\"children\":[],\"id\":1264622039642255751,\"parentId\":1264622039642255681,\"pid\":1264622039642255681,\"title\":\"设为默认应用\",\"value\":\"1264622039642255751\",\"weight\":100}],\"id\":1264622039642255681,\"parentId\":1264622039642255671,\"pid\":1264622039642255671,\"title\":\"应用管理\",\"value\":\"1264622039642255681\",\"weight\":6},{\"children\":[{\"children\":[],\"id\":1264622039642255771,\"parentId\":1264622039642255761,\"pid\":1264622039642255761,\"title\":\"菜单列表\",\"value\":\"1264622039642255771\",\"weight\":100},{\"children\":[],\"id\":1264622039642255781,\"parentId\":1264622039642255761,\"pid\":1264622039642255761,\"title\":\"菜单增加\",\"value\":\"1264622039642255781\",\"weight\":100},{\"children\":[],\"id\":1264622039642255791,\"parentId\":1264622039642255761,\"pid\":1264622039642255761,\"title\":\"菜单编辑\",\"value\":\"1264622039642255791\",\"weight\":100},{\"children\":[],\"id\":1264622039642255801,\"parentId\":1264622039642255761,\"pid\":1264622039642255761,\"title\":\"菜单删除\",\"value\":\"1264622039642255801\",\"weight\":100},{\"children\":[],\"id\":1264622039642255811,\"parentId\":1264622039642255761,\"pid\":1264622039642255761,\"title\":\"菜单详情\",\"value\":\"1264622039642255811\",\"weight\":100},{\"children\":[],\"id\":1264622039642255821,\"parentId\":1264622039642255761,\"pid\":1264622039642255761,\"title\":\"菜单授权树\",\"value\":\"1264622039642255821\",\"weight\":100},{\"children\":[],\"id\":1264622039642255831,\"parentId\":1264622039642255761,\"pid\":1264622039642255761,\"title\":\"菜单树\",\"value\":\"1264622039642255831\",\"weight\":100},{\"children\":[],\"id\":1264622039642255841,\"parentId\":1264622039642255761,\"pid\":1264622039642255761,\"title\":\"菜单切换\",\"value\":\"1264622039642255841\",\"weight\":100}],\"id\":1264622039642255761,\"parentId\":1264622039642255671,\"pid\":1264622039642255671,\"title\":\"菜单管理\",\"value\":\"1264622039642255761\",\"weight\":7},{\"children\":[{\"children\":[],\"id\":1264622039642255881,\"parentId\":1264622039642255851,\"pid\":1264622039642255851,\"title\":\"角色编辑\",\"value\":\"1264622039642255881\",\"weight\":100},{\"children\":[],\"id\":1264622039642255891,\"parentId\":1264622039642255851,\"pid\":1264622039642255851,\"title\":\"角色删除\",\"value\":\"1264622039642255891\",\"weight\":100},{\"children\":[],\"id\":1264622039642255901,\"parentId\":1264622039642255851,\"pid\":1264622039642255851,\"title\":\"角色详情\",\"value\":\"1264622039642255901\",\"weight\":100},{\"children\":[],\"id\":1264622039642255911,\"parentId\":1264622039642255851,\"pid\":1264622039642255851,\"title\":\"角色下拉\",\"value\":\"1264622039642255911\",\"weight\":100},{\"children\":[],\"id\":1264622039642255921,\"parentId\":1264622039642255851,\"pid\":1264622039642255851,\"title\":\"角色授权菜单\",\"value\":\"1264622039642255921\",\"weight\":100},{\"children\":[],\"id\":1264622039642255931,\"parentId\":1264622039642255851,\"pid\":1264622039642255851,\"title\":\"角色拥有菜单\",\"value\":\"1264622039642255931\",\"weight\":100},{\"children\":[],\"id\":1264622039642255941,\"parentId\":1264622039642255851,\"pid\":1264622039642255851,\"title\":\"角色授权数据\",\"value\":\"1264622039642255941\",\"weight\":100},{\"children\":[],\"id\":1264622039642255951,\"parentId\":1264622039642255851,\"pid\":1264622039642255851,\"title\":\"角色拥有数据\",\"value\":\"1264622039642255951\",\"weight\":100},{\"children\":[],\"id\":1264622039642255861,\"parentId\":1264622039642255851,\"pid\":1264622039642255851,\"title\":\"角色查询\",\"value\":\"1264622039642255861\",\"weight\":100},{\"children\":[],\"id\":1264622039642255871,\"parentId\":1264622039642255851,\"pid\":1264622039642255851,\"title\":\"角色增加\",\"value\":\"1264622039642255871\",\"weight\":100}],\"id\":1264622039642255851,\"parentId\":1264622039642255671,\"pid\":1264622039642255671,\"title\":\"角色管理\",\"value\":\"1264622039642255851\",\"weight\":8}],\"id\":1264622039642255671,\"parentId\":0,\"pid\":0,\"title\":\"权限管理\",\"value\":\"1264622039642255671\",\"weight\":3},{\"children\":[{\"children\":[{\"children\":[],\"id\":1264622039642255981,\"parentId\":1264622039642255971,\"pid\":1264622039642255971,\"title\":\"配置查询\",\"value\":\"1264622039642255981\",\"weight\":100},{\"children\":[],\"id\":1264622039642255991,\"parentId\":1264622039642255971,\"pid\":1264622039642255971,\"title\":\"配置列表\",\"value\":\"1264622039642255991\",\"weight\":100},{\"children\":[],\"id\":1264622039642256001,\"parentId\":1264622039642255971,\"pid\":1264622039642255971,\"title\":\"配置增加\",\"value\":\"1264622039642256001\",\"weight\":100},{\"children\":[],\"id\":1264622039642256011,\"parentId\":1264622039642255971,\"pid\":1264622039642255971,\"title\":\"配置编辑\",\"value\":\"1264622039642256011\",\"weight\":100},{\"children\":[],\"id\":1264622039642256021,\"parentId\":1264622039642255971,\"pid\":1264622039642255971,\"title\":\"配置删除\",\"value\":\"1264622039642256021\",\"weight\":100},{\"children\":[],\"id\":1264622039642256031,\"parentId\":1264622039642255971,\"pid\":1264622039642255971,\"title\":\"配置详情\",\"value\":\"1264622039642256031\",\"weight\":100}],\"id\":1264622039642255971,\"parentId\":1264622039642255961,\"pid\":1264622039642255961,\"title\":\"系统配置\",\"value\":\"1264622039642255971\",\"weight\":9},{\"children\":[{\"children\":[],\"id\":1264622039642256051,\"parentId\":1264622039642256041,\"pid\":1264622039642256041,\"title\":\"发送文本邮件\",\"value\":\"1264622039642256051\",\"weight\":100},{\"children\":[],\"id\":1264622039642256061,\"parentId\":1264622039642256041,\"pid\":1264622039642256041,\"title\":\"发送html邮件\",\"value\":\"1264622039642256061\",\"weight\":100}],\"id\":1264622039642256041,\"parentId\":1264622039642255961,\"pid\":1264622039642255961,\"title\":\"邮件发送\",\"value\":\"1264622039642256041\",\"weight\":10},{\"children\":[{\"children\":[],\"id\":1264622039642256081,\"parentId\":1264622039642256071,\"pid\":1264622039642256071,\"title\":\"短信发送查询\",\"value\":\"1264622039642256081\",\"weight\":100},{\"children\":[],\"id\":1264622039642256091,\"parentId\":1264622039642256071,\"pid\":1264622039642256071,\"title\":\"发送验证码短信\",\"value\":\"1264622039642256091\",\"weight\":100},{\"children\":[],\"id\":1264622039642256101,\"parentId\":1264622039642256071,\"pid\":1264622039642256071,\"title\":\"验证短信验证码\",\"value\":\"1264622039642256101\",\"weight\":100}],\"id\":1264622039642256071,\"parentId\":1264622039642255961,\"pid\":1264622039642255961,\"title\":\"短信管理\",\"value\":\"1264622039642256071\",\"weight\":11},{\"children\":[{\"children\":[],\"id\":1264622039642256131,\"parentId\":1264622039642256111,\"pid\":1264622039642256111,\"title\":\"字典类型列表\",\"value\":\"1264622039642256131\",\"weight\":100},{\"children\":[],\"id\":1264622039642256141,\"parentId\":1264622039642256111,\"pid\":1264622039642256111,\"title\":\"字典类型增加\",\"value\":\"1264622039642256141\",\"weight\":100},{\"children\":[],\"id\":1264622039642256151,\"parentId\":1264622039642256111,\"pid\":1264622039642256111,\"title\":\"字典类型删除\",\"value\":\"1264622039642256151\",\"weight\":100},{\"children\":[],\"id\":1264622039642256161,\"parentId\":1264622039642256111,\"pid\":1264622039642256111,\"title\":\"字典类型编辑\",\"value\":\"1264622039642256161\",\"weight\":100},{\"children\":[],\"id\":1264622039642256171,\"parentId\":1264622039642256111,\"pid\":1264622039642256111,\"title\":\"字典类型详情\",\"value\":\"1264622039642256171\",\"weight\":100},{\"children\":[],\"id\":1264622039642256181,\"parentId\":1264622039642256111,\"pid\":1264622039642256111,\"title\":\"字典类型下拉\",\"value\":\"1264622039642256181\",\"weight\":100},{\"children\":[],\"id\":1264622039642256191,\"parentId\":1264622039642256111,\"pid\":1264622039642256111,\"title\":\"字典类型修改状态\",\"value\":\"1264622039642256191\",\"weight\":100},{\"children\":[],\"id\":1264622039642256201,\"parentId\":1264622039642256111,\"pid\":1264622039642256111,\"title\":\"字典值查询\",\"value\":\"1264622039642256201\",\"weight\":100},{\"children\":[],\"id\":1264622039642256211,\"parentId\":1264622039642256111,\"pid\":1264622039642256111,\"title\":\"字典值列表\",\"value\":\"1264622039642256211\",\"weight\":100},{\"children\":[],\"id\":1264622039642256221,\"parentId\":1264622039642256111,\"pid\":1264622039642256111,\"title\":\"字典值增加\",\"value\":\"1264622039642256221\",\"weight\":100},{\"children\":[],\"id\":1264622039642256231,\"parentId\":1264622039642256111,\"pid\":1264622039642256111,\"title\":\"字典值删除\",\"value\":\"1264622039642256231\",\"weight\":100},{\"children\":[],\"id\":1264622039642256241,\"parentId\":1264622039642256111,\"pid\":1264622039642256111,\"title\":\"字典值编辑\",\"value\":\"1264622039642256241\",\"weight\":100},{\"children\":[],\"id\":1264622039642256251,\"parentId\":1264622039642256111,\"pid\":1264622039642256111,\"title\":\"字典值详情\",\"value\":\"1264622039642256251\",\"weight\":100},{\"children\":[],\"id\":1264622039642256261,\"parentId\":1264622039642256111,\"pid\":1264622039642256111,\"title\":\"字典值修改状态\",\"value\":\"1264622039642256261\",\"weight\":100},{\"children\":[],\"id\":1264622039642256121,\"parentId\":1264622039642256111,\"pid\":1264622039642256111,\"title\":\"字典类型查询\",\"value\":\"1264622039642256121\",\"weight\":100}],\"id\":1264622039642256111,\"parentId\":1264622039642255961,\"pid\":1264622039642255961,\"title\":\"字典管理\",\"value\":\"1264622039642256111\",\"weight\":12},{\"children\":[],\"id\":1264622039642256271,\"parentId\":1264622039642255961,\"pid\":1264622039642255961,\"title\":\"接口文档\",\"value\":\"1264622039642256271\",\"weight\":13}],\"id\":1264622039642255961,\"parentId\":0,\"pid\":0,\"title\":\"开发管理\",\"value\":\"1264622039642255961\",\"weight\":4},{\"children\":[{\"children\":[{\"children\":[],\"id\":1264622039642256301,\"parentId\":1264622039642256291,\"pid\":1264622039642256291,\"title\":\"访问日志查询\",\"value\":\"1264622039642256301\",\"weight\":100},{\"children\":[],\"id\":1264622039642256311,\"parentId\":1264622039642256291,\"pid\":1264622039642256291,\"title\":\"访问日志清空\",\"value\":\"1264622039642256311\",\"weight\":100}],\"id\":1264622039642256291,\"parentId\":1264622039642256281,\"pid\":1264622039642256281,\"title\":\"访问日志\",\"value\":\"1264622039642256291\",\"weight\":14},{\"children\":[{\"children\":[],\"id\":1264622039642256331,\"parentId\":1264622039642256321,\"pid\":1264622039642256321,\"title\":\"操作日志查询\",\"value\":\"1264622039642256331\",\"weight\":100},{\"children\":[],\"id\":1264622039642256341,\"parentId\":1264622039642256321,\"pid\":1264622039642256321,\"title\":\"操作日志清空\",\"value\":\"1264622039642256341\",\"weight\":100}],\"id\":1264622039642256321,\"parentId\":1264622039642256281,\"pid\":1264622039642256281,\"title\":\"操作日志\",\"value\":\"1264622039642256321\",\"weight\":15}],\"id\":1264622039642256281,\"parentId\":0,\"pid\":0,\"title\":\"日志管理\",\"value\":\"1264622039642256281\",\"weight\":5},{\"children\":[{\"children\":[{\"children\":[],\"id\":1264622039642256371,\"parentId\":1264622039642256361,\"pid\":1264622039642256361,\"title\":\"服务监控查询\",\"value\":\"1264622039642256371\",\"weight\":100}],\"id\":1264622039642256361,\"parentId\":1264622039642256351,\"pid\":1264622039642256351,\"title\":\"服务监控\",\"value\":\"1264622039642256361\",\"weight\":16},{\"children\":[{\"children\":[],\"id\":1264622039642256391,\"parentId\":1264622039642256381,\"pid\":1264622039642256381,\"title\":\"在线用户列表\",\"value\":\"1264622039642256391\",\"weight\":100},{\"children\":[],\"id\":1264622039642256401,\"parentId\":1264622039642256381,\"pid\":1264622039642256381,\"title\":\"在线用户强退\",\"value\":\"1264622039642256401\",\"weight\":100}],\"id\":1264622039642256381,\"parentId\":1264622039642256351,\"pid\":1264622039642256351,\"title\":\"在线用户\",\"value\":\"1264622039642256381\",\"weight\":17},{\"children\":[],\"id\":1264622039642256411,\"parentId\":1264622039642256351,\"pid\":1264622039642256351,\"title\":\"数据监控\",\"value\":\"1264622039642256411\",\"weight\":18}],\"id\":1264622039642256351,\"parentId\":0,\"pid\":0,\"title\":\"系统监控\",\"value\":\"1264622039642256351\",\"weight\":6},{\"children\":[{\"children\":[{\"children\":[],\"id\":1264622039642256441,\"parentId\":1264622039642256431,\"pid\":1264622039642256431,\"title\":\"公告查询\",\"value\":\"1264622039642256441\",\"weight\":100},{\"children\":[],\"id\":1264622039642256451,\"parentId\":1264622039642256431,\"pid\":1264622039642256431,\"title\":\"公告增加\",\"value\":\"1264622039642256451\",\"weight\":100},{\"children\":[],\"id\":1264622039642256461,\"parentId\":1264622039642256431,\"pid\":1264622039642256431,\"title\":\"公告编辑\",\"value\":\"1264622039642256461\",\"weight\":100},{\"children\":[],\"id\":1264622039642256471,\"parentId\":1264622039642256431,\"pid\":1264622039642256431,\"title\":\"公告删除\",\"value\":\"1264622039642256471\",\"weight\":100},{\"children\":[],\"id\":1264622039642256481,\"parentId\":1264622039642256431,\"pid\":1264622039642256431,\"title\":\"公告查看\",\"value\":\"1264622039642256481\",\"weight\":100},{\"children\":[],\"id\":1264622039642256491,\"parentId\":1264622039642256431,\"pid\":1264622039642256431,\"title\":\"公告修改状态\",\"value\":\"1264622039642256491\",\"weight\":100}],\"id\":1264622039642256431,\"parentId\":1264622039642256421,\"pid\":1264622039642256421,\"title\":\"公告管理\",\"value\":\"1264622039642256431\",\"weight\":19},{\"children\":[{\"children\":[],\"id\":1264622039642256511,\"parentId\":1264622039642256501,\"pid\":1264622039642256501,\"title\":\"已收公告查询\",\"value\":\"1264622039642256511\",\"weight\":100}],\"id\":1264622039642256501,\"parentId\":1264622039642256421,\"pid\":1264622039642256421,\"title\":\"已收公告\",\"value\":\"1264622039642256501\",\"weight\":20}],\"id\":1264622039642256421,\"parentId\":0,\"pid\":0,\"title\":\"通知公告\",\"value\":\"1264622039642256421\",\"weight\":7},{\"children\":[{\"children\":[{\"children\":[],\"id\":1264622039642256541,\"parentId\":1264622039642256531,\"pid\":1264622039642256531,\"title\":\"文件查询\",\"value\":\"1264622039642256541\",\"weight\":100},{\"children\":[],\"id\":1264622039642256551,\"parentId\":1264622039642256531,\"pid\":1264622039642256531,\"title\":\"文件列表\",\"value\":\"1264622039642256551\",\"weight\":100},{\"children\":[],\"id\":1264622039642256561,\"parentId\":1264622039642256531,\"pid\":1264622039642256531,\"title\":\"文件删除\",\"value\":\"1264622039642256561\",\"weight\":100},{\"children\":[],\"id\":1264622039642256571,\"parentId\":1264622039642256531,\"pid\":1264622039642256531,\"title\":\"文件详情\",\"value\":\"1264622039642256571\",\"weight\":100},{\"children\":[],\"id\":1264622039642256581,\"parentId\":1264622039642256531,\"pid\":1264622039642256531,\"title\":\"文件上传\",\"value\":\"1264622039642256581\",\"weight\":100},{\"children\":[],\"id\":1264622039642256591,\"parentId\":1264622039642256531,\"pid\":1264622039642256531,\"title\":\"文件下载\",\"value\":\"1264622039642256591\",\"weight\":100},{\"children\":[],\"id\":1264622039642256601,\"parentId\":1264622039642256531,\"pid\":1264622039642256531,\"title\":\"图片预览\",\"value\":\"1264622039642256601\",\"weight\":100}],\"id\":1264622039642256531,\"parentId\":1264622039642256521,\"pid\":1264622039642256521,\"title\":\"系统文件\",\"value\":\"1264622039642256531\",\"weight\":21}],\"id\":1264622039642256521,\"parentId\":0,\"pid\":0,\"title\":\"文件管理\",\"value\":\"1264622039642256521\",\"weight\":8},{\"children\":[{\"children\":[{\"children\":[],\"id\":1264622039642256641,\"parentId\":1264622039642256621,\"pid\":1264622039642256621,\"title\":\"定时任务列表\",\"value\":\"1264622039642256641\",\"weight\":100},{\"children\":[],\"id\":1264622039642256651,\"parentId\":1264622039642256621,\"pid\":1264622039642256621,\"title\":\"定时任务详情\",\"value\":\"1264622039642256651\",\"weight\":100},{\"children\":[],\"id\":1264622039642256661,\"parentId\":1264622039642256621,\"pid\":1264622039642256621,\"title\":\"定时任务增加\",\"value\":\"1264622039642256661\",\"weight\":100},{\"children\":[],\"id\":1264622039642256671,\"parentId\":1264622039642256621,\"pid\":1264622039642256621,\"title\":\"定时任务删除\",\"value\":\"1264622039642256671\",\"weight\":100},{\"children\":[],\"id\":1264622039642256681,\"parentId\":1264622039642256621,\"pid\":1264622039642256621,\"title\":\"定时任务编辑\",\"value\":\"1264622039642256681\",\"weight\":100},{\"children\":[],\"id\":1264622039642256691,\"parentId\":1264622039642256621,\"pid\":1264622039642256621,\"title\":\"定时任务可执行列表\",\"value\":\"1264622039642256691\",\"weight\":100},{\"children\":[],\"id\":1264622039642256701,\"parentId\":1264622039642256621,\"pid\":1264622039642256621,\"title\":\"定时任务启动\",\"value\":\"1264622039642256701\",\"weight\":100},{\"children\":[],\"id\":1264622039642256711,\"parentId\":1264622039642256621,\"pid\":1264622039642256621,\"title\":\"定时任务关闭\",\"value\":\"1264622039642256711\",\"weight\":100},{\"children\":[],\"id\":1264622039642256631,\"parentId\":1264622039642256621,\"pid\":1264622039642256621,\"title\":\"定时任务查询\",\"value\":\"1264622039642256631\",\"weight\":100}],\"id\":1264622039642256621,\"parentId\":1264622039642256611,\"pid\":1264622039642256611,\"title\":\"任务管理\",\"value\":\"1264622039642256621\",\"weight\":22}],\"id\":1264622039642256611,\"parentId\":0,\"pid\":0,\"title\":\"定时任务\",\"value\":\"1264622039642256611\",\"weight\":100}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:24:11', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733629903994882', '系统角色_拥有菜单', '6', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysRole/ownMenu', 'com.cn.xiaonuo.sys.modular.role.controller.SysRoleController', 'ownMenu', 'GET', '{\"id\":1265476890672672817}', '{\"code\":200,\"data\":[1264622039642255311,1264622039642255331,1264622039642255321,1264622039642255341,1264622039642255351,1264622039642255361,1264622039642255371,1264622039642255381,1264622039642255391,1264622039642255401,1264622039642255411,1264622039642255421,1264622039642255431,1264622039642255441,1264622039642255451,1264622039642255461,1264622039642255471,1264622039642255481,1264622039642255491,1264622039642255501,1264622039642255511,1264622039642255521,1264622039642255531,1264622039642255541,1264622039642255551,1264622039642255561,1264622039642255571,1264622039642255581,1264622039642255591,1264622039642255601,1264622039642255621,1264622039642255631,1264622039642255641,1264622039642255651,1264622039642255661,1264622039642255611,1264622039642257321,1264622039642257331,1264622039642257471,1264622039642257481,1264622039642257341,1264622039642257411,1264622039642257421,1264622039642257431,1264622039642257441,1264622039642257451,1264622039642257461,1264622039642257351,1264622039642257361,1264622039642257371,1264622039642257381,1264622039642257391,1264622039642257401,1264622039642257491,1264622039642257501,1264622039642257511,1264622039642256831,1264622039642257031,1264622039642257021,1264622039642257061,1264622039642257261,1264622039642257301,1264622039642257271,1264622039642257462,1264622039642256912,1264622039642255911,1264622039642257522,1264622039642257523,1264622039642257524,1264622039642257525,1264622039642257532,1264622039642257531,1264622039642257311,1264622039642257312,1264622039642257313,1264622039642257314,1264622039642256821,1264622039642257022],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:24:12', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733650158288897', '系统菜单_授权树', '7', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysMenu/treeForGrant', 'com.cn.xiaonuo.sys.modular.menu.controller.SysMenuController', 'treeForGrant', 'GET', '{}', '{\"code\":200,\"data\":[{\"children\":[{\"children\":[],\"id\":1264622039642255331,\"parentId\":1264622039642255311,\"pid\":1264622039642255311,\"title\":\"工作台\",\"value\":\"1264622039642255331\",\"weight\":2},{\"children\":[],\"id\":1264622039642255321,\"parentId\":1264622039642255311,\"pid\":1264622039642255311,\"title\":\"分析页\",\"value\":\"1264622039642255321\",\"weight\":100}],\"id\":1264622039642255311,\"parentId\":0,\"pid\":0,\"title\":\"主控面板\",\"value\":\"1264622039642255311\",\"weight\":1},{\"children\":[{\"children\":[{\"children\":[],\"id\":1264622039642255361,\"parentId\":1264622039642255351,\"pid\":1264622039642255351,\"title\":\"用户查询\",\"value\":\"1264622039642255361\",\"weight\":100},{\"children\":[],\"id\":1264622039642255371,\"parentId\":1264622039642255351,\"pid\":1264622039642255351,\"title\":\"用户编辑\",\"value\":\"1264622039642255371\",\"weight\":100},{\"children\":[],\"id\":1264622039642255381,\"parentId\":1264622039642255351,\"pid\":1264622039642255351,\"title\":\"用户增加\",\"value\":\"1264622039642255381\",\"weight\":100},{\"children\":[],\"id\":1264622039642255391,\"parentId\":1264622039642255351,\"pid\":1264622039642255351,\"title\":\"用户删除\",\"value\":\"1264622039642255391\",\"weight\":100},{\"children\":[],\"id\":1264622039642255401,\"parentId\":1264622039642255351,\"pid\":1264622039642255351,\"title\":\"用户详情\",\"value\":\"1264622039642255401\",\"weight\":100},{\"children\":[],\"id\":1264622039642255411,\"parentId\":1264622039642255351,\"pid\":1264622039642255351,\"title\":\"用户导出\",\"value\":\"1264622039642255411\",\"weight\":100},{\"children\":[],\"id\":1264622039642255421,\"parentId\":1264622039642255351,\"pid\":1264622039642255351,\"title\":\"用户选择器\",\"value\":\"1264622039642255421\",\"weight\":100},{\"children\":[],\"id\":1264622039642255431,\"parentId\":1264622039642255351,\"pid\":1264622039642255351,\"title\":\"用户授权角色\",\"value\":\"1264622039642255431\",\"weight\":100},{\"children\":[],\"id\":1264622039642255441,\"parentId\":1264622039642255351,\"pid\":1264622039642255351,\"title\":\"用户拥有角色\",\"value\":\"1264622039642255441\",\"weight\":100},{\"children\":[],\"id\":1264622039642255451,\"parentId\":1264622039642255351,\"pid\":1264622039642255351,\"title\":\"用户授权数据\",\"value\":\"1264622039642255451\",\"weight\":100},{\"children\":[],\"id\":1264622039642255461,\"parentId\":1264622039642255351,\"pid\":1264622039642255351,\"title\":\"用户拥有数据\",\"value\":\"1264622039642255461\",\"weight\":100},{\"children\":[],\"id\":1264622039642255471,\"parentId\":1264622039642255351,\"pid\":1264622039642255351,\"title\":\"用户更新信息\",\"value\":\"1264622039642255471\",\"weight\":100},{\"children\":[],\"id\":1264622039642255481,\"parentId\":1264622039642255351,\"pid\":1264622039642255351,\"title\":\"用户修改密码\",\"value\":\"1264622039642255481\",\"weight\":100},{\"children\":[],\"id\":1264622039642255491,\"parentId\":1264622039642255351,\"pid\":1264622039642255351,\"title\":\"用户修改状态\",\"value\":\"1264622039642255491\",\"weight\":100},{\"children\":[],\"id\":1264622039642255501,\"parentId\":1264622039642255351,\"pid\":1264622039642255351,\"title\":\"用户修改头像\",\"value\":\"1264622039642255501\",\"weight\":100},{\"children\":[],\"id\":1264622039642255511,\"parentId\":1264622039642255351,\"pid\":1264622039642255351,\"title\":\"用户重置密码\",\"value\":\"1264622039642255511\",\"weight\":100}],\"id\":1264622039642255351,\"parentId\":1264622039642255341,\"pid\":1264622039642255341,\"title\":\"用户管理\",\"value\":\"1264622039642255351\",\"weight\":3},{\"children\":[{\"children\":[],\"id\":1264622039642255531,\"parentId\":1264622039642255521,\"pid\":1264622039642255521,\"title\":\"机构查询\",\"value\":\"1264622039642255531\",\"weight\":100},{\"children\":[],\"id\":1264622039642255541,\"parentId\":1264622039642255521,\"pid\":1264622039642255521,\"title\":\"机构列表\",\"value\":\"1264622039642255541\",\"weight\":100},{\"children\":[],\"id\":1264622039642255551,\"parentId\":1264622039642255521,\"pid\":1264622039642255521,\"title\":\"机构增加\",\"value\":\"1264622039642255551\",\"weight\":100},{\"children\":[],\"id\":1264622039642255561,\"parentId\":1264622039642255521,\"pid\":1264622039642255521,\"title\":\"机构编辑\",\"value\":\"1264622039642255561\",\"weight\":100},{\"children\":[],\"id\":1264622039642255571,\"parentId\":1264622039642255521,\"pid\":1264622039642255521,\"title\":\"机构删除\",\"value\":\"1264622039642255571\",\"weight\":100},{\"children\":[],\"id\":1264622039642255581,\"parentId\":1264622039642255521,\"pid\":1264622039642255521,\"title\":\"机构详情\",\"value\":\"1264622039642255581\",\"weight\":100},{\"children\":[],\"id\":1264622039642255591,\"parentId\":1264622039642255521,\"pid\":1264622039642255521,\"title\":\"机构树\",\"value\":\"1264622039642255591\",\"weight\":100}],\"id\":1264622039642255521,\"parentId\":1264622039642255341,\"pid\":1264622039642255341,\"title\":\"机构管理\",\"value\":\"1264622039642255521\",\"weight\":4},{\"children\":[{\"children\":[],\"id\":1264622039642255621,\"parentId\":1264622039642255601,\"pid\":1264622039642255601,\"title\":\"职位列表\",\"value\":\"1264622039642255621\",\"weight\":100},{\"children\":[],\"id\":1264622039642255631,\"parentId\":1264622039642255601,\"pid\":1264622039642255601,\"title\":\"职位增加\",\"value\":\"1264622039642255631\",\"weight\":100},{\"children\":[],\"id\":1264622039642255641,\"parentId\":1264622039642255601,\"pid\":1264622039642255601,\"title\":\"职位编辑\",\"value\":\"1264622039642255641\",\"weight\":100},{\"children\":[],\"id\":1264622039642255651,\"parentId\":1264622039642255601,\"pid\":1264622039642255601,\"title\":\"职位删除\",\"value\":\"1264622039642255651\",\"weight\":100},{\"children\":[],\"id\":1264622039642255661,\"parentId\":1264622039642255601,\"pid\":1264622039642255601,\"title\":\"职位详情\",\"value\":\"1264622039642255661\",\"weight\":100},{\"children\":[],\"id\":1264622039642255611,\"parentId\":1264622039642255601,\"pid\":1264622039642255601,\"title\":\"职位查询\",\"value\":\"1264622039642255611\",\"weight\":100}],\"id\":1264622039642255601,\"parentId\":1264622039642255341,\"pid\":1264622039642255341,\"title\":\"职位管理\",\"value\":\"1264622039642255601\",\"weight\":5}],\"id\":1264622039642255341,\"parentId\":0,\"pid\":0,\"title\":\"组织架构\",\"value\":\"1264622039642255341\",\"weight\":2},{\"children\":[{\"children\":[{\"children\":[],\"id\":1264622039642255691,\"parentId\":1264622039642255681,\"pid\":1264622039642255681,\"title\":\"应用查询\",\"value\":\"1264622039642255691\",\"weight\":100},{\"children\":[],\"id\":1264622039642255701,\"parentId\":1264622039642255681,\"pid\":1264622039642255681,\"title\":\"应用列表\",\"value\":\"1264622039642255701\",\"weight\":100},{\"children\":[],\"id\":1264622039642255711,\"parentId\":1264622039642255681,\"pid\":1264622039642255681,\"title\":\"应用增加\",\"value\":\"1264622039642255711\",\"weight\":100},{\"children\":[],\"id\":1264622039642255721,\"parentId\":1264622039642255681,\"pid\":1264622039642255681,\"title\":\"应用编辑\",\"value\":\"1264622039642255721\",\"weight\":100},{\"children\":[],\"id\":1264622039642255731,\"parentId\":1264622039642255681,\"pid\":1264622039642255681,\"title\":\"应用删除\",\"value\":\"1264622039642255731\",\"weight\":100},{\"children\":[],\"id\":1264622039642255741,\"parentId\":1264622039642255681,\"pid\":1264622039642255681,\"title\":\"应用详情\",\"value\":\"1264622039642255741\",\"weight\":100},{\"children\":[],\"id\":1264622039642255751,\"parentId\":1264622039642255681,\"pid\":1264622039642255681,\"title\":\"设为默认应用\",\"value\":\"1264622039642255751\",\"weight\":100}],\"id\":1264622039642255681,\"parentId\":1264622039642255671,\"pid\":1264622039642255671,\"title\":\"应用管理\",\"value\":\"1264622039642255681\",\"weight\":6},{\"children\":[{\"children\":[],\"id\":1264622039642255771,\"parentId\":1264622039642255761,\"pid\":1264622039642255761,\"title\":\"菜单列表\",\"value\":\"1264622039642255771\",\"weight\":100},{\"children\":[],\"id\":1264622039642255781,\"parentId\":1264622039642255761,\"pid\":1264622039642255761,\"title\":\"菜单增加\",\"value\":\"1264622039642255781\",\"weight\":100},{\"children\":[],\"id\":1264622039642255791,\"parentId\":1264622039642255761,\"pid\":1264622039642255761,\"title\":\"菜单编辑\",\"value\":\"1264622039642255791\",\"weight\":100},{\"children\":[],\"id\":1264622039642255801,\"parentId\":1264622039642255761,\"pid\":1264622039642255761,\"title\":\"菜单删除\",\"value\":\"1264622039642255801\",\"weight\":100},{\"children\":[],\"id\":1264622039642255811,\"parentId\":1264622039642255761,\"pid\":1264622039642255761,\"title\":\"菜单详情\",\"value\":\"1264622039642255811\",\"weight\":100},{\"children\":[],\"id\":1264622039642255821,\"parentId\":1264622039642255761,\"pid\":1264622039642255761,\"title\":\"菜单授权树\",\"value\":\"1264622039642255821\",\"weight\":100},{\"children\":[],\"id\":1264622039642255831,\"parentId\":1264622039642255761,\"pid\":1264622039642255761,\"title\":\"菜单树\",\"value\":\"1264622039642255831\",\"weight\":100},{\"children\":[],\"id\":1264622039642255841,\"parentId\":1264622039642255761,\"pid\":1264622039642255761,\"title\":\"菜单切换\",\"value\":\"1264622039642255841\",\"weight\":100}],\"id\":1264622039642255761,\"parentId\":1264622039642255671,\"pid\":1264622039642255671,\"title\":\"菜单管理\",\"value\":\"1264622039642255761\",\"weight\":7},{\"children\":[{\"children\":[],\"id\":1264622039642255881,\"parentId\":1264622039642255851,\"pid\":1264622039642255851,\"title\":\"角色编辑\",\"value\":\"1264622039642255881\",\"weight\":100},{\"children\":[],\"id\":1264622039642255891,\"parentId\":1264622039642255851,\"pid\":1264622039642255851,\"title\":\"角色删除\",\"value\":\"1264622039642255891\",\"weight\":100},{\"children\":[],\"id\":1264622039642255901,\"parentId\":1264622039642255851,\"pid\":1264622039642255851,\"title\":\"角色详情\",\"value\":\"1264622039642255901\",\"weight\":100},{\"children\":[],\"id\":1264622039642255911,\"parentId\":1264622039642255851,\"pid\":1264622039642255851,\"title\":\"角色下拉\",\"value\":\"1264622039642255911\",\"weight\":100},{\"children\":[],\"id\":1264622039642255921,\"parentId\":1264622039642255851,\"pid\":1264622039642255851,\"title\":\"角色授权菜单\",\"value\":\"1264622039642255921\",\"weight\":100},{\"children\":[],\"id\":1264622039642255931,\"parentId\":1264622039642255851,\"pid\":1264622039642255851,\"title\":\"角色拥有菜单\",\"value\":\"1264622039642255931\",\"weight\":100},{\"children\":[],\"id\":1264622039642255941,\"parentId\":1264622039642255851,\"pid\":1264622039642255851,\"title\":\"角色授权数据\",\"value\":\"1264622039642255941\",\"weight\":100},{\"children\":[],\"id\":1264622039642255951,\"parentId\":1264622039642255851,\"pid\":1264622039642255851,\"title\":\"角色拥有数据\",\"value\":\"1264622039642255951\",\"weight\":100},{\"children\":[],\"id\":1264622039642255861,\"parentId\":1264622039642255851,\"pid\":1264622039642255851,\"title\":\"角色查询\",\"value\":\"1264622039642255861\",\"weight\":100},{\"children\":[],\"id\":1264622039642255871,\"parentId\":1264622039642255851,\"pid\":1264622039642255851,\"title\":\"角色增加\",\"value\":\"1264622039642255871\",\"weight\":100}],\"id\":1264622039642255851,\"parentId\":1264622039642255671,\"pid\":1264622039642255671,\"title\":\"角色管理\",\"value\":\"1264622039642255851\",\"weight\":8}],\"id\":1264622039642255671,\"parentId\":0,\"pid\":0,\"title\":\"权限管理\",\"value\":\"1264622039642255671\",\"weight\":3},{\"children\":[{\"children\":[{\"children\":[],\"id\":1264622039642255981,\"parentId\":1264622039642255971,\"pid\":1264622039642255971,\"title\":\"配置查询\",\"value\":\"1264622039642255981\",\"weight\":100},{\"children\":[],\"id\":1264622039642255991,\"parentId\":1264622039642255971,\"pid\":1264622039642255971,\"title\":\"配置列表\",\"value\":\"1264622039642255991\",\"weight\":100},{\"children\":[],\"id\":1264622039642256001,\"parentId\":1264622039642255971,\"pid\":1264622039642255971,\"title\":\"配置增加\",\"value\":\"1264622039642256001\",\"weight\":100},{\"children\":[],\"id\":1264622039642256011,\"parentId\":1264622039642255971,\"pid\":1264622039642255971,\"title\":\"配置编辑\",\"value\":\"1264622039642256011\",\"weight\":100},{\"children\":[],\"id\":1264622039642256021,\"parentId\":1264622039642255971,\"pid\":1264622039642255971,\"title\":\"配置删除\",\"value\":\"1264622039642256021\",\"weight\":100},{\"children\":[],\"id\":1264622039642256031,\"parentId\":1264622039642255971,\"pid\":1264622039642255971,\"title\":\"配置详情\",\"value\":\"1264622039642256031\",\"weight\":100}],\"id\":1264622039642255971,\"parentId\":1264622039642255961,\"pid\":1264622039642255961,\"title\":\"系统配置\",\"value\":\"1264622039642255971\",\"weight\":9},{\"children\":[{\"children\":[],\"id\":1264622039642256051,\"parentId\":1264622039642256041,\"pid\":1264622039642256041,\"title\":\"发送文本邮件\",\"value\":\"1264622039642256051\",\"weight\":100},{\"children\":[],\"id\":1264622039642256061,\"parentId\":1264622039642256041,\"pid\":1264622039642256041,\"title\":\"发送html邮件\",\"value\":\"1264622039642256061\",\"weight\":100}],\"id\":1264622039642256041,\"parentId\":1264622039642255961,\"pid\":1264622039642255961,\"title\":\"邮件发送\",\"value\":\"1264622039642256041\",\"weight\":10},{\"children\":[{\"children\":[],\"id\":1264622039642256081,\"parentId\":1264622039642256071,\"pid\":1264622039642256071,\"title\":\"短信发送查询\",\"value\":\"1264622039642256081\",\"weight\":100},{\"children\":[],\"id\":1264622039642256091,\"parentId\":1264622039642256071,\"pid\":1264622039642256071,\"title\":\"发送验证码短信\",\"value\":\"1264622039642256091\",\"weight\":100},{\"children\":[],\"id\":1264622039642256101,\"parentId\":1264622039642256071,\"pid\":1264622039642256071,\"title\":\"验证短信验证码\",\"value\":\"1264622039642256101\",\"weight\":100}],\"id\":1264622039642256071,\"parentId\":1264622039642255961,\"pid\":1264622039642255961,\"title\":\"短信管理\",\"value\":\"1264622039642256071\",\"weight\":11},{\"children\":[{\"children\":[],\"id\":1264622039642256131,\"parentId\":1264622039642256111,\"pid\":1264622039642256111,\"title\":\"字典类型列表\",\"value\":\"1264622039642256131\",\"weight\":100},{\"children\":[],\"id\":1264622039642256141,\"parentId\":1264622039642256111,\"pid\":1264622039642256111,\"title\":\"字典类型增加\",\"value\":\"1264622039642256141\",\"weight\":100},{\"children\":[],\"id\":1264622039642256151,\"parentId\":1264622039642256111,\"pid\":1264622039642256111,\"title\":\"字典类型删除\",\"value\":\"1264622039642256151\",\"weight\":100},{\"children\":[],\"id\":1264622039642256161,\"parentId\":1264622039642256111,\"pid\":1264622039642256111,\"title\":\"字典类型编辑\",\"value\":\"1264622039642256161\",\"weight\":100},{\"children\":[],\"id\":1264622039642256171,\"parentId\":1264622039642256111,\"pid\":1264622039642256111,\"title\":\"字典类型详情\",\"value\":\"1264622039642256171\",\"weight\":100},{\"children\":[],\"id\":1264622039642256181,\"parentId\":1264622039642256111,\"pid\":1264622039642256111,\"title\":\"字典类型下拉\",\"value\":\"1264622039642256181\",\"weight\":100},{\"children\":[],\"id\":1264622039642256191,\"parentId\":1264622039642256111,\"pid\":1264622039642256111,\"title\":\"字典类型修改状态\",\"value\":\"1264622039642256191\",\"weight\":100},{\"children\":[],\"id\":1264622039642256201,\"parentId\":1264622039642256111,\"pid\":1264622039642256111,\"title\":\"字典值查询\",\"value\":\"1264622039642256201\",\"weight\":100},{\"children\":[],\"id\":1264622039642256211,\"parentId\":1264622039642256111,\"pid\":1264622039642256111,\"title\":\"字典值列表\",\"value\":\"1264622039642256211\",\"weight\":100},{\"children\":[],\"id\":1264622039642256221,\"parentId\":1264622039642256111,\"pid\":1264622039642256111,\"title\":\"字典值增加\",\"value\":\"1264622039642256221\",\"weight\":100},{\"children\":[],\"id\":1264622039642256231,\"parentId\":1264622039642256111,\"pid\":1264622039642256111,\"title\":\"字典值删除\",\"value\":\"1264622039642256231\",\"weight\":100},{\"children\":[],\"id\":1264622039642256241,\"parentId\":1264622039642256111,\"pid\":1264622039642256111,\"title\":\"字典值编辑\",\"value\":\"1264622039642256241\",\"weight\":100},{\"children\":[],\"id\":1264622039642256251,\"parentId\":1264622039642256111,\"pid\":1264622039642256111,\"title\":\"字典值详情\",\"value\":\"1264622039642256251\",\"weight\":100},{\"children\":[],\"id\":1264622039642256261,\"parentId\":1264622039642256111,\"pid\":1264622039642256111,\"title\":\"字典值修改状态\",\"value\":\"1264622039642256261\",\"weight\":100},{\"children\":[],\"id\":1264622039642256121,\"parentId\":1264622039642256111,\"pid\":1264622039642256111,\"title\":\"字典类型查询\",\"value\":\"1264622039642256121\",\"weight\":100}],\"id\":1264622039642256111,\"parentId\":1264622039642255961,\"pid\":1264622039642255961,\"title\":\"字典管理\",\"value\":\"1264622039642256111\",\"weight\":12},{\"children\":[],\"id\":1264622039642256271,\"parentId\":1264622039642255961,\"pid\":1264622039642255961,\"title\":\"接口文档\",\"value\":\"1264622039642256271\",\"weight\":13}],\"id\":1264622039642255961,\"parentId\":0,\"pid\":0,\"title\":\"开发管理\",\"value\":\"1264622039642255961\",\"weight\":4},{\"children\":[{\"children\":[{\"children\":[],\"id\":1264622039642256301,\"parentId\":1264622039642256291,\"pid\":1264622039642256291,\"title\":\"访问日志查询\",\"value\":\"1264622039642256301\",\"weight\":100},{\"children\":[],\"id\":1264622039642256311,\"parentId\":1264622039642256291,\"pid\":1264622039642256291,\"title\":\"访问日志清空\",\"value\":\"1264622039642256311\",\"weight\":100}],\"id\":1264622039642256291,\"parentId\":1264622039642256281,\"pid\":1264622039642256281,\"title\":\"访问日志\",\"value\":\"1264622039642256291\",\"weight\":14},{\"children\":[{\"children\":[],\"id\":1264622039642256331,\"parentId\":1264622039642256321,\"pid\":1264622039642256321,\"title\":\"操作日志查询\",\"value\":\"1264622039642256331\",\"weight\":100},{\"children\":[],\"id\":1264622039642256341,\"parentId\":1264622039642256321,\"pid\":1264622039642256321,\"title\":\"操作日志清空\",\"value\":\"1264622039642256341\",\"weight\":100}],\"id\":1264622039642256321,\"parentId\":1264622039642256281,\"pid\":1264622039642256281,\"title\":\"操作日志\",\"value\":\"1264622039642256321\",\"weight\":15}],\"id\":1264622039642256281,\"parentId\":0,\"pid\":0,\"title\":\"日志管理\",\"value\":\"1264622039642256281\",\"weight\":5},{\"children\":[{\"children\":[{\"children\":[],\"id\":1264622039642256371,\"parentId\":1264622039642256361,\"pid\":1264622039642256361,\"title\":\"服务监控查询\",\"value\":\"1264622039642256371\",\"weight\":100}],\"id\":1264622039642256361,\"parentId\":1264622039642256351,\"pid\":1264622039642256351,\"title\":\"服务监控\",\"value\":\"1264622039642256361\",\"weight\":16},{\"children\":[{\"children\":[],\"id\":1264622039642256391,\"parentId\":1264622039642256381,\"pid\":1264622039642256381,\"title\":\"在线用户列表\",\"value\":\"1264622039642256391\",\"weight\":100},{\"children\":[],\"id\":1264622039642256401,\"parentId\":1264622039642256381,\"pid\":1264622039642256381,\"title\":\"在线用户强退\",\"value\":\"1264622039642256401\",\"weight\":100}],\"id\":1264622039642256381,\"parentId\":1264622039642256351,\"pid\":1264622039642256351,\"title\":\"在线用户\",\"value\":\"1264622039642256381\",\"weight\":17},{\"children\":[],\"id\":1264622039642256411,\"parentId\":1264622039642256351,\"pid\":1264622039642256351,\"title\":\"数据监控\",\"value\":\"1264622039642256411\",\"weight\":18}],\"id\":1264622039642256351,\"parentId\":0,\"pid\":0,\"title\":\"系统监控\",\"value\":\"1264622039642256351\",\"weight\":6},{\"children\":[{\"children\":[{\"children\":[],\"id\":1264622039642256441,\"parentId\":1264622039642256431,\"pid\":1264622039642256431,\"title\":\"公告查询\",\"value\":\"1264622039642256441\",\"weight\":100},{\"children\":[],\"id\":1264622039642256451,\"parentId\":1264622039642256431,\"pid\":1264622039642256431,\"title\":\"公告增加\",\"value\":\"1264622039642256451\",\"weight\":100},{\"children\":[],\"id\":1264622039642256461,\"parentId\":1264622039642256431,\"pid\":1264622039642256431,\"title\":\"公告编辑\",\"value\":\"1264622039642256461\",\"weight\":100},{\"children\":[],\"id\":1264622039642256471,\"parentId\":1264622039642256431,\"pid\":1264622039642256431,\"title\":\"公告删除\",\"value\":\"1264622039642256471\",\"weight\":100},{\"children\":[],\"id\":1264622039642256481,\"parentId\":1264622039642256431,\"pid\":1264622039642256431,\"title\":\"公告查看\",\"value\":\"1264622039642256481\",\"weight\":100},{\"children\":[],\"id\":1264622039642256491,\"parentId\":1264622039642256431,\"pid\":1264622039642256431,\"title\":\"公告修改状态\",\"value\":\"1264622039642256491\",\"weight\":100}],\"id\":1264622039642256431,\"parentId\":1264622039642256421,\"pid\":1264622039642256421,\"title\":\"公告管理\",\"value\":\"1264622039642256431\",\"weight\":19},{\"children\":[{\"children\":[],\"id\":1264622039642256511,\"parentId\":1264622039642256501,\"pid\":1264622039642256501,\"title\":\"已收公告查询\",\"value\":\"1264622039642256511\",\"weight\":100}],\"id\":1264622039642256501,\"parentId\":1264622039642256421,\"pid\":1264622039642256421,\"title\":\"已收公告\",\"value\":\"1264622039642256501\",\"weight\":20}],\"id\":1264622039642256421,\"parentId\":0,\"pid\":0,\"title\":\"通知公告\",\"value\":\"1264622039642256421\",\"weight\":7},{\"children\":[{\"children\":[{\"children\":[],\"id\":1264622039642256541,\"parentId\":1264622039642256531,\"pid\":1264622039642256531,\"title\":\"文件查询\",\"value\":\"1264622039642256541\",\"weight\":100},{\"children\":[],\"id\":1264622039642256551,\"parentId\":1264622039642256531,\"pid\":1264622039642256531,\"title\":\"文件列表\",\"value\":\"1264622039642256551\",\"weight\":100},{\"children\":[],\"id\":1264622039642256561,\"parentId\":1264622039642256531,\"pid\":1264622039642256531,\"title\":\"文件删除\",\"value\":\"1264622039642256561\",\"weight\":100},{\"children\":[],\"id\":1264622039642256571,\"parentId\":1264622039642256531,\"pid\":1264622039642256531,\"title\":\"文件详情\",\"value\":\"1264622039642256571\",\"weight\":100},{\"children\":[],\"id\":1264622039642256581,\"parentId\":1264622039642256531,\"pid\":1264622039642256531,\"title\":\"文件上传\",\"value\":\"1264622039642256581\",\"weight\":100},{\"children\":[],\"id\":1264622039642256591,\"parentId\":1264622039642256531,\"pid\":1264622039642256531,\"title\":\"文件下载\",\"value\":\"1264622039642256591\",\"weight\":100},{\"children\":[],\"id\":1264622039642256601,\"parentId\":1264622039642256531,\"pid\":1264622039642256531,\"title\":\"图片预览\",\"value\":\"1264622039642256601\",\"weight\":100}],\"id\":1264622039642256531,\"parentId\":1264622039642256521,\"pid\":1264622039642256521,\"title\":\"系统文件\",\"value\":\"1264622039642256531\",\"weight\":21}],\"id\":1264622039642256521,\"parentId\":0,\"pid\":0,\"title\":\"文件管理\",\"value\":\"1264622039642256521\",\"weight\":8},{\"children\":[{\"children\":[{\"children\":[],\"id\":1264622039642256641,\"parentId\":1264622039642256621,\"pid\":1264622039642256621,\"title\":\"定时任务列表\",\"value\":\"1264622039642256641\",\"weight\":100},{\"children\":[],\"id\":1264622039642256651,\"parentId\":1264622039642256621,\"pid\":1264622039642256621,\"title\":\"定时任务详情\",\"value\":\"1264622039642256651\",\"weight\":100},{\"children\":[],\"id\":1264622039642256661,\"parentId\":1264622039642256621,\"pid\":1264622039642256621,\"title\":\"定时任务增加\",\"value\":\"1264622039642256661\",\"weight\":100},{\"children\":[],\"id\":1264622039642256671,\"parentId\":1264622039642256621,\"pid\":1264622039642256621,\"title\":\"定时任务删除\",\"value\":\"1264622039642256671\",\"weight\":100},{\"children\":[],\"id\":1264622039642256681,\"parentId\":1264622039642256621,\"pid\":1264622039642256621,\"title\":\"定时任务编辑\",\"value\":\"1264622039642256681\",\"weight\":100},{\"children\":[],\"id\":1264622039642256691,\"parentId\":1264622039642256621,\"pid\":1264622039642256621,\"title\":\"定时任务可执行列表\",\"value\":\"1264622039642256691\",\"weight\":100},{\"children\":[],\"id\":1264622039642256701,\"parentId\":1264622039642256621,\"pid\":1264622039642256621,\"title\":\"定时任务启动\",\"value\":\"1264622039642256701\",\"weight\":100},{\"children\":[],\"id\":1264622039642256711,\"parentId\":1264622039642256621,\"pid\":1264622039642256621,\"title\":\"定时任务关闭\",\"value\":\"1264622039642256711\",\"weight\":100},{\"children\":[],\"id\":1264622039642256631,\"parentId\":1264622039642256621,\"pid\":1264622039642256621,\"title\":\"定时任务查询\",\"value\":\"1264622039642256631\",\"weight\":100}],\"id\":1264622039642256621,\"parentId\":1264622039642256611,\"pid\":1264622039642256611,\"title\":\"任务管理\",\"value\":\"1264622039642256621\",\"weight\":22}],\"id\":1264622039642256611,\"parentId\":0,\"pid\":0,\"title\":\"定时任务\",\"value\":\"1264622039642256611\",\"weight\":100}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:24:16', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733650380587009', '系统角色_拥有菜单', '6', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysRole/ownMenu', 'com.cn.xiaonuo.sys.modular.role.controller.SysRoleController', 'ownMenu', 'GET', '{\"id\":1265476890672672818}', '{\"code\":200,\"data\":[1264622039642255671,1264622039642255681,1264622039642255761,1264622039642255851,1264622039642255691,1264622039642255701,1264622039642255711,1264622039642255721,1264622039642255731,1264622039642255741,1264622039642255751,1264622039642255771,1264622039642255781,1264622039642255791,1264622039642255801,1264622039642255811,1264622039642255821,1264622039642255831,1264622039642255841,1264622039642255881,1264622039642255891,1264622039642255901,1264622039642255911,1264622039642255921,1264622039642255931,1264622039642255941,1264622039642255951,1264622039642255861,1264622039642255871,1264622039642257021,1264622039642257031,1264622039642256831,1264622039642257261,1264622039642257271,1264622039642257301,1264622039642257321,1264622039642257331,1264622039642257471,1264622039642257481,1264622039642257341,1264622039642257411,1264622039642257421,1264622039642257431,1264622039642257441,1264622039642257451,1264622039642257461,1264622039642257351,1264622039642257361,1264622039642257371,1264622039642257381,1264622039642257391,1264622039642257401,1264622039642257491,1264622039642257501,1264622039642257511,1264622039642255591,1264622039642257061,1264622039642257462,1264622039642256912,1264622039642255421,1264622039642257022,1264622039642256821,1264622039642257311,1264622039642257312,1264622039642257313,1264622039642257314,1264622039642257522,1264622039642257523,1264622039642257524,1264622039642257525,1264622039642257531,1264622039642257532],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:24:16', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733693443506177', '系统字典类型_下拉', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysDictType/dropDown', 'com.cn.xiaonuo.sys.modular.dict.controller.SysDictTypeController', 'dropDown', 'GET', '{\"code\":\"consts_type\"}', '{\"code\":200,\"data\":[{\"code\":\"DEFAULT\",\"value\":\"默认常量\"},{\"code\":\"ALIYUN_SMS\",\"value\":\"阿里云短信\"},{\"code\":\"TENCENT_SMS\",\"value\":\"腾讯云短信\"},{\"code\":\"EMAIL\",\"value\":\"邮件配置\"},{\"code\":\"FILE_PATH\",\"value\":\"文件上传路径\"},{\"code\":\"OAUTH\",\"value\":\"Oauth配置\"}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:24:27', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733694747934722', '系统参数配置_查询', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysConfig/page', 'com.cn.xiaonuo.sys.modular.consts.controller.SysConfigController', 'page', 'GET', '{}', '{\"code\":200,\"data\":{\"pageNo\":1,\"pageSize\":10,\"rainbow\":[1,2,3,4],\"rows\":[{\"code\":\"XIAONUO_TENCENT_SMS_SECRET_ID\",\"createTime\":1591525463000,\"createUser\":1265476890672672808,\"groupCode\":\"TENCENT_SMS\",\"id\":1269575927357071361,\"name\":\"腾讯云短信secretId\",\"remark\":\"腾讯云短信secretId\",\"status\":0,\"sysFlag\":\"Y\",\"value\":\"你的secretId\"},{\"code\":\"XIAONUO_TENCENT_SMS_SIGN\",\"createTime\":1591525502000,\"createUser\":1265476890672672808,\"groupCode\":\"TENCENT_SMS\",\"id\":1269576089294954497,\"name\":\"腾讯云短信签名\",\"remark\":\"腾讯云短信签名\",\"status\":0,\"sysFlag\":\"Y\",\"value\":\"XiaoNuo快速开发平台\"},{\"code\":\"XIAONUO_TENCENT_SMS_SDK_APP_ID\",\"createTime\":1591525491000,\"createUser\":1265476890672672808,\"groupCode\":\"TENCENT_SMS\",\"id\":1269576044084551682,\"name\":\"腾讯云短信sdkAppId\",\"remark\":\"腾讯云短信sdkAppId\",\"status\":0,\"sysFlag\":\"Y\",\"value\":\"1400375123\"},{\"code\":\"XIAONUO_TENCENT_SMS_SECRET_KEY\",\"createTime\":1591525479000,\"createUser\":1265476890672672808,\"groupCode\":\"TENCENT_SMS\",\"id\":1269575991693500418,\"name\":\"腾讯云短信secretKey\",\"remark\":\"腾讯云短信secretKey\",\"status\":0,\"sysFlag\":\"Y\",\"value\":\"你的secretkey\"},{\"code\":\"XIAONUO_ENABLE_OAUTH_LOGIN\",\"createTime\":1595991955000,\"createUser\":1265476890672672808,\"groupCode\":\"OAUTH\",\"id\":1288309751255412737,\"name\":\"Oauth用户登录的开关\",\"remark\":\"Oauth用户登录的开关\",\"status\":0,\"sysFlag\":\"Y\",\"value\":\"true\"},{\"code\":\"XIAONUO_OAUTH_GITEE_CLIENT_ID\",\"createTime\":1595992025000,\"createUser\":1265476890672672808,\"groupCode\":\"OAUTH\",\"id\":1288310043346743297,\"name\":\"Oauth码云登录ClientId\",\"remark\":\"Oauth码云登录ClientId\",\"status\":0,\"sysFlag\":\"Y\",\"value\":\"你的clientId\"},{\"code\":\"XIAONUO_OAUTH_GITEE_REDIRECT_URI\",\"createTime\":1595992081000,\"createUser\":1265476890672672808,\"groupCode\":\"OAUTH\",\"id\":1288310280056483841,\"name\":\"Oauth码云登录回调地址\",\"remark\":\"Oauth码云登录回调地址\",\"status\":0,\"sysFlag\":\"Y\",\"value\":\"http://localhost:82/oauth/callback/gitee\"},{\"code\":\"XIAONUO_OAUTH_GITEE_CLIENT_SECRET\",\"createTime\":1595992052000,\"createUser\":1265476890672672808,\"groupCode\":\"OAUTH\",\"id\":1288310157876408321,\"name\":\"Oauth码云登录ClientSecret\",\"remark\":\"Oauth码云登录ClientSecret\",\"status\":0,\"sysFlag\":\"Y\",\"value\":\"你的clientSecret\"},{\"code\":\"XIAONUO_FILE_UPLOAD_PATH_FOR_WINDOWS\",\"createTime\":1591717357000,\"createUser\":1265476890672672808,\"groupCode\":\"FILE_PATH\",\"id\":1270380786649972738,\"name\":\"win本地上传文件路径\",\"remark\":\"win本地上传文件路径\",\"status\":0,\"sysFlag\":\"Y\",\"value\":\"C:\\\\XNXX\\\\PROJECT\\\\XiaoNuo\\\\img\"},{\"code\":\"XIAONUO_FILE_UPLOAD_PATH_FOR_LINUX\",\"createTime\":1591717357000,\"createUser\":1265476890672672808,\"groupCode\":\"FILE_PATH\",\"id\":1270380786649972739,\"name\":\"linux/mac本地上传文件路径\",\"remark\":\"linux/mac本地上传文件路径\",\"status\":0,\"sysFlag\":\"Y\",\"value\":\"C:\\\\XNXX\\\\PROJECT\\\\XiaoNuo\\\\img\"}],\"totalPage\":4,\"totalRows\":36},\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:24:27', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733713651662849', '短信发送记录查询', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sms/page', 'com.cn.xiaonuo.sys.modular.sms.controller.SmsSenderController', 'page', 'GET', '{}', '{\"code\":200,\"data\":{\"pageNo\":1,\"pageSize\":10,\"rainbow\":[],\"rows\":[],\"totalPage\":0,\"totalRows\":0},\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:24:32', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733713832017921', '系统字典类型_下拉', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysDictType/dropDown', 'com.cn.xiaonuo.sys.modular.dict.controller.SysDictTypeController', 'dropDown', 'GET', '{\"code\":\"send_type\"}', '{\"code\":200,\"data\":[{\"code\":\"2\",\"value\":\"发送失败\"},{\"code\":\"3\",\"value\":\"失效\"},{\"code\":\"1\",\"value\":\"发送成功\"},{\"code\":\"0\",\"value\":\"未发送\"}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:24:32', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733713840406529', '系统字典类型_下拉', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysDictType/dropDown', 'com.cn.xiaonuo.sys.modular.dict.controller.SysDictTypeController', 'dropDown', 'GET', '{\"code\":\"sms_send_source\"}', '{\"code\":200,\"data\":[{\"code\":\"3\",\"value\":\"其他\"},{\"code\":\"1\",\"value\":\"app\"},{\"code\":\"2\",\"value\":\"pc\"}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:24:32', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733717682388994', '系统字典类型_下拉', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysDictType/dropDown', 'com.cn.xiaonuo.sys.modular.dict.controller.SysDictTypeController', 'dropDown', 'GET', '{\"code\":\"common_status\"}', '{\"code\":200,\"data\":[{\"code\":\"0\",\"value\":\"正常\"},{\"code\":\"1\",\"value\":\"停用\"},{\"code\":\"2\",\"value\":\"删除\"}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:24:33', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733718848405506', '系统字典类型_分页查询', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysDictType/page', 'com.cn.xiaonuo.sys.modular.dict.controller.SysDictTypeController', 'page', 'GET', '{}', '{\"code\":200,\"data\":{\"pageNo\":1,\"pageSize\":10,\"rainbow\":[1,2,3],\"rows\":[{\"code\":\"ended_status\",\"createTime\":1596727164000,\"createUser\":1265476890672672808,\"id\":1291393441594408961,\"name\":\"是否结束\",\"remark\":\"是否结束\",\"sort\":100,\"status\":0},{\"code\":\"notice_type\",\"createTime\":1593751309000,\"createUser\":1265476890672672808,\"id\":1278911800547147777,\"name\":\"通知公告类型\",\"remark\":\"通知公告类型\",\"sort\":100,\"status\":0},{\"code\":\"event_type\",\"createTime\":1590546525000,\"createUser\":1265476890672672808,\"id\":1265469962873610241,\"name\":\"事件类型\",\"remark\":\"事件类型\",\"sort\":100,\"status\":0},{\"code\":\"form_type\",\"createTime\":1590546463000,\"createUser\":1265476890672672808,\"id\":1265469702042427393,\"name\":\"表单类型\",\"remark\":\"表单类型\",\"sort\":100,\"status\":0},{\"code\":\"data_scope_type\",\"createTime\":1590546064000,\"createUser\":1265476890672672808,\"id\":1265468028632571905,\"name\":\"数据范围类型\",\"remark\":\"数据范围类型\",\"sort\":100,\"status\":0},{\"code\":\"run_status\",\"createTime\":1593678627000,\"createUser\":1265476890672672808,\"id\":1278606951432855553,\"name\":\"运行状态\",\"remark\":\"定时任务运行状态\",\"sort\":100,\"status\":0},{\"code\":\"send_type\",\"createTime\":1590545616000,\"createUser\":1265476890672672808,\"id\":1265466149622128641,\"name\":\"发送类型\",\"remark\":\"发送类型\",\"sort\":100,\"status\":0},{\"code\":\"open_type\",\"createTime\":1590545760000,\"createUser\":1265476890672672808,\"id\":1265466752209395713,\"name\":\"打开方式\",\"remark\":\"打开方式\",\"sort\":100,\"status\":0},{\"code\":\"script_type\",\"createTime\":1590546343000,\"createUser\":1265476890672672808,\"id\":1265469198583341057,\"name\":\"脚本类型\",\"remark\":\"脚本类型\",\"sort\":100,\"status\":0},{\"code\":\"file_storage_location\",\"createTime\":1593480162000,\"createUser\":1265476890672672808,\"id\":1277774529430654977,\"name\":\"文件存储位置\",\"remark\":\"文件存储位置\",\"sort\":100,\"status\":0}],\"totalPage\":3,\"totalRows\":29},\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:24:33', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733719443996673', '系统字典类型_下拉', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysDictType/dropDown', 'com.cn.xiaonuo.sys.modular.dict.controller.SysDictTypeController', 'dropDown', 'GET', '{\"code\":\"common_status\"}', '{\"code\":200,\"data\":[{\"code\":\"0\",\"value\":\"正常\"},{\"code\":\"1\",\"value\":\"停用\"},{\"code\":\"2\",\"value\":\"删除\"}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:24:33', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733741585727489', '系统字典类型_下拉', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysDictType/dropDown', 'com.cn.xiaonuo.sys.modular.dict.controller.SysDictTypeController', 'dropDown', 'GET', '{\"code\":\"yes_or_no\"}', '{\"code\":200,\"data\":[{\"code\":\"N\",\"value\":\"否\"},{\"code\":\"Y\",\"value\":\"是\"}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:24:38', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733741585727490', '系统字典类型_下拉', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysDictType/dropDown', 'com.cn.xiaonuo.sys.modular.dict.controller.SysDictTypeController', 'dropDown', 'GET', '{\"code\":\"vis_type\"}', '{\"code\":200,\"data\":[{\"code\":\"1\",\"value\":\"登录\"},{\"code\":\"2\",\"value\":\"登出\"}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:24:38', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733745217994754', '系统字典类型_下拉', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysDictType/dropDown', 'com.cn.xiaonuo.sys.modular.dict.controller.SysDictTypeController', 'dropDown', 'GET', '{\"code\":\"op_type\"}', '{\"code\":200,\"data\":[{\"code\":\"5\",\"value\":\"查询\"},{\"code\":\"8\",\"value\":\"导入\"},{\"code\":\"11\",\"value\":\"强退\"},{\"code\":\"4\",\"value\":\"更新\"},{\"code\":\"7\",\"value\":\"树\"},{\"code\":\"12\",\"value\":\"清空\"},{\"code\":\"10\",\"value\":\"授权\"},{\"code\":\"13\",\"value\":\"修改状态\"},{\"code\":\"9\",\"value\":\"导出\"},{\"code\":\"3\",\"value\":\"编辑\"},{\"code\":\"6\",\"value\":\"详情\"},{\"code\":\"0\",\"value\":\"其它\"},{\"code\":\"1\",\"value\":\"增加\"},{\"code\":\"2\",\"value\":\"删除\"}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:24:39', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733746262376449', '系统字典类型_下拉', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysDictType/dropDown', 'com.cn.xiaonuo.sys.modular.dict.controller.SysDictTypeController', 'dropDown', 'GET', '{\"code\":\"yes_or_no\"}', '{\"code\":200,\"data\":[{\"code\":\"N\",\"value\":\"否\"},{\"code\":\"Y\",\"value\":\"是\"}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:24:39', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733757251452930', '系统属性监控_查询', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysMachine/query', 'com.cn.xiaonuo.sys.modular.monitor.controller.SysMachineController', 'query', 'GET', '', '{\"code\":200,\"data\":{\"sysJavaInfo\":{\"javaName\":\"Java(TM) SE Runtime Environment\",\"javaVersion\":\"1.8.0_201-b09\",\"jvmName\":\"Java HotSpot(TM) 64-Bit Server VM\",\"jvmVendor\":\"Oracle Corporation\",\"jvmVersion\":\"25.201-b09\"},\"sysJvmMemInfo\":{\"jvmFreeMemory\":\"533.42 MB\",\"jvmMaxMemory\":\"7.1 GB\",\"jvmMemoryUsedRate\":\"35.34%\",\"jvmTotalMemory\":\"825 MB\",\"jvmUsableMemory\":\"6.81 GB\",\"jvmUsedMemory\":\"291.58 MB\"},\"sysOsInfo\":{\"osArch\":\"amd64\",\"osHostAddress\":\"192.168.117.16\",\"osHostName\":\"KJ-YBS\",\"osName\":\"Windows 10\",\"osVersion\":\"10.0\"}},\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:24:42', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733760552370178', '系统在线用户_列表', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysOnlineUser/list', 'com.cn.xiaonuo.sys.modular.monitor.controller.SysOnlineUserController', 'list', 'GET', '{}', '{\"code\":200,\"data\":{\"pageNo\":1,\"pageSize\":10,\"rainbow\":[1],\"rows\":[{\"account\":\"superAdmin\",\"lastLoginAddress\":\"-\",\"lastLoginBrowser\":\"Chrome\",\"lastLoginIp\":\"127.0.0.1\",\"lastLoginOs\":\"Windows 10 or Windows Server 2016\",\"lastLoginTime\":\"2020-12-01 19:21:22\",\"nickName\":\"超级管理员\",\"sessionId\":\"3d9a3223-d0a1-4042-a292-6ff9c2b25d53\"}],\"totalPage\":1,\"totalRows\":1},\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:24:43', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733778625626113', '系统字典类型_下拉', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysDictType/dropDown', 'com.cn.xiaonuo.sys.modular.dict.controller.SysDictTypeController', 'dropDown', 'GET', '{\"code\":\"notice_status\"}', '{\"code\":200,\"data\":[{\"code\":\"2\",\"value\":\"撤回\"},{\"code\":\"0\",\"value\":\"草稿\"},{\"code\":\"3\",\"value\":\"删除\"},{\"code\":\"1\",\"value\":\"发布\"}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:24:47', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733778789203969', '系统通知公告_查询', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysNotice/page', 'com.cn.xiaonuo.sys.modular.notice.controller.SysNoticeController', 'page', 'GET', '{}', '{\"code\":200,\"data\":{\"pageNo\":1,\"pageSize\":10,\"rainbow\":[1],\"rows\":[{\"content\":\"

  

\",\"createTime\":1599962094000,\"createUser\":1280700700074041345,\"id\":1304961721068220417,\"publicOrgId\":1265476890672672771,\"publicOrgName\":\"研发部\",\"publicTime\":1599962094000,\"publicUserId\":1280700700074041345,\"publicUserName\":\"老俞\",\"status\":1,\"title\":\"北京的秋天\",\"type\":1},{\"content\":\"
  

\",\"createTime\":1599962867000,\"createUser\":1265476890672672808,\"id\":1304964964817104898,\"publicTime\":1599962867000,\"publicUserId\":1265476890672672808,\"publicUserName\":\"超级管理员\",\"status\":1,\"title\":\"北京的秋天\",\"type\":1}],\"totalPage\":1,\"totalRows\":2},\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:24:47', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733778885672962', '系统字典类型_下拉', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysDictType/dropDown', 'com.cn.xiaonuo.sys.modular.dict.controller.SysDictTypeController', 'dropDown', 'GET', '{\"code\":\"notice_type\"}', '{\"code\":200,\"data\":[{\"code\":\"1\",\"value\":\"通知\"},{\"code\":\"2\",\"value\":\"公告\"}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:24:47', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733782471802882', '系统字典类型_下拉', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysDictType/dropDown', 'com.cn.xiaonuo.sys.modular.dict.controller.SysDictTypeController', 'dropDown', 'GET', '{\"code\":\"notice_status\"}', '{\"code\":200,\"data\":[{\"code\":\"2\",\"value\":\"撤回\"},{\"code\":\"0\",\"value\":\"草稿\"},{\"code\":\"3\",\"value\":\"删除\"},{\"code\":\"1\",\"value\":\"发布\"}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:24:48', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733783293886466', '系统通知公告_已收', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysNotice/received', 'com.cn.xiaonuo.sys.modular.notice.controller.SysNoticeController', 'received', 'GET', '{}', '{\"code\":200,\"data\":{\"pageNo\":1,\"pageSize\":10,\"rainbow\":[],\"rows\":[],\"totalPage\":0,\"totalRows\":0},\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:24:48', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733783746871298', '系统字典类型_下拉', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysDictType/dropDown', 'com.cn.xiaonuo.sys.modular.dict.controller.SysDictTypeController', 'dropDown', 'GET', '{\"code\":\"notice_type\"}', '{\"code\":200,\"data\":[{\"code\":\"1\",\"value\":\"通知\"},{\"code\":\"2\",\"value\":\"公告\"}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:24:48', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733789476290561', '系统字典类型_下拉', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysDictType/dropDown', 'com.cn.xiaonuo.sys.modular.dict.controller.SysDictTypeController', 'dropDown', 'GET', '{\"code\":\"notice_status\"}', '{\"code\":200,\"data\":[{\"code\":\"2\",\"value\":\"撤回\"},{\"code\":\"0\",\"value\":\"草稿\"},{\"code\":\"3\",\"value\":\"删除\"},{\"code\":\"1\",\"value\":\"发布\"}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:24:50', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733789476290562', '系统字典类型_下拉', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysDictType/dropDown', 'com.cn.xiaonuo.sys.modular.dict.controller.SysDictTypeController', 'dropDown', 'GET', '{\"code\":\"notice_type\"}', '{\"code\":200,\"data\":[{\"code\":\"1\",\"value\":\"通知\"},{\"code\":\"2\",\"value\":\"公告\"}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:24:50', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733789484679170', '系统通知公告_查询', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysNotice/page', 'com.cn.xiaonuo.sys.modular.notice.controller.SysNoticeController', 'page', 'GET', '{}', '{\"code\":200,\"data\":{\"pageNo\":1,\"pageSize\":10,\"rainbow\":[1],\"rows\":[{\"content\":\"

  

\",\"createTime\":1599962094000,\"createUser\":1280700700074041345,\"id\":1304961721068220417,\"publicOrgId\":1265476890672672771,\"publicOrgName\":\"研发部\",\"publicTime\":1599962094000,\"publicUserId\":1280700700074041345,\"publicUserName\":\"老俞\",\"status\":1,\"title\":\"北京的秋天\",\"type\":1},{\"content\":\"
  

\",\"createTime\":1599962867000,\"createUser\":1265476890672672808,\"id\":1304964964817104898,\"publicTime\":1599962867000,\"publicUserId\":1265476890672672808,\"publicUserName\":\"超级管理员\",\"status\":1,\"title\":\"北京的秋天\",\"type\":1}],\"totalPage\":1,\"totalRows\":2},\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:24:50', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733809298571266', '系统字典类型_下拉', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysDictType/dropDown', 'com.cn.xiaonuo.sys.modular.dict.controller.SysDictTypeController', 'dropDown', 'GET', '{\"code\":\"file_storage_location\"}', '{\"code\":200,\"data\":[{\"code\":\"4\",\"value\":\"本地\"},{\"code\":\"1\",\"value\":\"阿里云\"},{\"code\":\"2\",\"value\":\"腾讯云\"},{\"code\":\"3\",\"value\":\"minio\"}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:24:54', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733810456199170', '文件信息表_分页查询', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysFileInfo/page', 'com.cn.xiaonuo.sys.modular.file.controller.SysFileInfoController', 'page', 'GET', '{}', '{\"code\":200,\"data\":{\"pageNo\":1,\"pageSize\":10,\"rainbow\":[1],\"rows\":[{\"createTime\":1604389896000,\"createUser\":1265476890672672808,\"fileBucket\":\"defaultBucket\",\"fileLocation\":4,\"fileObjectName\":\"1323533270338170882.png\",\"fileOriginName\":\"xiaonuo_logo.png\",\"fileSizeInfo\":\"30.23 kB\",\"fileSizeKb\":30,\"fileSuffix\":\"png\",\"id\":1323533270338170882},{\"createTime\":1604393273000,\"createUser\":1265476890672672808,\"fileBucket\":\"defaultBucket\",\"fileLocation\":4,\"fileObjectName\":\"1323547434033016833.png\",\"fileOriginName\":\"xiaonuo_logo_b.png\",\"fileSizeInfo\":\"30.03 kB\",\"fileSizeKb\":30,\"fileSuffix\":\"png\",\"id\":1323547434033016833},{\"createTime\":1604402642000,\"createUser\":1265476890672672808,\"fileBucket\":\"defaultBucket\",\"fileLocation\":4,\"fileObjectName\":\"1323586730685218817.png\",\"fileOriginName\":\"xiaonuo_logo_b.png\",\"fileSizeInfo\":\"30.4 kB\",\"fileSizeKb\":30,\"fileSuffix\":\"png\",\"id\":1323586730685218817},{\"createTime\":1604646491000,\"createUser\":1265476890672672808,\"fileBucket\":\"defaultBucket\",\"fileLocation\":4,\"fileObjectName\":\"1324609505700892673.png\",\"fileOriginName\":\"xiaonuo_logo_pt_wz.png\",\"fileSizeInfo\":\"29.23 kB\",\"fileSizeKb\":29,\"fileSuffix\":\"png\",\"id\":1324609505700892673}],\"totalPage\":1,\"totalRows\":4},\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:24:55', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733821998923777', '系统字典类型_下拉', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysDictType/dropDown', 'com.cn.xiaonuo.sys.modular.dict.controller.SysDictTypeController', 'dropDown', 'GET', '{\"code\":\"run_status\"}', '{\"code\":200,\"data\":[{\"code\":\"1\",\"value\":\"运行\"},{\"code\":\"2\",\"value\":\"停止\"}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:24:57', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733822036672514', '定时任务_分页查询', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysTimers/page', 'com.cn.xiaonuo.sys.modular.timer.controller.SysTimersController', 'page', 'GET', '{}', '{\"code\":200,\"data\":{\"pageNo\":1,\"pageSize\":10,\"rainbow\":[1],\"rows\":[{\"actionClass\":\"com.cn.xiaonuo.sys.modular.timer.tasks.RefreshConstantsTaskRunner\",\"createTime\":1596099380000,\"createUser\":1265476890672672808,\"cron\":\"0 0/1 * * * ?\",\"id\":1288760324837851137,\"jobStatus\":1,\"remark\":\"定时同步sys_config表的数据到缓存常量中\",\"timerName\":\"定时同步缓存常量\",\"updateTime\":1596099532000,\"updateUser\":1265476890672672808},{\"actionClass\":\"com.cn.xiaonuo.sys.modular.timer.tasks.SystemOutTaskRunner\",\"createTime\":1599964477000,\"createUser\":1265476890672672808,\"cron\":\"0 0 * * * ? *\",\"id\":1304971718170832898,\"jobStatus\":2,\"remark\":\"定时打印一句话\",\"timerName\":\"定时打印一句话\",\"updateTime\":1600864668000,\"updateUser\":1265476890672672808}],\"totalPage\":1,\"totalRows\":2},\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:24:57', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733845096955906', '系统字典类型_下拉', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysDictType/dropDown', 'com.cn.xiaonuo.sys.modular.dict.controller.SysDictTypeController', 'dropDown', 'GET', '{\"code\":\"run_status\"}', '{\"code\":200,\"data\":[{\"code\":\"1\",\"value\":\"运行\"},{\"code\":\"2\",\"value\":\"停止\"}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:25:03', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733845105344514', '定时任务_分页查询', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysTimers/page', 'com.cn.xiaonuo.sys.modular.timer.controller.SysTimersController', 'page', 'GET', '{}', '{\"code\":200,\"data\":{\"pageNo\":1,\"pageSize\":10,\"rainbow\":[1],\"rows\":[{\"actionClass\":\"com.cn.xiaonuo.sys.modular.timer.tasks.RefreshConstantsTaskRunner\",\"createTime\":1596099380000,\"createUser\":1265476890672672808,\"cron\":\"0 0/1 * * * ?\",\"id\":1288760324837851137,\"jobStatus\":1,\"remark\":\"定时同步sys_config表的数据到缓存常量中\",\"timerName\":\"定时同步缓存常量\",\"updateTime\":1596099532000,\"updateUser\":1265476890672672808},{\"actionClass\":\"com.cn.xiaonuo.sys.modular.timer.tasks.SystemOutTaskRunner\",\"createTime\":1599964477000,\"createUser\":1265476890672672808,\"cron\":\"0 0 * * * ? *\",\"id\":1304971718170832898,\"jobStatus\":2,\"remark\":\"定时打印一句话\",\"timerName\":\"定时打印一句话\",\"updateTime\":1600864668000,\"updateUser\":1265476890672672808}],\"totalPage\":1,\"totalRows\":2},\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:25:03', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733919503908866', '系统属性监控_查询', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysMachine/query', 'com.cn.xiaonuo.sys.modular.monitor.controller.SysMachineController', 'query', 'GET', '', '{\"code\":200,\"data\":{\"sysJavaInfo\":{\"javaName\":\"Java(TM) SE Runtime Environment\",\"javaVersion\":\"1.8.0_201-b09\",\"jvmName\":\"Java HotSpot(TM) 64-Bit Server VM\",\"jvmVendor\":\"Oracle Corporation\",\"jvmVersion\":\"25.201-b09\"},\"sysJvmMemInfo\":{\"jvmFreeMemory\":\"496.5 MB\",\"jvmMaxMemory\":\"7.1 GB\",\"jvmMemoryUsedRate\":\"39.82%\",\"jvmTotalMemory\":\"825 MB\",\"jvmUsableMemory\":\"6.78 GB\",\"jvmUsedMemory\":\"328.5 MB\"},\"sysOsInfo\":{\"osArch\":\"amd64\",\"osHostAddress\":\"192.168.117.16\",\"osHostName\":\"KJ-YBS\",\"osName\":\"Windows 10\",\"osVersion\":\"10.0\"}},\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:25:21', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333733926810386434', '系统在线用户_列表', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysOnlineUser/list', 'com.cn.xiaonuo.sys.modular.monitor.controller.SysOnlineUserController', 'list', 'GET', '{}', '{\"code\":200,\"data\":{\"pageNo\":1,\"pageSize\":10,\"rainbow\":[1],\"rows\":[{\"account\":\"superAdmin\",\"lastLoginAddress\":\"-\",\"lastLoginBrowser\":\"Chrome\",\"lastLoginIp\":\"127.0.0.1\",\"lastLoginOs\":\"Windows 10 or Windows Server 2016\",\"lastLoginTime\":\"2020-12-01 19:21:22\",\"nickName\":\"超级管理员\",\"sessionId\":\"3d9a3223-d0a1-4042-a292-6ff9c2b25d53\"}],\"totalPage\":1,\"totalRows\":1},\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:25:22', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333734084381999106', '系统组织机构_树', '7', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysOrg/tree', 'com.cn.xiaonuo.sys.modular.org.controller.SysOrgController', 'tree', 'GET', '{}', '{\"code\":200,\"data\":[{\"children\":[{\"children\":[{\"children\":[],\"id\":1265476890672672771,\"parentId\":1265476890672672769,\"pid\":1265476890672672769,\"title\":\"研发部\",\"value\":\"1265476890672672771\",\"weight\":100},{\"children\":[],\"id\":1265476890672672772,\"parentId\":1265476890672672769,\"pid\":1265476890672672769,\"title\":\"企划部\",\"value\":\"1265476890672672772\",\"weight\":100}],\"id\":1265476890672672769,\"parentId\":1265476890651701250,\"pid\":1265476890651701250,\"title\":\"华夏集团北京分公司\",\"value\":\"1265476890672672769\",\"weight\":100},{\"children\":[{\"children\":[{\"children\":[],\"id\":1265476890672672775,\"parentId\":1265476890672672773,\"pid\":1265476890672672773,\"title\":\"市场部二部\",\"value\":\"1265476890672672775\",\"weight\":100}],\"id\":1265476890672672773,\"parentId\":1265476890672672770,\"pid\":1265476890672672770,\"title\":\"市场部\",\"value\":\"1265476890672672773\",\"weight\":100},{\"children\":[],\"id\":1265476890672672774,\"parentId\":1265476890672672770,\"pid\":1265476890672672770,\"title\":\"财务部\",\"value\":\"1265476890672672774\",\"weight\":100}],\"id\":1265476890672672770,\"parentId\":1265476890651701250,\"pid\":1265476890651701250,\"title\":\"华夏集团成都分公司\",\"value\":\"1265476890672672770\",\"weight\":100}],\"id\":1265476890651701250,\"parentId\":0,\"pid\":0,\"title\":\"华夏集团\",\"value\":\"1265476890651701250\",\"weight\":100}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:26:00', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333734085682233345', '系统用户_查询', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysUser/page', 'com.cn.xiaonuo.sys.modular.user.controller.SysUserController', 'page', 'GET', '{}', '{\"code\":200,\"data\":{\"pageNo\":1,\"pageSize\":10,\"rainbow\":[1],\"rows\":[{\"account\":\"yubaoshan\",\"avatar\":1307866860842360834,\"birthday\":718041600000,\"email\":\"await183@qq.com\",\"id\":1275735541155614721,\"name\":\"俞宝山\",\"nickName\":\"Await\",\"phone\":\"18200001102\",\"sex\":1,\"status\":0,\"sysEmpInfo\":{\"jobNum\":\"102\",\"orgId\":1265476890672672769,\"orgName\":\"华夏集团北京分公司\"},\"tel\":\"\"},{\"account\":\"xuyuxiang\",\"avatar\":1307863777357832194,\"birthday\":1593532800000,\"id\":1280709549107552257,\"name\":\"徐玉祥\",\"nickName\":\"就是那个锅\",\"phone\":\"18200001100\",\"sex\":1,\"status\":0,\"sysEmpInfo\":{\"jobNum\":\"100\",\"orgId\":1265476890672672770,\"orgName\":\"华夏集团成都分公司\"}}],\"totalPage\":1,\"totalRows\":2},\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:26:00', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333734085795479554', '系统字典类型_下拉', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysDictType/dropDown', 'com.cn.xiaonuo.sys.modular.dict.controller.SysDictTypeController', 'dropDown', 'GET', '{\"code\":\"sex\"}', '{\"code\":200,\"data\":[{\"code\":\"1\",\"value\":\"男\"},{\"code\":\"2\",\"value\":\"女\"},{\"code\":\"3\",\"value\":\"未知\"}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:26:00', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333734085900337154', '系统字典类型_下拉', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysDictType/dropDown', 'com.cn.xiaonuo.sys.modular.dict.controller.SysDictTypeController', 'dropDown', 'GET', '{\"code\":\"common_status\"}', '{\"code\":200,\"data\":[{\"code\":\"0\",\"value\":\"正常\"},{\"code\":\"1\",\"value\":\"停用\"},{\"code\":\"2\",\"value\":\"删除\"}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:26:00', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333734090790895618', '系统组织机构_树', '7', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysOrg/tree', 'com.cn.xiaonuo.sys.modular.org.controller.SysOrgController', 'tree', 'GET', '{}', '{\"code\":200,\"data\":[{\"children\":[{\"children\":[{\"children\":[],\"id\":1265476890672672771,\"parentId\":1265476890672672769,\"pid\":1265476890672672769,\"title\":\"研发部\",\"value\":\"1265476890672672771\",\"weight\":100},{\"children\":[],\"id\":1265476890672672772,\"parentId\":1265476890672672769,\"pid\":1265476890672672769,\"title\":\"企划部\",\"value\":\"1265476890672672772\",\"weight\":100}],\"id\":1265476890672672769,\"parentId\":1265476890651701250,\"pid\":1265476890651701250,\"title\":\"华夏集团北京分公司\",\"value\":\"1265476890672672769\",\"weight\":100},{\"children\":[{\"children\":[{\"children\":[],\"id\":1265476890672672775,\"parentId\":1265476890672672773,\"pid\":1265476890672672773,\"title\":\"市场部二部\",\"value\":\"1265476890672672775\",\"weight\":100}],\"id\":1265476890672672773,\"parentId\":1265476890672672770,\"pid\":1265476890672672770,\"title\":\"市场部\",\"value\":\"1265476890672672773\",\"weight\":100},{\"children\":[],\"id\":1265476890672672774,\"parentId\":1265476890672672770,\"pid\":1265476890672672770,\"title\":\"财务部\",\"value\":\"1265476890672672774\",\"weight\":100}],\"id\":1265476890672672770,\"parentId\":1265476890651701250,\"pid\":1265476890651701250,\"title\":\"华夏集团成都分公司\",\"value\":\"1265476890672672770\",\"weight\":100}],\"id\":1265476890651701250,\"parentId\":0,\"pid\":0,\"title\":\"华夏集团\",\"value\":\"1265476890651701250\",\"weight\":100}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:26:01', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333734091025776641', '系统机构_查询', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysOrg/page', 'com.cn.xiaonuo.sys.modular.org.controller.SysOrgController', 'page', 'GET', '{}', '{\"code\":200,\"data\":{\"pageNo\":1,\"pageSize\":10,\"rainbow\":[1],\"rows\":[{\"code\":\"hxjt_bj\",\"createTime\":1585212942000,\"createUser\":1265476890672672808,\"id\":1265476890672672769,\"name\":\"华夏集团北京分公司\",\"pid\":1265476890651701250,\"pids\":\"[0],[1265476890651701250],\",\"remark\":\"华夏集团北京分公司\",\"sort\":100,\"status\":0},{\"code\":\"hxjt_cd\",\"createTime\":1585212962000,\"createUser\":1265476890672672808,\"id\":1265476890672672770,\"name\":\"华夏集团成都分公司\",\"pid\":1265476890651701250,\"pids\":\"[0],[1265476890651701250],\",\"remark\":\"华夏集团成都分公司\",\"sort\":100,\"status\":0},{\"code\":\"hxjt\",\"createTime\":1585212653000,\"createUser\":1265476890672672808,\"id\":1265476890651701250,\"name\":\"华夏集团\",\"pid\":0,\"pids\":\"[0],\",\"remark\":\"华夏集团总公司\",\"sort\":100,\"status\":0},{\"code\":\"hxjt_bj_yfb\",\"createTime\":1585212996000,\"createUser\":1265476890672672808,\"id\":1265476890672672771,\"name\":\"研发部\",\"pid\":1265476890672672769,\"pids\":\"[0],[1265476890651701250],[1265476890672672769],\",\"remark\":\"华夏集团北京分公司研发部\",\"sort\":100,\"status\":0},{\"code\":\"hxjt_bj_qhb\",\"createTime\":1585213026000,\"createUser\":1265476890672672808,\"id\":1265476890672672772,\"name\":\"企划部\",\"pid\":1265476890672672769,\"pids\":\"[0],[1265476890651701250],[1265476890672672769],\",\"remark\":\"华夏集团北京分公司企划部\",\"sort\":100,\"status\":0},{\"code\":\"hxjt_cd_scb\",\"createTime\":1585213055000,\"createUser\":1265476890672672808,\"id\":1265476890672672773,\"name\":\"市场部\",\"pid\":1265476890672672770,\"pids\":\"[0],[1265476890651701250],[1265476890672672770],\",\"remark\":\"华夏集团成都分公司市场部\",\"sort\":100,\"status\":0},{\"code\":\"hxjt_cd_cwb\",\"createTime\":1585213081000,\"createUser\":1265476890672672808,\"id\":1265476890672672774,\"name\":\"财务部\",\"pid\":1265476890672672770,\"pids\":\"[0],[1265476890651701250],[1265476890672672770],\",\"remark\":\"华夏集团成都分公司财务部\",\"sort\":100,\"status\":0},{\"code\":\"hxjt_cd_scb_2b\",\"createTime\":1586158610000,\"createUser\":1265476890672672808,\"id\":1265476890672672775,\"name\":\"市场部二部\",\"pid\":1265476890672672773,\"pids\":\"[0],[1265476890651701250],[1265476890672672770],[1265476890672672773],\",\"remark\":\"华夏集团成都分公司市场部二部\",\"sort\":100,\"status\":0}],\"totalPage\":1,\"totalRows\":8},\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:26:02', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333734091835277313', '系统机构_查询', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysOrg/page', 'com.cn.xiaonuo.sys.modular.org.controller.SysOrgController', 'page', 'GET', '{}', '{\"code\":200,\"data\":{\"pageNo\":1,\"pageSize\":10,\"rainbow\":[1],\"rows\":[{\"code\":\"hxjt_bj\",\"createTime\":1585212942000,\"createUser\":1265476890672672808,\"id\":1265476890672672769,\"name\":\"华夏集团北京分公司\",\"pid\":1265476890651701250,\"pids\":\"[0],[1265476890651701250],\",\"remark\":\"华夏集团北京分公司\",\"sort\":100,\"status\":0},{\"code\":\"hxjt_cd\",\"createTime\":1585212962000,\"createUser\":1265476890672672808,\"id\":1265476890672672770,\"name\":\"华夏集团成都分公司\",\"pid\":1265476890651701250,\"pids\":\"[0],[1265476890651701250],\",\"remark\":\"华夏集团成都分公司\",\"sort\":100,\"status\":0},{\"code\":\"hxjt\",\"createTime\":1585212653000,\"createUser\":1265476890672672808,\"id\":1265476890651701250,\"name\":\"华夏集团\",\"pid\":0,\"pids\":\"[0],\",\"remark\":\"华夏集团总公司\",\"sort\":100,\"status\":0},{\"code\":\"hxjt_bj_yfb\",\"createTime\":1585212996000,\"createUser\":1265476890672672808,\"id\":1265476890672672771,\"name\":\"研发部\",\"pid\":1265476890672672769,\"pids\":\"[0],[1265476890651701250],[1265476890672672769],\",\"remark\":\"华夏集团北京分公司研发部\",\"sort\":100,\"status\":0},{\"code\":\"hxjt_bj_qhb\",\"createTime\":1585213026000,\"createUser\":1265476890672672808,\"id\":1265476890672672772,\"name\":\"企划部\",\"pid\":1265476890672672769,\"pids\":\"[0],[1265476890651701250],[1265476890672672769],\",\"remark\":\"华夏集团北京分公司企划部\",\"sort\":100,\"status\":0},{\"code\":\"hxjt_cd_scb\",\"createTime\":1585213055000,\"createUser\":1265476890672672808,\"id\":1265476890672672773,\"name\":\"市场部\",\"pid\":1265476890672672770,\"pids\":\"[0],[1265476890651701250],[1265476890672672770],\",\"remark\":\"华夏集团成都分公司市场部\",\"sort\":100,\"status\":0},{\"code\":\"hxjt_cd_cwb\",\"createTime\":1585213081000,\"createUser\":1265476890672672808,\"id\":1265476890672672774,\"name\":\"财务部\",\"pid\":1265476890672672770,\"pids\":\"[0],[1265476890651701250],[1265476890672672770],\",\"remark\":\"华夏集团成都分公司财务部\",\"sort\":100,\"status\":0},{\"code\":\"hxjt_cd_scb_2b\",\"createTime\":1586158610000,\"createUser\":1265476890672672808,\"id\":1265476890672672775,\"name\":\"市场部二部\",\"pid\":1265476890672672773,\"pids\":\"[0],[1265476890651701250],[1265476890672672770],[1265476890672672773],\",\"remark\":\"华夏集团成都分公司市场部二部\",\"sort\":100,\"status\":0}],\"totalPage\":1,\"totalRows\":8},\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:26:02', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333734098462277634', '系统职位_查询', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysPos/page', 'com.cn.xiaonuo.sys.modular.pos.controller.SysPosController', 'page', 'GET', '{}', '{\"code\":200,\"data\":{\"pageNo\":1,\"pageSize\":10,\"rainbow\":[1],\"rows\":[{\"code\":\"zjl\",\"createTime\":1585222134000,\"createUser\":1265476890672672808,\"id\":1265476890672672787,\"name\":\"总经理\",\"remark\":\"总经理职位\",\"sort\":100,\"status\":0,\"updateTime\":1591102864000,\"updateUser\":1265476890672672808},{\"code\":\"fzjl\",\"createTime\":1585222197000,\"createUser\":1265476890672672808,\"id\":1265476890672672788,\"name\":\"副总经理\",\"remark\":\"副总经理职位\",\"sort\":100,\"status\":0},{\"code\":\"bmjl\",\"createTime\":1585222309000,\"createUser\":1265476890672672808,\"id\":1265476890672672789,\"name\":\"部门经理\",\"remark\":\"部门经理职位\",\"sort\":100,\"status\":0},{\"code\":\"gzry\",\"createTime\":1590550320000,\"createUser\":1265476890672672808,\"id\":1265476890672672790,\"name\":\"工作人员\",\"remark\":\"工作人员职位\",\"sort\":100,\"status\":0,\"updateTime\":1590979895000,\"updateUser\":1265476890672672808}],\"totalPage\":1,\"totalRows\":4},\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:26:03', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333734210706046978', '文件信息表_上传文件', '0', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysFileInfo/upload', 'com.cn.xiaonuo.sys.modular.file.controller.SysFileInfoController', 'upload', 'POST', '', '{\"code\":200,\"data\":1333734209900740609,\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:26:30', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333734212153081858', '系统用户_修改头像', '4', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysUser/updateAvatar', 'com.cn.xiaonuo.sys.modular.user.controller.SysUserController', 'updateAvatar', 'POST', '{\"avatar\":1333734209900740609,\"id\":1265476890672672808}', '{\"code\":200,\"message\":\"请求成功\",\"success\":true}', '2020-12-01 19:26:30', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333744727797497857', '系统字典类型_树', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysDictType/tree', 'com.cn.xiaonuo.sys.modular.dict.controller.SysDictTypeController', 'tree', 'GET', '', '{\"code\":200,\"data\":[{\"children\":[{\"children\":[],\"code\":\"0\",\"id\":1265216617500102656,\"name\":\"正常\",\"pid\":1265216211667636226},{\"children\":[],\"code\":\"1\",\"id\":1265216617500102657,\"name\":\"停用\",\"pid\":1265216211667636226},{\"children\":[],\"code\":\"2\",\"id\":1265216938389524482,\"name\":\"删除\",\"pid\":1265216211667636226}],\"code\":\"common_status\",\"id\":1265216211667636226,\"name\":\"通用状态\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"1\",\"id\":1265216536659087357,\"name\":\"男\",\"pid\":1265216211667636234},{\"children\":[],\"code\":\"2\",\"id\":1265216536659087358,\"name\":\"女\",\"pid\":1265216211667636234},{\"children\":[],\"code\":\"3\",\"id\":1265216536659087359,\"name\":\"未知\",\"pid\":1265216211667636234}],\"code\":\"sex\",\"id\":1265216211667636234,\"name\":\"性别\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"DEFAULT\",\"id\":1265216536659087361,\"name\":\"默认常量\",\"pid\":1265216211667636235},{\"children\":[],\"code\":\"ALIYUN_SMS\",\"id\":1265216536659087363,\"name\":\"阿里云短信\",\"pid\":1265216211667636235},{\"children\":[],\"code\":\"TENCENT_SMS\",\"id\":1265216536659087364,\"name\":\"腾讯云短信\",\"pid\":1265216211667636235},{\"children\":[],\"code\":\"EMAIL\",\"id\":1265216536659087365,\"name\":\"邮件配置\",\"pid\":1265216211667636235},{\"children\":[],\"code\":\"FILE_PATH\",\"id\":1265216536659087366,\"name\":\"文件上传路径\",\"pid\":1265216211667636235},{\"children\":[],\"code\":\"OAUTH\",\"id\":1265216536659087367,\"name\":\"Oauth配置\",\"pid\":1265216211667636235}],\"code\":\"consts_type\",\"id\":1265216211667636235,\"name\":\"常量的分类\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"N\",\"id\":1265217669028892673,\"name\":\"否\",\"pid\":1265217074079453185},{\"children\":[],\"code\":\"Y\",\"id\":1265217706584690689,\"name\":\"是\",\"pid\":1265217074079453185}],\"code\":\"yes_or_no\",\"id\":1265217074079453185,\"name\":\"是否\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"1\",\"id\":1265220776437731330,\"name\":\"登录\",\"pid\":1265217846770913282},{\"children\":[],\"code\":\"2\",\"id\":1265220806070489090,\"name\":\"登出\",\"pid\":1265217846770913282}],\"code\":\"vis_type\",\"id\":1265217846770913282,\"name\":\"访问类型\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"0\",\"id\":1265221129564573697,\"name\":\"目录\",\"pid\":1265221049302372354},{\"children\":[],\"code\":\"1\",\"id\":1265221163119005697,\"name\":\"菜单\",\"pid\":1265221049302372354},{\"children\":[],\"code\":\"2\",\"id\":1265221188091891713,\"name\":\"按钮\",\"pid\":1265221049302372354}],\"code\":\"menu_type\",\"id\":1265221049302372354,\"name\":\"菜单类型\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"0\",\"id\":1265466389204967426,\"name\":\"未发送\",\"pid\":1265466149622128641},{\"children\":[],\"code\":\"1\",\"id\":1265466432670539778,\"name\":\"发送成功\",\"pid\":1265466149622128641},{\"children\":[],\"code\":\"2\",\"id\":1265466486097584130,\"name\":\"发送失败\",\"pid\":1265466149622128641},{\"children\":[],\"code\":\"3\",\"id\":1265466530477514754,\"name\":\"失效\",\"pid\":1265466149622128641}],\"code\":\"send_type\",\"id\":1265466149622128641,\"name\":\"发送类型\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"0\",\"id\":1265466835009150978,\"name\":\"无\",\"pid\":1265466752209395713},{\"children\":[],\"code\":\"1\",\"id\":1265466874758569986,\"name\":\"组件\",\"pid\":1265466752209395713},{\"children\":[],\"code\":\"2\",\"id\":1265466925476093953,\"name\":\"内链\",\"pid\":1265466752209395713},{\"children\":[],\"code\":\"3\",\"id\":1265466962209808385,\"name\":\"外链\",\"pid\":1265466752209395713}],\"code\":\"open_type\",\"id\":1265466752209395713,\"name\":\"打开方式\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"1\",\"id\":1265467428423475202,\"name\":\"系统权重\",\"pid\":1265467337566461954},{\"children\":[],\"code\":\"2\",\"id\":1265467503090475009,\"name\":\"业务权重\",\"pid\":1265467337566461954}],\"code\":\"menu_weight\",\"id\":1265467337566461954,\"name\":\"菜单权重\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"1\",\"id\":1265467709110493186,\"name\":\"事假\",\"pid\":1265467629167058946},{\"children\":[],\"code\":\"2\",\"id\":1265467745013735426,\"name\":\"病假\",\"pid\":1265467629167058946},{\"children\":[],\"code\":\"3\",\"id\":1265467785253888001,\"name\":\"婚假\",\"pid\":1265467629167058946},{\"children\":[],\"code\":\"4\",\"id\":1265467823426248706,\"name\":\"丧假\",\"pid\":1265467629167058946},{\"children\":[],\"code\":\"5\",\"id\":1265467855781109762,\"name\":\"产假\",\"pid\":1265467629167058946},{\"children\":[],\"code\":\"6\",\"id\":1265467895782187010,\"name\":\"其他\",\"pid\":1265467629167058946}],\"code\":\"leave_type\",\"id\":1265467629167058946,\"name\":\"请假类型\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"1\",\"id\":1265468138431062018,\"name\":\"全部数据\",\"pid\":1265468028632571905},{\"children\":[],\"code\":\"2\",\"id\":1265468194928336897,\"name\":\"本部门及以下数据\",\"pid\":1265468028632571905},{\"children\":[],\"code\":\"3\",\"id\":1265468241992622082,\"name\":\"本部门数据\",\"pid\":1265468028632571905},{\"children\":[],\"code\":\"4\",\"id\":1265468273634451457,\"name\":\"仅本人数据\",\"pid\":1265468028632571905},{\"children\":[],\"code\":\"5\",\"id\":1265468302046666753,\"name\":\"自定义数据\",\"pid\":1265468028632571905}],\"code\":\"data_scope_type\",\"id\":1265468028632571905,\"name\":\"数据范围类型\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"1\",\"id\":1265468508100239362,\"name\":\"app\",\"pid\":1265468437904367618},{\"children\":[],\"code\":\"2\",\"id\":1265468543433056258,\"name\":\"pc\",\"pid\":1265468437904367618},{\"children\":[],\"code\":\"3\",\"id\":1265468576874242050,\"name\":\"其他\",\"pid\":1265468437904367618}],\"code\":\"sms_send_source\",\"id\":1265468437904367618,\"name\":\"短信发送来源\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"1\",\"id\":1265468839764828161,\"name\":\"Integer\",\"pid\":1265468761230680066},{\"children\":[],\"code\":\"2\",\"id\":1265468871641538562,\"name\":\"String\",\"pid\":1265468761230680066},{\"children\":[],\"code\":\"3\",\"id\":1265468898896125954,\"name\":\"Long\",\"pid\":1265468761230680066},{\"children\":[],\"code\":\"4\",\"id\":1265468922275176450,\"name\":\"Double\",\"pid\":1265468761230680066},{\"children\":[],\"code\":\"5\",\"id\":1265468946648276993,\"name\":\"Boolean\",\"pid\":1265468761230680066},{\"children\":[],\"code\":\"6\",\"id\":1265468970450952193,\"name\":\"Date\",\"pid\":1265468761230680066},{\"children\":[],\"code\":\"7\",\"id\":1265468970450952194,\"name\":\"List\",\"pid\":1265468761230680066}],\"code\":\"filed_type\",\"id\":1265468761230680066,\"name\":\"字段类型\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"1\",\"id\":1265469305756196865,\"name\":\"流程脚本\",\"pid\":1265469198583341057},{\"children\":[],\"code\":\"2\",\"id\":1265469330859106306,\"name\":\"系统脚本\",\"pid\":1265469198583341057}],\"code\":\"script_type\",\"id\":1265469198583341057,\"name\":\"脚本类型\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"1\",\"id\":1265469526330449922,\"name\":\"groovy\",\"pid\":1265469441454514178}],\"code\":\"script_language_type\",\"id\":1265469441454514178,\"name\":\"脚本语言类型\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"1\",\"id\":1265469753078718464,\"name\":\"启动\",\"pid\":1265469702042427393},{\"children\":[],\"code\":\"2\",\"id\":1265469753078718465,\"name\":\"全局\",\"pid\":1265469702042427393},{\"children\":[],\"code\":\"3\",\"id\":1265469779460890626,\"name\":\"节点\",\"pid\":1265469702042427393}],\"code\":\"form_type\",\"id\":1265469702042427393,\"name\":\"表单类型\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"PROCESS_STARTED\",\"id\":1265470046877130753,\"name\":\"流程启动\",\"pid\":1265469962873610241},{\"children\":[],\"code\":\"PROCESS_COMPLETED\",\"id\":1265470074517594113,\"name\":\"流程完成\",\"pid\":1265469962873610241},{\"children\":[],\"code\":\"PROCESS_CANCELLED\",\"id\":1265470103152107521,\"name\":\"流程取消\",\"pid\":1265469962873610241},{\"children\":[],\"code\":\"ACTIVITY_STARTED\",\"id\":1265470125725851649,\"name\":\"活动开始\",\"pid\":1265469962873610241},{\"children\":[],\"code\":\"ACTIVITY_COMPLETED\",\"id\":1265470153416646657,\"name\":\"活动完成\",\"pid\":1265469962873610241},{\"children\":[],\"code\":\"ACTIVITY_CANCELLED\",\"id\":1265470179165478913,\"name\":\"活动取消\",\"pid\":1265469962873610241},{\"children\":[],\"code\":\"TASK_ASSIGNED\",\"id\":1265470207363784705,\"name\":\"任务分配\",\"pid\":1265469962873610241},{\"children\":[],\"code\":\"TASK_CREATED\",\"id\":1265470236853936130,\"name\":\"任务创建\",\"pid\":1265469962873610241},{\"children\":[],\"code\":\"TASK_COMPLETED\",\"id\":1265470266780295170,\"name\":\"任务完成\",\"pid\":1265469962873610241},{\"children\":[],\"code\":\"SEQUENCEFLOW_TAKEN\",\"id\":1265470296446607361,\"name\":\"连接线\",\"pid\":1265469962873610241}],\"code\":\"event_type\",\"id\":1265469962873610241,\"name\":\"事件类型\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"1\",\"id\":1265470296446607362,\"name\":\"全局\",\"pid\":1265469962873610242},{\"children\":[],\"code\":\"2\",\"id\":1265470296446607363,\"name\":\"节点\",\"pid\":1265469962873610242}],\"code\":\"event_node_type\",\"id\":1265469962873610242,\"name\":\"事件节点类型\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"0\",\"id\":1265470526197997569,\"name\":\"草稿\",\"pid\":1265470456631271426},{\"children\":[],\"code\":\"1\",\"id\":1265470552823439361,\"name\":\"审核中\",\"pid\":1265470456631271426},{\"children\":[],\"code\":\"2\",\"id\":1265470575615287297,\"name\":\"已退回\",\"pid\":1265470456631271426},{\"children\":[],\"code\":\"3\",\"id\":1265470607588466690,\"name\":\"已完成\",\"pid\":1265470456631271426}],\"code\":\"process_status\",\"id\":1265470456631271426,\"name\":\"流程状态\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"0\",\"id\":1275617233011335170,\"name\":\"其它\",\"pid\":1275617093517172738},{\"children\":[],\"code\":\"1\",\"id\":1275617295355469826,\"name\":\"增加\",\"pid\":1275617093517172738},{\"children\":[],\"code\":\"2\",\"id\":1275617348610547714,\"name\":\"删除\",\"pid\":1275617093517172738},{\"children\":[],\"code\":\"3\",\"id\":1275617395515449346,\"name\":\"编辑\",\"pid\":1275617093517172738},{\"children\":[],\"code\":\"4\",\"id\":1275617433612312577,\"name\":\"更新\",\"pid\":1275617093517172738},{\"children\":[],\"code\":\"5\",\"id\":1275617472707420161,\"name\":\"查询\",\"pid\":1275617093517172738},{\"children\":[],\"code\":\"6\",\"id\":1275617502973517826,\"name\":\"详情\",\"pid\":1275617093517172738},{\"children\":[],\"code\":\"7\",\"id\":1275617536959963137,\"name\":\"树\",\"pid\":1275617093517172738},{\"children\":[],\"code\":\"8\",\"id\":1275617619524837377,\"name\":\"导入\",\"pid\":1275617093517172738},{\"children\":[],\"code\":\"9\",\"id\":1275617651816783873,\"name\":\"导出\",\"pid\":1275617093517172738},{\"children\":[],\"code\":\"10\",\"id\":1275617683475390465,\"name\":\"授权\",\"pid\":1275617093517172738},{\"children\":[],\"code\":\"11\",\"id\":1275617709928865793,\"name\":\"强退\",\"pid\":1275617093517172738},{\"children\":[],\"code\":\"12\",\"id\":1275617739091861505,\"name\":\"清空\",\"pid\":1275617093517172738},{\"children\":[],\"code\":\"13\",\"id\":1275617788601425921,\"name\":\"修改状态\",\"pid\":1275617093517172738}],\"code\":\"op_type\",\"id\":1275617093517172738,\"name\":\"操作类型\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"1\",\"id\":1277774590944317441,\"name\":\"阿里云\",\"pid\":1277774529430654977},{\"children\":[],\"code\":\"2\",\"id\":1277774666055913474,\"name\":\"腾讯云\",\"pid\":1277774529430654977},{\"children\":[],\"code\":\"3\",\"id\":1277774695168577538,\"name\":\"minio\",\"pid\":1277774529430654977},{\"children\":[],\"code\":\"4\",\"id\":1277774726835572737,\"name\":\"本地\",\"pid\":1277774529430654977}],\"code\":\"file_storage_location\",\"id\":1277774529430654977,\"name\":\"文件存储位置\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"1\",\"id\":1278607123583868929,\"name\":\"运行\",\"pid\":1278606951432855553},{\"children\":[],\"code\":\"2\",\"id\":1278607162943217666,\"name\":\"停止\",\"pid\":1278606951432855553}],\"code\":\"run_status\",\"id\":1278606951432855553,\"name\":\"运行状态\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"1\",\"id\":1278939265862004738,\"name\":\"通知\",\"pid\":1278911800547147777},{\"children\":[],\"code\":\"2\",\"id\":1278939319922388994,\"name\":\"公告\",\"pid\":1278911800547147777}],\"code\":\"notice_type\",\"id\":1278911800547147777,\"name\":\"通知公告类型\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"0\",\"id\":1278939399001796609,\"name\":\"草稿\",\"pid\":1278911952657776642},{\"children\":[],\"code\":\"1\",\"id\":1278939432686252034,\"name\":\"发布\",\"pid\":1278911952657776642},{\"children\":[],\"code\":\"2\",\"id\":1278939458804183041,\"name\":\"撤回\",\"pid\":1278911952657776642},{\"children\":[],\"code\":\"3\",\"id\":1278939485878415362,\"name\":\"删除\",\"pid\":1278911952657776642}],\"code\":\"notice_status\",\"id\":1278911952657776642,\"name\":\"通知公告状态\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"0\",\"id\":1278992343223025665,\"name\":\"委托中\",\"pid\":1278992276965605377},{\"children\":[],\"code\":\"1\",\"id\":1278992370066571266,\"name\":\"委托结束\",\"pid\":1278992276965605377},{\"children\":[],\"code\":\"2\",\"id\":1278992396788482050,\"name\":\"未委托\",\"pid\":1278992276965605377}],\"code\":\"delegate_status\",\"id\":1278992276965605377,\"name\":\"委托状态\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"true\",\"id\":1291391148769738754,\"name\":\"是\",\"pid\":1291391077990858754},{\"children\":[],\"code\":\"false\",\"id\":1291391205719998465,\"name\":\"否\",\"pid\":1291391077990858754}],\"code\":\"suspended_status\",\"id\":1291391077990858754,\"name\":\"流程是否挂起\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"true\",\"id\":1291393684314587138,\"name\":\"是\",\"pid\":1291393441594408961},{\"children\":[],\"code\":\"false\",\"id\":1291393766048989186,\"name\":\"否\",\"pid\":1291393441594408961}],\"code\":\"ended_status\",\"id\":1291393441594408961,\"name\":\"是否结束\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"com.mysql.cj.jdbc.Driver\",\"id\":1300767954291433474,\"name\":\"Mysql\",\"pid\":1300767512828354562},{\"children\":[],\"code\":\"oracle.jdbc.OracleDriver\",\"id\":1300768214854180866,\"name\":\"Oracle\",\"pid\":1300767512828354562},{\"children\":[],\"code\":\"com.microsoft.jdbc.sqlserver.SQLServerDriver\",\"id\":1300768392747196417,\"name\":\"Sqlserver\",\"pid\":1300767512828354562}],\"code\":\"jdbc_driver\",\"id\":1300767512828354562,\"name\":\"JDBC驱动类型\",\"pid\":0},{\"children\":[{\"children\":[],\"code\":\"0\",\"id\":1300768392747196418,\"name\":\"未支付\",\"pid\":1300767512828354563},{\"children\":[],\"code\":\"1\",\"id\":1300768392747196419,\"name\":\"已支付\",\"pid\":1300767512828354563},{\"children\":[],\"code\":\"2\",\"id\":1300768392747196420,\"name\":\"已退款\",\"pid\":1300767512828354563},{\"children\":[],\"code\":\"3\",\"id\":1300768392747196421,\"name\":\"已关闭\",\"pid\":1300767512828354563},{\"children\":[],\"code\":\"4\",\"id\":1300768392747196422,\"name\":\"已关闭有退款\",\"pid\":1300767512828354563}],\"code\":\"alipay_trade_status\",\"id\":1300767512828354563,\"name\":\"支付宝交易状态\",\"pid\":0}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 20:08:18', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333744765906944001', '系统字典类型_下拉', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysDictType/dropDown', 'com.cn.xiaonuo.sys.modular.dict.controller.SysDictTypeController', 'dropDown', 'GET', '{\"code\":\"run_status\"}', '{\"code\":200,\"data\":[{\"code\":\"1\",\"value\":\"运行\"},{\"code\":\"2\",\"value\":\"停止\"}],\"message\":\"请求成功\",\"success\":true}', '2020-12-01 20:08:27', 'superAdmin'); +INSERT INTO `sys_op_log` VALUES ('1333744766947131394', '定时任务_分页查询', '5', 'Y', 0xE68890E58A9F, '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '/sysTimers/page', 'com.cn.xiaonuo.sys.modular.timer.controller.SysTimersController', 'page', 'GET', '{}', '{\"code\":200,\"data\":{\"pageNo\":1,\"pageSize\":10,\"rainbow\":[1],\"rows\":[{\"actionClass\":\"com.cn.xiaonuo.sys.modular.timer.tasks.RefreshConstantsTaskRunner\",\"createTime\":1596099380000,\"createUser\":1265476890672672808,\"cron\":\"0 0/1 * * * ?\",\"id\":1288760324837851137,\"jobStatus\":1,\"remark\":\"定时同步sys_config表的数据到缓存常量中\",\"timerName\":\"定时同步缓存常量\",\"updateTime\":1596099532000,\"updateUser\":1265476890672672808},{\"actionClass\":\"com.cn.xiaonuo.sys.modular.timer.tasks.SystemOutTaskRunner\",\"createTime\":1599964477000,\"createUser\":1265476890672672808,\"cron\":\"0 0 * * * ? *\",\"id\":1304971718170832898,\"jobStatus\":2,\"remark\":\"定时打印一句话\",\"timerName\":\"定时打印一句话\",\"updateTime\":1600864668000,\"updateUser\":1265476890672672808}],\"totalPage\":1,\"totalRows\":2},\"message\":\"请求成功\",\"success\":true}', '2020-12-01 20:08:27', 'superAdmin'); + +-- ---------------------------- +-- Table structure for `sys_org` +-- ---------------------------- +DROP TABLE IF EXISTS `sys_org`; +CREATE TABLE `sys_org` ( + `id` bigint(20) NOT NULL COMMENT '主键', + `pid` bigint(20) NOT NULL COMMENT '父id', + `pids` text NOT NULL COMMENT '父ids', + `name` varchar(100) NOT NULL COMMENT '名称', + `code` varchar(50) NOT NULL COMMENT '编码', + `sort` int(11) NOT NULL COMMENT '排序', + `remark` varchar(255) DEFAULT NULL COMMENT '描述', + `status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '状态(字典 0正常 1停用 2删除)', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `create_user` bigint(20) DEFAULT NULL COMMENT '创建人', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `update_user` bigint(20) DEFAULT NULL COMMENT '更新人', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='系统组织机构表'; + +-- ---------------------------- +-- Records of sys_org +-- ---------------------------- +INSERT INTO `sys_org` VALUES ('1265476890651701250', '0', '[0],', '华夏集团', 'hxjt', '100', '华夏集团总公司', '0', '2020-03-26 16:50:53', '1265476890672672808', null, null); +INSERT INTO `sys_org` VALUES ('1265476890672672769', '1265476890651701250', '[0],[1265476890651701250],', '华夏集团北京分公司', 'hxjt_bj', '100', '华夏集团北京分公司', '0', '2020-03-26 16:55:42', '1265476890672672808', null, null); +INSERT INTO `sys_org` VALUES ('1265476890672672770', '1265476890651701250', '[0],[1265476890651701250],', '华夏集团成都分公司', 'hxjt_cd', '100', '华夏集团成都分公司', '0', '2020-03-26 16:56:02', '1265476890672672808', null, null); +INSERT INTO `sys_org` VALUES ('1265476890672672771', '1265476890672672769', '[0],[1265476890651701250],[1265476890672672769],', '研发部', 'hxjt_bj_yfb', '100', '华夏集团北京分公司研发部', '0', '2020-03-26 16:56:36', '1265476890672672808', null, null); +INSERT INTO `sys_org` VALUES ('1265476890672672772', '1265476890672672769', '[0],[1265476890651701250],[1265476890672672769],', '企划部', 'hxjt_bj_qhb', '100', '华夏集团北京分公司企划部', '0', '2020-03-26 16:57:06', '1265476890672672808', null, null); +INSERT INTO `sys_org` VALUES ('1265476890672672773', '1265476890672672770', '[0],[1265476890651701250],[1265476890672672770],', '市场部', 'hxjt_cd_scb', '100', '华夏集团成都分公司市场部', '0', '2020-03-26 16:57:35', '1265476890672672808', null, null); +INSERT INTO `sys_org` VALUES ('1265476890672672774', '1265476890672672770', '[0],[1265476890651701250],[1265476890672672770],', '财务部', 'hxjt_cd_cwb', '100', '华夏集团成都分公司财务部', '0', '2020-03-26 16:58:01', '1265476890672672808', null, null); +INSERT INTO `sys_org` VALUES ('1265476890672672775', '1265476890672672773', '[0],[1265476890651701250],[1265476890672672770],[1265476890672672773],', '市场部二部', 'hxjt_cd_scb_2b', '100', '华夏集团成都分公司市场部二部', '0', '2020-04-06 15:36:50', '1265476890672672808', null, null); + +-- ---------------------------- +-- Table structure for `sys_pos` +-- ---------------------------- +DROP TABLE IF EXISTS `sys_pos`; +CREATE TABLE `sys_pos` ( + `id` bigint(20) NOT NULL COMMENT '主键', + `name` varchar(100) NOT NULL COMMENT '名称', + `code` varchar(50) NOT NULL COMMENT '编码', + `sort` int(11) NOT NULL COMMENT '排序', + `remark` varchar(255) DEFAULT NULL COMMENT '备注', + `status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '状态(字典 0正常 1停用 2删除)', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `create_user` bigint(20) DEFAULT NULL COMMENT '创建人', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `update_user` bigint(20) DEFAULT NULL COMMENT '更新人', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE KEY `CODE_UNI` (`code`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='系统职位表'; + +-- ---------------------------- +-- Records of sys_pos +-- ---------------------------- +INSERT INTO `sys_pos` VALUES ('1265476890672672787', '总经理', 'zjl', '100', '总经理职位', '0', '2020-03-26 19:28:54', '1265476890672672808', '2020-06-02 21:01:04', '1265476890672672808'); +INSERT INTO `sys_pos` VALUES ('1265476890672672788', '副总经理', 'fzjl', '100', '副总经理职位', '0', '2020-03-26 19:29:57', '1265476890672672808', null, null); +INSERT INTO `sys_pos` VALUES ('1265476890672672789', '部门经理', 'bmjl', '100', '部门经理职位', '0', '2020-03-26 19:31:49', '1265476890672672808', null, null); +INSERT INTO `sys_pos` VALUES ('1265476890672672790', '工作人员', 'gzry', '100', '工作人员职位', '0', '2020-05-27 11:32:00', '1265476890672672808', '2020-06-01 10:51:35', '1265476890672672808'); + +-- ---------------------------- +-- Table structure for `sys_role` +-- ---------------------------- +DROP TABLE IF EXISTS `sys_role`; +CREATE TABLE `sys_role` ( + `id` bigint(20) NOT NULL COMMENT '主键id', + `name` varchar(100) NOT NULL COMMENT '名称', + `code` varchar(50) NOT NULL COMMENT '编码', + `sort` int(11) NOT NULL COMMENT '序号', + `data_scope_type` tinyint(4) NOT NULL DEFAULT '1' COMMENT '数据范围类型(字典 1全部数据 2本部门及以下数据 3本部门数据 4仅本人数据 5自定义数据)', + `remark` varchar(255) DEFAULT NULL COMMENT '备注', + `status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '状态(字典 0正常 1停用 2删除)', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `create_user` bigint(20) DEFAULT NULL COMMENT '创建人', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `update_user` bigint(20) DEFAULT NULL COMMENT '更新人', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='系统角色表'; + +-- ---------------------------- +-- Records of sys_role +-- ---------------------------- +INSERT INTO `sys_role` VALUES ('1265476890672672817', '组织架构管理员', 'ent_manager_role', '100', '1', '组织架构管理员', '0', '2020-04-02 19:27:26', '1265476890672672808', '2020-09-12 15:54:07', '1265476890672672808'); +INSERT INTO `sys_role` VALUES ('1265476890672672818', '权限管理员', 'auth_role', '101', '5', '权限管理员', '0', '2020-04-02 19:28:40', '1265476890672672808', '2020-07-16 10:52:21', '1265476890672672808'); +INSERT INTO `sys_role` VALUES ('1265476890672672819', '公告发布员', 'notice_produce_role', '102', '5', '公告发布员', '0', '2020-05-29 15:48:11', '1265476890672672808', '2020-08-08 19:28:34', '1265476890672672808'); + +-- ---------------------------- +-- Table structure for `sys_role_data_scope` +-- ---------------------------- +DROP TABLE IF EXISTS `sys_role_data_scope`; +CREATE TABLE `sys_role_data_scope` ( + `id` bigint(20) NOT NULL COMMENT '主键', + `role_id` bigint(20) NOT NULL COMMENT '角色id', + `org_id` bigint(20) NOT NULL COMMENT '机构id', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='系统角色数据范围表'; + +-- ---------------------------- +-- Records of sys_role_data_scope +-- ---------------------------- +INSERT INTO `sys_role_data_scope` VALUES ('1277435908822102018', '1265476890672672818', '1265476890651701250'); +INSERT INTO `sys_role_data_scope` VALUES ('1277435909635796993', '1265476890672672818', '1265476890672672769'); +INSERT INTO `sys_role_data_scope` VALUES ('1277435910432714754', '1265476890672672818', '1265476890672672771'); +INSERT INTO `sys_role_data_scope` VALUES ('1277435911233826818', '1265476890672672818', '1265476890672672772'); +INSERT INTO `sys_role_data_scope` VALUES ('1277435912018161666', '1265476890672672818', '1265476890672672770'); +INSERT INTO `sys_role_data_scope` VALUES ('1277435912810885122', '1265476890672672818', '1265476890672672773'); +INSERT INTO `sys_role_data_scope` VALUES ('1277435913595219970', '1265476890672672818', '1265476890672672775'); +INSERT INTO `sys_role_data_scope` VALUES ('1277435914392137730', '1265476890672672818', '1265476890672672774'); +INSERT INTO `sys_role_data_scope` VALUES ('1292060127645429762', '1265476890672672819', '1265476890672672774'); + +-- ---------------------------- +-- Table structure for `sys_role_menu` +-- ---------------------------- +DROP TABLE IF EXISTS `sys_role_menu`; +CREATE TABLE `sys_role_menu` ( + `id` bigint(20) NOT NULL COMMENT '主键', + `role_id` bigint(20) NOT NULL COMMENT '角色id', + `menu_id` bigint(20) NOT NULL COMMENT '菜单id', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='系统角色菜单表'; + +-- ---------------------------- +-- Records of sys_role_menu +-- ---------------------------- +INSERT INTO `sys_role_menu` VALUES ('1304366872187256834', '1265476890672672818', '1264622039642255671'); +INSERT INTO `sys_role_menu` VALUES ('1304366872602492929', '1265476890672672818', '1264622039642255681'); +INSERT INTO `sys_role_menu` VALUES ('1304366873026117634', '1265476890672672818', '1264622039642255761'); +INSERT INTO `sys_role_menu` VALUES ('1304366873449742337', '1265476890672672818', '1264622039642255851'); +INSERT INTO `sys_role_menu` VALUES ('1304366873864978433', '1265476890672672818', '1264622039642255691'); +INSERT INTO `sys_role_menu` VALUES ('1304366874284408834', '1265476890672672818', '1264622039642255701'); +INSERT INTO `sys_role_menu` VALUES ('1304366874703839233', '1265476890672672818', '1264622039642255711'); +INSERT INTO `sys_role_menu` VALUES ('1304366875119075330', '1265476890672672818', '1264622039642255721'); +INSERT INTO `sys_role_menu` VALUES ('1304366875538505730', '1265476890672672818', '1264622039642255731'); +INSERT INTO `sys_role_menu` VALUES ('1304366875962130433', '1265476890672672818', '1264622039642255741'); +INSERT INTO `sys_role_menu` VALUES ('1304366876377366529', '1265476890672672818', '1264622039642255751'); +INSERT INTO `sys_role_menu` VALUES ('1304366876800991233', '1265476890672672818', '1264622039642255771'); +INSERT INTO `sys_role_menu` VALUES ('1304366877216227330', '1265476890672672818', '1264622039642255781'); +INSERT INTO `sys_role_menu` VALUES ('1304366877639852033', '1265476890672672818', '1264622039642255791'); +INSERT INTO `sys_role_menu` VALUES ('1304366878067671041', '1265476890672672818', '1264622039642255801'); +INSERT INTO `sys_role_menu` VALUES ('1304366878487101441', '1265476890672672818', '1264622039642255811'); +INSERT INTO `sys_role_menu` VALUES ('1304366878898143233', '1265476890672672818', '1264622039642255821'); +INSERT INTO `sys_role_menu` VALUES ('1304366879325962242', '1265476890672672818', '1264622039642255831'); +INSERT INTO `sys_role_menu` VALUES ('1304366879745392641', '1265476890672672818', '1264622039642255841'); +INSERT INTO `sys_role_menu` VALUES ('1304366880160628738', '1265476890672672818', '1264622039642255881'); +INSERT INTO `sys_role_menu` VALUES ('1304366880580059138', '1265476890672672818', '1264622039642255891'); +INSERT INTO `sys_role_menu` VALUES ('1304366880999489537', '1265476890672672818', '1264622039642255901'); +INSERT INTO `sys_role_menu` VALUES ('1304366881423114242', '1265476890672672818', '1264622039642255911'); +INSERT INTO `sys_role_menu` VALUES ('1304366881838350338', '1265476890672672818', '1264622039642255921'); +INSERT INTO `sys_role_menu` VALUES ('1304366882261975042', '1265476890672672818', '1264622039642255931'); +INSERT INTO `sys_role_menu` VALUES ('1304366882685599745', '1265476890672672818', '1264622039642255941'); +INSERT INTO `sys_role_menu` VALUES ('1304366883100835842', '1265476890672672818', '1264622039642255951'); +INSERT INTO `sys_role_menu` VALUES ('1304366883520266242', '1265476890672672818', '1264622039642255861'); +INSERT INTO `sys_role_menu` VALUES ('1304366883939696642', '1265476890672672818', '1264622039642255871'); +INSERT INTO `sys_role_menu` VALUES ('1304366884363321346', '1265476890672672818', '1264622039642257021'); +INSERT INTO `sys_role_menu` VALUES ('1304366884782751746', '1265476890672672818', '1264622039642257031'); +INSERT INTO `sys_role_menu` VALUES ('1304366885197987842', '1265476890672672818', '1264622039642256831'); +INSERT INTO `sys_role_menu` VALUES ('1304366885617418242', '1265476890672672818', '1264622039642257261'); +INSERT INTO `sys_role_menu` VALUES ('1304366886045237250', '1265476890672672818', '1264622039642257271'); +INSERT INTO `sys_role_menu` VALUES ('1304366886473056258', '1265476890672672818', '1264622039642257301'); +INSERT INTO `sys_role_menu` VALUES ('1304366886884098050', '1265476890672672818', '1264622039642257321'); +INSERT INTO `sys_role_menu` VALUES ('1304366887307722754', '1265476890672672818', '1264622039642257331'); +INSERT INTO `sys_role_menu` VALUES ('1304366887722958850', '1265476890672672818', '1264622039642257471'); +INSERT INTO `sys_role_menu` VALUES ('1304366888142389250', '1265476890672672818', '1264622039642257481'); +INSERT INTO `sys_role_menu` VALUES ('1304366888566013954', '1265476890672672818', '1264622039642257341'); +INSERT INTO `sys_role_menu` VALUES ('1304366888981250049', '1265476890672672818', '1264622039642257411'); +INSERT INTO `sys_role_menu` VALUES ('1304366889404874754', '1265476890672672818', '1264622039642257421'); +INSERT INTO `sys_role_menu` VALUES ('1304366889820110850', '1265476890672672818', '1264622039642257431'); +INSERT INTO `sys_role_menu` VALUES ('1304366890235346946', '1265476890672672818', '1264622039642257441'); +INSERT INTO `sys_role_menu` VALUES ('1304366890663165954', '1265476890672672818', '1264622039642257451'); +INSERT INTO `sys_role_menu` VALUES ('1304366891082596354', '1265476890672672818', '1264622039642257461'); +INSERT INTO `sys_role_menu` VALUES ('1304366891506221057', '1265476890672672818', '1264622039642257351'); +INSERT INTO `sys_role_menu` VALUES ('1304366891925651458', '1265476890672672818', '1264622039642257361'); +INSERT INTO `sys_role_menu` VALUES ('1304366892345081858', '1265476890672672818', '1264622039642257371'); +INSERT INTO `sys_role_menu` VALUES ('1304366892764512258', '1265476890672672818', '1264622039642257381'); +INSERT INTO `sys_role_menu` VALUES ('1304366893183942658', '1265476890672672818', '1264622039642257391'); +INSERT INTO `sys_role_menu` VALUES ('1304366893607567361', '1265476890672672818', '1264622039642257401'); +INSERT INTO `sys_role_menu` VALUES ('1304366894031192065', '1265476890672672818', '1264622039642257491'); +INSERT INTO `sys_role_menu` VALUES ('1304366894446428162', '1265476890672672818', '1264622039642257501'); +INSERT INTO `sys_role_menu` VALUES ('1304366894865858562', '1265476890672672818', '1264622039642257511'); +INSERT INTO `sys_role_menu` VALUES ('1304366895285288961', '1265476890672672818', '1264622039642255591'); +INSERT INTO `sys_role_menu` VALUES ('1304366895708913665', '1265476890672672818', '1264622039642257061'); +INSERT INTO `sys_role_menu` VALUES ('1304366896132538369', '1265476890672672818', '1264622039642257462'); +INSERT INTO `sys_role_menu` VALUES ('1304366896556163074', '1265476890672672818', '1264622039642256912'); +INSERT INTO `sys_role_menu` VALUES ('1304366896979787777', '1265476890672672818', '1264622039642255421'); +INSERT INTO `sys_role_menu` VALUES ('1304366897399218178', '1265476890672672818', '1264622039642257022'); +INSERT INTO `sys_role_menu` VALUES ('1304366897827037185', '1265476890672672818', '1264622039642256821'); +INSERT INTO `sys_role_menu` VALUES ('1304366898242273282', '1265476890672672818', '1264622039642257311'); +INSERT INTO `sys_role_menu` VALUES ('1304366898670092290', '1265476890672672818', '1264622039642257312'); +INSERT INTO `sys_role_menu` VALUES ('1304366899089522690', '1265476890672672818', '1264622039642257313'); +INSERT INTO `sys_role_menu` VALUES ('1304366899508953089', '1265476890672672818', '1264622039642257314'); +INSERT INTO `sys_role_menu` VALUES ('1304366899932577793', '1265476890672672818', '1264622039642257522'); +INSERT INTO `sys_role_menu` VALUES ('1304366900352008193', '1265476890672672818', '1264622039642257523'); +INSERT INTO `sys_role_menu` VALUES ('1304366900771438594', '1265476890672672818', '1264622039642257524'); +INSERT INTO `sys_role_menu` VALUES ('1304366901190868994', '1265476890672672818', '1264622039642257525'); +INSERT INTO `sys_role_menu` VALUES ('1304366901610299394', '1265476890672672818', '1264622039642257531'); +INSERT INTO `sys_role_menu` VALUES ('1304366902033924097', '1265476890672672818', '1264622039642257532'); +INSERT INTO `sys_role_menu` VALUES ('1307864773769273346', '1265476890672672819', '1264622039642256431'); +INSERT INTO `sys_role_menu` VALUES ('1307864774197092353', '1265476890672672819', '1264622039642256421'); +INSERT INTO `sys_role_menu` VALUES ('1307864774624911362', '1265476890672672819', '1264622039642256441'); +INSERT INTO `sys_role_menu` VALUES ('1307864775048536065', '1265476890672672819', '1264622039642256451'); +INSERT INTO `sys_role_menu` VALUES ('1307864775467966465', '1265476890672672819', '1264622039642256461'); +INSERT INTO `sys_role_menu` VALUES ('1307864775887396866', '1265476890672672819', '1264622039642256471'); +INSERT INTO `sys_role_menu` VALUES ('1307864776311021570', '1265476890672672819', '1264622039642256481'); +INSERT INTO `sys_role_menu` VALUES ('1307864776730451969', '1265476890672672819', '1264622039642256491'); +INSERT INTO `sys_role_menu` VALUES ('1307864777154076673', '1265476890672672819', '1264622039642256501'); +INSERT INTO `sys_role_menu` VALUES ('1307864777573507074', '1265476890672672819', '1264622039642256511'); +INSERT INTO `sys_role_menu` VALUES ('1307864778005520386', '1265476890672672819', '1264622039642255421'); +INSERT INTO `sys_role_menu` VALUES ('1307864778424950785', '1265476890672672819', '1264622039642257321'); +INSERT INTO `sys_role_menu` VALUES ('1307864778840186881', '1265476890672672819', '1264622039642257331'); +INSERT INTO `sys_role_menu` VALUES ('1307864779263811585', '1265476890672672819', '1264622039642257021'); +INSERT INTO `sys_role_menu` VALUES ('1307864779683241986', '1265476890672672819', '1264622039642257011'); +INSERT INTO `sys_role_menu` VALUES ('1307864780106866689', '1265476890672672819', '1264622039642256831'); +INSERT INTO `sys_role_menu` VALUES ('1307864780530491393', '1265476890672672819', '1264622039642257061'); +INSERT INTO `sys_role_menu` VALUES ('1307864780945727489', '1265476890672672819', '1264622039642257501'); +INSERT INTO `sys_role_menu` VALUES ('1307864781369352193', '1265476890672672819', '1264622039642257491'); +INSERT INTO `sys_role_menu` VALUES ('1307864781792976897', '1265476890672672819', '1264622039642257511'); +INSERT INTO `sys_role_menu` VALUES ('1307864782216601602', '1265476890672672819', '1264622039642257271'); +INSERT INTO `sys_role_menu` VALUES ('1307864782631837697', '1265476890672672819', '1264622039642257261'); +INSERT INTO `sys_role_menu` VALUES ('1307864783063851009', '1265476890672672819', '1264622039642257301'); +INSERT INTO `sys_role_menu` VALUES ('1307864783483281410', '1265476890672672819', '1264622039642257471'); +INSERT INTO `sys_role_menu` VALUES ('1307864783902711809', '1265476890672672819', '1264622039642257341'); +INSERT INTO `sys_role_menu` VALUES ('1307864784322142210', '1265476890672672819', '1264622039642257481'); +INSERT INTO `sys_role_menu` VALUES ('1307864784745766913', '1265476890672672819', '1264622039642257411'); +INSERT INTO `sys_role_menu` VALUES ('1307864785169391618', '1265476890672672819', '1264622039642257431'); +INSERT INTO `sys_role_menu` VALUES ('1307864785588822018', '1265476890672672819', '1264622039642257421'); +INSERT INTO `sys_role_menu` VALUES ('1307864786012446722', '1265476890672672819', '1264622039642257441'); +INSERT INTO `sys_role_menu` VALUES ('1307864786436071426', '1265476890672672819', '1264622039642257451'); +INSERT INTO `sys_role_menu` VALUES ('1307864786859696130', '1265476890672672819', '1264622039642257461'); +INSERT INTO `sys_role_menu` VALUES ('1307864787274932225', '1265476890672672819', '1264622039642257351'); +INSERT INTO `sys_role_menu` VALUES ('1307864787702751233', '1265476890672672819', '1264622039642257361'); +INSERT INTO `sys_role_menu` VALUES ('1307864788113793026', '1265476890672672819', '1264622039642257371'); +INSERT INTO `sys_role_menu` VALUES ('1307864788541612034', '1265476890672672819', '1264622039642257381'); +INSERT INTO `sys_role_menu` VALUES ('1307864788961042433', '1265476890672672819', '1264622039642257391'); +INSERT INTO `sys_role_menu` VALUES ('1307864789384667138', '1265476890672672819', '1264622039642257401'); +INSERT INTO `sys_role_menu` VALUES ('1307864789808291841', '1265476890672672819', '1264622039642257462'); +INSERT INTO `sys_role_menu` VALUES ('1307864790227722241', '1265476890672672819', '1264622039642257031'); +INSERT INTO `sys_role_menu` VALUES ('1307864790659735554', '1265476890672672819', '1264622039642256912'); +INSERT INTO `sys_role_menu` VALUES ('1307864791079165953', '1265476890672672819', '1264622039642257022'); +INSERT INTO `sys_role_menu` VALUES ('1307864791494402050', '1265476890672672819', '1264622039642257311'); +INSERT INTO `sys_role_menu` VALUES ('1307864791913832450', '1265476890672672819', '1264622039642257312'); +INSERT INTO `sys_role_menu` VALUES ('1307864792345845762', '1265476890672672819', '1264622039642257313'); +INSERT INTO `sys_role_menu` VALUES ('1307864792769470465', '1265476890672672819', '1264622039642257314'); +INSERT INTO `sys_role_menu` VALUES ('1307864793193095169', '1265476890672672819', '1264622039642257522'); +INSERT INTO `sys_role_menu` VALUES ('1307864793612525570', '1265476890672672819', '1264622039642257523'); +INSERT INTO `sys_role_menu` VALUES ('1307864794027761665', '1265476890672672819', '1264622039642257524'); +INSERT INTO `sys_role_menu` VALUES ('1307864794459774978', '1265476890672672819', '1264622039642257525'); +INSERT INTO `sys_role_menu` VALUES ('1307864794875011073', '1265476890672672819', '1264622039642257532'); +INSERT INTO `sys_role_menu` VALUES ('1307864795307024385', '1265476890672672819', '1264622039642257531'); +INSERT INTO `sys_role_menu` VALUES ('1307864795722260482', '1265476890672672819', '1264622039642256821'); +INSERT INTO `sys_role_menu` VALUES ('1307864929906434049', '1265476890672672817', '1264622039642255311'); +INSERT INTO `sys_role_menu` VALUES ('1307864930338447362', '1265476890672672817', '1264622039642255331'); +INSERT INTO `sys_role_menu` VALUES ('1307864930753683457', '1265476890672672817', '1264622039642255321'); +INSERT INTO `sys_role_menu` VALUES ('1307864931181502465', '1265476890672672817', '1264622039642255341'); +INSERT INTO `sys_role_menu` VALUES ('1307864931596738561', '1265476890672672817', '1264622039642255351'); +INSERT INTO `sys_role_menu` VALUES ('1307864932020363266', '1265476890672672817', '1264622039642255361'); +INSERT INTO `sys_role_menu` VALUES ('1307864932439793666', '1265476890672672817', '1264622039642255371'); +INSERT INTO `sys_role_menu` VALUES ('1307864932863418369', '1265476890672672817', '1264622039642255381'); +INSERT INTO `sys_role_menu` VALUES ('1307864933287043073', '1265476890672672817', '1264622039642255391'); +INSERT INTO `sys_role_menu` VALUES ('1307864933706473474', '1265476890672672817', '1264622039642255401'); +INSERT INTO `sys_role_menu` VALUES ('1307864934130098177', '1265476890672672817', '1264622039642255411'); +INSERT INTO `sys_role_menu` VALUES ('1307864934553722881', '1265476890672672817', '1264622039642255421'); +INSERT INTO `sys_role_menu` VALUES ('1307864934973153281', '1265476890672672817', '1264622039642255431'); +INSERT INTO `sys_role_menu` VALUES ('1307864935392583681', '1265476890672672817', '1264622039642255441'); +INSERT INTO `sys_role_menu` VALUES ('1307864935820402689', '1265476890672672817', '1264622039642255451'); +INSERT INTO `sys_role_menu` VALUES ('1307864936239833090', '1265476890672672817', '1264622039642255461'); +INSERT INTO `sys_role_menu` VALUES ('1307864936663457793', '1265476890672672817', '1264622039642255471'); +INSERT INTO `sys_role_menu` VALUES ('1307864937087082498', '1265476890672672817', '1264622039642255481'); +INSERT INTO `sys_role_menu` VALUES ('1307864937506512898', '1265476890672672817', '1264622039642255491'); +INSERT INTO `sys_role_menu` VALUES ('1307864937938526210', '1265476890672672817', '1264622039642255501'); +INSERT INTO `sys_role_menu` VALUES ('1307864938357956610', '1265476890672672817', '1264622039642255511'); +INSERT INTO `sys_role_menu` VALUES ('1307864938777387010', '1265476890672672817', '1264622039642255521'); +INSERT INTO `sys_role_menu` VALUES ('1307864939201011713', '1265476890672672817', '1264622039642255531'); +INSERT INTO `sys_role_menu` VALUES ('1307864939624636418', '1265476890672672817', '1264622039642255541'); +INSERT INTO `sys_role_menu` VALUES ('1307864940044066817', '1265476890672672817', '1264622039642255551'); +INSERT INTO `sys_role_menu` VALUES ('1307864940467691522', '1265476890672672817', '1264622039642255561'); +INSERT INTO `sys_role_menu` VALUES ('1307864940933259265', '1265476890672672817', '1264622039642255571'); +INSERT INTO `sys_role_menu` VALUES ('1307864941356883970', '1265476890672672817', '1264622039642255581'); +INSERT INTO `sys_role_menu` VALUES ('1307864941776314369', '1265476890672672817', '1264622039642255591'); +INSERT INTO `sys_role_menu` VALUES ('1307864942195744769', '1265476890672672817', '1264622039642255601'); +INSERT INTO `sys_role_menu` VALUES ('1307864942619369473', '1265476890672672817', '1264622039642255621'); +INSERT INTO `sys_role_menu` VALUES ('1307864943042994178', '1265476890672672817', '1264622039642255631'); +INSERT INTO `sys_role_menu` VALUES ('1307864943462424577', '1265476890672672817', '1264622039642255641'); +INSERT INTO `sys_role_menu` VALUES ('1307864943886049282', '1265476890672672817', '1264622039642255651'); +INSERT INTO `sys_role_menu` VALUES ('1307864944309673986', '1265476890672672817', '1264622039642255661'); +INSERT INTO `sys_role_menu` VALUES ('1307864944733298690', '1265476890672672817', '1264622039642255611'); +INSERT INTO `sys_role_menu` VALUES ('1307864945156923393', '1265476890672672817', '1264622039642257321'); +INSERT INTO `sys_role_menu` VALUES ('1307864945576353793', '1265476890672672817', '1264622039642257331'); +INSERT INTO `sys_role_menu` VALUES ('1307864945999978497', '1265476890672672817', '1264622039642257471'); +INSERT INTO `sys_role_menu` VALUES ('1307864946423603201', '1265476890672672817', '1264622039642257481'); +INSERT INTO `sys_role_menu` VALUES ('1307864946847227905', '1265476890672672817', '1264622039642257341'); +INSERT INTO `sys_role_menu` VALUES ('1307864947266658305', '1265476890672672817', '1264622039642257411'); +INSERT INTO `sys_role_menu` VALUES ('1307864947681894402', '1265476890672672817', '1264622039642257421'); +INSERT INTO `sys_role_menu` VALUES ('1307864948109713409', '1265476890672672817', '1264622039642257431'); +INSERT INTO `sys_role_menu` VALUES ('1307864948529143810', '1265476890672672817', '1264622039642257441'); +INSERT INTO `sys_role_menu` VALUES ('1307864948952768513', '1265476890672672817', '1264622039642257451'); +INSERT INTO `sys_role_menu` VALUES ('1307864949380587522', '1265476890672672817', '1264622039642257461'); +INSERT INTO `sys_role_menu` VALUES ('1307864949804212225', '1265476890672672817', '1264622039642257351'); +INSERT INTO `sys_role_menu` VALUES ('1307864950223642626', '1265476890672672817', '1264622039642257361'); +INSERT INTO `sys_role_menu` VALUES ('1307864950638878721', '1265476890672672817', '1264622039642257371'); +INSERT INTO `sys_role_menu` VALUES ('1307864951066697729', '1265476890672672817', '1264622039642257381'); +INSERT INTO `sys_role_menu` VALUES ('1307864951490322433', '1265476890672672817', '1264622039642257391'); +INSERT INTO `sys_role_menu` VALUES ('1307864951913947137', '1265476890672672817', '1264622039642257401'); +INSERT INTO `sys_role_menu` VALUES ('1307864952329183233', '1265476890672672817', '1264622039642257491'); +INSERT INTO `sys_role_menu` VALUES ('1307864952757002241', '1265476890672672817', '1264622039642257501'); +INSERT INTO `sys_role_menu` VALUES ('1307864953176432642', '1265476890672672817', '1264622039642257511'); +INSERT INTO `sys_role_menu` VALUES ('1307864953600057346', '1265476890672672817', '1264622039642256831'); +INSERT INTO `sys_role_menu` VALUES ('1307864954019487746', '1265476890672672817', '1264622039642257031'); +INSERT INTO `sys_role_menu` VALUES ('1307864954447306754', '1265476890672672817', '1264622039642257021'); +INSERT INTO `sys_role_menu` VALUES ('1307864954870931458', '1265476890672672817', '1264622039642257061'); +INSERT INTO `sys_role_menu` VALUES ('1307864955290361857', '1265476890672672817', '1264622039642257261'); +INSERT INTO `sys_role_menu` VALUES ('1307864955709792258', '1265476890672672817', '1264622039642257301'); +INSERT INTO `sys_role_menu` VALUES ('1307864956133416962', '1265476890672672817', '1264622039642257271'); +INSERT INTO `sys_role_menu` VALUES ('1307864956557041665', '1265476890672672817', '1264622039642257462'); +INSERT INTO `sys_role_menu` VALUES ('1307864956976472066', '1265476890672672817', '1264622039642256912'); +INSERT INTO `sys_role_menu` VALUES ('1307864957400096770', '1265476890672672817', '1264622039642255911'); +INSERT INTO `sys_role_menu` VALUES ('1307864957861470210', '1265476890672672817', '1264622039642257522'); +INSERT INTO `sys_role_menu` VALUES ('1307864958280900610', '1265476890672672817', '1264622039642257523'); +INSERT INTO `sys_role_menu` VALUES ('1307864958704525314', '1265476890672672817', '1264622039642257524'); +INSERT INTO `sys_role_menu` VALUES ('1307864959132344321', '1265476890672672817', '1264622039642257525'); +INSERT INTO `sys_role_menu` VALUES ('1307864959555969026', '1265476890672672817', '1264622039642257532'); +INSERT INTO `sys_role_menu` VALUES ('1307864959975399425', '1265476890672672817', '1264622039642257531'); +INSERT INTO `sys_role_menu` VALUES ('1307864960399024129', '1265476890672672817', '1264622039642257311'); +INSERT INTO `sys_role_menu` VALUES ('1307864960822648833', '1265476890672672817', '1264622039642257312'); +INSERT INTO `sys_role_menu` VALUES ('1307864961242079233', '1265476890672672817', '1264622039642257313'); +INSERT INTO `sys_role_menu` VALUES ('1307864961657315330', '1265476890672672817', '1264622039642257314'); +INSERT INTO `sys_role_menu` VALUES ('1307864962085134337', '1265476890672672817', '1264622039642256821'); +INSERT INTO `sys_role_menu` VALUES ('1307864962504564737', '1265476890672672817', '1264622039642257022'); + +-- ---------------------------- +-- Table structure for `sys_sms` +-- ---------------------------- +DROP TABLE IF EXISTS `sys_sms`; +CREATE TABLE `sys_sms` ( + `id` bigint(20) NOT NULL COMMENT '主键', + `phone_numbers` varchar(200) COLLATE utf8_bin NOT NULL COMMENT '手机号', + `validate_code` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '短信验证码', + `template_code` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '短信模板ID', + `biz_id` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '回执id,可根据该id查询具体的发送状态', + `status` tinyint(4) NOT NULL COMMENT '发送状态(字典 0 未发送,1 发送成功,2 发送失败,3 失效)', + `source` tinyint(4) NOT NULL COMMENT '来源(字典 1 app, 2 pc, 3 其他)', + `invalid_time` datetime DEFAULT NULL COMMENT '失效时间', + `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `create_user` bigint(20) DEFAULT NULL COMMENT '创建人', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `update_user` bigint(20) DEFAULT NULL COMMENT '更新人', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin ROW_FORMAT=DYNAMIC COMMENT='短信信息发送表'; + +-- ---------------------------- +-- Records of sys_sms +-- ---------------------------- + +-- ---------------------------- +-- Table structure for `sys_tenant_info` +-- ---------------------------- +DROP TABLE IF EXISTS `sys_tenant_info`; +CREATE TABLE `sys_tenant_info` ( + `id` bigint(20) NOT NULL COMMENT '主键id', + `name` varchar(255) DEFAULT NULL COMMENT '租户名称', + `code` varchar(255) DEFAULT NULL COMMENT '租户的编码', + `db_name` varchar(255) DEFAULT NULL COMMENT '关联的数据库名称', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `create_user` bigint(20) DEFAULT NULL COMMENT '创建人', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `update_user` bigint(20) DEFAULT NULL COMMENT '更新人', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='租户表'; + +-- ---------------------------- +-- Records of sys_tenant_info +-- ---------------------------- +INSERT INTO `sys_tenant_info` VALUES ('1301724123547000811', '总公司(管理单位)', 'default', 'master', '2020-09-04 11:29:51', '1265476890672672808', null, null); +INSERT INTO `sys_tenant_info` VALUES ('1304687130978660353', '北京分公司', 'beijing', 'xiaonuo_tenant_db_beijing', '2020-09-12 15:43:47', '1265476890672672808', null, null); +INSERT INTO `sys_tenant_info` VALUES ('1304687938700955650', '广州分公司', 'guangzhou', 'xiaonuo_tenant_db_guangzhou', '2020-09-12 15:46:59', '1265476890672672808', null, null); + +-- ---------------------------- +-- Table structure for `sys_timers` +-- ---------------------------- +DROP TABLE IF EXISTS `sys_timers`; +CREATE TABLE `sys_timers` ( + `id` bigint(20) NOT NULL COMMENT '定时器id', + `timer_name` varchar(255) DEFAULT '' COMMENT '任务名称', + `action_class` varchar(255) DEFAULT NULL COMMENT '执行任务的class的类名(实现了TimerTaskRunner接口的类的全称)', + `cron` varchar(255) DEFAULT '' COMMENT '定时任务表达式', + `job_status` tinyint(4) DEFAULT '0' COMMENT '状态(字典 1运行 2停止)', + `remark` varchar(1000) DEFAULT '' COMMENT '备注信息', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `create_user` bigint(20) DEFAULT NULL COMMENT '创建人', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `update_user` bigint(20) DEFAULT NULL COMMENT '更新人', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='定时任务'; + +-- ---------------------------- +-- Records of sys_timers +-- ---------------------------- +INSERT INTO `sys_timers` VALUES ('1288760324837851137', '定时同步缓存常量', 'com.cn.xiaonuo.sys.modular.timer.tasks.RefreshConstantsTaskRunner', '0 0/1 * * * ?', '1', '定时同步sys_config表的数据到缓存常量中', '2020-07-30 16:56:20', '1265476890672672808', '2020-07-30 16:58:52', '1265476890672672808'); +INSERT INTO `sys_timers` VALUES ('1304971718170832898', '定时打印一句话', 'com.cn.xiaonuo.sys.modular.timer.tasks.SystemOutTaskRunner', '0 0 * * * ? *', '2', '定时打印一句话', '2020-09-13 10:34:37', '1265476890672672808', '2020-09-23 20:37:48', '1265476890672672808'); + +-- ---------------------------- +-- Table structure for `sys_user` +-- ---------------------------- +DROP TABLE IF EXISTS `sys_user`; +CREATE TABLE `sys_user` ( + `id` bigint(20) NOT NULL COMMENT '主键', + `account` varchar(50) NOT NULL COMMENT '账号', + `password` varchar(100) NOT NULL COMMENT '密码', + `nick_name` varchar(50) DEFAULT NULL COMMENT '昵称', + `name` varchar(100) NOT NULL COMMENT '姓名', + `avatar` bigint(20) DEFAULT NULL COMMENT '头像', + `birthday` date DEFAULT NULL COMMENT '生日', + `sex` tinyint(4) NOT NULL COMMENT '性别(字典 1男 2女 3未知)', + `email` varchar(50) DEFAULT NULL COMMENT '邮箱', + `phone` varchar(50) DEFAULT NULL COMMENT '手机', + `tel` varchar(50) DEFAULT NULL COMMENT '电话', + `last_login_ip` varchar(100) DEFAULT NULL COMMENT '最后登陆IP', + `last_login_time` datetime DEFAULT NULL COMMENT '最后登陆时间', + `admin_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '管理员类型(0超级管理员 1非管理员)', + `status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '状态(字典 0正常 1冻结 2删除)', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `create_user` bigint(20) DEFAULT NULL COMMENT '创建人', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `update_user` bigint(20) DEFAULT NULL COMMENT '更新人', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='系统用户表'; + +-- ---------------------------- +-- Records of sys_user +-- ---------------------------- +INSERT INTO `sys_user` VALUES ('1265476890672672808', 'superAdmin', '$2a$09$PiCiFNspSlTBE9CakVs8ZOqx0xa03X9wOm01gMasHch4929TpEWCC', '超级管理员', '超级管理员', '1333734209900740609', '2020-03-18', '1', 'superAdmin@qq.com', '15228937093', '1234567890', '127.0.0.1', '2020-12-01 20:08:17', '1', '0', '2020-05-29 16:39:28', '-1', '2020-12-01 20:08:17', '-1'); +INSERT INTO `sys_user` VALUES ('1275735541155614721', 'yubaoshan', '$2a$09$PiCiFNspSlTBE9CakVs8ZOqx0xa03X9wOm01gMasHch4929TpEWCC', 'Await', '俞宝山', '1307866860842360834', '1992-10-03', '1', 'await183@qq.com', '18200001102', '', '127.0.0.1', '2020-09-23 10:15:10', '2', '0', '2020-06-24 18:20:30', '1265476890672672808', '2020-09-23 10:15:10', '-1'); +INSERT INTO `sys_user` VALUES ('1280709549107552257', 'xuyuxiang', '$2a$09$PiCiFNspSlTBE9CakVs8ZOqx0xa03X9wOm01gMasHch4929TpEWCC', '就是那个锅', '徐玉祥', '1307863777357832194', '2020-07-01', '1', null, '18200001100', null, '127.0.0.1', '2020-09-23 10:16:54', '2', '0', '2020-07-08 11:45:26', '1265476890672672808', '2020-09-23 10:16:54', '-1'); + +-- ---------------------------- +-- Table structure for `sys_user_data_scope` +-- ---------------------------- +DROP TABLE IF EXISTS `sys_user_data_scope`; +CREATE TABLE `sys_user_data_scope` ( + `id` bigint(20) NOT NULL COMMENT '主键', + `user_id` bigint(20) NOT NULL COMMENT '用户id', + `org_id` bigint(20) NOT NULL COMMENT '机构id', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='系统用户数据范围表'; + +-- ---------------------------- +-- Records of sys_user_data_scope +-- ---------------------------- +INSERT INTO `sys_user_data_scope` VALUES ('1277459951742840834', '1266277099455635457', '1265476890672672770'); +INSERT INTO `sys_user_data_scope` VALUES ('1277459952577507330', '1266277099455635457', '1265476890672672773'); +INSERT INTO `sys_user_data_scope` VALUES ('1277459953424756737', '1266277099455635457', '1265476890672672775'); +INSERT INTO `sys_user_data_scope` VALUES ('1277459954267811841', '1266277099455635457', '1265476890672672774'); +INSERT INTO `sys_user_data_scope` VALUES ('1280712043527249922', '1265476890672672809', '1265476890651701250'); +INSERT INTO `sys_user_data_scope` VALUES ('1280712043535638529', '1265476890672672809', '1265476890672672769'); +INSERT INTO `sys_user_data_scope` VALUES ('1280712043535638530', '1265476890672672809', '1265476890672672771'); +INSERT INTO `sys_user_data_scope` VALUES ('1280712043535638531', '1265476890672672809', '1265476890672672772'); +INSERT INTO `sys_user_data_scope` VALUES ('1280712043544027137', '1265476890672672809', '1265476890672672770'); +INSERT INTO `sys_user_data_scope` VALUES ('1280712043544027138', '1265476890672672809', '1265476890672672773'); +INSERT INTO `sys_user_data_scope` VALUES ('1280712043552415746', '1265476890672672809', '1265476890672672775'); +INSERT INTO `sys_user_data_scope` VALUES ('1280712043552415747', '1265476890672672809', '1265476890672672774'); +INSERT INTO `sys_user_data_scope` VALUES ('1280712071570366466', '1275735541155614721', '1265476890672672769'); +INSERT INTO `sys_user_data_scope` VALUES ('1280712071570366467', '1275735541155614721', '1265476890672672771'); +INSERT INTO `sys_user_data_scope` VALUES ('1280712071578755074', '1275735541155614721', '1265476890672672772'); +INSERT INTO `sys_user_data_scope` VALUES ('1285129189085609986', '1280700700074041345', '1265476890672672770'); +INSERT INTO `sys_user_data_scope` VALUES ('1285129189093998594', '1280700700074041345', '1265476890672672773'); +INSERT INTO `sys_user_data_scope` VALUES ('1285129189102387201', '1280700700074041345', '1265476890672672775'); +INSERT INTO `sys_user_data_scope` VALUES ('1285129189106581505', '1280700700074041345', '1265476890672672774'); + +-- ---------------------------- +-- Table structure for `sys_user_role` +-- ---------------------------- +DROP TABLE IF EXISTS `sys_user_role`; +CREATE TABLE `sys_user_role` ( + `id` bigint(20) NOT NULL COMMENT '主键', + `user_id` bigint(20) NOT NULL COMMENT '用户id', + `role_id` bigint(20) NOT NULL COMMENT '角色id', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='系统用户角色表'; + +-- ---------------------------- +-- Records of sys_user_role +-- ---------------------------- +INSERT INTO `sys_user_role` VALUES ('1283596900713574402', '1275735541155614721', '1265476890672672817'); +INSERT INTO `sys_user_role` VALUES ('1283596920384860162', '1280700700074041345', '1265476890672672819'); +INSERT INTO `sys_user_role` VALUES ('1283596949627547649', '1280709549107552257', '1265476890672672818'); + +-- ---------------------------- +-- Table structure for `sys_vis_log` +-- ---------------------------- +DROP TABLE IF EXISTS `sys_vis_log`; +CREATE TABLE `sys_vis_log` ( + `id` bigint(20) NOT NULL COMMENT '主键', + `name` varchar(50) DEFAULT NULL COMMENT '名称', + `success` char(1) DEFAULT NULL COMMENT '是否执行成功(Y-是,N-否)', + `message` text COMMENT '具体消息', + `ip` varchar(255) DEFAULT NULL COMMENT 'ip', + `location` varchar(255) DEFAULT NULL COMMENT '地址', + `browser` varchar(255) DEFAULT NULL COMMENT '浏览器', + `os` varchar(255) DEFAULT NULL COMMENT '操作系统', + `vis_type` tinyint(4) NOT NULL COMMENT '操作类型(字典 1登入 2登出)', + `vis_time` datetime DEFAULT NULL COMMENT '访问时间', + `account` varchar(50) DEFAULT NULL COMMENT '访问账号', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='系统访问日志表'; + +-- ---------------------------- +-- Records of sys_vis_log +-- ---------------------------- +INSERT INTO `sys_vis_log` VALUES ('1323528612294590466', '登录', 'Y', '登录成功', '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '1', '2020-11-03 15:33:06', 'superAdmin'); +INSERT INTO `sys_vis_log` VALUES ('1323532458933284866', '登录', 'Y', '登录成功', '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '1', '2020-11-03 15:48:23', 'superAdmin'); +INSERT INTO `sys_vis_log` VALUES ('1323551754279383041', '登出', 'Y', '登出成功', '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '2', '2020-11-03 17:05:03', 'superAdmin'); +INSERT INTO `sys_vis_log` VALUES ('1333732923599978497', '登录', 'Y', '登录成功', '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '1', '2020-12-01 19:21:23', 'superAdmin'); +INSERT INTO `sys_vis_log` VALUES ('1333737954386608129', '登出', 'Y', '登出成功', '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '2', '2020-12-01 19:41:23', 'superAdmin'); +INSERT INTO `sys_vis_log` VALUES ('1333744725968781314', '登录', 'Y', '登录成功', '127.0.0.1', '-', 'Chrome', 'Windows 10 or Windows Server 2016', '1', '2020-12-01 20:08:17', 'superAdmin'); diff --git a/_web/.browserslistrc b/_web/.browserslistrc new file mode 100644 index 00000000..8f960439 --- /dev/null +++ b/_web/.browserslistrc @@ -0,0 +1,3 @@ +> 1% +last 2 versions +not ie <= 10 diff --git a/_web/.editorconfig b/_web/.editorconfig new file mode 100644 index 00000000..6f77dff8 --- /dev/null +++ b/_web/.editorconfig @@ -0,0 +1,39 @@ +[*] +charset=utf-8 +end_of_line=lf +insert_final_newline=false +indent_style=space +indent_size=2 + +[{*.ng,*.sht,*.html,*.shtm,*.shtml,*.htm}] +indent_style=space +indent_size=2 + +[{*.jhm,*.xslt,*.xul,*.rng,*.xsl,*.xsd,*.ant,*.tld,*.fxml,*.jrxml,*.xml,*.jnlp,*.wsdl}] +indent_style=space +indent_size=2 + +[{.babelrc,.stylelintrc,jest.config,.eslintrc,.prettierrc,*.json,*.jsb3,*.jsb2,*.bowerrc}] +indent_style=space +indent_size=2 + +[*.svg] +indent_style=space +indent_size=2 + +[*.js.map] +indent_style=space +indent_size=2 + +[*.less] +indent_style=space +indent_size=2 + +[*.vue] +indent_style=space +indent_size=2 + +[{.analysis_options,*.yml,*.yaml}] +indent_style=space +indent_size=2 + diff --git a/_web/.env b/_web/.env new file mode 100644 index 00000000..c30c4684 --- /dev/null +++ b/_web/.env @@ -0,0 +1,3 @@ +NODE_ENV=production +VUE_APP_PREVIEW=true +VUE_APP_API_BASE_URL=http://www.xiaonuo.vip:82 \ No newline at end of file diff --git a/_web/.env.development b/_web/.env.development new file mode 100644 index 00000000..71e03777 --- /dev/null +++ b/_web/.env.development @@ -0,0 +1,3 @@ +NODE_ENV=development +VUE_APP_PREVIEW=true +VUE_APP_API_BASE_URL=http://www.xiaonuo.vip:82 \ No newline at end of file diff --git a/_web/.env.preview b/_web/.env.preview new file mode 100644 index 00000000..8d94bbee --- /dev/null +++ b/_web/.env.preview @@ -0,0 +1,3 @@ +NODE_ENV=production +VUE_APP_PREVIEW=false +VUE_APP_API_BASE_URL=http://www.xiaonuo.vip:82 \ No newline at end of file diff --git a/_web/.eslintrc.js b/_web/.eslintrc.js new file mode 100644 index 00000000..5bece06c --- /dev/null +++ b/_web/.eslintrc.js @@ -0,0 +1,75 @@ +module.exports = { + root: true, + env: { + node: true + }, + 'extends': [ + 'plugin:vue/strongly-recommended', + '@vue/standard' + ], + rules: { + 'no-console': 'off', + 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', + 'generator-star-spacing': 'off', + 'no-mixed-operators': 0, + 'vue/max-attributes-per-line': [ + 2, + { + 'singleline': 5, + 'multiline': { + 'max': 1, + 'allowFirstLine': false + } + } + ], + 'vue/attribute-hyphenation': 0, + 'vue/html-self-closing': 0, + 'vue/component-name-in-template-casing': 0, + 'vue/html-closing-bracket-spacing': 0, + 'vue/singleline-html-element-content-newline': 0, + 'vue/no-unused-components': 0, + 'vue/multiline-html-element-content-newline': 0, + 'vue/no-use-v-if-with-v-for': 0, + 'vue/html-closing-bracket-newline': 0, + 'vue/no-parsing-error': 0, + 'no-tabs': 0, + 'quotes': [ + 2, + 'single', + { + 'avoidEscape': true, + 'allowTemplateLiterals': true + } + ], + 'semi': [ + 2, + 'never', + { + 'beforeStatementContinuationChars': 'never' + } + ], + 'no-delete-var': 2, + 'prefer-const': [ + 2, + { + 'ignoreReadBeforeAssign': false + } + ], + 'template-curly-spacing': 'off', + 'indent': 'off' + }, + parserOptions: { + parser: 'babel-eslint' + }, + overrides: [ + { + files: [ + '**/__tests__/*.{j,t}s?(x)', + '**/tests/unit/**/*.spec.{j,t}s?(x)' + ], + env: { + jest: true + } + } + ] +} diff --git a/_web/.gitignore b/_web/.gitignore new file mode 100644 index 00000000..25768809 --- /dev/null +++ b/_web/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +dist/ +.idea/ \ No newline at end of file diff --git a/_web/.prettierrc b/_web/.prettierrc new file mode 100644 index 00000000..cbe842ac --- /dev/null +++ b/_web/.prettierrc @@ -0,0 +1,5 @@ +{ + "printWidth": 120, + "semi": false, + "singleQuote": true +} diff --git a/_web/.travis.yml b/_web/.travis.yml new file mode 100644 index 00000000..a08bfcb2 --- /dev/null +++ b/_web/.travis.yml @@ -0,0 +1,7 @@ +language: node_js +node_js: + - 10.15.0 +cache: yarn +script: + - yarn + - yarn run lint --no-fix && yarn run build diff --git a/_web/LICENSE b/_web/LICENSE new file mode 100644 index 00000000..66eef0be --- /dev/null +++ b/_web/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Anan Yang + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/_web/babel.config.js b/_web/babel.config.js new file mode 100644 index 00000000..e80ad97b --- /dev/null +++ b/_web/babel.config.js @@ -0,0 +1,28 @@ +const IS_PROD = ['production', 'prod'].includes(process.env.NODE_ENV) + +const plugins = [] +if (IS_PROD) { + plugins.push('transform-remove-console') +} + +// lazy load ant-design-vue +// if your use import on Demand, Use this code +plugins.push(['import', { + 'libraryName': 'ant-design-vue', + 'libraryDirectory': 'es', + 'style': true // `style: true` 会加载 less 文件 +}]) + +module.exports = { + presets: [ + '@vue/cli-plugin-babel/preset', + [ + '@babel/preset-env', + { + 'useBuiltIns': 'entry', + 'corejs': 3 + } + ] + ], + plugins +} diff --git a/_web/config/plugin.config.js b/_web/config/plugin.config.js new file mode 100644 index 00000000..2ad9b194 --- /dev/null +++ b/_web/config/plugin.config.js @@ -0,0 +1,46 @@ +const ThemeColorReplacer = require('webpack-theme-color-replacer') +const generate = require('@ant-design/colors/lib/generate').default + +const getAntdSerials = (color) => { + // 淡化(即less的tint) + const lightens = new Array(9).fill().map((t, i) => { + return ThemeColorReplacer.varyColor.lighten(color, i / 10) + }) + const colorPalettes = generate(color) + const rgb = ThemeColorReplacer.varyColor.toNum3(color.replace('#', '')).join(',') + return lightens.concat(colorPalettes).concat(rgb) +} + +const themePluginOption = { + fileName: 'css/theme-colors-[contenthash:8].css', + matchColors: getAntdSerials('#1890ff'), // 主色系列 + // 改变样式选择器,解决样式覆盖问题 + changeSelector (selector) { + switch (selector) { + case '.ant-calendar-today .ant-calendar-date': + return ':not(.ant-calendar-selected-date):not(.ant-calendar-selected-day)' + selector + case '.ant-btn:focus,.ant-btn:hover': + return '.ant-btn:focus:not(.ant-btn-primary):not(.ant-btn-danger),.ant-btn:hover:not(.ant-btn-primary):not(.ant-btn-danger)' + case '.ant-btn.active,.ant-btn:active': + return '.ant-btn.active:not(.ant-btn-primary):not(.ant-btn-danger),.ant-btn:active:not(.ant-btn-primary):not(.ant-btn-danger)' + case '.ant-steps-item-process .ant-steps-item-icon > .ant-steps-icon': + case '.ant-steps-item-process .ant-steps-item-icon>.ant-steps-icon': + return ':not(.ant-steps-item-process)' + selector + case '.ant-menu-horizontal>.ant-menu-item-active,.ant-menu-horizontal>.ant-menu-item-open,.ant-menu-horizontal>.ant-menu-item-selected,.ant-menu-horizontal>.ant-menu-item:hover,.ant-menu-horizontal>.ant-menu-submenu-active,.ant-menu-horizontal>.ant-menu-submenu-open,.ant-menu-horizontal>.ant-menu-submenu-selected,.ant-menu-horizontal>.ant-menu-submenu:hover': + case '.ant-menu-horizontal > .ant-menu-item-active,.ant-menu-horizontal > .ant-menu-item-open,.ant-menu-horizontal > .ant-menu-item-selected,.ant-menu-horizontal > .ant-menu-item:hover,.ant-menu-horizontal > .ant-menu-submenu-active,.ant-menu-horizontal > .ant-menu-submenu-open,.ant-menu-horizontal > .ant-menu-submenu-selected,.ant-menu-horizontal > .ant-menu-submenu:hover': + return '.ant-menu-horizontal > .ant-menu-item-active,.ant-menu-horizontal > .ant-menu-item-open,.ant-menu-horizontal > .ant-menu-item-selected,.ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-item:hover,.ant-menu-horizontal > .ant-menu-submenu-active,.ant-menu-horizontal > .ant-menu-submenu-open,.ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-submenu-selected,.ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-submenu:hover' + case '.ant-menu-horizontal > .ant-menu-item-selected > a': + case '.ant-menu-horizontal>.ant-menu-item-selected>a': + return '.ant-menu-horizontal:not(ant-menu-light):not(.ant-menu-dark) > .ant-menu-item-selected > a' + case '.ant-menu-horizontal > .ant-menu-item > a:hover': + case '.ant-menu-horizontal>.ant-menu-item>a:hover': + return '.ant-menu-horizontal:not(ant-menu-light):not(.ant-menu-dark) > .ant-menu-item > a:hover' + default : + return selector + } + } +} + +const createThemeColorReplacerPlugin = () => new ThemeColorReplacer(themePluginOption) + +module.exports = createThemeColorReplacerPlugin diff --git a/_web/jest.config.js b/_web/jest.config.js new file mode 100644 index 00000000..29fee32b --- /dev/null +++ b/_web/jest.config.js @@ -0,0 +1,23 @@ +module.exports = { + moduleFileExtensions: [ + 'js', + 'jsx', + 'json', + 'vue' + ], + transform: { + '^.+\\.vue$': 'vue-jest', + '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub', + '^.+\\.jsx?$': 'babel-jest' + }, + moduleNameMapper: { + '^@/(.*)$': '/src/$1' + }, + snapshotSerializers: [ + 'jest-serializer-vue' + ], + testMatch: [ + '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)' + ], + testURL: 'http://localhost/' +} diff --git a/_web/jsconfig.json b/_web/jsconfig.json new file mode 100644 index 00000000..1bd0da4c --- /dev/null +++ b/_web/jsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "es6", + "baseUrl": ".", + "paths": { + "@/*": ["src/*"] + } + }, + "exclude": ["node_modules", "dist"], + "include": ["src/**/*"] +} diff --git a/_web/package.json b/_web/package.json new file mode 100644 index 00000000..e6b8ba26 --- /dev/null +++ b/_web/package.json @@ -0,0 +1,84 @@ +{ + "name": "vue-antd-pro", + "version": "2.1.0", + "private": true, + "scripts": { + "serve": "vue-cli-service serve", + "build": "vue-cli-service build", + "test:unit": "vue-cli-service test:unit", + "build:preview": "vue-cli-service build --mode preview", + "postinstall": "opencollective-postinstall" + }, + "dependencies": { + "@antv/data-set": "^0.10.2", + "ant-design-vue": "1.5.0-rc.6", + "axios": "^0.19.0", + "babel-polyfill": "^6.26.0", + "clipboard": "^2.0.6", + "core-js": "^3.1.2", + "default-passive-events": "^1.0.10", + "enquire.js": "^2.1.6", + "font-awesome": "^4.7.0", + "jquery": "^3.5.1", + "lodash.clonedeep": "^4.5.0", + "lodash.get": "^4.4.2", + "lodash.pick": "^4.4.0", + "md5": "^2.2.1", + "mockjs2": "1.0.8", + "moment": "^2.24.0", + "nprogress": "^0.2.0", + "print-js": "^1.0.63", + "raphael": "^2.3.0", + "viser-vue": "^2.4.6", + "vue": "^2.6.10", + "vue-clipboard2": "^0.2.1", + "vue-codemirror-lite": "^1.0.4", + "vue-cropper": "0.4.9", + "vue-ls": "^3.2.1", + "vue-quill-editor": "^3.0.6", + "vue-router": "^3.1.2", + "vue-svg-component-runtime": "^1.0.1", + "vuedraggable": "^2.23.2", + "vuex": "^3.1.1", + "wangeditor": "^3.1.1" + }, + "devDependencies": { + "@ant-design/colors": "^3.2.1", + "@vue/cli-plugin-babel": "^4.0.4", + "@vue/cli-plugin-eslint": "^4.0.4", + "@vue/cli-plugin-router": "^4.0.4", + "@vue/cli-plugin-unit-jest": "^4.0.4", + "@vue/cli-plugin-vuex": "^4.0.4", + "@vue/cli-service": "^4.0.4", + "@vue/eslint-config-prettier": "^5.0.0", + "@vue/eslint-config-standard": "^4.0.0", + "@vue/test-utils": "^1.0.0-beta.29", + "babel-eslint": "^10.0.1", + "babel-plugin-import": "^1.13.0", + "babel-plugin-transform-remove-console": "^6.9.4", + "eslint": "^6.8.0", + "eslint-plugin-html": "^5.0.0", + "eslint-plugin-prettier": "^3.1.0", + "eslint-plugin-vue": "^5.2.3", + "less": "^3.0.4", + "less-loader": "^5.0.0", + "opencollective": "^1.0.3", + "opencollective-postinstall": "^2.0.2", + "prettier": "^1.18.2", + "vue-svg-icon-loader": "^2.1.1", + "vue-template-compiler": "^2.6.10", + "webpack-theme-color-replacer": "^1.2.17" + }, + "collective": { + "type": "opencollective", + "url": "https://opencollective.com/ant-design-pro-vue" + }, + "main": ".eslintrc.js", + "directories": { + "test": "tests" + }, + "keywords": [], + "author": "", + "license": "ISC", + "description": "" +} diff --git a/_web/postcss.config.js b/_web/postcss.config.js new file mode 100644 index 00000000..961986e2 --- /dev/null +++ b/_web/postcss.config.js @@ -0,0 +1,5 @@ +module.exports = { + plugins: { + autoprefixer: {} + } +} diff --git a/_web/public/avatar2.jpg b/_web/public/avatar2.jpg new file mode 100644 index 00000000..9adb2d1b Binary files /dev/null and b/_web/public/avatar2.jpg differ diff --git a/_web/public/index.html b/_web/public/index.html new file mode 100644 index 00000000..fbaf3efc --- /dev/null +++ b/_web/public/index.html @@ -0,0 +1,34 @@ + + + + + + + + XiaoNuo快速开发平台 + + + <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css) { %> + + <% } %> + + + +
+
+

XiaoNuo

+
+ +
+
XiaoNuo快速开发平台
+
+
+ +<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %> + +<% } %> + + + diff --git a/_web/public/loading/loading.css b/_web/public/loading/loading.css new file mode 100644 index 00000000..a899eac7 --- /dev/null +++ b/_web/public/loading/loading.css @@ -0,0 +1 @@ +#preloadingAnimation{position:fixed;left:0;top:0;height:100%;width:100%;background:#ffffff;user-select:none;z-index: 9999;overflow: hidden}.lds-roller{display:inline-block;position:relative;left:50%;top:50%;transform:translate(-50%,-50%);width:64px;height:64px;}.lds-roller div{animation:lds-roller 1.2s cubic-bezier(0.5,0,0.5,1) infinite;transform-origin:32px 32px;}.lds-roller div:after{content:" ";display:block;position:absolute;width:6px;height:6px;border-radius:50%;background:#13c2c2;margin:-3px 0 0 -3px;}.lds-roller div:nth-child(1){animation-delay:-0.036s;}.lds-roller div:nth-child(1):after{top:50px;left:50px;}.lds-roller div:nth-child(2){animation-delay:-0.072s;}.lds-roller div:nth-child(2):after{top:54px;left:45px;}.lds-roller div:nth-child(3){animation-delay:-0.108s;}.lds-roller div:nth-child(3):after{top:57px;left:39px;}.lds-roller div:nth-child(4){animation-delay:-0.144s;}.lds-roller div:nth-child(4):after{top:58px;left:32px;}.lds-roller div:nth-child(5){animation-delay:-0.18s;}.lds-roller div:nth-child(5):after{top:57px;left:25px;}.lds-roller div:nth-child(6){animation-delay:-0.216s;}.lds-roller div:nth-child(6):after{top:54px;left:19px;}.lds-roller div:nth-child(7){animation-delay:-0.252s;}.lds-roller div:nth-child(7):after{top:50px;left:14px;}.lds-roller div:nth-child(8){animation-delay:-0.288s;}.lds-roller div:nth-child(8):after{top:45px;left:10px;}#preloadingAnimation .load-tips{color: #13c2c2;font-size:2rem;position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);margin-top:80px;text-align:center;width:400px;height:64px;} @keyframes lds-roller{0%{transform:rotate(0deg);} 100%{transform:rotate(360deg);}} \ No newline at end of file diff --git a/_web/public/loading/loading.html b/_web/public/loading/loading.html new file mode 100644 index 00000000..018c402e --- /dev/null +++ b/_web/public/loading/loading.html @@ -0,0 +1 @@ +
Loading
diff --git a/_web/public/loading/option2/html_code_segment.html b/_web/public/loading/option2/html_code_segment.html new file mode 100644 index 00000000..5c85af3b --- /dev/null +++ b/_web/public/loading/option2/html_code_segment.html @@ -0,0 +1,5 @@ +
+
+ +
+
diff --git a/_web/public/loading/option2/loading.css b/_web/public/loading/option2/loading.css new file mode 100644 index 00000000..c35cd73a --- /dev/null +++ b/_web/public/loading/option2/loading.css @@ -0,0 +1 @@ +.preloading-animate{background:#ffffff;width:100%;height:100%;position:fixed;left:0;top:0;z-index:299;}.preloading-animate .preloading-wrapper{position:absolute;width:5rem;height:5rem;left:50%;top:50%;transform:translate(-50%,-50%);}.preloading-animate .preloading-wrapper .preloading-balls{font-size:5rem;} \ No newline at end of file diff --git a/_web/public/loading/option2/loading.svg b/_web/public/loading/option2/loading.svg new file mode 100644 index 00000000..7ff7322d --- /dev/null +++ b/_web/public/loading/option2/loading.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/_web/public/logo.png b/_web/public/logo.png new file mode 100644 index 00000000..e85a4737 Binary files /dev/null and b/_web/public/logo.png differ diff --git a/_web/src/App.vue b/_web/src/App.vue new file mode 100644 index 00000000..bbca4b86 --- /dev/null +++ b/_web/src/App.vue @@ -0,0 +1,24 @@ + + + diff --git a/_web/src/api/modular/main/README.md b/_web/src/api/modular/main/README.md new file mode 100644 index 00000000..fadf99a4 --- /dev/null +++ b/_web/src/api/modular/main/README.md @@ -0,0 +1 @@ +/** 您的业务接口文件全写在此文件夹下面,升级底座直接迁移代码即可 **/ diff --git a/_web/src/api/modular/system/README.md b/_web/src/api/modular/system/README.md new file mode 100644 index 00000000..46aab4d5 --- /dev/null +++ b/_web/src/api/modular/system/README.md @@ -0,0 +1 @@ +/** 此文件夹下代码尽量不要动,底座升级直接覆盖替换 **/ diff --git a/_web/src/api/modular/system/appManage.js b/_web/src/api/modular/system/appManage.js new file mode 100644 index 00000000..d3ed844c --- /dev/null +++ b/_web/src/api/modular/system/appManage.js @@ -0,0 +1,92 @@ +/** + * 系统应用 + * + * @author yubaoshan + * @date 2020年4月23日12:10:57 + */ +import { axios } from '@/utils/request' + +/** + * 系统应用列表 + * + * @author yubaoshan + * @date 2020年7月9日15:05:01 + */ +export function getAppPage (parameter) { + return axios({ + url: '/sysApp/page', + method: 'get', + params: parameter + }) +} + +/** + * 系统应用列表 + * + * @author yubaoshan + * @date 2020年7月9日15:05:01 + */ +export function getAppList (parameter) { + return axios({ + url: '/sysApp/list', + method: 'get', + params: parameter + }) +} + +/** + * 新增系统应用 + * + * @author yubaoshan + * @date 2020年7月9日15:05:01 + */ +export function sysAppAdd (parameter) { + return axios({ + url: '/sysApp/add', + method: 'post', + data: parameter + }) +} + +/** + * 编辑系统应用 + * + * @author yubaoshan + * @param parameter + * @returns {*} + */ +export function sysAppEdit (parameter) { + return axios({ + url: '/sysApp/edit', + method: 'post', + data: parameter + }) +} + +/** + * 删除系统应用 + * + * @author yubaoshan + * @date 2020年7月9日15:05:01 + */ +export function sysAppDelete (parameter) { + return axios({ + url: '/sysApp/delete', + method: 'post', + data: parameter + }) +} + +/** + * 设为默认应用 + * + * @author yubaoshan + * @date 2020年7月9日15:05:01 + */ +export function sysAppSetAsDefault (parameter) { + return axios({ + url: '/sysApp/setAsDefault', + method: 'post', + data: parameter + }) +} diff --git a/_web/src/api/modular/system/configManage.js b/_web/src/api/modular/system/configManage.js new file mode 100644 index 00000000..34bdd41c --- /dev/null +++ b/_web/src/api/modular/system/configManage.js @@ -0,0 +1,85 @@ +import { axios } from '@/utils/request' + +/** + * 分页查询配置列表 + * + * @author yubaoshan + * @date 2020/5/25 01:57 + */ +export function sysConfigPage (parameter) { + return axios({ + url: '/sysConfig/page', + method: 'get', + params: parameter + }) +} + +/** + * 添加系统参数配置 + * + * @author yubaoshan + * @date 2020/5/25 01:57 + */ +export function sysConfigAdd (parameter) { + return axios({ + url: '/sysConfig/add', + method: 'post', + data: parameter + }) +} + +/** + * 编辑系统参数配置 + * + * @author yubaoshan + * @date 2020/5/25 01:57 + */ +export function sysConfigEdit (parameter) { + return axios({ + url: '/sysConfig/edit', + method: 'post', + data: parameter + }) +} + +/** + * 删除系统参数配置 + * + * @author yubaoshan + * @date 2020/5/25 01:57 + */ +export function sysConfigDelete (parameter) { + return axios({ + url: '/sysConfig/delete', + method: 'post', + data: parameter + }) +} + +/** + * 获取字典类型下所有字典,举例,返回格式为:[{code:"M",value:"男"},{code:"F",value:"女"}] + * + * @author yubaoshan + * @date 2020/5/25 02:06 + */ +export function sysDictTypeDropDown (parameter) { + return axios({ + url: '/sysDictType/dropDown', + method: 'get', + params: parameter + }) +} + +/** + * 获取系统的所有任务列表 + * + * @author yubaoshan + * @date 2020/7/8 20:46 + */ +export function sysTimersGetActionClasses (parameter) { + return axios({ + url: '/sysTimers/getActionClasses', + method: 'get', + params: parameter + }) +} diff --git a/_web/src/api/modular/system/dictDataManage.js b/_web/src/api/modular/system/dictDataManage.js new file mode 100644 index 00000000..2240b849 --- /dev/null +++ b/_web/src/api/modular/system/dictDataManage.js @@ -0,0 +1,57 @@ +import { axios } from '@/utils/request' + +/** + * 查询系统字典值 + * + * @author yubaoshan + * @date 2020/5/17 02:24 + */ +export function sysDictDataPage (parameter) { + return axios({ + url: '/sysDictData/page', + method: 'get', + params: parameter + }) +} + +/** + * 添加系统字典值 + * + * @author yubaoshan + * @date 2020/5/17 02:24 + */ +export function sysDictDataAdd (parameter) { + return axios({ + url: '/sysDictData/add', + method: 'post', + data: parameter + }) +} + +/** + * 编辑系统字典值 + * + * @author yubaoshan + * @date 2020/5/17 02:25 + */ +export function sysDictDataEdit (parameter) { + return axios({ + url: '/sysDictData/edit', + method: 'post', + data: parameter + }) +} + +/** + * 删除系统字典值 + * + * @author yubaoshan + * @date 2020/5/17 02:25 + */ +export function sysDictDataDelete (parameter) { + return axios({ + url: '/sysDictData/delete', + method: 'post', + data: parameter + }) +} diff --git a/_web/src/api/modular/system/dictManage.js b/_web/src/api/modular/system/dictManage.js new file mode 100644 index 00000000..bbc44bd4 --- /dev/null +++ b/_web/src/api/modular/system/dictManage.js @@ -0,0 +1,85 @@ +import { axios } from '@/utils/request' + +/** + * 分页查询系统字典类型 + * + * @author yubaoshan + * @date 2020/5/17 01:46 + */ +export function sysDictTypePage (parameter) { + return axios({ + url: '/sysDictType/page', + method: 'get', + params: parameter + }) +} + +/** + * 添加系统字典类型 + * + * @author yubaoshan + * @date 2020/5/17 01:46 + */ +export function sysDictTypeAdd (parameter) { + return axios({ + url: '/sysDictType/add', + method: 'post', + data: parameter + }) +} + +/** + * 编辑系统字典类型 + * + * @author yubaoshan + * @date 2020/5/17 01:50 + */ +export function sysDictTypeEdit (parameter) { + return axios({ + url: '/sysDictType/edit', + method: 'post', + data: parameter + }) +} + +/** + * 删除系统字典类型 + * + * @author yubaoshan + * @date 2020/5/17 01:50 + */ +export function sysDictTypeDelete (parameter) { + return axios({ + url: '/sysDictType/delete', + method: 'post', + data: parameter + }) +} + +/** + * 获取字典类型下所有字典,举例,返回格式为:[{code:"M",value:"男"},{code:"F",value:"女"}] + * + * @author yubaoshan + * @date 2020/6/10 00:10 + */ +export function sysDictTypeDropDown (parameter) { + return axios({ + url: '/sysDictType/dropDown', + method: 'get', + params: parameter + }) +} + +/** + * 获取所有字典,启动时加入缓存使用 + * + * @author yubaoshan + * @date 2020/6/10 00:10 + */ +export function sysDictTypeTree (parameter) { + return axios({ + url: '/sysDictType/tree', + method: 'get', + params: parameter + }) +} diff --git a/_web/src/api/modular/system/emailManage.js b/_web/src/api/modular/system/emailManage.js new file mode 100644 index 00000000..1321bccd --- /dev/null +++ b/_web/src/api/modular/system/emailManage.js @@ -0,0 +1,29 @@ +import { axios } from '@/utils/request' + +/** + * 发送邮件 + * + * @author yubaoshan + * @date 2020/7/3 23:22 + */ +export function emailSendEmail (parameter) { + return axios({ + url: '/email/sendEmail', + method: 'post', + data: parameter + }) +} + +/** + * 发送html邮件 + * + * @author yubaoshan + * @date 2020/7/3 23:23 + */ +export function emailSendEmailHtml (parameter) { + return axios({ + url: '/email/sendEmailHtml', + method: 'post', + data: parameter + }) +} diff --git a/_web/src/api/modular/system/fileManage.js b/_web/src/api/modular/system/fileManage.js new file mode 100644 index 00000000..0a52f049 --- /dev/null +++ b/_web/src/api/modular/system/fileManage.js @@ -0,0 +1,101 @@ +import { axios } from '@/utils/request' + +/** + * 分页查询文件信息表 + * + * @author yubaoshan + * @date 2020/6/30 00:20 + */ +export function sysFileInfoPage (parameter) { + return axios({ + url: '/sysFileInfo/page', + method: 'get', + params: parameter + }) +} + +/** + * 获取全部文件信息表 + * + * @author yubaoshan + * @date 2020/6/30 00:20 + */ +export function sysFileInfoList (parameter) { + return axios({ + url: '/sysFileInfo/list', + method: 'get', + params: parameter + }) +} + +/** + * 上传文件 + * + * @author yubaoshan + * @date 2020/6/30 00:20 + */ +export function sysFileInfoUpload (parameter) { + return axios({ + url: '/sysFileInfo/upload', + method: 'post', + data: parameter + }) +} + +/** + * 下载文件 + * + * @author yubaoshan + * @date 2020/6/30 00:20 + */ +export function sysFileInfoDownload (parameter) { + return axios({ + url: '/sysFileInfo/download', + method: 'get', + params: parameter, + responseType: 'blob' + }) +} + +/** + * 查看图片 + * + * @author yubaoshan + * @date 2020/6/30 00:20 + */ +export function sysFileInfoPreview (parameter) { + return axios({ + url: '/sysFileInfo/preview', + method: 'get', + params: parameter, + responseType: 'arraybuffer' + }) +} + +/** + * 查看详情文件信息表 + * + * @author yubaoshan + * @date 2020/6/30 00:20 + */ +export function sysFileInfoDetail (parameter) { + return axios({ + url: '/sysFileInfo/detail', + method: 'get', + params: parameter + }) +} + +/** + * 删除文件信息表 + * + * @author yubaoshan + * @date 2020/6/30 00:20 + */ +export function sysFileInfoDelete (parameter) { + return axios({ + url: '/sysFileInfo/delete', + method: 'post', + data: parameter + }) +} diff --git a/_web/src/api/modular/system/logManage.js b/_web/src/api/modular/system/logManage.js new file mode 100644 index 00000000..3c3a041b --- /dev/null +++ b/_web/src/api/modular/system/logManage.js @@ -0,0 +1,57 @@ +import { axios } from '@/utils/request' + +/** + * 查询访问日志 + * + * @author yubaoshan + * @date 2020/5/19 11:57 + */ +export function sysVisLogPage (parameter) { + return axios({ + url: '/sysVisLog/page', + method: 'get', + params: parameter + }) +} + +/** + * 查询操作日志 + * + * @author yubaoshan + * @date 2020/5/19 11:57 + */ +export function sysOpLogPage (parameter) { + return axios({ + url: '/sysOpLog/page', + method: 'get', + params: parameter + }) +} + +/** + * 清空访问日志 + * + * @author yubaoshan + * @date 2020/6/23 23:09 + */ +export function sysVisLogDelete (parameter) { + return axios({ + url: '/sysVisLog/delete', + method: 'post', + data: parameter + }) +} + +/** + * 清空登录日志 + * + * @author yubaoshan + * @date 2020/6/23 23:09 + */ +export function sysOpLogDelete (parameter) { + return axios({ + url: '/sysOpLog/delete', + method: 'post', + data: parameter + }) +} diff --git a/_web/src/api/modular/system/loginManage.js b/_web/src/api/modular/system/loginManage.js new file mode 100644 index 00000000..69fababc --- /dev/null +++ b/_web/src/api/modular/system/loginManage.js @@ -0,0 +1,77 @@ +/** + * 系统应用 + * + * @author yubaoshan + * @date 2020/5/26 19:06 + */ +import { axios } from '@/utils/request' + +/** + * 登录 + * + * @author yubaoshan + * @date 2020/5/26 19:06 + */ +export function login (parameter) { + return axios({ + url: '/login', + method: 'post', + data: parameter + }) +} + +/** + * 登出 + * + * @author yubaoshan + * @date 2020/5/26 19:07 + */ +export function logout (parameter) { + return axios({ + url: '/logout', + method: 'get', + params: parameter + }) +} + +/** + * 获取登录用户信息 + * + * @author yubaoshan + * @date 2020/5/26 19:08 + */ +export function getLoginUser (parameter) { + return axios({ + url: '/getLoginUser', + method: 'get', + params: parameter + }) +} + +/** + * 获取租户开关 + * + * @author yubaoshan + * @date 2020/9/5 1:24 + */ +export function getTenantOpen (parameter) { + return axios({ + url: '/getTenantOpen', + method: 'get', + params: parameter + }) +} + +/** + * 获取短信验证码 + * + * @author yubaoshan + * @date 2020/5/26 19:29 + */ +export function getSmsCaptcha (parameter) { + return axios({ + url: '/getSmsCaptcha', + method: 'get', + params: parameter + }) +} diff --git a/_web/src/api/modular/system/machineManage.js b/_web/src/api/modular/system/machineManage.js new file mode 100644 index 00000000..a154d048 --- /dev/null +++ b/_web/src/api/modular/system/machineManage.js @@ -0,0 +1,15 @@ +import { axios } from '@/utils/request' + +/** + * 系统属性监控 + * + * @author yubaoshan + * @date 2020/6/8 19:47 + */ +export function sysMachineQuery (parameter) { + return axios({ + url: '/sysMachine/query', + method: 'get', + params: parameter + }) +} diff --git a/_web/src/api/modular/system/menuManage.js b/_web/src/api/modular/system/menuManage.js new file mode 100644 index 00000000..7ac62c41 --- /dev/null +++ b/_web/src/api/modular/system/menuManage.js @@ -0,0 +1,114 @@ +import { axios } from '@/utils/request' + +/** + * 获取菜单列表 + * + * @author yubaoshan + * @param parameter + * @returns {*} + */ +export function getMenuList (parameter) { + return axios({ + url: '/sysMenu/list', + method: 'get', + params: parameter + }) +} + +/** + * 获取系统菜单树,用于新增,编辑时选择上级节点 + * + * @author yubaoshan + * @date 2020/4/23 12:22 + */ +export function getMenuTree (parameter) { + return axios({ + url: '/sysMenu/tree', + method: 'get', + params: parameter + }) +} + +/** + * 增加菜单 + * + * @author yubaoshan + * @date 2020/4/24 23:23 + */ +export function sysMenuAdd (parameter) { + return axios({ + url: '/sysMenu/add', + method: 'post', + data: parameter + }) +} + +/** + * 增加菜单 + * + * @author yubaoshan + * @date 2020/4/24 23:23 + */ +export function sysMenuDelete (parameter) { + return axios({ + url: '/sysMenu/delete', + method: 'post', + data: parameter + }) +} + +/** + * 查看菜单详情 + * + * @author yubaoshan + * @date 2020/4/25 01:11 + */ +export function sysMenuDetail (parameter) { + return axios({ + url: '/sysMenu/detail', + method: 'post', + data: parameter + }) +} + +/** + * 编辑系统菜单 + * + * @author yubaoshan + * @date 2020/4/25 01:11 + */ +export function sysMenuEdit (parameter) { + return axios({ + url: '/sysMenu/edit', + method: 'post', + data: parameter + }) +} + +/** + * 获取系统菜单树,用于给角色授权时选择 + * + * @author yubaoshan + * @date 2020/6/2 17:30 + */ +export function SysMenuTreeForGrant (parameter) { + return axios({ + url: '/sysMenu/treeForGrant', + method: 'get', + params: parameter + }) +} + +/** + * 根据系统切换菜单 + * + * @author yubaoshan + * @date 2020/6/28 15:25 + */ +export function sysMenuChange (parameter) { + return axios({ + url: '/sysMenu/change', + method: 'post', + data: parameter + }) +} diff --git a/_web/src/api/modular/system/noticeManage.js b/_web/src/api/modular/system/noticeManage.js new file mode 100644 index 00000000..d4f7277f --- /dev/null +++ b/_web/src/api/modular/system/noticeManage.js @@ -0,0 +1,85 @@ +import { axios } from '@/utils/request' + +/** + * 查询系统通知公告 + * + * @author yubaoshan + * @date 2020/6/30 01:56 + */ +export function sysNoticePage (parameter) { + return axios({ + url: '/sysNotice/page', + method: 'get', + params: parameter + }) +} + +/** + * 添加系统通知公告 + * + * @author yubaoshan + * @date 2020/6/30 01:56 + */ +export function sysNoticeAdd (parameter) { + return axios({ + url: '/sysNotice/add', + method: 'post', + data: parameter + }) +} + +/** + * 编辑系统通知公告 + * + * @author yubaoshan + * @date 2020/6/30 01:56 + */ +export function sysNoticeEdit (parameter) { + return axios({ + url: '/sysNotice/edit', + method: 'post', + data: parameter + }) +} + +/** + * 删除系统通知公告 + * + * @author yubaoshan + * @date 2020/6/30 01:56 + */ +export function sysNoticeDelete (parameter) { + return axios({ + url: '/sysNotice/delete', + method: 'post', + data: parameter + }) +} + +/** + * 通知公告详情 + * + * @author yubaoshan + * @date 2020/6/30 01:56 + */ +export function sysNoticeDetail (parameter) { + return axios({ + url: '/sysNotice/detail', + method: 'get', + params: parameter + }) +} + +/** + * 修改状态 + * + * @author yubaoshan + * @date 2020/7/30 02:23 + */ +export function sysNoticeChangeStatus (parameter) { + return axios({ + url: '/sysNotice/changeStatus', + method: 'post', + data: parameter + }) +} diff --git a/_web/src/api/modular/system/noticeReceivedManage.js b/_web/src/api/modular/system/noticeReceivedManage.js new file mode 100644 index 00000000..a87237e6 --- /dev/null +++ b/_web/src/api/modular/system/noticeReceivedManage.js @@ -0,0 +1,15 @@ +import { axios } from '@/utils/request' + +/** + * 查询我收到的系统通知公告 + * + * @author yubaoshan + * @date 2020/7/3 03:02 + */ +export function sysNoticeReceived (parameter) { + return axios({ + url: '/sysNotice/received', + method: 'get', + params: parameter + }) +} diff --git a/_web/src/api/modular/system/onlineUserManage.js b/_web/src/api/modular/system/onlineUserManage.js new file mode 100644 index 00000000..7abc49a0 --- /dev/null +++ b/_web/src/api/modular/system/onlineUserManage.js @@ -0,0 +1,29 @@ +import { axios } from '@/utils/request' + +/** + * 在线用户列表 + * + * @author yubaoshan + * @date 2020/6/8 11:11 + */ +export function sysOnlineUserList (parameter) { + return axios({ + url: '/sysOnlineUser/list', + method: 'get', + params: parameter + }) +} + +/** + * 强制下线 + * + * @author yubaoshan + * @date 2020/6/8 11:11 + */ +export function sysOnlineUserForceExist (parameter) { + return axios({ + url: '/sysOnlineUser/forceExist', + method: 'post', + data: parameter + }) +} diff --git a/_web/src/api/modular/system/orgManage.js b/_web/src/api/modular/system/orgManage.js new file mode 100644 index 00000000..6ad82f62 --- /dev/null +++ b/_web/src/api/modular/system/orgManage.js @@ -0,0 +1,85 @@ +import { axios } from '@/utils/request' + +/** + * 获取机构树 + * + * @author yubaoshan + * @date 2020/4/26 12:08 + */ +export function getOrgTree (parameter) { + return axios({ + url: '/sysOrg/tree', + method: 'get', + params: parameter + }) +} + +/** + * 获取机构列表 + * + * @author yubaoshan + * @date 2020/5/11 12:59 + */ +export function getOrgList (parameter) { + return axios({ + url: '/sysOrg/list', + method: 'get', + params: parameter + }) +} + +/** + * 获取机构列表 + * + * @author yubaoshan + * @date 2020/5/11 16:17 + */ +export function getOrgPage (parameter) { + return axios({ + url: '/sysOrg/page', + method: 'get', + params: parameter + }) +} + +/** + * 新增机构 + * + * @author yubaoshan + * @date 2020/5/11 13:56 + */ +export function sysOrgAdd (parameter) { + return axios({ + url: '/sysOrg/add', + method: 'post', + data: parameter + }) +} + +/** + * 编辑机构 + * + * @author yubaoshan + * @date 2020/5/11 13:56 + */ +export function sysOrgEdit (parameter) { + return axios({ + url: '/sysOrg/edit', + method: 'post', + data: parameter + }) +} + +/** + * 删除机构 + * + * @author yubaoshan + * @date 2020/5/11 12:59 + */ +export function sysOrgDelete (parameter) { + return axios({ + url: '/sysOrg/delete', + method: 'post', + data: parameter + }) +} diff --git a/_web/src/api/modular/system/posManage.js b/_web/src/api/modular/system/posManage.js new file mode 100644 index 00000000..847cf612 --- /dev/null +++ b/_web/src/api/modular/system/posManage.js @@ -0,0 +1,71 @@ +import { axios } from '@/utils/request' + +/** + * 查询系统职位 + * + * @author yubaoshan + * @date 2020/5/25 01:31 + */ +export function sysPosPage (parameter) { + return axios({ + url: '/sysPos/page', + method: 'get', + params: parameter + }) +} + +/** + * 系统职位列表 + * + * @author yubaoshan + * @date 2020/6/21 23:50 + */ +export function sysPosList (parameter) { + return axios({ + url: '/sysPos/list', + method: 'get', + params: parameter + }) +} + +/** + * 添加系统职位 + * + * @author yubaoshan + * @date 2020/5/25 01:31 + */ +export function sysPosAdd (parameter) { + return axios({ + url: '/sysPos/add', + method: 'post', + data: parameter + }) +} + +/** + * 编辑系统职位 + * + * @author yubaoshan + * @date 2020/5/25 01:31 + */ +export function sysPosEdit (parameter) { + return axios({ + url: '/sysPos/edit', + method: 'post', + data: parameter + }) +} + +/** + * 删除系统职位 + * + * @author yubaoshan + * @date 2020/5/25 01:31 + */ +export function sysPosDelete (parameter) { + return axios({ + url: '/sysPos/delete', + method: 'post', + data: parameter + }) +} diff --git a/_web/src/api/modular/system/roleManage.js b/_web/src/api/modular/system/roleManage.js new file mode 100644 index 00000000..40bb8336 --- /dev/null +++ b/_web/src/api/modular/system/roleManage.js @@ -0,0 +1,141 @@ +import { axios } from '@/utils/request' + +/** + * 获取角色列表 + * + * @author yubaoshan + * @date 2020/5/6 11:44 + */ +export function getRolePage (parameter) { + return axios({ + url: '/sysRole/page', + method: 'get', + params: parameter + }) +} + +/** + * 增加角色 + * + * @author yubaoshan + * @date 2020/5/6 11:44 + */ +export function sysRoleAdd (parameter) { + return axios({ + url: '/sysRole/add', + method: 'post', + data: parameter + }) +} + +/** + * 编辑角色 + * + * @author yubaoshan + * @date 2020/5/6 11:44 + */ +export function sysRoleEdit (parameter) { + return axios({ + url: '/sysRole/edit', + method: 'post', + data: parameter + }) +} + +/** + * 删除角色 + * + * @author yubaoshan + * @date 2020/5/6 17:51 + */ +export function sysRoleDelete (parameter) { + return axios({ + url: '/sysRole/delete', + method: 'post', + data: parameter + }) +} + +/** + * 删除角色 + * + * @author yubaoshan + * @date 2020/5/7 11:28 + */ +export function sysRoleDeteil (parameter) { + return axios({ + url: '/sysRole/detail', + method: 'get', + params: parameter + }) +} + +/** + * 获取授权角色列表 + * + * @author yubaoshan + * @date 2020/5/26 23:59 + */ +export function sysRoleDropDown (parameter) { + return axios({ + url: '/sysRole/dropDown', + method: 'get', + params: parameter + }) +} + +/** + * 拥有菜单 + * + * @author yubaoshan + * @date 2020/6/02 19:02 + */ +export function sysRoleOwnMenu (parameter) { + return axios({ + url: '/sysRole/ownMenu', + method: 'get', + params: parameter + }) +} + +/** + * 授权菜单 + * + * @author yubaoshan + * @date 2020/6/2 21:10 + */ +export function sysRoleGrantMenu (parameter) { + return axios({ + url: '/sysRole/grantMenu', + method: 'post', + data: parameter + }) +} + +/** + * 拥有数据 + * + * @author yubaoshan + * @date 2020/6/02 21:40 + */ +export function sysRoleOwnData (parameter) { + return axios({ + url: '/sysRole/ownData', + method: 'get', + params: parameter + }) +} + +/** + * 授权数据 + * + * @author yubaoshan + * @date 2020/6/2 21:50 + */ +export function sysRoleGrantData (parameter) { + return axios({ + url: '/sysRole/grantData', + method: 'post', + data: parameter + }) +} diff --git a/_web/src/api/modular/system/smsManage.js b/_web/src/api/modular/system/smsManage.js new file mode 100644 index 00000000..9973bd2e --- /dev/null +++ b/_web/src/api/modular/system/smsManage.js @@ -0,0 +1,43 @@ +import { axios } from '@/utils/request' + +/** + * 发送记录查询 + * + * @author yubaoshan + * @date 2020/7/3 22:11 + */ +export function smsPage (parameter) { + return axios({ + url: '/sms/page', + method: 'get', + params: parameter + }) +} + +/** + * 验证短信验证码 + * + * @author yubaoshan + * @date 2020/7/3 22:12 + */ +export function sysSendLoginMessage (parameter) { + return axios({ + url: '/sms/sendLoginMessage', + method: 'post', + data: parameter + }) +} + +/** + * 验证短信验证码 + * + * @author yubaoshan + * @date 2020/7/3 22:12 + */ +export function sysValidateMessage (parameter) { + return axios({ + url: '/sms/validateMessage', + method: 'post', + data: parameter + }) +} diff --git a/_web/src/api/modular/system/timersManage.js b/_web/src/api/modular/system/timersManage.js new file mode 100644 index 00000000..7ca18f74 --- /dev/null +++ b/_web/src/api/modular/system/timersManage.js @@ -0,0 +1,127 @@ +import { axios } from '@/utils/request' + +/** + * 分页查询定时任务 + * + * @author yubaoshan + * @date 2020/7/3 03:13 + */ +export function sysTimersPage (parameter) { + return axios({ + url: '/sysTimers/page', + method: 'get', + params: parameter + }) +} + +/** + * 获取全部定时任务 + * + * @author yubaoshan + * @date 2020/7/3 03:23 + */ +export function sysTimersList (parameter) { + return axios({ + url: '/sysTimers/list', + method: 'get', + params: parameter + }) +} + +/** + * 查看详情定时任务 + * + * @author yubaoshan + * @date 2020/7/3 03:23 + */ +export function sysTimersDetail (parameter) { + return axios({ + url: '/sysTimers/detail', + method: 'get', + params: parameter + }) +} + +/** + * 添加定时任务 + * + * @author yubaoshan + * @date 2020/7/3 03:23 + */ +export function sysTimersAdd (parameter) { + return axios({ + url: '/sysTimers/add', + method: 'post', + data: parameter + }) +} + +/** + * 删除定时任务 + * + * @author yubaoshan + * @date 2020/7/3 03:23 + */ +export function sysTimersDelete (parameter) { + return axios({ + url: '/sysTimers/delete', + method: 'post', + data: parameter + }) +} + +/** + * 编辑定时任务 + * + * @author yubaoshan + * @date 2020/7/3 03:23 + */ +export function sysTimersEdit (parameter) { + return axios({ + url: '/sysTimers/edit', + method: 'post', + data: parameter + }) +} + +/** + * 获取系统的所有任务列表 + * + * @author yubaoshan + * @date 2020/7/3 03:23 + */ +export function sysTimersGetActionClasses (parameter) { + return axios({ + url: '/sysTimers/getActionClasses', + method: 'post', + data: parameter + }) +} + +/** + * 启动定时任务 + * + * @author yubaoshan + * @date 2020/7/3 03:23 + */ +export function sysTimersStart (parameter) { + return axios({ + url: '/sysTimers/start', + method: 'post', + data: parameter + }) +} + +/** + * 停止定时任务 + * + * @author yubaoshan + * @date 2020/7/3 03:23 + */ +export function sysTimersStop (parameter) { + return axios({ + url: '/sysTimers/stop', + method: 'post', + data: parameter + }) +} diff --git a/_web/src/api/modular/system/userManage.js b/_web/src/api/modular/system/userManage.js new file mode 100644 index 00000000..3dce14c9 --- /dev/null +++ b/_web/src/api/modular/system/userManage.js @@ -0,0 +1,211 @@ +import { axios } from '@/utils/request' + +/** + * 获取用户列表 + * + * @author yubaoshan + * @date 2020/4/26 12:08 + */ +export function getUserPage (parameter) { + return axios({ + url: '/sysUser/page', + method: 'get', + params: parameter + }) +} + +/** + * 增加用户 + * + * @author yubaoshan + * @date 2020/5/5 02:08 + */ +export function sysUserAdd (parameter) { + return axios({ + url: '/sysUser/add', + method: 'post', + data: parameter + }) +} + +/** + * 编辑用户 + * + * @author yubaoshan + * @date 2020/5/5 02:08 + */ +export function sysUserEdit (parameter) { + return axios({ + url: '/sysUser/edit', + method: 'post', + data: parameter + }) +} + +/** + * 获取用户详情 + * + * @author yubaoshan + * @date 2020/5/5 19:55 + */ +export function sysUserDetail (parameter) { + return axios({ + url: '/sysUser/detail', + method: 'get', + params: parameter + }) +} + +/** + * 删除用户 + * + * @author yubaoshan + * @date 2020/5/7 19:31 + */ +export function sysUserDelete (parameter) { + return axios({ + url: '/sysUser/delete', + method: 'post', + data: parameter + }) +} + +/** + * 拥有角色 + * + * @author yubaoshan + * @date 2020/6/3 11:58 + */ +export function sysUserOwnRole (parameter) { + return axios({ + url: '/sysUser/ownRole', + method: 'get', + params: parameter + }) +} + +/** + * 授权角色 + * + * @author yubaoshan + * @date 2020/5/26 23:59 + */ +export function sysUserGrantRole (parameter) { + return axios({ + url: '/sysUser/grantRole', + method: 'post', + data: parameter + }) +} + +/** + * 拥有数据 + * + * @author yubaoshan + * @date 2020/6/2 23:14 + */ +export function sysUserOwnData (parameter) { + return axios({ + url: '/sysUser/ownData', + method: 'get', + params: parameter + }) +} + +/** + * 授权数据 + * + * @author yubaoshan + * @date 2020/6/2 23:15 + */ +export function sysUserGrantData (parameter) { + return axios({ + url: '/sysUser/grantData', + method: 'post', + data: parameter + }) +} + +/** + * 修改状态 + * + * @author yubaoshan + * @date 2020/6/23 21:36 + */ +export function sysUserChangeStatus (parameter) { + return axios({ + url: '/sysUser/changeStatus', + method: 'post', + data: parameter + }) +} + +/** + * 重置密码 + * + * @author yubaoshan + * @date 2020/6/23 22:04 + */ +export function sysUserResetPwd (parameter) { + return axios({ + url: '/sysUser/resetPwd', + method: 'post', + data: parameter + }) +} + +/** + * 修改密码 + * + * @author yubaoshan + * @date 2020/6/25 00:25 + */ +export function sysUserUpdatePwd (parameter) { + return axios({ + url: '/sysUser/updatePwd', + method: 'post', + data: parameter + }) +} + +/** + * 用户选择器 + * + * @author yubaoshan + * @date 2020/6/25 00:25 + */ +export function sysUserSelector (parameter) { + return axios({ + url: '/sysUser/selector', + method: 'get', + params: parameter + }) +} + +/** + * 修改头像 + * + * @author yubaoshan + * @date 2020/9/20 2:21 + */ +export function sysUserUpdateAvatar (parameter) { + return axios({ + url: '/sysUser/updateAvatar', + method: 'post', + data: parameter + }) +} + +/** + * 更新基本信息 + * + * @author yubaoshan + * @date 2020/9/20 03:12 + */ +export function sysUserUpdateInfo (parameter) { + return axios({ + url: '/sysUser/updateInfo', + method: 'post', + data: parameter + }) +} diff --git a/_web/src/assets/background.svg b/_web/src/assets/background.svg new file mode 100644 index 00000000..89c25976 --- /dev/null +++ b/_web/src/assets/background.svg @@ -0,0 +1,69 @@ + + + + Group 21 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_web/src/assets/icons/bx-analyse.svg b/_web/src/assets/icons/bx-analyse.svg new file mode 100644 index 00000000..b02a8d66 --- /dev/null +++ b/_web/src/assets/icons/bx-analyse.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/_web/src/assets/logo.png b/_web/src/assets/logo.png new file mode 100644 index 00000000..e85a4737 Binary files /dev/null and b/_web/src/assets/logo.png differ diff --git a/_web/src/assets/logo.svg b/_web/src/assets/logo.svg new file mode 100644 index 00000000..50d43aa1 --- /dev/null +++ b/_web/src/assets/logo.svg @@ -0,0 +1,376 @@ + + + + diff --git a/_web/src/assets/welcome.png b/_web/src/assets/welcome.png new file mode 100644 index 00000000..94abec24 Binary files /dev/null and b/_web/src/assets/welcome.png differ diff --git a/_web/src/components/ArticleListContent/ArticleListContent.vue b/_web/src/components/ArticleListContent/ArticleListContent.vue new file mode 100644 index 00000000..8f399787 --- /dev/null +++ b/_web/src/components/ArticleListContent/ArticleListContent.vue @@ -0,0 +1,89 @@ + + + + + diff --git a/_web/src/components/ArticleListContent/index.js b/_web/src/components/ArticleListContent/index.js new file mode 100644 index 00000000..37d35c7d --- /dev/null +++ b/_web/src/components/ArticleListContent/index.js @@ -0,0 +1,3 @@ +import ArticleListContent from './ArticleListContent' + +export default ArticleListContent diff --git a/_web/src/components/AvatarList/Item.vue b/_web/src/components/AvatarList/Item.vue new file mode 100644 index 00000000..26e149ee --- /dev/null +++ b/_web/src/components/AvatarList/Item.vue @@ -0,0 +1,46 @@ + + + diff --git a/_web/src/components/AvatarList/List.vue b/_web/src/components/AvatarList/List.vue new file mode 100644 index 00000000..446ceeb8 --- /dev/null +++ b/_web/src/components/AvatarList/List.vue @@ -0,0 +1,99 @@ + + + diff --git a/_web/src/components/AvatarList/index.js b/_web/src/components/AvatarList/index.js new file mode 100644 index 00000000..dd6bb8ba --- /dev/null +++ b/_web/src/components/AvatarList/index.js @@ -0,0 +1,4 @@ +import AvatarList from './List' +import './index.less' + +export default AvatarList diff --git a/_web/src/components/AvatarList/index.less b/_web/src/components/AvatarList/index.less new file mode 100644 index 00000000..9ce073fd --- /dev/null +++ b/_web/src/components/AvatarList/index.less @@ -0,0 +1,60 @@ +@import "../index"; + +@avatar-list-prefix-cls: ~"@{ant-pro-prefix}-avatar-list"; +@avatar-list-item-prefix-cls: ~"@{ant-pro-prefix}-avatar-list-item"; + +.@{avatar-list-prefix-cls} { + display: inline-block; + + ul { + list-style: none; + display: inline-block; + padding: 0; + margin: 0 0 0 8px; + font-size: 0; + } +} + +.@{avatar-list-item-prefix-cls} { + display: inline-block; + font-size: @font-size-base; + margin-left: -8px; + width: @avatar-size-base; + height: @avatar-size-base; + + :global { + .ant-avatar { + border: 1px solid #fff; + cursor: pointer; + } + } + + &.large { + width: @avatar-size-lg; + height: @avatar-size-lg; + } + + &.small { + width: @avatar-size-sm; + height: @avatar-size-sm; + } + + &.mini { + width: 20px; + height: 20px; + + :global { + .ant-avatar { + width: 20px; + height: 20px; + line-height: 20px; + + .ant-avatar-string { + font-size: 12px; + line-height: 18px; + } + } + } + } +} + diff --git a/_web/src/components/AvatarList/index.md b/_web/src/components/AvatarList/index.md new file mode 100644 index 00000000..dc9c0920 --- /dev/null +++ b/_web/src/components/AvatarList/index.md @@ -0,0 +1,64 @@ +# AvatarList 用户头像列表 + + +一组用户头像,常用在项目/团队成员列表。可通过设置 `size` 属性来指定头像大小。 + + + +引用方式: + +```javascript +import AvatarList from '@/components/AvatarList' +const AvatarListItem = AvatarList.AvatarItem + +export default { + components: { + AvatarList, + AvatarListItem + } +} +``` + + + +## 代码演示 [demo](https://pro.loacg.com/test/home) + +```html + + + + + +``` +或 +```html + + + + + + + + + +``` + + + +## API + +### AvatarList + +| 参数 | 说明 | 类型 | 默认值 | +| ---------------- | -------- | ---------------------------------- | --------- | +| size | 头像大小 | `large`、`small` 、`mini`, `default` | `default` | +| maxLength | 要显示的最大项目 | number | - | +| excessItemsStyle | 多余的项目风格 | CSSProperties | - | + +### AvatarList.Item + +| 参数 | 说明 | 类型 | 默认值 | +| ---- | ------ | --------- | --- | +| tips | 头像展示文案 | string | - | +| src | 头像图片连接 | string | - | + diff --git a/_web/src/components/Charts/Bar.vue b/_web/src/components/Charts/Bar.vue new file mode 100644 index 00000000..44828453 --- /dev/null +++ b/_web/src/components/Charts/Bar.vue @@ -0,0 +1,62 @@ + + + diff --git a/_web/src/components/Charts/ChartCard.vue b/_web/src/components/Charts/ChartCard.vue new file mode 100644 index 00000000..fc1f4252 --- /dev/null +++ b/_web/src/components/Charts/ChartCard.vue @@ -0,0 +1,120 @@ + + + + + diff --git a/_web/src/components/Charts/Liquid.vue b/_web/src/components/Charts/Liquid.vue new file mode 100644 index 00000000..4019fb18 --- /dev/null +++ b/_web/src/components/Charts/Liquid.vue @@ -0,0 +1,67 @@ + + + + + diff --git a/_web/src/components/Charts/MiniArea.vue b/_web/src/components/Charts/MiniArea.vue new file mode 100644 index 00000000..58fe92c7 --- /dev/null +++ b/_web/src/components/Charts/MiniArea.vue @@ -0,0 +1,56 @@ + + + + + diff --git a/_web/src/components/Charts/MiniBar.vue b/_web/src/components/Charts/MiniBar.vue new file mode 100644 index 00000000..beac404b --- /dev/null +++ b/_web/src/components/Charts/MiniBar.vue @@ -0,0 +1,57 @@ + + + + + diff --git a/_web/src/components/Charts/MiniProgress.vue b/_web/src/components/Charts/MiniProgress.vue new file mode 100644 index 00000000..e6913631 --- /dev/null +++ b/_web/src/components/Charts/MiniProgress.vue @@ -0,0 +1,75 @@ + + + + + diff --git a/_web/src/components/Charts/MiniSmoothArea.vue b/_web/src/components/Charts/MiniSmoothArea.vue new file mode 100644 index 00000000..e5455c22 --- /dev/null +++ b/_web/src/components/Charts/MiniSmoothArea.vue @@ -0,0 +1,40 @@ + + + + + diff --git a/_web/src/components/Charts/Radar.vue b/_web/src/components/Charts/Radar.vue new file mode 100644 index 00000000..5ee88ade --- /dev/null +++ b/_web/src/components/Charts/Radar.vue @@ -0,0 +1,68 @@ + + + + + diff --git a/_web/src/components/Charts/RankList.vue b/_web/src/components/Charts/RankList.vue new file mode 100644 index 00000000..afb56a1a --- /dev/null +++ b/_web/src/components/Charts/RankList.vue @@ -0,0 +1,77 @@ + + + + + diff --git a/_web/src/components/Charts/TagCloud.vue b/_web/src/components/Charts/TagCloud.vue new file mode 100644 index 00000000..74d1b3f1 --- /dev/null +++ b/_web/src/components/Charts/TagCloud.vue @@ -0,0 +1,113 @@ + + + diff --git a/_web/src/components/Charts/TransferBar.vue b/_web/src/components/Charts/TransferBar.vue new file mode 100644 index 00000000..7f96f0be --- /dev/null +++ b/_web/src/components/Charts/TransferBar.vue @@ -0,0 +1,64 @@ + + + diff --git a/_web/src/components/Charts/Trend.vue b/_web/src/components/Charts/Trend.vue new file mode 100644 index 00000000..2dce37e2 --- /dev/null +++ b/_web/src/components/Charts/Trend.vue @@ -0,0 +1,82 @@ + + + + + diff --git a/_web/src/components/Charts/chart.less b/_web/src/components/Charts/chart.less new file mode 100644 index 00000000..e04fa095 --- /dev/null +++ b/_web/src/components/Charts/chart.less @@ -0,0 +1,13 @@ +.antv-chart-mini { + position: relative; + width: 100%; + + .chart-wrapper { + position: absolute; + bottom: -28px; + width: 100%; + +/* margin: 0 -5px; + overflow: hidden;*/ + } +} \ No newline at end of file diff --git a/_web/src/components/Charts/smooth.area.less b/_web/src/components/Charts/smooth.area.less new file mode 100644 index 00000000..eabdb753 --- /dev/null +++ b/_web/src/components/Charts/smooth.area.less @@ -0,0 +1,14 @@ +@import "../index"; + +@smoothArea-prefix-cls: ~"@{ant-pro-prefix}-smooth-area"; + +.@{smoothArea-prefix-cls} { + position: relative; + width: 100%; + + .chart-wrapper { + position: absolute; + bottom: -28px; + width: 100%; + } +} \ No newline at end of file diff --git a/_web/src/components/CountDown/CountDown.vue b/_web/src/components/CountDown/CountDown.vue new file mode 100644 index 00000000..575dd4aa --- /dev/null +++ b/_web/src/components/CountDown/CountDown.vue @@ -0,0 +1,102 @@ + + + + + diff --git a/_web/src/components/CountDown/index.js b/_web/src/components/CountDown/index.js new file mode 100644 index 00000000..35e954f2 --- /dev/null +++ b/_web/src/components/CountDown/index.js @@ -0,0 +1,3 @@ +import CountDown from './CountDown' + +export default CountDown diff --git a/_web/src/components/CountDown/index.md b/_web/src/components/CountDown/index.md new file mode 100644 index 00000000..fd46809b --- /dev/null +++ b/_web/src/components/CountDown/index.md @@ -0,0 +1,34 @@ +# CountDown 倒计时 + +倒计时组件。 + + + +引用方式: + +```javascript +import CountDown from '@/components/CountDown/CountDown' + +export default { + components: { + CountDown + } +} +``` + + + +## 代码演示 [demo](https://pro.loacg.com/test/home) + +```html + +``` + + + +## API + +| 参数 | 说明 | 类型 | 默认值 | +|----------|------------------------------------------|-------------|-------| +| target | 目标时间 | Date | - | +| onEnd | 倒计时结束回调 | funtion | -| diff --git a/_web/src/components/DescriptionList/DescriptionList.vue b/_web/src/components/DescriptionList/DescriptionList.vue new file mode 100644 index 00000000..7f98fec4 --- /dev/null +++ b/_web/src/components/DescriptionList/DescriptionList.vue @@ -0,0 +1,153 @@ + + + + + diff --git a/_web/src/components/DescriptionList/index.js b/_web/src/components/DescriptionList/index.js new file mode 100644 index 00000000..7aed83d4 --- /dev/null +++ b/_web/src/components/DescriptionList/index.js @@ -0,0 +1,2 @@ +import DescriptionList from './DescriptionList' +export default DescriptionList diff --git a/_web/src/components/Dialog.js b/_web/src/components/Dialog.js new file mode 100644 index 00000000..78e95b27 --- /dev/null +++ b/_web/src/components/Dialog.js @@ -0,0 +1,113 @@ +import Modal from 'ant-design-vue/es/modal' +export default (Vue) => { + function dialog (component, componentProps, modalProps) { + const _vm = this + modalProps = modalProps || {} + if (!_vm || !_vm._isVue) { + return + } + let dialogDiv = document.querySelector('body>div[type=dialog]') + if (!dialogDiv) { + dialogDiv = document.createElement('div') + dialogDiv.setAttribute('type', 'dialog') + document.body.appendChild(dialogDiv) + } + + const handle = function (checkFunction, afterHandel) { + if (checkFunction instanceof Function) { + const res = checkFunction() + if (res instanceof Promise) { + res.then(c => { + c && afterHandel() + }) + } else { + res && afterHandel() + } + } else { + // checkFunction && afterHandel() + checkFunction || afterHandel() + } + } + + const dialogInstance = new Vue({ + data () { + return { + visible: true + } + }, + router: _vm.$router, + store: _vm.$store, + mounted () { + this.$on('close', (v) => { + this.handleClose() + }) + }, + methods: { + handleClose () { + handle(this.$refs._component.onCancel, () => { + this.visible = false + this.$refs._component.$emit('close') + this.$refs._component.$emit('cancel') + dialogInstance.$destroy() + }) + }, + handleOk () { + handle(this.$refs._component.onOK || this.$refs._component.onOk, () => { + this.visible = false + this.$refs._component.$emit('close') + this.$refs._component.$emit('ok') + dialogInstance.$destroy() + }) + } + }, + render: function (h) { + const that = this + const modalModel = modalProps && modalProps.model + if (modalModel) { + delete modalProps.model + } + const ModalProps = Object.assign({}, modalModel && { model: modalModel } || {}, { + attrs: Object.assign({}, { + ...(modalProps.attrs || modalProps) + }, { + visible: this.visible + }), + on: Object.assign({}, { + ...(modalProps.on || modalProps) + }, { + ok: () => { + that.handleOk() + }, + cancel: () => { + that.handleClose() + } + }) + }) + + const componentModel = componentProps && componentProps.model + if (componentModel) { + delete componentProps.model + } + const ComponentProps = Object.assign({}, componentModel && { model: componentModel } || {}, { + ref: '_component', + attrs: Object.assign({}, { + ...((componentProps && componentProps.attrs) || componentProps) + }), + on: Object.assign({}, { + ...((componentProps && componentProps.on) || componentProps) + }) + }) + + return h(Modal, ModalProps, [h(component, ComponentProps)]) + } + }).$mount(dialogDiv) + } + + Object.defineProperty(Vue.prototype, '$dialog', { + get: () => { + return function () { + dialog.apply(this, arguments) + } + } + }) +} diff --git a/_web/src/components/Editor/QuillEditor.vue b/_web/src/components/Editor/QuillEditor.vue new file mode 100644 index 00000000..731701c8 --- /dev/null +++ b/_web/src/components/Editor/QuillEditor.vue @@ -0,0 +1,82 @@ + + + + + diff --git a/_web/src/components/Editor/WangEditor.vue b/_web/src/components/Editor/WangEditor.vue new file mode 100644 index 00000000..7a79a9e0 --- /dev/null +++ b/_web/src/components/Editor/WangEditor.vue @@ -0,0 +1,126 @@ + + + + diff --git a/_web/src/components/Ellipsis/Ellipsis.vue b/_web/src/components/Ellipsis/Ellipsis.vue new file mode 100644 index 00000000..5d592008 --- /dev/null +++ b/_web/src/components/Ellipsis/Ellipsis.vue @@ -0,0 +1,64 @@ + diff --git a/_web/src/components/Ellipsis/index.js b/_web/src/components/Ellipsis/index.js new file mode 100644 index 00000000..91e3ff4f --- /dev/null +++ b/_web/src/components/Ellipsis/index.js @@ -0,0 +1,3 @@ +import Ellipsis from './Ellipsis' + +export default Ellipsis diff --git a/_web/src/components/Ellipsis/index.md b/_web/src/components/Ellipsis/index.md new file mode 100644 index 00000000..f528ac7f --- /dev/null +++ b/_web/src/components/Ellipsis/index.md @@ -0,0 +1,38 @@ +# Ellipsis 文本自动省略号 + +文本过长自动处理省略号,支持按照文本长度和最大行数两种方式截取。 + + + +引用方式: + +```javascript +import Ellipsis from '@/components/Ellipsis' + +export default { + components: { + Ellipsis + } +} +``` + + + +## 代码演示 [demo](https://pro.loacg.com/test/home) + +```html + + There were injuries alleged in three cases in 2015, and a + fourth incident in September, according to the safety recall report. After meeting with US regulators in October, the firm decided to issue a voluntary recall. + +``` + + + +## API + + +参数 | 说明 | 类型 | 默认值 +----|------|-----|------ +tooltip | 移动到文本展示完整内容的提示 | boolean | - +length | 在按照长度截取下的文本最大字符数,超过则截取省略 | number | - \ No newline at end of file diff --git a/_web/src/components/Exception/ExceptionPage.vue b/_web/src/components/Exception/ExceptionPage.vue new file mode 100644 index 00000000..832896ca --- /dev/null +++ b/_web/src/components/Exception/ExceptionPage.vue @@ -0,0 +1,130 @@ + + + + diff --git a/_web/src/components/Exception/index.js b/_web/src/components/Exception/index.js new file mode 100644 index 00000000..dda91be1 --- /dev/null +++ b/_web/src/components/Exception/index.js @@ -0,0 +1,2 @@ +import ExceptionPage from './ExceptionPage.vue' +export default ExceptionPage diff --git a/_web/src/components/Exception/type.js b/_web/src/components/Exception/type.js new file mode 100644 index 00000000..8158f0f9 --- /dev/null +++ b/_web/src/components/Exception/type.js @@ -0,0 +1,19 @@ +const types = { + 403: { + img: 'https://gw.alipayobjects.com/zos/rmsportal/wZcnGqRDyhPOEYFcZDnb.svg', + title: '403', + desc: '抱歉,你无权访问该页面' + }, + 404: { + img: 'https://gw.alipayobjects.com/zos/rmsportal/KpnpchXsobRgLElEozzI.svg', + title: '404', + desc: '抱歉,你访问的页面不存在或仍在开发中' + }, + 500: { + img: 'https://gw.alipayobjects.com/zos/rmsportal/RVRUAYdCGeYNBWoKiIwB.svg', + title: '500', + desc: '抱歉,服务器出错了' + } +} + +export default types diff --git a/_web/src/components/FooterToolbar/FooterToolBar.vue b/_web/src/components/FooterToolbar/FooterToolBar.vue new file mode 100644 index 00000000..f4056dc7 --- /dev/null +++ b/_web/src/components/FooterToolbar/FooterToolBar.vue @@ -0,0 +1,30 @@ + + + + + diff --git a/_web/src/components/FooterToolbar/index.js b/_web/src/components/FooterToolbar/index.js new file mode 100644 index 00000000..a0bf1459 --- /dev/null +++ b/_web/src/components/FooterToolbar/index.js @@ -0,0 +1,4 @@ +import FooterToolBar from './FooterToolBar' +import './index.less' + +export default FooterToolBar diff --git a/_web/src/components/FooterToolbar/index.less b/_web/src/components/FooterToolbar/index.less new file mode 100644 index 00000000..f56273ff --- /dev/null +++ b/_web/src/components/FooterToolbar/index.less @@ -0,0 +1,23 @@ +@import "../index"; + +@footer-toolbar-prefix-cls: ~"@{ant-pro-prefix}-footer-toolbar"; + +.@{footer-toolbar-prefix-cls} { + position: fixed; + width: 100%; + bottom: 0; + right: 0; + height: 56px; + line-height: 56px; + box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.03); + background: #fff; + border-top: 1px solid #e8e8e8; + padding: 0 24px; + z-index: 9; + + &:after { + content: ""; + display: block; + clear: both; + } +} \ No newline at end of file diff --git a/_web/src/components/FooterToolbar/index.md b/_web/src/components/FooterToolbar/index.md new file mode 100644 index 00000000..c1aec2c4 --- /dev/null +++ b/_web/src/components/FooterToolbar/index.md @@ -0,0 +1,48 @@ +# FooterToolbar 底部工具栏 + +固定在底部的工具栏。 + + + +## 何时使用 + +固定在内容区域的底部,不随滚动条移动,常用于长页面的数据搜集和提交工作。 + + + +引用方式: + +```javascript +import FooterToolBar from '@/components/FooterToolbar' + +export default { + components: { + FooterToolBar + } +} +``` + + + +## 代码演示 + +```html + + 提交 + +``` +或 +```html + + 提交 + +``` + + +## API + +参数 | 说明 | 类型 | 默认值 +----|------|-----|------ +children (slot) | 工具栏内容,向右对齐 | - | - +extra | 额外信息,向左对齐 | String, Object | - + diff --git a/_web/src/components/GlobalFooter/GlobalFooter.vue b/_web/src/components/GlobalFooter/GlobalFooter.vue new file mode 100644 index 00000000..1cebf921 --- /dev/null +++ b/_web/src/components/GlobalFooter/GlobalFooter.vue @@ -0,0 +1,46 @@ + + + + + diff --git a/_web/src/components/GlobalFooter/index.js b/_web/src/components/GlobalFooter/index.js new file mode 100644 index 00000000..832e0bdf --- /dev/null +++ b/_web/src/components/GlobalFooter/index.js @@ -0,0 +1,2 @@ +import GlobalFooter from './GlobalFooter' +export default GlobalFooter diff --git a/_web/src/components/GlobalHeader/GlobalHeader.vue b/_web/src/components/GlobalHeader/GlobalHeader.vue new file mode 100644 index 00000000..d06a4896 --- /dev/null +++ b/_web/src/components/GlobalHeader/GlobalHeader.vue @@ -0,0 +1,165 @@ + + + + + diff --git a/_web/src/components/GlobalHeader/index.js b/_web/src/components/GlobalHeader/index.js new file mode 100644 index 00000000..0807c872 --- /dev/null +++ b/_web/src/components/GlobalHeader/index.js @@ -0,0 +1,2 @@ +import GlobalHeader from './GlobalHeader' +export default GlobalHeader diff --git a/_web/src/components/IconSelector/IconSelector.vue b/_web/src/components/IconSelector/IconSelector.vue new file mode 100644 index 00000000..810d297c --- /dev/null +++ b/_web/src/components/IconSelector/IconSelector.vue @@ -0,0 +1,86 @@ + + + + + diff --git a/_web/src/components/IconSelector/README.md b/_web/src/components/IconSelector/README.md new file mode 100644 index 00000000..503095d0 --- /dev/null +++ b/_web/src/components/IconSelector/README.md @@ -0,0 +1,48 @@ +IconSelector +==== + +> 图标选择组件,常用于为某一个数据设定一个图标时使用 +> eg: 设定菜单列表时,为每个菜单设定一个图标 + +该组件由 [@Saraka](https://github.com/saraka-tsukai) 封装 + + + +### 使用方式 + +```vue + + + +``` + + + +### 事件 + + +| 名称 | 说明 | 类型 | 默认值 | +| ------ | -------------------------- | ------ | ------ | +| change | 当改变了 `icon` 选中项触发 | String | - | diff --git a/_web/src/components/IconSelector/icons.js b/_web/src/components/IconSelector/icons.js new file mode 100644 index 00000000..2afc40a7 --- /dev/null +++ b/_web/src/components/IconSelector/icons.js @@ -0,0 +1,36 @@ +/** + * 增加新的图标时,请遵循以下数据结构 + * Adding new icon please follow the data structure below + */ +export default [ + { + key: 'directional', + title: '方向性图标', + icons: ['step-backward', 'step-forward', 'fast-backward', 'fast-forward', 'shrink', 'arrows-alt', 'down', 'up', 'left', 'right', 'caret-up', 'caret-down', 'caret-left', 'caret-right', 'up-circle', 'down-circle', 'left-circle', 'right-circle', 'double-right', 'double-left', 'vertical-left', 'vertical-right', 'forward', 'backward', 'rollback', 'enter', 'retweet', 'swap', 'swap-left', 'swap-right', 'arrow-up', 'arrow-down', 'arrow-left', 'arrow-right', 'play-circle', 'up-square', 'down-square', 'left-square', 'right-square', 'login', 'logout', 'menu-fold', 'menu-unfold', 'border-bottom', 'border-horizontal', 'border-inner', 'border-left', 'border-right', 'border-top', 'border-verticle', 'pic-center', 'pic-left', 'pic-right', 'radius-bottomleft', 'radius-bottomright', 'radius-upleft', 'fullscreen', 'fullscreen-exit'] + }, + { + key: 'suggested', + title: '提示建议性图标', + icons: ['question', 'question-circle', 'plus', 'plus-circle', 'pause', 'pause-circle', 'minus', 'minus-circle', 'plus-square', 'minus-square', 'info', 'info-circle', 'exclamation', 'exclamation-circle', 'close', 'close-circle', 'close-square', 'check', 'check-circle', 'check-square', 'clock-circle', 'warning', 'issues-close', 'stop'] + }, + { + key: 'editor', + title: '编辑类图标', + icons: ['edit', 'form.vue', 'copy', 'scissor', 'delete', 'snippets', 'diff', 'highlight', 'align-center', 'align-left', 'align-right', 'bg-colors', 'bold', 'italic', 'underline', 'strikethrough', 'redo', 'undo', 'zoom-in', 'zoom-out', 'font-colors', 'font-size', 'line-height', 'column-height', 'dash', 'small-dash', 'sort-ascending', 'sort-descending', 'drag', 'ordered-list', 'radius-setting'] + }, + { + key: 'data', + title: '数据类图标', + icons: ['area-chart', 'pie-chart', 'bar-chart', 'dot-chart', 'line-chart', 'radar-chart', 'heat-map', 'fall', 'rise', 'stock', 'box-plot', 'fund', 'sliders'] + }, + { + key: 'brand_logo', + title: '网站通用图标', + icons: ['lock', 'unlock', 'bars', 'book', 'calendar', 'cloud', 'cloud-download', 'code', 'copy', 'credit-card', 'delete', 'desktop', 'download', 'ellipsis', 'file', 'file-text', 'file-unknown', 'file-pdf', 'file-word', 'file-excel', 'file-jpg', 'file-ppt', 'file-markdown', 'file-add', 'folder', 'folder-open', 'folder-add', 'hdd', 'frown', 'meh', 'smile', 'inbox', 'laptop', 'appstore', 'link', 'mail', 'mobile', 'notification', 'paper-clip', 'picture', 'poweroff', 'reload', 'search', 'setting', 'share-alt', 'shopping-cart', 'tablet', 'tag', 'tags', 'to-top', 'upload', 'user', 'video-camera', 'home', 'loading', 'loading-3-quarters', 'cloud-upload', 'star', 'heart', 'environment', 'eye', 'camera', 'save', 'team', 'solution', 'phone', 'filter', 'exception', 'export', 'customer-service', 'qrcode', 'scan', 'like', 'dislike', 'message', 'pay-circle', 'calculator', 'pushpin', 'bulb', 'select', 'switcher', 'rocket', 'bell', 'disconnect', 'database', 'compass', 'barcode', 'hourglass', 'key', 'flag', 'layout', 'printer', 'sound', 'usb', 'skin', 'tool', 'sync', 'wifi', 'car', 'schedule', 'user-add', 'user-delete', 'usergroup-add', 'usergroup-delete', 'man', 'woman', 'shop', 'gift', 'idcard', 'medicine-box', 'red-envelope', 'coffee', 'copyright', 'trademark', 'safety', 'wallet', 'bank', 'trophy', 'contacts', 'global', 'shake', 'api', 'fork', 'dashboard', 'table', 'profile', 'alert', 'audit', 'branches', 'build', 'border', 'crown', 'experiment', 'fire', 'money-collect', 'property-safety', 'read', 'reconciliation', 'rest', 'security-scan', 'insurance', 'interaction', 'safety-certificate', 'project', 'thunderbolt', 'block', 'cluster', 'deployment-unit', 'dollar', 'euro', 'pound', 'file-done', 'file-exclamation', 'file-protect', 'file-search', 'file-sync', 'gateway', 'gold', 'robot', 'shopping'] + }, + { + key: 'application', + title: '品牌和标识', + icons: ['android', 'apple', 'windows', 'ie', 'chrome', 'github', 'aliwangwang', 'dingding', 'weibo-square', 'weibo-circle', 'taobao-circle', 'html5', 'weibo', 'twitter', 'wechat', 'youtube', 'alipay-circle', 'taobao', 'skype', 'qq', 'medium-workmark', 'gitlab', 'medium', 'linkedin', 'google-plus', 'dropbox', 'facebook', 'codepen', 'code-sandbox', 'amazon', 'google', 'codepen-circle', 'alipay', 'ant-design', 'aliyun', 'zhihu', 'slack', 'slack-square', 'behance', 'behance-square', 'dribbble', 'dribbble-square', 'instagram', 'yuque', 'alibaba', 'yahoo'] + } +] diff --git a/_web/src/components/IconSelector/index.js b/_web/src/components/IconSelector/index.js new file mode 100644 index 00000000..2d27d70f --- /dev/null +++ b/_web/src/components/IconSelector/index.js @@ -0,0 +1,2 @@ +import IconSelector from './IconSelector' +export default IconSelector diff --git a/_web/src/components/Menu/SideMenu.vue b/_web/src/components/Menu/SideMenu.vue new file mode 100644 index 00000000..62fb01d9 --- /dev/null +++ b/_web/src/components/Menu/SideMenu.vue @@ -0,0 +1,61 @@ + + + diff --git a/_web/src/components/Menu/index.js b/_web/src/components/Menu/index.js new file mode 100644 index 00000000..43485098 --- /dev/null +++ b/_web/src/components/Menu/index.js @@ -0,0 +1,2 @@ +import SMenu from './menu' +export default SMenu diff --git a/_web/src/components/Menu/menu.js b/_web/src/components/Menu/menu.js new file mode 100644 index 00000000..2b3f7a20 --- /dev/null +++ b/_web/src/components/Menu/menu.js @@ -0,0 +1,177 @@ +import Menu from 'ant-design-vue/es/menu' +import Icon from 'ant-design-vue/es/icon' + +export default { + name: 'SMenu', + props: { + menu: { + type: Array, + required: true + }, + theme: { + type: String, + required: false, + default: 'dark' + }, + mode: { + type: String, + required: false, + default: 'inline' + }, + collapsed: { + type: Boolean, + required: false, + default: false + } + }, + data () { + return { + openKeys: [], + selectedKeys: [], + cachedOpenKeys: [] + } + }, + computed: { + rootSubmenuKeys: vm => { + const keys = [] + vm.menu.forEach(item => keys.push(item.path)) + return keys + } + }, + mounted () { + this.updateMenu() + }, + watch: { + collapsed (val) { + if (val) { + this.cachedOpenKeys = this.openKeys.concat() + this.openKeys = [] + } else { + this.openKeys = this.cachedOpenKeys + } + }, + $route: function () { + this.updateMenu() + } + }, + methods: { + // select menu item + onOpenChange (openKeys) { + // 在水平模式下时执行,并且不再执行后续 + if (this.mode === 'horizontal') { + this.openKeys = openKeys + return + } + // 非水平模式时 + const latestOpenKey = openKeys.find(key => !this.openKeys.includes(key)) + if (!this.rootSubmenuKeys.includes(latestOpenKey)) { + this.openKeys = openKeys + } else { + this.openKeys = latestOpenKey ? [latestOpenKey] : [] + } + }, + onSelect ({ item, key, selectedKeys }) { + this.selectedKeys = selectedKeys + this.$emit('select', { item, key, selectedKeys }) + }, + updateMenu () { + const routes = this.$route.matched.concat() + const { hidden } = this.$route.meta + if (routes.length >= 3 && hidden) { + routes.pop() + this.selectedKeys = [routes[routes.length - 1].path] + } else { + this.selectedKeys = [routes.pop().path] + } + const openKeys = [] + if (this.mode === 'inline') { + routes.forEach(item => { + openKeys.push(item.path) + }) + } + + this.collapsed ? (this.cachedOpenKeys = openKeys) : (this.openKeys = openKeys) + }, + + // render + renderItem (menu) { + if (!menu.hidden) { + return menu.children && !menu.hideChildrenInMenu ? this.renderSubMenu(menu) : this.renderMenuItem(menu) + } + return null + }, + renderMenuItem (menu) { + const target = menu.meta.target || null + const CustomTag = target && 'a' || 'router-link' + const props = { to: { name: menu.name } } + const attrs = { href: menu.path, target: menu.meta.target } + + if (menu.children && menu.hideChildrenInMenu) { + // 把有子菜单的 并且 父菜单是要隐藏子菜单的 + // 都给子菜单增加一个 hidden 属性 + // 用来给刷新页面时, selectedKeys 做控制用 + menu.children.forEach(item => { + item.meta = Object.assign(item.meta, { hidden: true }) + }) + } + + return ( + + + {this.renderIcon(menu.meta.icon)} + {menu.meta.title} + + + ) + }, + renderSubMenu (menu) { + const itemArr = [] + if (!menu.hideChildrenInMenu) { + menu.children.forEach(item => itemArr.push(this.renderItem(item))) + } + return ( + + + {this.renderIcon(menu.meta.icon)} + {menu.meta.title} + + {itemArr} + + ) + }, + renderIcon (icon) { + if (icon === 'none' || icon === undefined) { + return null + } + const props = {} + typeof (icon) === 'object' ? props.component = icon : props.type = icon + return ( + + ) + } + }, + + render () { + const dynamicProps = { + props: { + mode: this.mode, + theme: this.theme, + openKeys: this.openKeys, + selectedKeys: this.selectedKeys + }, + on: { + openChange: this.onOpenChange, + select: this.onSelect + } + } + + const menuTree = this.menu.map(item => { + if (item.hidden) { + return null + } + return this.renderItem(item) + }) + + return ({menuTree}) + } +} diff --git a/_web/src/components/Menu/menu.render.js b/_web/src/components/Menu/menu.render.js new file mode 100644 index 00000000..011639fb --- /dev/null +++ b/_web/src/components/Menu/menu.render.js @@ -0,0 +1,156 @@ +import Menu from 'ant-design-vue/es/menu' +import Icon from 'ant-design-vue/es/icon' + +const { Item, SubMenu } = Menu + +export default { + name: 'SMenu', + props: { + menu: { + type: Array, + required: true + }, + theme: { + type: String, + required: false, + default: 'dark' + }, + mode: { + type: String, + required: false, + default: 'inline' + }, + collapsed: { + type: Boolean, + required: false, + default: false + } + }, + data () { + return { + openKeys: [], + selectedKeys: [], + cachedOpenKeys: [] + } + }, + computed: { + rootSubmenuKeys: vm => { + const keys = [] + vm.menu.forEach(item => keys.push(item.path)) + return keys + } + }, + created () { + this.updateMenu() + }, + watch: { + collapsed (val) { + if (val) { + this.cachedOpenKeys = this.openKeys.concat() + this.openKeys = [] + } else { + this.openKeys = this.cachedOpenKeys + } + }, + $route: function () { + this.updateMenu() + } + }, + methods: { + renderIcon: function (h, icon) { + if (icon === 'none' || icon === undefined) { + return null + } + const props = {} + typeof (icon) === 'object' ? props.component = icon : props.type = icon + return h(Icon, { props: { ...props } }) + }, + renderMenuItem: function (h, menu, pIndex, index) { + const target = menu.meta.target || null + return h(Item, { key: menu.path ? menu.path : 'item_' + pIndex + '_' + index }, [ + h('router-link', { attrs: { to: { name: menu.name }, target: target } }, [ + this.renderIcon(h, menu.meta.icon), + h('span', [menu.meta.title]) + ]) + ]) + }, + renderSubMenu: function (h, menu, pIndex, index) { + const this2_ = this + const subItem = [h('span', { slot: 'title' }, [this.renderIcon(h, menu.meta.icon), h('span', [menu.meta.title])])] + const itemArr = [] + const pIndex_ = pIndex + '_' + index + console.log('menu', menu) + if (!menu.hideChildrenInMenu) { + menu.children.forEach(function (item, i) { + itemArr.push(this2_.renderItem(h, item, pIndex_, i)) + }) + } + return h(SubMenu, { key: menu.path ? menu.path : 'submenu_' + pIndex + '_' + index }, subItem.concat(itemArr)) + }, + renderItem: function (h, menu, pIndex, index) { + if (!menu.hidden) { + return menu.children && !menu.hideChildrenInMenu + ? this.renderSubMenu(h, menu, pIndex, index) + : this.renderMenuItem(h, menu, pIndex, index) + } + }, + renderMenu: function (h, menuTree) { + const this2_ = this + const menuArr = [] + menuTree.forEach(function (menu, i) { + if (!menu.hidden) { + menuArr.push(this2_.renderItem(h, menu, '0', i)) + } + }) + return menuArr + }, + onOpenChange (openKeys) { + const latestOpenKey = openKeys.find(key => !this.openKeys.includes(key)) + if (!this.rootSubmenuKeys.includes(latestOpenKey)) { + this.openKeys = openKeys + } else { + this.openKeys = latestOpenKey ? [latestOpenKey] : [] + } + }, + updateMenu () { + const routes = this.$route.matched.concat() + + if (routes.length >= 4 && this.$route.meta.hidden) { + routes.pop() + this.selectedKeys = [routes[2].path] + } else { + this.selectedKeys = [routes.pop().path] + } + + const openKeys = [] + if (this.mode === 'inline') { + routes.forEach(item => { + openKeys.push(item.path) + }) + } + + this.collapsed ? (this.cachedOpenKeys = openKeys) : (this.openKeys = openKeys) + } + }, + render (h) { + return h( + Menu, + { + props: { + theme: this.$props.theme, + mode: this.$props.mode, + openKeys: this.openKeys, + selectedKeys: this.selectedKeys + }, + on: { + openChange: this.onOpenChange, + select: obj => { + this.selectedKeys = obj.selectedKeys + this.$emit('select', obj) + } + } + }, + this.renderMenu(h, this.menu) + ) + } +} diff --git a/_web/src/components/MultiTab/MultiTab.vue b/_web/src/components/MultiTab/MultiTab.vue new file mode 100644 index 00000000..bfb6e57a --- /dev/null +++ b/_web/src/components/MultiTab/MultiTab.vue @@ -0,0 +1,162 @@ + diff --git a/_web/src/components/MultiTab/events.js b/_web/src/components/MultiTab/events.js new file mode 100644 index 00000000..b0230b55 --- /dev/null +++ b/_web/src/components/MultiTab/events.js @@ -0,0 +1,2 @@ +import Vue from 'vue' +export default new Vue() diff --git a/_web/src/components/MultiTab/index.js b/_web/src/components/MultiTab/index.js new file mode 100644 index 00000000..02a1c77d --- /dev/null +++ b/_web/src/components/MultiTab/index.js @@ -0,0 +1,40 @@ +import events from './events' +import MultiTab from './MultiTab' +import './index.less' + +const api = { + /** + * open new tab on route fullPath + * @param config + */ + open: function (config) { + events.$emit('open', config) + }, + rename: function (key, name) { + events.$emit('rename', { key: key, name: name }) + }, + /** + * close current page + */ + closeCurrentPage: function () { + this.close() + }, + /** + * close route fullPath tab + * @param config + */ + close: function (config) { + events.$emit('close', config) + } +} + +MultiTab.install = function (Vue) { + if (Vue.prototype.$multiTab) { + return + } + api.instance = events + Vue.prototype.$multiTab = api + Vue.component('multi-tab', MultiTab) +} + +export default MultiTab diff --git a/_web/src/components/MultiTab/index.less b/_web/src/components/MultiTab/index.less new file mode 100644 index 00000000..773e3af3 --- /dev/null +++ b/_web/src/components/MultiTab/index.less @@ -0,0 +1,25 @@ +@import '../index'; + +@multi-tab-prefix-cls: ~"@{ant-pro-prefix}-multi-tab"; +@multi-tab-wrapper-prefix-cls: ~"@{ant-pro-prefix}-multi-tab-wrapper"; + +/* +.topmenu .@{multi-tab-prefix-cls} { + max-width: 1200px; + margin: -23px auto 24px auto; +} +*/ +.@{multi-tab-prefix-cls} { + margin: -23px -24px 24px -24px; + background: #fff; +} + +.topmenu .@{multi-tab-wrapper-prefix-cls} { + max-width: 1200px; + margin: 0 auto; +} + +.topmenu.content-width-Fluid .@{multi-tab-wrapper-prefix-cls} { + max-width: 100%; + margin: 0 auto; +} diff --git a/_web/src/components/NProgress/nprogress.less b/_web/src/components/NProgress/nprogress.less new file mode 100644 index 00000000..7826c0ea --- /dev/null +++ b/_web/src/components/NProgress/nprogress.less @@ -0,0 +1,76 @@ +@import url('../index.less'); + +/* Make clicks pass-through */ +#nprogress { + pointer-events: none; +} + +#nprogress .bar { + background: @primary-color; + + position: fixed; + z-index: 1031; + top: 0; + left: 0; + + width: 100%; + height: 2px; +} + +/* Fancy blur effect */ +#nprogress .peg { + display: block; + position: absolute; + right: 0px; + width: 100px; + height: 100%; + box-shadow: 0 0 10px @primary-color, 0 0 5px @primary-color; + opacity: 1.0; + + -webkit-transform: rotate(3deg) translate(0px, -4px); + -ms-transform: rotate(3deg) translate(0px, -4px); + transform: rotate(3deg) translate(0px, -4px); +} + +/* Remove these to get rid of the spinner */ +#nprogress .spinner { + display: block; + position: fixed; + z-index: 1031; + top: 15px; + right: 15px; +} + +#nprogress .spinner-icon { + width: 18px; + height: 18px; + box-sizing: border-box; + + border: solid 2px transparent; + border-top-color: @primary-color; + border-left-color: @primary-color; + border-radius: 50%; + + -webkit-animation: nprogress-spinner 400ms linear infinite; + animation: nprogress-spinner 400ms linear infinite; +} + +.nprogress-custom-parent { + overflow: hidden; + position: relative; +} + +.nprogress-custom-parent #nprogress .spinner, +.nprogress-custom-parent #nprogress .bar { + position: absolute; +} + +@-webkit-keyframes nprogress-spinner { + 0% { -webkit-transform: rotate(0deg); } + 100% { -webkit-transform: rotate(360deg); } +} +@keyframes nprogress-spinner { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + diff --git a/_web/src/components/NoticeIcon/NoticeIcon.vue b/_web/src/components/NoticeIcon/NoticeIcon.vue new file mode 100644 index 00000000..8ae1c80d --- /dev/null +++ b/_web/src/components/NoticeIcon/NoticeIcon.vue @@ -0,0 +1,90 @@ + + + + + + diff --git a/_web/src/components/NoticeIcon/index.js b/_web/src/components/NoticeIcon/index.js new file mode 100644 index 00000000..659b9ec0 --- /dev/null +++ b/_web/src/components/NoticeIcon/index.js @@ -0,0 +1,2 @@ +import NoticeIcon from './NoticeIcon' +export default NoticeIcon diff --git a/_web/src/components/NumberInfo/NumberInfo.vue b/_web/src/components/NumberInfo/NumberInfo.vue new file mode 100644 index 00000000..bdde3e05 --- /dev/null +++ b/_web/src/components/NumberInfo/NumberInfo.vue @@ -0,0 +1,54 @@ + + + + + diff --git a/_web/src/components/NumberInfo/index.js b/_web/src/components/NumberInfo/index.js new file mode 100644 index 00000000..659a2f38 --- /dev/null +++ b/_web/src/components/NumberInfo/index.js @@ -0,0 +1,3 @@ +import NumberInfo from './NumberInfo' + +export default NumberInfo diff --git a/_web/src/components/NumberInfo/index.less b/_web/src/components/NumberInfo/index.less new file mode 100644 index 00000000..719113da --- /dev/null +++ b/_web/src/components/NumberInfo/index.less @@ -0,0 +1,55 @@ +@import "../index"; + +@numberInfo-prefix-cls: ~"@{ant-pro-prefix}-number-info"; + +.@{numberInfo-prefix-cls} { + + .ant-pro-number-info-subtitle { + color: @text-color-secondary; + font-size: @font-size-base; + height: 22px; + line-height: 22px; + overflow: hidden; + text-overflow: ellipsis; + word-break: break-all; + white-space: nowrap; + } + + .number-info-value { + margin-top: 4px; + font-size: 0; + overflow: hidden; + text-overflow: ellipsis; + word-break: break-all; + white-space: nowrap; + + & > span { + color: @heading-color; + display: inline-block; + line-height: 32px; + height: 32px; + font-size: 24px; + margin-right: 32px; + } + + .sub-total { + color: @text-color-secondary; + font-size: @font-size-lg; + vertical-align: top; + margin-right: 0; + i { + font-size: 12px; + transform: scale(0.82); + margin-left: 4px; + } + :global { + .anticon-caret-up { + color: @red-6; + } + .anticon-caret-down { + color: @green-6; + } + } + } + } +} \ No newline at end of file diff --git a/_web/src/components/NumberInfo/index.md b/_web/src/components/NumberInfo/index.md new file mode 100644 index 00000000..147adc43 --- /dev/null +++ b/_web/src/components/NumberInfo/index.md @@ -0,0 +1,43 @@ +# NumberInfo 数据文本 + +常用在数据卡片中,用于突出展示某个业务数据。 + + + +引用方式: + +```javascript +import NumberInfo from '@/components/NumberInfo' + +export default { + components: { + NumberInfo + } +} +``` + + + +## 代码演示 [demo](https://pro.loacg.com/test/home) + +```html + +``` + + + +## API + +参数 | 说明 | 类型 | 默认值 +----|------|-----|------ +title | 标题 | ReactNode\|string | - +subTitle | 子标题 | ReactNode\|string | - +total | 总量 | ReactNode\|string | - +subTotal | 子总量 | ReactNode\|string | - +status | 增加状态 | 'up \| down' | - +theme | 状态样式 | string | 'light' +gap | 设置数字和描述之间的间距(像素)| number | 8 diff --git a/_web/src/components/PageHeader/PageHeader.vue b/_web/src/components/PageHeader/PageHeader.vue new file mode 100644 index 00000000..80e686e9 --- /dev/null +++ b/_web/src/components/PageHeader/PageHeader.vue @@ -0,0 +1,202 @@ + + + + + diff --git a/_web/src/components/PageHeader/index.js b/_web/src/components/PageHeader/index.js new file mode 100644 index 00000000..ec1078c1 --- /dev/null +++ b/_web/src/components/PageHeader/index.js @@ -0,0 +1,2 @@ +import PageHeader from './PageHeader' +export default PageHeader diff --git a/_web/src/components/PageLoading/index.jsx b/_web/src/components/PageLoading/index.jsx new file mode 100644 index 00000000..af6d6d61 --- /dev/null +++ b/_web/src/components/PageLoading/index.jsx @@ -0,0 +1,106 @@ +import { Spin } from 'ant-design-vue' + +export const PageLoading = { + name: 'PageLoading', + props: { + tip: { + type: String, + default: 'Loading..' + }, + size: { + type: String, + default: 'large' + } + }, + render () { + const style = { + textAlign: 'center', + background: 'rgba(0,0,0,0.6)', + position: 'fixed', + top: 0, + bottom: 0, + left: 0, + right: 0, + zIndex: 1100 + } + const spinStyle = { + position: 'absolute', + left: '50%', + top: '40%', + transform: 'translate(-50%, -50%)' + } + return (
+ +
) + } +} + +const version = '0.0.1' +const loading = {} + +loading.newInstance = (Vue, options) => { + let loadingElement = document.querySelector('body>div[type=loading]') + if (!loadingElement) { + loadingElement = document.createElement('div') + loadingElement.setAttribute('type', 'loading') + loadingElement.setAttribute('class', 'ant-loading-wrapper') + document.body.appendChild(loadingElement) + } + + const cdProps = Object.assign({ visible: false, size: 'large', tip: 'Loading...' }, options) + + const instance = new Vue({ + data () { + return { + ...cdProps + } + }, + render () { + const { tip } = this + const props = {} + this.tip && (props.tip = tip) + if (this.visible) { + return + } + return null + } + }).$mount(loadingElement) + + function update (config) { + const { visible, size, tip } = { ...cdProps, ...config } + instance.$set(instance, 'visible', visible) + if (tip) { + instance.$set(instance, 'tip', tip) + } + if (size) { + instance.$set(instance, 'size', size) + } + } + + return { + instance, + update + } +} + +const api = { + show: function (options) { + this.instance.update({ ...options, visible: true }) + }, + hide: function () { + this.instance.update({ visible: false }) + } +} + +const install = function (Vue, options) { + if (Vue.prototype.$loading) { + return + } + api.instance = loading.newInstance(Vue, options) + Vue.prototype.$loading = api +} + +export default { + version, + install +} diff --git a/_web/src/components/Result/Result.vue b/_web/src/components/Result/Result.vue new file mode 100644 index 00000000..99f7f192 --- /dev/null +++ b/_web/src/components/Result/Result.vue @@ -0,0 +1,109 @@ + + + + + diff --git a/_web/src/components/Result/index.js b/_web/src/components/Result/index.js new file mode 100644 index 00000000..51cb3b2a --- /dev/null +++ b/_web/src/components/Result/index.js @@ -0,0 +1,2 @@ +import Result from './Result.vue' +export default Result diff --git a/_web/src/components/Search/GlobalSearch.jsx b/_web/src/components/Search/GlobalSearch.jsx new file mode 100644 index 00000000..bd9e604d --- /dev/null +++ b/_web/src/components/Search/GlobalSearch.jsx @@ -0,0 +1,63 @@ +import { Select } from 'ant-design-vue' +import './index.less' + +const GlobalSearch = { + name: 'GlobalSearch', + data () { + return { + visible: false + } + }, + mounted () { + const keyboardHandle = (e) => { + e.preventDefault() + e.stopPropagation() + const { ctrlKey, shiftKey, altKey, keyCode } = e + console.log('keyCode:', e.keyCode, e) + // key is `K` and hold ctrl + if (keyCode === 75 && ctrlKey && !shiftKey && !altKey) { + this.visible = !this.visible + } + } + document.addEventListener('keydown', keyboardHandle) + }, + render () { + const { visible } = this + const handleSearch = (e) => { + this.$emit('search', e) + } + + const handleChange = (e) => { + this.$emit('change', e) + } + if (!visible) { + return null + } + return ( + + ) + } +} + +GlobalSearch.install = function (Vue) { + Vue.component(GlobalSearch.name, GlobalSearch) +} + +export default GlobalSearch diff --git a/_web/src/components/Search/index.less b/_web/src/components/Search/index.less new file mode 100644 index 00000000..d3978522 --- /dev/null +++ b/_web/src/components/Search/index.less @@ -0,0 +1,25 @@ +@import "~ant-design-vue/es/style/themes/default"; + +.global-search-wrapper { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: @zindex-modal-mask; + background: @modal-mask-bg; + + .global-search-box { + position: absolute; + top: 20%; + left: 50%; + width: 450px; + transform: translate(-50%, -50%); + + .global-search-tips { + color: @white; + font-size: @font-size-lg; + text-align: right; + } + } +} \ No newline at end of file diff --git a/_web/src/components/SettingDrawer/SettingDrawer.vue b/_web/src/components/SettingDrawer/SettingDrawer.vue new file mode 100644 index 00000000..fec9d01a --- /dev/null +++ b/_web/src/components/SettingDrawer/SettingDrawer.vue @@ -0,0 +1,352 @@ + + + + + diff --git a/_web/src/components/SettingDrawer/SettingItem.vue b/_web/src/components/SettingDrawer/SettingItem.vue new file mode 100644 index 00000000..2b3b553c --- /dev/null +++ b/_web/src/components/SettingDrawer/SettingItem.vue @@ -0,0 +1,38 @@ + + + + + diff --git a/_web/src/components/SettingDrawer/index.js b/_web/src/components/SettingDrawer/index.js new file mode 100644 index 00000000..8260f2d3 --- /dev/null +++ b/_web/src/components/SettingDrawer/index.js @@ -0,0 +1,2 @@ +import SettingDrawer from './SettingDrawer' +export default SettingDrawer diff --git a/_web/src/components/SettingDrawer/settingConfig.js b/_web/src/components/SettingDrawer/settingConfig.js new file mode 100644 index 00000000..a0c4a68a --- /dev/null +++ b/_web/src/components/SettingDrawer/settingConfig.js @@ -0,0 +1,108 @@ +import { message } from 'ant-design-vue/es' +// import defaultSettings from '../defaultSettings'; +import themeColor from './themeColor.js' + +// let lessNodesAppended + +const colorList = [ + { + key: '薄暮', color: '#F5222D' + }, + { + key: '火山', color: '#FA541C' + }, + { + key: '日暮', color: '#FAAD14' + }, + { + key: '明青', color: '#13C2C2' + }, + { + key: '极光绿', color: '#52C41A' + }, + { + key: '拂晓蓝(默认)', color: '#1890FF' + }, + { + key: '极客蓝', color: '#2F54EB' + }, + { + key: '酱紫', color: '#722ED1' + } +] + +const updateTheme = newPrimaryColor => { + const hideMessage = message.loading('正在切换主题!', 0) + themeColor.changeColor(newPrimaryColor).finally(t => { + setTimeout(() => { + hideMessage() + }, 10) + }) +} + +/* +const updateTheme = primaryColor => { + // Don't compile less in production! + /* if (process.env.NODE_ENV === 'production') { + return; + } * / + // Determine if the component is remounted + if (!primaryColor) { + return + } + const hideMessage = message.loading('正在编译主题!', 0) + function buildIt () { + if (!window.less) { + return + } + setTimeout(() => { + window.less + .modifyVars({ + '@primary-color': primaryColor + }) + .then(() => { + hideMessage() + }) + .catch(() => { + message.error('Failed to update theme') + hideMessage() + }) + }, 200) + } + if (!lessNodesAppended) { + // insert less.js and color.less + const lessStyleNode = document.createElement('link') + const lessConfigNode = document.createElement('script') + const lessScriptNode = document.createElement('script') + lessStyleNode.setAttribute('rel', 'stylesheet/less') + lessStyleNode.setAttribute('href', '/color.less') + lessConfigNode.innerHTML = ` + window.less = { + async: true, + env: 'production', + javascriptEnabled: true + }; + ` + lessScriptNode.src = 'https://gw.alipayobjects.com/os/lib/less.js/3.8.1/less.min.js' + lessScriptNode.async = true + lessScriptNode.onload = () => { + buildIt() + lessScriptNode.onload = null + } + document.body.appendChild(lessStyleNode) + document.body.appendChild(lessConfigNode) + document.body.appendChild(lessScriptNode) + lessNodesAppended = true + } else { + buildIt() + } +} +*/ + +const updateColorWeak = colorWeak => { + // document.body.className = colorWeak ? 'colorWeak' : ''; + const app = document.body.querySelector('#app') + colorWeak ? app.classList.add('colorWeak') : app.classList.remove('colorWeak') +} + +export { updateTheme, colorList, updateColorWeak } diff --git a/_web/src/components/SettingDrawer/themeColor.js b/_web/src/components/SettingDrawer/themeColor.js new file mode 100644 index 00000000..10dfbd4c --- /dev/null +++ b/_web/src/components/SettingDrawer/themeColor.js @@ -0,0 +1,24 @@ +import client from 'webpack-theme-color-replacer/client' +import generate from '@ant-design/colors/lib/generate' + +export default { + getAntdSerials (color) { + // 淡化(即less的tint) + const lightens = new Array(9).fill().map((t, i) => { + return client.varyColor.lighten(color, i / 10) + }) + // colorPalette变换得到颜色值 + const colorPalettes = generate(color) + const rgb = client.varyColor.toNum3(color.replace('#', '')).join(',') + return lightens.concat(colorPalettes).concat(rgb) + }, + changeColor (newColor) { + var options = { + newColors: this.getAntdSerials(newColor), // new colors array, one-to-one corresponde with `matchColors` + changeUrl (cssUrl) { + return `/${cssUrl}` // while router is not `hash` mode, it needs absolute path + } + } + return client.changer.changeColor(options, Promise) + } +} diff --git a/_web/src/components/StandardFormRow/StandardFormRow.vue b/_web/src/components/StandardFormRow/StandardFormRow.vue new file mode 100644 index 00000000..a4e261b7 --- /dev/null +++ b/_web/src/components/StandardFormRow/StandardFormRow.vue @@ -0,0 +1,122 @@ + + + + + diff --git a/_web/src/components/StandardFormRow/index.js b/_web/src/components/StandardFormRow/index.js new file mode 100644 index 00000000..8155cc73 --- /dev/null +++ b/_web/src/components/StandardFormRow/index.js @@ -0,0 +1,3 @@ +import StandardFormRow from './StandardFormRow' + +export default StandardFormRow diff --git a/_web/src/components/Table/README.md b/_web/src/components/Table/README.md new file mode 100644 index 00000000..5d37c4be --- /dev/null +++ b/_web/src/components/Table/README.md @@ -0,0 +1,341 @@ +Table 重封装组件说明 +==== + + +封装说明 +---- + +> 基础的使用方式与 API 与 [官方版(Table)](https://vuecomponent.github.io/ant-design-vue/components/table-cn/) 本一致,在其基础上,封装了加载数据的方法。 +> +> 你无需在你是用表格的页面进行分页逻辑处理,仅需向 Table 组件传递绑定 `:data="Promise"` 对象即可 + +该 `table` 由 [@Saraka](https://github.com/saraka-tsukai) 完成封装 + + +例子1 +---- +(基础使用) + +```vue + + + + + +``` + + + +例子2 +---- + +(简单的表格,最后一列是各种操作) + +```vue + + + +``` + + + +内置方法 +---- + +通过 `this.$refs.table` 调用 + +`this.$refs.table.refresh(true)` 刷新列表 (用户新增/修改数据后,重载列表数据) + +> 注意:要调用 `refresh(bool)` 需要给表格组件设定 `ref` 值 +> +> `refresh()` 方法可以传一个 `bool` 值,当有传值 或值为 `true` 时,则刷新时会强制刷新到第一页(常用户页面 搜索 按钮进行搜索时,结果从第一页开始分页) + + +内置属性 +---- +> 除去 `a-table` 自带属性外,还而外提供了一些额外属性属性 + + +| 属性 | 说明 | 类型 | 默认值 | +| -------------- | ----------------------------------------------- | ----------------- | ------ | +| alert | 设置是否显示表格信息栏 | [object, boolean] | null | +| showPagination | 显示分页选择器,可传 'auto' \| boolean | [string, boolean] | 'auto' | +| data | 加载数据方法 必须为 `Promise` 对象 **必须绑定** | Promise | - | + + +`alert` 属性对象: + +```javascript +alert: { + show: Boolean, + clear: [Function, Boolean] +} +``` + +注意事项 +---- + +> 你可能需要为了与后端提供的接口返回结果一致而去修改以下代码: +> (需要注意的是,这里的修改是全局性的,意味着整个项目所有使用该 table 组件都需要遵守这个返回结果定义的字段。) +> +> 文档中的结构有可能由于组件 bug 进行修正而改动。实际修改请以当时最新版本为准 + +修改 `@/components/table/index.js` 第 156 行起 + + + +```javascript +result.then(r => { + this.localPagination = this.showPagination && Object.assign({}, this.localPagination, { + current: r.pageNo, // 返回结果中的当前分页数 + total: r.totalCount, // 返回结果中的总记录数 + showSizeChanger: this.showSizeChanger, + pageSize: (pagination && pagination.pageSize) || + this.localPagination.pageSize + }) || false + // 为防止删除数据后导致页面当前页面数据长度为 0 ,自动翻页到上一页 + if (r.data.length === 0 && this.showPagination && this.localPagination.current > 1) { + this.localPagination.current-- + this.loadData() + return + } + + // 这里用于判断接口是否有返回 r.totalCount 且 this.showPagination = true 且 pageNo 和 pageSize 存在 且 totalCount 小于等于 pageNo * pageSize 的大小 + // 当情况满足时,表示数据不满足分页大小,关闭 table 分页功能 + try { + if ((['auto', true].includes(this.showPagination) && r.totalCount <= (r.pageNo * this.localPagination.pageSize))) { + this.localPagination.hideOnSinglePage = true + } + } catch (e) { + this.localPagination = false + } + console.log('loadData -> this.localPagination', this.localPagination) + this.localDataSource = r.data // 返回结果中的数组数据 + this.localLoading = false + }) +``` +返回 JSON 例子: +```json +{ + "message": "", + "result": { + "data": [{ + id: 1, + cover: 'https://gw.alipayobjects.com/zos/rmsportal/WdGqmHpayyMjiEhcKoVE.png', + title: 'Alipay', + description: '那是一种内在的东西, 他们到达不了,也无法触及的', + status: 1, + updatedAt: '2018-07-26 00:00:00' + }, + { + id: 2, + cover: 'https://gw.alipayobjects.com/zos/rmsportal/zOsKZmFRdUtvpqCImOVY.png', + title: 'Angular', + description: '希望是一个好东西,也许是最好的,好东西是不会消亡的', + status: 1, + updatedAt: '2018-07-26 00:00:00' + }, + { + id: 3, + cover: 'https://gw.alipayobjects.com/zos/rmsportal/dURIMkkrRFpPgTuzkwnB.png', + title: 'Ant Design', + description: '城镇中有那么多的酒馆,她却偏偏走进了我的酒馆', + status: 1, + updatedAt: '2018-07-26 00:00:00' + }, + { + id: 4, + cover: 'https://gw.alipayobjects.com/zos/rmsportal/sfjbOqnsXXJgNCjCzDBL.png', + title: 'XiaoNuo', + description: '那时候我只会想自己想要什么,从不想自己拥有什么', + status: 1, + updatedAt: '2018-07-26 00:00:00' + }, + { + id: 5, + cover: 'https://gw.alipayobjects.com/zos/rmsportal/siCrBXXhmvTQGWPNLBow.png', + title: 'Bootstrap', + description: '凛冬将至', + status: 1, + updatedAt: '2018-07-26 00:00:00' + }, + { + id: 6, + cover: 'https://gw.alipayobjects.com/zos/rmsportal/ComBAopevLwENQdKWiIn.png', + title: 'Vue', + description: '生命就像一盒巧克力,结果往往出人意料', + status: 1, + updatedAt: '2018-07-26 00:00:00' + } + ], + "pageSize": 10, + "pageNo": 0, + "totalPage": 6, + "totalCount": 57 + }, + "status": 200, + "timestamp": 1534955098193 +} +``` + + + +更新时间 +---- + +该文档最后更新于: 2019-06-23 PM 17:19 \ No newline at end of file diff --git a/_web/src/components/Table/index.js b/_web/src/components/Table/index.js new file mode 100644 index 00000000..0397f88c --- /dev/null +++ b/_web/src/components/Table/index.js @@ -0,0 +1,329 @@ +import T from 'ant-design-vue/es/table/Table' +import get from 'lodash.get' + +export default { + data () { + return { + needTotalList: [], + + selectedRows: [], + selectedRowKeys: [], + + localLoading: false, + localDataSource: [], + localPagination: Object.assign({}, this.pagination) + } + }, + props: Object.assign({}, T.props, { + rowKey: { + type: [String, Function], + default: 'key' + }, + data: { + type: Function, + required: true + }, + pageNum: { + type: Number, + default: 1 + }, + pageSize: { + type: Number, + default: 10 + }, + showSizeChanger: { + type: Boolean, + default: true + }, + size: { + type: String, + default: 'default' + }, + /** + * alert: { + * show: true, + * clear: Function + * } + */ + alert: { + type: [Object, Boolean], + default: null + }, + rowSelection: { + type: Object, + default: null + }, + /** @Deprecated */ + showAlertInfo: { + type: Boolean, + default: false + }, + showPagination: { + type: String | Boolean, + default: 'auto' + }, + /** + * enable page URI mode + * + * e.g: + * /users/1 + * /users/2 + * /users/3?queryParam=test + * ... + */ + pageURI: { + type: Boolean, + default: false + } + }), + watch: { + 'localPagination.current' (val) { + this.pageURI && this.$router.push({ + ...this.$route, + name: this.$route.name, + params: Object.assign({}, this.$route.params, { + pageNo: val + }) + }) + }, + pageNum (val) { + Object.assign(this.localPagination, { + current: val + }) + }, + pageSize (val) { + Object.assign(this.localPagination, { + pageSize: val + }) + }, + showSizeChanger (val) { + Object.assign(this.localPagination, { + showSizeChanger: val + }) + } + }, + created () { + const { pageNo } = this.$route.params + const localPageNum = this.pageURI && (pageNo && parseInt(pageNo)) || this.pageNum + this.localPagination = ['auto', true].includes(this.showPagination) && Object.assign({}, this.localPagination, { + current: localPageNum, + pageSize: this.pageSize, + showSizeChanger: this.showSizeChanger, + showTotal: (total, range) => { + return range[0] + '-' + range[1] + '共' + total + '条' + } + }) || false + // console.log('this.localPagination', this.localPagination) + this.needTotalList = this.initTotalList(this.columns) + this.loadData() + }, + methods: { + /** + * 表格重新加载方法 + * 如果参数为 true, 则强制刷新到第一页 + * @param Boolean bool + */ + refresh (bool = false) { + bool && (this.localPagination = Object.assign({}, { + current: 1, pageSize: this.pageSize + })) + this.loadData() + }, + /** + * 加载数据方法 + * @param {Object} pagination 分页选项器 + * @param {Object} filters 过滤条件 + * @param {Object} sorter 排序条件 + */ + loadData (pagination, filters, sorter) { + this.localLoading = true + const parameter = Object.assign({ + pageNo: (pagination && pagination.current) || + this.showPagination && this.localPagination.current || this.pageNum, + pageSize: (pagination && pagination.pageSize) || + this.showPagination && this.localPagination.pageSize || this.pageSize + }, + (sorter && sorter.field && { + sortField: sorter.field + }) || {}, + (sorter && sorter.order && { + sortOrder: sorter.order + }) || {}, { + ...filters + } + ) + const result = this.data(parameter) + // 对接自己的通用数据接口需要修改下方代码中的 r.pageNo, r.totalCount, r.data + // eslint-disable-next-line + if ((typeof result === 'object' || typeof result === 'function') && typeof result.then === 'function') { + result.then(r => { + if (r == null) { + this.localLoading = false + return + } + this.localPagination = this.showPagination && Object.assign({}, this.localPagination, { + current: r.pageNo, // pageNo, // 返回结果中的当前分页数 + total: r.totalRows, // totalCount, // 返回结果中的总记录数 + showSizeChanger: this.showSizeChanger, + pageSize: (pagination && pagination.pageSize) || + this.localPagination.pageSize + }) || false + // 后端数据rows为null保存修复 + if (r.rows == null) { + r.rows = [] + } + // 为防止删除数据后导致页面当前页面数据长度为 0 ,自动翻页到上一页 + if (r.rows.length === 0 && this.showPagination && this.localPagination.current > 1) { + this.localPagination.current-- + this.loadData() + return + } + + // 这里用于判断接口是否有返回 r.totalCount 且 this.showPagination = true 且 pageNo 和 pageSize 存在 且 totalCount 小于等于 pageNo * pageSize 的大小 + // 当情况满足时,表示数据不满足分页大小,关闭 table 分页功能 + try { + if ((['auto', true].includes(this.showPagination) && r.totalCount <= (r.totalPage * this.localPagination.pageSize))) { + this.localPagination.hideOnSinglePage = true + } + } catch (e) { + this.localPagination = false + } + this.localDataSource = r.rows // 返回结果中的数组数据 + this.localLoading = false + }) + } + }, + initTotalList (columns) { + const totalList = [] + columns && columns instanceof Array && columns.forEach(column => { + if (column.needTotal) { + totalList.push({ + ...column, + total: 0 + }) + } + }) + return totalList + }, + /** + * 用于更新已选中的列表数据 total 统计 + * @param selectedRowKeys + * @param selectedRows + */ + updateSelect (selectedRowKeys, selectedRows) { + this.selectedRows = selectedRows + this.selectedRowKeys = selectedRowKeys + const list = this.needTotalList + this.needTotalList = list.map(item => { + return { + ...item, + total: selectedRows.reduce((sum, val) => { + const total = sum + parseInt(get(val, item.dataIndex)) + return isNaN(total) ? 0 : total + }, 0) + } + }) + }, + /** + * 清空 table 已选中项 + */ + clearSelected () { + if (this.rowSelection) { + this.rowSelection.onChange([], []) + this.updateSelect([], []) + } + }, + /** + * 处理交给 table 使用者去处理 clear 事件时,内部选中统计同时调用 + * @param callback + * @returns {*} + */ + renderClear (callback) { + if (this.selectedRowKeys.length <= 0) return null + return ( + { + callback() + this.clearSelected() + }}>清空 + ) + }, + renderAlert () { + // 绘制统计列数据 + // eslint-disable-next-line no-unused-vars + const needTotalItems = this.needTotalList.map((item) => { + return ( + {item.title}总计 {!item.customRender ? item.total : item.customRender(item.total)} + ) + }) + + // 绘制 清空 按钮 + // eslint-disable-next-line no-unused-vars + const clearItem = (typeof this.alert.clear === 'boolean' && this.alert.clear) ? ( + this.renderClear(this.clearSelected) + ) : (this.alert !== null && typeof this.alert.clear === 'function') ? ( + this.renderClear(this.alert.clear) + ) : null + + // 绘制 alert 组件 + // 统一先去除alert组件 + return '' + /* return ( + + + + ) */ + } + }, + + render () { + const props = {} + const localKeys = Object.keys(this.$data) + const showAlert = (typeof this.alert === 'object' && this.alert !== null && this.alert.show) && typeof this.rowSelection.selectedRowKeys !== 'undefined' || this.alert + + Object.keys(T.props).forEach(k => { + const localKey = `local${k.substring(0, 1).toUpperCase()}${k.substring(1)}` + if (localKeys.includes(localKey)) { + props[k] = this[localKey] + return props[k] + } + if (k === 'rowSelection') { + if (showAlert && this.rowSelection) { + // 如果需要使用alert,则重新绑定 rowSelection 事件 + // console.log('this.rowSelection', this.rowSelection) + props[k] = { + ...this.rowSelection, + selectedRows: this.selectedRows, + selectedRowKeys: this.selectedRowKeys, + onChange: (selectedRowKeys, selectedRows) => { + this.updateSelect(selectedRowKeys, selectedRows) + typeof this[k].onChange !== 'undefined' && this[k].onChange(selectedRowKeys, selectedRows) + } + } + return props[k] + } else if (!this.rowSelection) { + // 如果没打算开启 rowSelection 则清空默认的选择项 + props[k] = null + return props[k] + } + } + this[k] && (props[k] = this[k]) + return props[k] + }) + const table = ( + { this.$emit('expand', expanded, record) } }> + { Object.keys(this.$slots).map(name => ()) } + + ) + + return ( +
+ { showAlert ? this.renderAlert() : null } + { table } +
+ ) + } +} diff --git a/_web/src/components/TagSelect/TagSelectOption.jsx b/_web/src/components/TagSelect/TagSelectOption.jsx new file mode 100644 index 00000000..b5ae7997 --- /dev/null +++ b/_web/src/components/TagSelect/TagSelectOption.jsx @@ -0,0 +1,45 @@ +import { Tag } from 'ant-design-vue' +const { CheckableTag } = Tag + +export default { + name: 'TagSelectOption', + props: { + prefixCls: { + type: String, + default: 'ant-pro-tag-select-option' + }, + value: { + type: [String, Number, Object], + default: '' + }, + checked: { + type: Boolean, + default: false + } + }, + data () { + return { + localChecked: this.checked || false + } + }, + watch: { + 'checked' (val) { + this.localChecked = val + }, + '$parent.items': { + handler: function (val) { + this.value && val.hasOwnProperty(this.value) && (this.localChecked = val[this.value]) + }, + deep: true + } + }, + render () { + const { $slots, value } = this + const onChange = (checked) => { + this.$emit('change', { value, checked }) + } + return ( + {$slots.default} + ) + } +} diff --git a/_web/src/components/TagSelect/index.jsx b/_web/src/components/TagSelect/index.jsx new file mode 100644 index 00000000..af98ad7c --- /dev/null +++ b/_web/src/components/TagSelect/index.jsx @@ -0,0 +1,113 @@ +import PropTypes from 'ant-design-vue/es/_util/vue-types' +import Option from './TagSelectOption.jsx' +import { filterEmpty } from '@/components/_util/util' + +export default { + Option, + name: 'TagSelect', + model: { + prop: 'checked', + event: 'change' + }, + props: { + prefixCls: { + type: String, + default: 'ant-pro-tag-select' + }, + defaultValue: { + type: PropTypes.array, + default: null + }, + value: { + type: PropTypes.array, + default: null + }, + expandable: { + type: Boolean, + default: false + }, + hideCheckAll: { + type: Boolean, + default: false + } + }, + data () { + return { + expand: false, + localCheckAll: false, + items: this.getItemsKey(filterEmpty(this.$slots.default)), + val: this.value || this.defaultValue || [] + } + }, + methods: { + onChange (checked) { + const key = Object.keys(this.items).filter(key => key === checked.value) + this.items[key] = checked.checked + const bool = Object.values(this.items).lastIndexOf(false) + if (bool === -1) { + this.localCheckAll = true + } else { + this.localCheckAll = false + } + }, + onCheckAll (checked) { + Object.keys(this.items).forEach(v => { + this.items[v] = checked.checked + }) + this.localCheckAll = checked.checked + }, + getItemsKey (items) { + const totalItem = {} + items.forEach(item => { + totalItem[item.componentOptions.propsData && item.componentOptions.propsData.value] = false + }) + return totalItem + }, + // CheckAll Button + renderCheckAll () { + const props = { + on: { + change: (checked) => { + this.onCheckAll(checked) + checked.value = 'total' + this.$emit('change', checked) + } + } + } + const checkAllElement = + return !this.hideCheckAll && checkAllElement || null + }, + // expandable + renderExpandable () { + + }, + // render option + renderTags (items) { + const listeners = { + change: (checked) => { + this.onChange(checked) + this.$emit('change', checked) + } + } + + return items.map(vnode => { + const options = vnode.componentOptions + options.listeners = listeners + return vnode + }) + } + }, + render () { + const { $props: { prefixCls } } = this + const classString = { + [`${prefixCls}`]: true + } + const tagItems = filterEmpty(this.$slots.default) + return ( +
+ {this.renderCheckAll()} + {this.renderTags(tagItems)} +
+ ) + } +} diff --git a/_web/src/components/TextArea/index.jsx b/_web/src/components/TextArea/index.jsx new file mode 100644 index 00000000..00aeb2fc --- /dev/null +++ b/_web/src/components/TextArea/index.jsx @@ -0,0 +1,69 @@ +import './style.less' +import { getStrFullLength, cutStrByFullLength } from '../_util/util' +import Input from 'ant-design-vue/es/input' +const TextArea = Input.TextArea + +export default { + name: 'LimitTextArea', + model: { + prop: 'value', + event: 'change' + }, + props: Object.assign({}, TextArea.props, { + prefixCls: { + type: String, + default: 'ant-textarea-limit' + }, + // eslint-disable-next-line + value: { + type: String + }, + limit: { + type: Number, + default: 200 + } + }), + data () { + return { + currentLimit: 0 + } + }, + watch: { + value (val) { + this.calcLimitNum(val) + } + }, + created () { + this.calcLimitNum(this.value) + }, + methods: { + handleChange (e) { + const value = e.target.value + const len = getStrFullLength(value) + if (len <= this.limit) { + this.currentLimit = len + this.$emit('change', value) + return + } else { + const str = cutStrByFullLength(value, this.limit) + this.currentLimit = getStrFullLength(str) + this.$emit('change', str) + } + console.error('limit out! currentLimit:', this.currentLimit) + }, + calcLimitNum (val) { + const len = getStrFullLength(val) + this.currentLimit = len + } + }, + render () { + const { prefixCls, ...props } = this.$props + return ( +
+ + {this.currentLimit}/{this.limit} +
+ ) + } +} diff --git a/_web/src/components/TextArea/style.less b/_web/src/components/TextArea/style.less new file mode 100644 index 00000000..6dee494c --- /dev/null +++ b/_web/src/components/TextArea/style.less @@ -0,0 +1,12 @@ +.ant-textarea-limit { + position: relative; + + .limit { + position: absolute; + color: #909399; + background: #fff; + font-size: 12px; + bottom: 5px; + right: 10px; + } +} \ No newline at end of file diff --git a/_web/src/components/Tree/Tree.jsx b/_web/src/components/Tree/Tree.jsx new file mode 100644 index 00000000..e5a2a113 --- /dev/null +++ b/_web/src/components/Tree/Tree.jsx @@ -0,0 +1,124 @@ +import { Menu, Icon, Input } from 'ant-design-vue' + +const { Item, ItemGroup, SubMenu } = Menu +const { Search } = Input + +export default { + name: 'Tree', + props: { + dataSource: { + type: Array, + required: true + }, + openKeys: { + type: Array, + default: () => [] + }, + search: { + type: Boolean, + default: false + } + }, + created () { + this.localOpenKeys = this.openKeys.slice(0) + }, + data () { + return { + localOpenKeys: [] + } + }, + methods: { + handlePlus (item) { + this.$emit('add', item) + }, + handleTitleClick (...args) { + this.$emit('titleClick', { args }) + }, + + renderSearch () { + return ( + + ) + }, + renderIcon (icon) { + return icon && () || null + }, + renderMenuItem (item) { + return ( + + { this.renderIcon(item.icon) } + { item.title } + this.handlePlus(item) } }}> + + ) + }, + renderItem (item) { + return item.children ? this.renderSubItem(item, item.key) : this.renderMenuItem(item, item.key) + }, + renderItemGroup (item) { + const childrenItems = item.children.map(o => { + return this.renderItem(o, o.key) + }) + + return ( + + + { childrenItems } + + ) + }, + renderSubItem (item, key) { + const childrenItems = item.children && item.children.map(o => { + return this.renderItem(o, o.key) + }) + + const title = ( + + { this.renderIcon(item.icon) } + { item.title } + + ) + + if (item.group) { + return this.renderItemGroup(item) + } + // titleClick={this.handleTitleClick(item)} + return ( + + { title } + { childrenItems } + + ) + } + }, + render () { + const { dataSource, search } = this.$props + + // this.localOpenKeys = openKeys.slice(0) + const list = dataSource.map(item => { + return this.renderItem(item) + }) + + return ( +
+ { search ? this.renderSearch() : null } + this.$emit('click', item), 'update:openKeys': val => { this.localOpenKeys = val } } }} openKeys={this.localOpenKeys}> + { list } + +
+ ) + } +} diff --git a/_web/src/components/Trend/Trend.vue b/_web/src/components/Trend/Trend.vue new file mode 100644 index 00000000..526e1cc6 --- /dev/null +++ b/_web/src/components/Trend/Trend.vue @@ -0,0 +1,41 @@ + + + + + diff --git a/_web/src/components/Trend/index.js b/_web/src/components/Trend/index.js new file mode 100644 index 00000000..9f142280 --- /dev/null +++ b/_web/src/components/Trend/index.js @@ -0,0 +1,3 @@ +import Trend from './Trend.vue' + +export default Trend diff --git a/_web/src/components/Trend/index.less b/_web/src/components/Trend/index.less new file mode 100644 index 00000000..8a3d24cf --- /dev/null +++ b/_web/src/components/Trend/index.less @@ -0,0 +1,42 @@ +@import "../index"; + +@trend-prefix-cls: ~"@{ant-pro-prefix}-trend"; + +.@{trend-prefix-cls} { + display: inline-block; + font-size: @font-size-base; + line-height: 22px; + + .up, + .down { + margin-left: 4px; + position: relative; + top: 1px; + + i { + font-size: 12px; + transform: scale(0.83); + } + } + + .item-text { + display: inline-block; + margin-left: 8px; + color: rgba(0,0,0,.85); + } + + .up { + color: @red-6; + } + .down { + color: @green-6; + top: -1px; + } + + &.reverse-color .up { + color: @green-6; + } + &.reverse-color .down { + color: @red-6; + } +} \ No newline at end of file diff --git a/_web/src/components/Trend/index.md b/_web/src/components/Trend/index.md new file mode 100644 index 00000000..8881f0e1 --- /dev/null +++ b/_web/src/components/Trend/index.md @@ -0,0 +1,45 @@ +# Trend 趋势标记 + +趋势符号,标记上升和下降趋势。通常用绿色代表“好”,红色代表“不好”,股票涨跌场景除外。 + + + +引用方式: + +```javascript +import Trend from '@/components/Trend' + +export default { + components: { + Trend + } +} +``` + + + +## 代码演示 [demo](https://pro.loacg.com/test/home) + +```html +5% +``` +或 +```html + + 工资 + 5% + +``` +或 +```html +5% +``` + + +## API + +| 参数 | 说明 | 类型 | 默认值 | +|----------|------------------------------------------|-------------|-------| +| flag | 上升下降标识:`up|down` | string | - | +| reverseColor | 颜色反转 | Boolean | false | + diff --git a/_web/src/components/_util/util.js b/_web/src/components/_util/util.js new file mode 100644 index 00000000..dd33231f --- /dev/null +++ b/_web/src/components/_util/util.js @@ -0,0 +1,46 @@ +/** + * components util + */ + +/** + * 清理空值,对象 + * @param children + * @returns {*[]} + */ +export function filterEmpty (children = []) { + return children.filter(c => c.tag || (c.text && c.text.trim() !== '')) +} + +/** + * 获取字符串长度,英文字符 长度1,中文字符长度2 + * @param {*} str + */ +export const getStrFullLength = (str = '') => + str.split('').reduce((pre, cur) => { + const charCode = cur.charCodeAt(0) + if (charCode >= 0 && charCode <= 128) { + return pre + 1 + } + return pre + 2 + }, 0) + +/** + * 截取字符串,根据 maxLength 截取后返回 + * @param {*} str + * @param {*} maxLength + */ +export const cutStrByFullLength = (str = '', maxLength) => { + let showLength = 0 + return str.split('').reduce((pre, cur) => { + const charCode = cur.charCodeAt(0) + if (charCode >= 0 && charCode <= 128) { + showLength += 1 + } else { + showLength += 2 + } + if (showLength <= maxLength) { + return pre + cur + } + return pre + }, '') +} diff --git a/_web/src/components/global.less b/_web/src/components/global.less new file mode 100644 index 00000000..7e942663 --- /dev/null +++ b/_web/src/components/global.less @@ -0,0 +1,514 @@ +@import './index.less'; + +body { + + +} + +#app { + height: 100%; + + &.colorWeak { + filter: invert(80%); + } + &.userLayout { + overflow: auto; + } +} + +.layout.ant-layout { + height: auto; + overflow-x: hidden; + + &.mobile, + &.tablet { + .ant-layout-content { + .content { + margin: 24px 0 0; + } + } + + /** + * ant-table-wrapper + * 覆盖的表格手机模式样式,如果想修改在手机上表格最低宽度,可以在这里改动 + */ + .ant-table-wrapper { + .ant-table-content { + overflow-y: auto; + } + .ant-table-body { + min-width: 800px; + } + } + .topmenu { + /* 必须为 topmenu 才能启用流式布局 */ + &.content-width-Fluid { + .header-index-wide { + margin-left: 0; + } + } + } + } + + &.mobile { + .sidemenu { + .ant-header-fixedHeader { + &.ant-header-side-opened, + &.ant-header-side-closed { + width: 100%; + } + } + } + } + + &.ant-layout-has-sider { + flex-direction: row; + } + + .trigger { + font-size: 20px; + line-height: 64px; + padding: 0 24px; + cursor: pointer; + transition: color 0.3s; + &:hover { + background: rgba(0, 0, 0, 0.025); + } + } + + .topmenu { + .ant-header-fixedHeader { + position: fixed; + top: 0; + right: 0; + z-index: 9; + width: 100%; + transition: width 0.2s; + + &.ant-header-side-opened { + width: 100%; + } + + &.ant-header-side-closed { + width: 100%; + } + } + /* 必须为 topmenu 才能启用流式布局 */ + &.content-width-Fluid { + .header-index-wide { + max-width: unset; + .header-index-left { + flex: 1 1 1000px; + .logo{ + margin-left: 25px; + } + .ant-menu.ant-menu-horizontal{ + max-width: calc(100vw - 190px - 238px - 25px); + flex: 1 1 calc(100vw - 190px - 238px - 25px); + } + } + .header-index-right{ + margin-right:25px; + } + } + + .page-header-index-wide { + max-width: unset; + } + } + } + + .sidemenu { + .ant-header-fixedHeader { + position: fixed; + top: 0; + right: 0; + z-index: 9; + width: 100%; + transition: width 0.2s; + + &.ant-header-side-opened { + width: calc(100% - 256px); + } + + &.ant-header-side-closed { + width: calc(100% - 80px); + } + } + } + + .header { + height: 64px; + padding: 0 12px 0 0; + background: #fff; + box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08); + position: relative; + } + + .header, + .top-nav-header-index { + .user-wrapper { + float: right; + height: 100%; + + .action { + cursor: pointer; + padding: 0 12px; + display: inline-block; + transition: all 0.3s; + height: 100%; + color: rgba(0, 0, 0, 0.65); + + &:hover { + background: rgba(0, 0, 0, 0.025); + } + + .avatar { + margin: 20px 8px 20px 0; + color: #1890ff; + background: hsla(0, 0%, 100%, 0.85); + vertical-align: middle; + } + + .icon { + font-size: 16px; + padding: 4px; + } + } + } + + &.dark { + .user-wrapper { + .action { + color: rgba(255, 255, 255, 0.85); + a { + color: rgba(255, 255, 255, 0.85); + } + + &:hover { + background: rgba(255, 255, 255, 0.16); + } + } + } + } + } + + &.mobile, + &.tablet { + .top-nav-header-index { + .header-index-wide { + .header-index-left { + .trigger { + color: rgba(255, 255, 255, 0.85); + padding: 0 12px; + } + + .logo.top-nav-header { + flex: 0 0 56px; + text-align: center; + line-height: 58px; + h1 { + display: none; + } + } + } + } + + &.light { + .header-index-wide { + .header-index-left { + .trigger { + color: rgba(0, 0, 0, 0.65); + } + } + } + } + } + } + + &.tablet { + // overflow: hidden; text-overflow:ellipsis; white-space: nowrap; + .top-nav-header-index { + .header-index-wide { + .header-index-left { + .logo > a { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + } + .ant-menu.ant-menu-horizontal { + flex: 1 1 auto; + white-space: normal; + } + } + } + } + + .top-nav-header-index { + box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08); + position: relative; + transition: background 0.3s, width 0.2s; + + .header-index-wide { + max-width: 1200px; + margin: auto; + padding-left: 0; + display: flex; + height: 64px; + + .ant-menu.ant-menu-horizontal { + max-width: 835px; + flex: 0 1 835px; + border: none; + height: 64px; + line-height: 64px; + } + + .header-index-left { + flex: 0 1 1000px; + display: flex; + + .logo.top-nav-header { + flex: 0 0 165px; + width: 165px; + height: 64px; + position: relative; + line-height: 64px; + transition: all 0.3s; + overflow: hidden; + + img, + svg { + display: inline-block; + vertical-align: middle; + height: 32px; + width: 32px; + } + + h1 { + color: #fff; + display: inline-block; + vertical-align: top; + font-size: 16px; + margin: 0 0 0 12px; + font-weight: 400; + } + } + } + + .header-index-right { + flex: 0 0 238px; + align-self: flex-end; + height: 64px; + overflow: hidden; + + .content-box { + float: right; + .action { + max-width: 140px; + overflow: hidden; + text-overflow:ellipsis; + white-space:nowrap; + } + } + } + } + + &.light { + background-color: #fff; + + .header-index-wide { + .header-index-left { + .logo { + h1 { + color: #002140; + } + } + } + } + } + } + + // 内容区 + .layout-content { + margin: 24px 24px 0px; + height: 100%; + height: 64px; + padding: 0 12px 0 0; + } + + // footer + .ant-layout-footer { + padding: 0; + } +} + +.topmenu { + .page-header-index-wide { + max-width: 1200px; + margin: 0 auto; + } +} + +// drawer-sider 自定义 +.ant-drawer.drawer-sider { + .sider { + box-shadow: none; + } + + &.dark { + .ant-drawer-content { + background-color: rgb(0, 21, 41); + } + } + &.light { + box-shadow: none; + .ant-drawer-content { + background-color: #fff; + } + } + + .ant-drawer-body { + padding: 0; + } +} + +// 菜单样式 +.sider { + box-shadow: 2px 0 6px rgba(0, 21, 41, 0.35); + position: relative; + z-index: @ant-global-sider-zindex; + min-height: 100vh; + + .ant-layout-sider-children { + overflow-y: hidden; + + &:hover { + overflow-y: auto; + } + } + + &.ant-fixed-sidemenu { + position: fixed; + height: 100%; + } + + .logo { + position: relative; + height: 64px; + padding-left: 24px; + overflow: hidden; + line-height: 64px; + background: #002140; + transition: all .3s; + + img, + svg, + h1 { + display: inline-block; + vertical-align: middle; + } + + img, + svg { + height: 32px; + width: 32px; + } + + h1 { + color: #fff; + font-size: 20px; + margin: 0 0 0 12px; + font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif; + font-weight: 600; + vertical-align: middle; + } + } + + &.light { + background-color: #fff; + box-shadow: 2px 0px 8px 0px rgba(29, 35, 41, 0.05); + + .logo { + background: #fff; + box-shadow: 1px 1px 0px 0px #e8e8e8; + + h1 { + color: unset; + } + } + + .ant-menu-light { + border-right-color: transparent; + } + } +} + +// 外置的样式控制 +.user-dropdown-menu { + span { + user-select: none; + } +} +.user-dropdown-menu-wrapper.ant-dropdown-menu { + padding: 4px 0; + + .ant-dropdown-menu-item { + width: 160px; + } + + .ant-dropdown-menu-item > .anticon:first-child, + .ant-dropdown-menu-item > a > .anticon:first-child, + .ant-dropdown-menu-submenu-title > .anticon:first-child .ant-dropdown-menu-submenu-title > a > .anticon:first-child { + min-width: 12px; + margin-right: 8px; + } +} + +// 数据列表 样式 +.table-alert { + margin-bottom: 16px; +} + +.table-page-search-wrapper { + .ant-form-inline { + .ant-form-item { + display: flex; + margin-bottom: 24px; + margin-right: 0; + + .ant-form-item-control-wrapper { + flex: 1 1; + display: inline-block; + vertical-align: middle; + } + + > .ant-form-item-label { + line-height: 32px; + padding-right: 8px; + width: auto; + } + .ant-form-item-control { + height: 32px; + line-height: 32px; + } + } + } + + .table-page-search-submitButtons { + display: block; + margin-bottom: 24px; + white-space: nowrap; + } +} + +.content { + .table-operator { + margin-bottom: 18px; + + button { + margin-right: 8px; + } + } +} diff --git a/_web/src/components/index.js b/_web/src/components/index.js new file mode 100644 index 00000000..21104408 --- /dev/null +++ b/_web/src/components/index.js @@ -0,0 +1,66 @@ +// chart +import Bar from '@/components/Charts/Bar' +import ChartCard from '@/components/Charts/ChartCard' +import Liquid from '@/components/Charts/Liquid' +import MiniArea from '@/components/Charts/MiniArea' +import MiniSmoothArea from '@/components/Charts/MiniSmoothArea' +import MiniBar from '@/components/Charts/MiniBar' +import MiniProgress from '@/components/Charts/MiniProgress' +import Radar from '@/components/Charts/Radar' +import RankList from '@/components/Charts/RankList' +import TransferBar from '@/components/Charts/TransferBar' +import TagCloud from '@/components/Charts/TagCloud' + +// pro components +import AvatarList from '@/components/AvatarList' +import CountDown from '@/components/CountDown' +import Ellipsis from '@/components/Ellipsis' +import FooterToolbar from '@/components/FooterToolbar' +import NumberInfo from '@/components/NumberInfo' +import DescriptionList from '@/components/DescriptionList' +import Tree from '@/components/Tree/Tree' +import Trend from '@/components/Trend' +import STable from '@/components/Table' +import MultiTab from '@/components/MultiTab' +import Result from '@/components/Result' +import IconSelector from '@/components/IconSelector' +import TagSelect from '@/components/TagSelect' +import ExceptionPage from '@/components/Exception' +import StandardFormRow from '@/components/StandardFormRow' +import ArticleListContent from '@/components/ArticleListContent' +import AntdEditor from '@/components/Editor/WangEditor' +import Dialog from '@/components/Dialog' + +export { + AvatarList, + Bar, + ChartCard, + Liquid, + MiniArea, + MiniSmoothArea, + MiniBar, + MiniProgress, + Radar, + TagCloud, + RankList, + TransferBar, + Trend, + CountDown, + Ellipsis, + FooterToolbar, + NumberInfo, + DescriptionList, + // 兼容写法,请勿继续使用 + DescriptionList as DetailList, + Tree, + STable, + MultiTab, + Result, + ExceptionPage, + IconSelector, + TagSelect, + StandardFormRow, + ArticleListContent, + AntdEditor, + Dialog +} diff --git a/_web/src/components/index.less b/_web/src/components/index.less new file mode 100644 index 00000000..e831c41e --- /dev/null +++ b/_web/src/components/index.less @@ -0,0 +1,6 @@ +@import "~ant-design-vue/lib/style/index"; + +// The prefix to use on all css classes from ant-pro. +@ant-pro-prefix : ant-pro; +@ant-global-sider-zindex : 106; +@ant-global-header-zindex : 105; \ No newline at end of file diff --git a/_web/src/components/tools/Breadcrumb.vue b/_web/src/components/tools/Breadcrumb.vue new file mode 100644 index 00000000..9bc141c0 --- /dev/null +++ b/_web/src/components/tools/Breadcrumb.vue @@ -0,0 +1,45 @@ + + + + + diff --git a/_web/src/components/tools/DetailList.vue b/_web/src/components/tools/DetailList.vue new file mode 100644 index 00000000..6745a082 --- /dev/null +++ b/_web/src/components/tools/DetailList.vue @@ -0,0 +1,5 @@ + diff --git a/_web/src/components/tools/HeadInfo.vue b/_web/src/components/tools/HeadInfo.vue new file mode 100644 index 00000000..7fbc692d --- /dev/null +++ b/_web/src/components/tools/HeadInfo.vue @@ -0,0 +1,67 @@ + + + + + diff --git a/_web/src/components/tools/LangSelect.vue b/_web/src/components/tools/LangSelect.vue new file mode 100644 index 00000000..283f3566 --- /dev/null +++ b/_web/src/components/tools/LangSelect.vue @@ -0,0 +1,46 @@ + + + diff --git a/_web/src/components/tools/Logo.vue b/_web/src/components/tools/Logo.vue new file mode 100644 index 00000000..5c7de3dc --- /dev/null +++ b/_web/src/components/tools/Logo.vue @@ -0,0 +1,53 @@ + + + diff --git a/_web/src/components/tools/TwoStepCaptcha.vue b/_web/src/components/tools/TwoStepCaptcha.vue new file mode 100644 index 00000000..01302b43 --- /dev/null +++ b/_web/src/components/tools/TwoStepCaptcha.vue @@ -0,0 +1,89 @@ + + + + diff --git a/_web/src/components/tools/UserMenu.vue b/_web/src/components/tools/UserMenu.vue new file mode 100644 index 00000000..172ac2f9 --- /dev/null +++ b/_web/src/components/tools/UserMenu.vue @@ -0,0 +1,178 @@ + + + + + diff --git a/_web/src/components/tools/index.js b/_web/src/components/tools/index.js new file mode 100644 index 00000000..e69de29b diff --git a/_web/src/config/defaultSettings.js b/_web/src/config/defaultSettings.js new file mode 100644 index 00000000..a95c913b --- /dev/null +++ b/_web/src/config/defaultSettings.js @@ -0,0 +1,35 @@ +/** + * 项目默认配置项 + * primaryColor - 默认主题色, 如果修改颜色不生效,请清理 localStorage + * navTheme - sidebar theme ['dark', 'light'] 两种主题 + * colorWeak - 色盲模式 + * layout - 整体布局方式 ['sidemenu', 'topmenu'] 两种布局 + * fixedHeader - 固定 Header : boolean + * fixSiderbar - 固定左侧菜单栏 : boolean + * autoHideHeader - 向下滚动时,隐藏 Header : boolean + * contentWidth - 内容区布局: 流式 | 固定 + * + * storageOptions: {} - Vue-ls 插件配置项 (localStorage/sessionStorage) + * production: 变量暂先设定为 false,目的是各种环境都正常显示设置抽屉,真实环境请放开注释 + * + * + */ + +export default { + primaryColor: '#1890ff', // primary color of ant design + navTheme: 'dark', // theme for nav menu + layout: 'sidemenu', // nav menu position: sidemenu or topmenu + contentWidth: 'Fixed', // layout of content: Fluid or Fixed, only works when layout is topmenu + fixedHeader: false, // sticky header + fixSiderbar: false, // sticky siderbar + autoHideHeader: false, // auto hide header + colorWeak: false, + multiTab: false, + production: process.env.NODE_ENV === 'production' && process.env.VUE_APP_PREVIEW !== 'true', + // vue-ls options + storageOptions: { + namespace: 'pro__', // key prefix + name: 'ls', // name variable Vue.[ls] or this.[$ls], + storage: 'local' // storage name session, local, memory + } +} diff --git a/_web/src/config/router.config.js b/_web/src/config/router.config.js new file mode 100644 index 00000000..cf098712 --- /dev/null +++ b/_web/src/config/router.config.js @@ -0,0 +1,98 @@ +// eslint-disable-next-line +import { UserLayout, BasicLayout, RouteView, BlankLayout, PageView } from '@/layouts' +import { bxAnaalyse } from '@/core/icons' + +export const asyncRouterMap = [ + + { + path: '/', + name: 'MenuIndex.vue', + component: BasicLayout, + meta: { title: '首页' }, + redirect: '/dashboard/workplace', + children: [ + // dashboard + { + path: 'dashboard', + name: 'dashboard', + redirect: '/dashboard/workplace', + component: RouteView, + // eslint-disable-next-line standard/object-curly-even-spacing + meta: { title: '仪表盘', keepAlive: true, icon: bxAnaalyse /* permission: [ 'dashboard' ] */ }, + children: [ + { + path: 'analysis/:pageNo([1-9]\\d*)?', + name: 'Analysis', + component: () => import('@/views/system/dashboard/Analysis'), + // eslint-disable-next-line standard/object-curly-even-spacing + meta: { title: '分析页', keepAlive: true /* permission: [ 'dashboard' ] */ } + }, + { + path: 'workplace', + name: 'Workplace', + component: () => import('@/views/system/dashboard/Workplace'), + // eslint-disable-next-line standard/object-curly-even-spacing + meta: { title: '工作台', keepAlive: false/*, permission: [ 'dashboard' ] */ } + } + ] + } + ] + }, + { + path: '*', redirect: '/404', hidden: true + } +] + +/** + * 基础路由 + * @type { *[] } + */ +export const constantRouterMap = [ + { + path: '/user', + component: UserLayout, + redirect: '/user/login', + hidden: true, + children: [ + { + path: 'login', + name: 'login', + component: () => import(/* webpackChunkName: "user" */ '@/views/userLoginReg/Login') + }, + { + path: 'register', + name: 'register', + component: () => import(/* webpackChunkName: "user" */ '@/views/userLoginReg/Register') + }, + { + path: 'register-result', + name: 'registerResult', + component: () => import(/* webpackChunkName: "user" */ '@/views/userLoginReg/RegisterResult') + }, + { + path: 'recover', + name: 'recover', + component: undefined + } + ] + }, + + { + path: '/test', + component: BlankLayout, + redirect: '/test/home', + children: [ + { + path: 'home', + name: 'TestHome', + component: () => import('@/views/Home') + } + ] + }, + + { + path: '/404', + component: () => import(/* webpackChunkName: "fail" */ '@/views/system/exception/404') + } + +] diff --git a/_web/src/core/bootstrap.js b/_web/src/core/bootstrap.js new file mode 100644 index 00000000..55268355 --- /dev/null +++ b/_web/src/core/bootstrap.js @@ -0,0 +1,34 @@ +import Vue from 'vue' +import store from '@/store/' +import { + ACCESS_TOKEN, + DEFAULT_COLOR, + DEFAULT_THEME, + DEFAULT_LAYOUT_MODE, + DEFAULT_COLOR_WEAK, + SIDEBAR_TYPE, + DEFAULT_FIXED_HEADER, + DEFAULT_FIXED_HEADER_HIDDEN, + DEFAULT_FIXED_SIDEMENU, + DEFAULT_CONTENT_WIDTH_TYPE, + DEFAULT_MULTI_TAB +} from '@/store/mutation-types' +import config from '@/config/defaultSettings' + +export default function Initializer () { + // console.log(`API_URL: ${process.env.VUE_APP_API_BASE_URL}`) + + store.commit('SET_SIDEBAR_TYPE', Vue.ls.get(SIDEBAR_TYPE, true)) + store.commit('TOGGLE_THEME', Vue.ls.get(DEFAULT_THEME, config.navTheme)) + store.commit('TOGGLE_LAYOUT_MODE', Vue.ls.get(DEFAULT_LAYOUT_MODE, config.layout)) + store.commit('TOGGLE_FIXED_HEADER', Vue.ls.get(DEFAULT_FIXED_HEADER, config.fixedHeader)) + store.commit('TOGGLE_FIXED_SIDERBAR', Vue.ls.get(DEFAULT_FIXED_SIDEMENU, config.fixSiderbar)) + store.commit('TOGGLE_CONTENT_WIDTH', Vue.ls.get(DEFAULT_CONTENT_WIDTH_TYPE, config.contentWidth)) + store.commit('TOGGLE_FIXED_HEADER_HIDDEN', Vue.ls.get(DEFAULT_FIXED_HEADER_HIDDEN, config.autoHideHeader)) + store.commit('TOGGLE_WEAK', Vue.ls.get(DEFAULT_COLOR_WEAK, config.colorWeak)) + store.commit('TOGGLE_COLOR', Vue.ls.get(DEFAULT_COLOR, config.primaryColor)) + store.commit('TOGGLE_MULTI_TAB', Vue.ls.get(DEFAULT_MULTI_TAB, config.multiTab)) + store.commit('SET_TOKEN', Vue.ls.get(ACCESS_TOKEN)) + + // last step +} diff --git a/_web/src/core/directives/action.js b/_web/src/core/directives/action.js new file mode 100644 index 00000000..bdc9ec04 --- /dev/null +++ b/_web/src/core/directives/action.js @@ -0,0 +1,34 @@ +import Vue from 'vue' +import store from '@/store' + +/** + * Action 权限指令 + * 指令用法: + * - 在需要控制 action 级别权限的组件上使用 v-action:[method] , 如下: + * 添加用户 + * 删除用户 + * 修改 + * + * - 当前用户没有权限时,组件上使用了该指令则会被隐藏 + * - 当后台权限跟 pro 提供的模式不同时,只需要针对这里的权限过滤进行修改即可 + * + * @see https://github.com/sendya/ant-design-pro-vue/pull/53 + */ +const action = Vue.directive('action', { + inserted: function (el, binding, vnode) { + const actionName = binding.arg + const roles = store.getters.roles + const elVal = vnode.context.$route.meta.permission + const permissionId = elVal instanceof String && [elVal] || elVal + roles.permissions.forEach(p => { + if (!permissionId.includes(p.permissionId)) { + return + } + if (p.actionList && !p.actionList.includes(actionName)) { + el.parentNode && el.parentNode.removeChild(el) || (el.style.display = 'none') + } + }) + } +}) + +export default action diff --git a/_web/src/core/icons.js b/_web/src/core/icons.js new file mode 100644 index 00000000..46b72616 --- /dev/null +++ b/_web/src/core/icons.js @@ -0,0 +1,11 @@ +/** + * Custom icon list + * All icons are loaded here for easy management + * @see https://vue.ant.design/components/icon/#Custom-Font-Icon + * + * 自定义图标加载表 + * 所有图标均从这里加载,方便管理 + */ +import bxAnaalyse from '@/assets/icons/bx-analyse.svg?inline' // path to your '*.svg?inline' file. + +export { bxAnaalyse } diff --git a/_web/src/core/lazy_lib/components_use.js b/_web/src/core/lazy_lib/components_use.js new file mode 100644 index 00000000..547a72bb --- /dev/null +++ b/_web/src/core/lazy_lib/components_use.js @@ -0,0 +1,112 @@ + +/** + * 该文件是为了按需加载,剔除掉了一些不需要的框架组件。 + * 减少了编译支持库包大小 + * @author yubaoshan + * 当需要更多组件依赖时,在该文件加入即可 + */ +import Vue from 'vue' +import { + ConfigProvider, + Layout, + Input, + InputNumber, + Button, + Switch, + Radio, + Checkbox, + Select, + Card, + Form, + Row, + Col, + Modal, + Table, + Tabs, + Icon, + Badge, + Popover, + Dropdown, + List, + Avatar, + Breadcrumb, + Steps, + Spin, + Menu, + Drawer, + Tooltip, + Alert, + Tag, + Divider, + DatePicker, + TimePicker, + Upload, + Progress, + Skeleton, + Popconfirm, + message, + notification, + TreeSelect, + Tree, + Transfer, + Empty, + PageHeader, + Descriptions, + Result +} from 'ant-design-vue' +// import VueCropper from 'vue-cropper' + +Vue.use(ConfigProvider) +Vue.use(Layout) +Vue.use(Input) +Vue.use(InputNumber) +Vue.use(Button) +Vue.use(Switch) +Vue.use(Radio) +Vue.use(Checkbox) +Vue.use(Select) +Vue.use(Card) +Vue.use(Form) +Vue.use(Row) +Vue.use(Col) +Vue.use(Modal) +Vue.use(Table) +Vue.use(Tabs) +Vue.use(Icon) +Vue.use(Badge) +Vue.use(Popover) +Vue.use(Dropdown) +Vue.use(List) +Vue.use(Avatar) +Vue.use(Breadcrumb) +Vue.use(Steps) +Vue.use(Spin) +Vue.use(Menu) +Vue.use(Drawer) +Vue.use(Tooltip) +Vue.use(Alert) +Vue.use(Tag) +Vue.use(Divider) +Vue.use(DatePicker) +Vue.use(TimePicker) +Vue.use(Upload) +Vue.use(Progress) +Vue.use(Skeleton) +Vue.use(Popconfirm) +// Vue.use(VueCropper) +Vue.use(notification) +Vue.use(TreeSelect) +Vue.use(Tree) +Vue.use(Transfer) +Vue.use(Empty) +Vue.use(PageHeader) +Vue.use(Descriptions) +Vue.use(Result) + +Vue.prototype.$confirm = Modal.confirm +Vue.prototype.$message = message +Vue.prototype.$notification = notification +Vue.prototype.$info = Modal.info +Vue.prototype.$success = Modal.success +Vue.prototype.$error = Modal.error +Vue.prototype.$warning = Modal.warning diff --git a/_web/src/core/lazy_use.js b/_web/src/core/lazy_use.js new file mode 100644 index 00000000..efd20474 --- /dev/null +++ b/_web/src/core/lazy_use.js @@ -0,0 +1,27 @@ +import Vue from 'vue' +import VueStorage from 'vue-ls' +import config from '@/config/defaultSettings' + +// base library +import '@/core/lazy_lib/components_use' +import Viser from 'viser-vue' + +// ext library +import VueClipboard from 'vue-clipboard2' +import VueCropper from 'vue-cropper' +import MultiTab from '@/components/MultiTab' +import PageLoading from '@/components/PageLoading' +import PermissionHelper from '@/utils/helper/permission' +import './directives/action' + +VueClipboard.config.autoSetContainer = true + +Vue.use(Viser) +Vue.use(MultiTab) +Vue.use(PageLoading) +Vue.use(VueStorage, config.storageOptions) +Vue.use(VueClipboard) +Vue.use(PermissionHelper) +Vue.use(VueCropper) + +process.env.NODE_ENV !== 'production' && console.warn('[antd-pro] NOTICE: Antd use lazy-load.') diff --git a/_web/src/core/use.js b/_web/src/core/use.js new file mode 100644 index 00000000..a17c2fc2 --- /dev/null +++ b/_web/src/core/use.js @@ -0,0 +1,30 @@ +import Vue from 'vue' +import VueStorage from 'vue-ls' +import config from '@/config/defaultSettings' + +// base library +import Antd from 'ant-design-vue' +import Viser from 'viser-vue' +import VueCropper from 'vue-cropper' +import 'ant-design-vue/dist/antd.less' + +// ext library +import VueClipboard from 'vue-clipboard2' +import MultiTab from '@/components/MultiTab' +import PageLoading from '@/components/PageLoading' +import PermissionHelper from '@/utils/helper/permission' +// import '@/components/use' +import './directives/action' + +VueClipboard.config.autoSetContainer = true + +Vue.use(Antd) +Vue.use(Viser) +Vue.use(MultiTab) +Vue.use(PageLoading) +Vue.use(VueStorage, config.storageOptions) +Vue.use(VueClipboard) +Vue.use(PermissionHelper) +Vue.use(VueCropper) + +process.env.NODE_ENV !== 'production' && console.warn('[antd-pro] WARNING: Antd now use fulled imported.') diff --git a/_web/src/layouts/BasicLayout.vue b/_web/src/layouts/BasicLayout.vue new file mode 100644 index 00000000..797a5755 --- /dev/null +++ b/_web/src/layouts/BasicLayout.vue @@ -0,0 +1,186 @@ + + + + + diff --git a/_web/src/layouts/BlankLayout.vue b/_web/src/layouts/BlankLayout.vue new file mode 100644 index 00000000..1bfbfbf9 --- /dev/null +++ b/_web/src/layouts/BlankLayout.vue @@ -0,0 +1,16 @@ + + + + + diff --git a/_web/src/layouts/Iframe.vue b/_web/src/layouts/Iframe.vue new file mode 100644 index 00000000..e2526a44 --- /dev/null +++ b/_web/src/layouts/Iframe.vue @@ -0,0 +1,29 @@ + + diff --git a/_web/src/layouts/PageView.vue b/_web/src/layouts/PageView.vue new file mode 100644 index 00000000..aba50ccc --- /dev/null +++ b/_web/src/layouts/PageView.vue @@ -0,0 +1,183 @@ + + + + + diff --git a/_web/src/layouts/RouteView.vue b/_web/src/layouts/RouteView.vue new file mode 100644 index 00000000..edae19e9 --- /dev/null +++ b/_web/src/layouts/RouteView.vue @@ -0,0 +1,32 @@ + diff --git a/_web/src/layouts/UserLayout.vue b/_web/src/layouts/UserLayout.vue new file mode 100644 index 00000000..f5f33078 --- /dev/null +++ b/_web/src/layouts/UserLayout.vue @@ -0,0 +1,152 @@ + + + + + diff --git a/_web/src/layouts/index.js b/_web/src/layouts/index.js new file mode 100644 index 00000000..a7ab0c97 --- /dev/null +++ b/_web/src/layouts/index.js @@ -0,0 +1,8 @@ +import UserLayout from './UserLayout' +import BlankLayout from './BlankLayout' +import BasicLayout from './BasicLayout' +import RouteView from './RouteView' +import PageView from './PageView' +import Iframe from './Iframe' + +export { UserLayout, BasicLayout, BlankLayout, RouteView, PageView, Iframe } diff --git a/_web/src/main.js b/_web/src/main.js new file mode 100644 index 00000000..debb37aa --- /dev/null +++ b/_web/src/main.js @@ -0,0 +1,32 @@ +// with polyfills +import 'core-js/stable' +import 'regenerator-runtime/runtime' +import Vue from 'vue' +import App from './App.vue' +import router from './router' +import store from './store/' +import { VueAxios } from './utils/request' +// WARNING: `mockjs` NOT SUPPORT `IE` PLEASE DO NOT USE IN `production` ENV. +import './mock' + +import bootstrap from './core/bootstrap' +import './core/lazy_use' +import './permission' // permission control +import './utils/filter' // global filter +import './components/global.less' +import { Dialog } from '@/components' +import { hasBtnPermission } from './utils/permissions' // button permission +import { sysApplication } from './utils/applocation' + +Vue.use(VueAxios) +Vue.use(Dialog) +Vue.prototype.hasPerm = hasBtnPermission +Vue.prototype.applocation = sysApplication +Vue.config.productionTip = false + +new Vue({ + router, + store, + created: bootstrap, + render: h => h(App) +}).$mount('#app') diff --git a/_web/src/mock/index.js b/_web/src/mock/index.js new file mode 100644 index 00000000..acb735f2 --- /dev/null +++ b/_web/src/mock/index.js @@ -0,0 +1,23 @@ +import { isIE } from '@/utils/util' + +// 判断环境不是 prod 或者 preview 是 true 时,加载 mock 服务 +if (process.env.NODE_ENV !== 'production' || process.env.VUE_APP_PREVIEW === 'true') { + if (isIE()) { + console.error('[antd-pro] ERROR: `mockjs` NOT SUPPORT `IE` PLEASE DO NOT USE IN `production` ENV.') + } + // 使用同步加载依赖 + // 防止 vuex 中的 GetInfo 早于 mock 运行,导致无法 mock 请求返回结果 + console.log('[antd-pro] mock mounting') + const Mock = require('mockjs2') + require('./services/auth') + require('./services/user') + require('./services/manage') + require('./services/other') + require('./services/tagCloud') + require('./services/article') + + Mock.setup({ + timeout: 800 // setter delay time + }) + console.log('[antd-pro] mock mounted') +} diff --git a/_web/src/mock/services/article.js b/_web/src/mock/services/article.js new file mode 100644 index 00000000..37057f7f --- /dev/null +++ b/_web/src/mock/services/article.js @@ -0,0 +1,89 @@ +import Mock from 'mockjs2' +import { builder, getQueryParameters } from '../util' + +const titles = [ + 'Alipay', + 'Angular', + 'Ant Design', + 'XiaoNuo', + 'Bootstrap', + 'React', + 'Vue', + 'Webpack' +] + +const avatar = ['https://gw.alipayobjects.com/zos/rmsportal/WdGqmHpayyMjiEhcKoVE.png', + 'https://gw.alipayobjects.com/zos/rmsportal/zOsKZmFRdUtvpqCImOVY.png', + 'https://gw.alipayobjects.com/zos/rmsportal/dURIMkkrRFpPgTuzkwnB.png', + 'https://gw.alipayobjects.com/zos/rmsportal/sfjbOqnsXXJgNCjCzDBL.png', + 'https://gw.alipayobjects.com/zos/rmsportal/siCrBXXhmvTQGWPNLBow.png' +] + +const covers = [ + 'https://gw.alipayobjects.com/zos/rmsportal/uMfMFlvUuceEyPpotzlq.png', + 'https://gw.alipayobjects.com/zos/rmsportal/iZBVOIhGJiAnhplqjvZW.png', + 'https://gw.alipayobjects.com/zos/rmsportal/iXjVmWVHbCJAyqvDxdtx.png', + 'https://gw.alipayobjects.com/zos/rmsportal/gLaIAoVWTtLbBWZNYEMg.png' +] + +const owner = [ + '付小小', + '吴加好', + '周星星', + '林东东', + '曲丽丽' +] + +const content = '段落示意:蚂蚁金服设计平台 ant.design,用最小的工作量,无缝接入蚂蚁金服生态,提供跨越设计与开发的体验解决方案。蚂蚁金服设计平台 ant.design,用最小的工作量,无缝接入蚂蚁金服生态,提供跨越设计与开发的体验解决方案。' +const description = '在中台产品的研发过程中,会出现不同的设计规范和实现方式,但其中往往存在很多类似的页面和组件,这些类似的组件会被抽离成一套标准规范。' +const href = 'https://ant.design' + +const article = (options) => { + const queryParameters = getQueryParameters(options) + console.log('queryParameters', queryParameters) + if (queryParameters && !queryParameters.count) { + queryParameters.count = 5 + } + const data = [] + for (let i = 0; i < queryParameters.count; i++) { + const tmpKey = i + 1 + const num = parseInt(Math.random() * (4 + 1), 10) + data.push({ + id: tmpKey, + avatar: avatar[num], + owner: owner[num], + content: content, + star: Mock.mock('@integer(1, 999)'), + percent: Mock.mock('@integer(1, 999)'), + like: Mock.mock('@integer(1, 999)'), + message: Mock.mock('@integer(1, 999)'), + description: description, + href: href, + title: titles[ i % 8 ], + updatedAt: Mock.mock('@datetime'), + members: [ + { + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ZiESqWwCXBRQoaPONSJe.png', + name: '曲丽丽', + id: 'member1' + }, + { + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/tBOxZPlITHqwlGjsJWaF.png', + name: '王昭君', + id: 'member2' + }, + { + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/sBxjgqiuHMGRkIjqlQCd.png', + name: '董娜娜', + id: 'member3' + } + ], + activeUser: Math.ceil(Math.random() * 100000) + 100000, + newUser: Math.ceil(Math.random() * 1000) + 1000, + cover: parseInt(i / 4, 10) % 2 === 0 ? covers[i % 4] : covers[3 - (i % 4)] + }) + } + return builder(data) +} + +Mock.mock(/\/list\/article/, 'get', article) diff --git a/_web/src/mock/services/auth.js b/_web/src/mock/services/auth.js new file mode 100644 index 00000000..25637c24 --- /dev/null +++ b/_web/src/mock/services/auth.js @@ -0,0 +1,50 @@ +import Mock from 'mockjs2' +import { builder, getBody } from '../util' + +const username = ['admin', 'super'] +// 强硬要求 ant.design 相同密码 +// '21232f297a57a5a743894a0e4a801fc3', +const password = ['8914de686ab28dc22f30d3d8e107ff6c'] // admin, ant.design + +const login = (options) => { + const body = getBody(options) + console.log('mock: body', body) + if (!username.includes(body.username) || !password.includes(body.password)) { + return builder({ isLogin: true }, '账户或密码错误', 401) + } + + return builder({ + 'id': Mock.mock('@guid'), + 'name': Mock.mock('@name'), + 'username': 'admin', + 'password': '', + 'avatar': 'https://gw.alipayobjects.com/zos/rmsportal/jZUIxmJycoymBprLOUbT.png', + 'status': 1, + 'telephone': '', + 'lastLoginIp': '27.154.74.117', + 'lastLoginTime': 1534837621348, + 'creatorId': 'admin', + 'createTime': 1497160610259, + 'deleted': 0, + 'roleId': 'admin', + 'lang': 'zh-CN', + 'token': '4291d7da9005377ec9aec4a71ea837f' + }, '', 200, { 'Custom-Header': Mock.mock('@guid') }) +} + +const logout = () => { + return builder({}, '[测试接口] 注销成功') +} + +const smsCaptcha = () => { + return builder({ captcha: Mock.mock('@integer(10000, 99999)') }) +} + +const twofactor = () => { + return builder({ stepCode: Mock.mock('@integer(0, 1)') }) +} + +Mock.mock(/\/auth\/login/, 'post', login) +Mock.mock(/\/auth\/logout/, 'post', logout) +Mock.mock(/\/account\/sms/, 'post', smsCaptcha) +Mock.mock(/\/auth\/2step-code/, 'post', twofactor) diff --git a/_web/src/mock/services/manage.js b/_web/src/mock/services/manage.js new file mode 100644 index 00000000..9ac472e4 --- /dev/null +++ b/_web/src/mock/services/manage.js @@ -0,0 +1,252 @@ +import Mock from 'mockjs2' +import { builder, getQueryParameters } from '../util' + +const totalCount = 5701 + +const serverList = (options) => { + const parameters = getQueryParameters(options) + + const result = [] + const pageNo = parseInt(parameters.pageNo) + const pageSize = parseInt(parameters.pageSize) + const totalPage = Math.ceil(totalCount / pageSize) + const key = (pageNo - 1) * pageSize + const next = (pageNo >= totalPage ? (totalCount % pageSize) : pageSize) + 1 + + for (let i = 1; i < next; i++) { + const tmpKey = key + i + result.push({ + key: tmpKey, + id: tmpKey, + no: 'No ' + tmpKey, + description: '这是一段描述', + callNo: Mock.mock('@integer(1, 999)'), + status: Mock.mock('@integer(0, 3)'), + updatedAt: Mock.mock('@datetime'), + editable: false + }) + } + + return builder({ + pageSize: pageSize, + pageNo: pageNo, + totalCount: totalCount, + totalPage: totalPage, + data: result + }) +} + +const projects = () => { + return builder({ + 'data': [{ + id: 1, + cover: 'https://gw.alipayobjects.com/zos/rmsportal/WdGqmHpayyMjiEhcKoVE.png', + title: 'Alipay', + description: '那是一种内在的东西, 他们到达不了,也无法触及的', + status: 1, + updatedAt: '2018-07-26 00:00:00' + }, + { + id: 2, + cover: 'https://gw.alipayobjects.com/zos/rmsportal/zOsKZmFRdUtvpqCImOVY.png', + title: 'Angular', + description: '希望是一个好东西,也许是最好的,好东西是不会消亡的', + status: 1, + updatedAt: '2018-07-26 00:00:00' + }, + { + id: 3, + cover: 'https://gw.alipayobjects.com/zos/rmsportal/dURIMkkrRFpPgTuzkwnB.png', + title: 'Ant Design', + description: '城镇中有那么多的酒馆,她却偏偏走进了我的酒馆', + status: 1, + updatedAt: '2018-07-26 00:00:00' + }, + { + id: 4, + cover: 'https://gw.alipayobjects.com/zos/rmsportal/sfjbOqnsXXJgNCjCzDBL.png', + title: 'XiaoNuo', + description: '那时候我只会想自己想要什么,从不想自己拥有什么', + status: 1, + updatedAt: '2018-07-26 00:00:00' + }, + { + id: 5, + cover: 'https://gw.alipayobjects.com/zos/rmsportal/siCrBXXhmvTQGWPNLBow.png', + title: 'Bootstrap', + description: '凛冬将至', + status: 1, + updatedAt: '2018-07-26 00:00:00' + }, + { + id: 6, + cover: 'https://gw.alipayobjects.com/zos/rmsportal/ComBAopevLwENQdKWiIn.png', + title: 'Vue', + description: '生命就像一盒巧克力,结果往往出人意料', + status: 1, + updatedAt: '2018-07-26 00:00:00' + } + ], + 'pageSize': 10, + 'pageNo': 0, + 'totalPage': 6, + 'totalCount': 57 + }) +} + +const activity = () => { + return builder([{ + id: 1, + user: { + nickname: '@name', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png' + }, + project: { + name: '白鹭酱油开发组', + action: '更新', + event: '番组计划' + }, + time: '2018-08-23 14:47:00' + }, + { + id: 1, + user: { + nickname: '蓝莓酱', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/jZUIxmJycoymBprLOUbT.png' + }, + project: { + name: '白鹭酱油开发组', + action: '更新', + event: '番组计划' + }, + time: '2018-08-23 09:35:37' + }, + { + id: 1, + user: { + nickname: '@name', + avatar: '@image(64x64)' + }, + project: { + name: '白鹭酱油开发组', + action: '创建', + event: '番组计划' + }, + time: '2017-05-27 00:00:00' + }, + { + id: 1, + user: { + nickname: '曲丽丽', + avatar: '@image(64x64)' + }, + project: { + name: '高逼格设计天团', + action: '更新', + event: '六月迭代' + }, + time: '2018-08-23 14:47:00' + }, + { + id: 1, + user: { + nickname: '@name', + avatar: '@image(64x64)' + }, + project: { + name: '高逼格设计天团', + action: 'created', + event: '六月迭代' + }, + time: '2018-08-23 14:47:00' + }, + { + id: 1, + user: { + nickname: '曲丽丽', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png' + }, + project: { + name: '高逼格设计天团', + action: 'created', + event: '六月迭代' + }, + time: '2018-08-23 14:47:00' + } + ]) +} + +const teams = () => { + return builder([{ + id: 1, + name: '科学搬砖组', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png' + }, + { + id: 2, + name: '程序员日常', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/cnrhVkzwxjPwAaCfPbdc.png' + }, + { + id: 1, + name: '设计天团', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/gaOngJwsRYRaVAuXXcmB.png' + }, + { + id: 1, + name: '中二少女团', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ubnKSIfAJTxIgXOKlciN.png' + }, + { + id: 1, + name: '骗你学计算机', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/WhxKECPNujWoWEFNdnJE.png' + } + ]) +} + +const radar = () => { + return builder([{ + item: '引用', + '个人': 70, + '团队': 30, + '部门': 40 + }, + { + item: '口碑', + '个人': 60, + '团队': 70, + '部门': 40 + }, + { + item: '产量', + '个人': 50, + '团队': 60, + '部门': 40 + }, + { + item: '贡献', + '个人': 40, + '团队': 50, + '部门': 40 + }, + { + item: '热度', + '个人': 60, + '团队': 70, + '部门': 40 + }, + { + item: '引用', + '个人': 70, + '团队': 50, + '部门': 40 + } + ]) +} + +Mock.mock(/\/service/, 'get', serverList) +Mock.mock(/\/list\/search\/projects/, 'get', projects) +Mock.mock(/\/workplace\/activity/, 'get', activity) +Mock.mock(/\/workplace\/teams/, 'get', teams) +Mock.mock(/\/workplace\/radar/, 'get', radar) diff --git a/_web/src/mock/services/other.js b/_web/src/mock/services/other.js new file mode 100644 index 00000000..56e2dd97 --- /dev/null +++ b/_web/src/mock/services/other.js @@ -0,0 +1,973 @@ +import Mock from 'mockjs2' +import { builder } from '../util' + +const orgTree = () => { + return builder([{ + 'key': 'key-01', + 'title': '研发中心', + 'icon': 'mail', + 'children': [{ + 'key': 'key-01-01', + 'title': '后端组', + 'icon': null, + 'group': true, + children: [{ + 'key': 'key-01-01-01', + 'title': 'JAVA', + 'icon': null + }, + { + 'key': 'key-01-01-02', + 'title': 'PHP', + 'icon': null + }, + { + 'key': 'key-01-01-03', + 'title': 'Golang', + 'icon': null + } + ] + }, { + 'key': 'key-01-02', + 'title': '前端组', + 'icon': null, + 'group': true, + children: [{ + 'key': 'key-01-02-01', + 'title': 'React', + 'icon': null + }, + { + 'key': 'key-01-02-02', + 'title': 'Vue', + 'icon': null + }, + { + 'key': 'key-01-02-03', + 'title': 'Angular', + 'icon': null + } + ] + }] + }, { + 'key': 'key-02', + 'title': '财务部', + 'icon': 'dollar', + 'children': [{ + 'key': 'key-02-01', + 'title': '会计核算', + 'icon': null + }, { + 'key': 'key-02-02', + 'title': '成本控制', + 'icon': null + }, { + 'key': 'key-02-03', + 'title': '内部控制', + 'icon': null, + 'children': [{ + 'key': 'key-02-03-01', + 'title': '财务制度建设', + 'icon': null + }, + { + 'key': 'key-02-03-02', + 'title': '会计核算', + 'icon': null + } + ] + }] + }]) +} + +const role = () => { + return builder({ + 'data': [{ + 'id': 'admin', + 'name': '管理员', + 'describe': '拥有所有权限', + 'status': 1, + 'creatorId': 'system', + 'createTime': 1497160610259, + 'deleted': 0, + 'permissions': [{ + 'roleId': 'admin', + 'permissionId': 'comment', + 'permissionName': '评论管理', + 'actions': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"query","defaultCheck":false,"describe":"查询"},{"action":"get","defaultCheck":false,"describe":"详情"},{"action":"edit","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"}]', + 'actionEntitySet': [{ + 'action': 'add', + 'describe': '新增', + 'defaultCheck': false + }, + { + 'action': 'query', + 'describe': '查询', + 'defaultCheck': false + }, + { + 'action': 'get', + 'describe': '详情', + 'defaultCheck': false + }, + { + 'action': 'edit', + 'describe': '修改', + 'defaultCheck': false + }, + { + 'action': 'delete', + 'describe': '删除', + 'defaultCheck': false + }], + 'actionList': ['delete', 'edit'], + 'dataAccess': null + }, + { + 'roleId': 'admin', + 'permissionId': 'member', + 'permissionName': '会员管理', + 'actions': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"query","defaultCheck":false,"describe":"查询"},{"action":"get","defaultCheck":false,"describe":"详情"},{"action":"edit","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"}]', + 'actionEntitySet': [{ + 'action': 'add', + 'describe': '新增', + 'defaultCheck': false + }, + { + 'action': 'query', + 'describe': '查询', + 'defaultCheck': false + }, + { + 'action': 'get', + 'describe': '详情', + 'defaultCheck': false + }, + { + 'action': 'edit', + 'describe': '修改', + 'defaultCheck': false + }, + { + 'action': 'delete', + 'describe': '删除', + 'defaultCheck': false + } + ], + 'actionList': ['query', 'get', 'edit', 'delete'], + 'dataAccess': null + }, + { + 'roleId': 'admin', + 'permissionId': 'menu', + 'permissionName': '菜单管理', + 'actions': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"import","defaultCheck":false,"describe":"导入"},{"action":"get","defaultCheck":false,"describe":"详情"},{"action":"edit","defaultCheck":false,"describe":"修改"}]', + 'actionEntitySet': [{ + 'action': 'add', + 'describe': '新增', + 'defaultCheck': false + }, + { + 'action': 'import', + 'describe': '导入', + 'defaultCheck': false + }, + { + 'action': 'get', + 'describe': '详情', + 'defaultCheck': false + }, + { + 'action': 'edit', + 'describe': '修改', + 'defaultCheck': false + } + ], + 'actionList': ['add', 'import'], + 'dataAccess': null + }, + { + 'roleId': 'admin', + 'permissionId': 'order', + 'permissionName': '订单管理', + 'actions': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"query","defaultCheck":false,"describe":"查询"},{"action":"get","defaultCheck":false,"describe":"详情"},{"action":"edit","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"}]', + 'actionEntitySet': [{ + 'action': 'add', + 'describe': '新增', + 'defaultCheck': false + }, + { + 'action': 'query', + 'describe': '查询', + 'defaultCheck': false + }, + { + 'action': 'get', + 'describe': '详情', + 'defaultCheck': false + }, + { + 'action': 'edit', + 'describe': '修改', + 'defaultCheck': false + }, + { + 'action': 'delete', + 'describe': '删除', + 'defaultCheck': false + } + ], + 'actionList': ['query', 'add', 'get'], + 'dataAccess': null + }, + { + 'roleId': 'admin', + 'permissionId': 'permission', + 'permissionName': '权限管理', + 'actions': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"get","defaultCheck":false,"describe":"详情"},{"action":"edit","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"}]', + 'actionEntitySet': [{ + 'action': 'add', + 'describe': '新增', + 'defaultCheck': false + }, + { + 'action': 'get', + 'describe': '详情', + 'defaultCheck': false + }, + { + 'action': 'edit', + 'describe': '修改', + 'defaultCheck': false + }, + { + 'action': 'delete', + 'describe': '删除', + 'defaultCheck': false + } + ], + 'actionList': ['add', 'get', 'edit', 'delete'], + 'dataAccess': null + }, + { + 'roleId': 'admin', + 'permissionId': 'role', + 'permissionName': '角色管理', + 'actions': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"get","defaultCheck":false,"describe":"详情"},{"action":"edit","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"}]', + 'actionEntitySet': [{ + 'action': 'add', + 'describe': '新增', + 'defaultCheck': false + }, + { + 'action': 'get', + 'describe': '详情', + 'defaultCheck': false + }, + { + 'action': 'edit', + 'describe': '修改', + 'defaultCheck': false + }, + { + 'action': 'delete', + 'describe': '删除', + 'defaultCheck': false + } + ], + 'actionList': null, + 'dataAccess': null + }, + { + 'roleId': 'admin', + 'permissionId': 'test', + 'permissionName': '测试权限', + 'actions': '[]', + 'actionEntitySet': [], + 'actionList': null, + 'dataAccess': null + }, + { + 'roleId': 'admin', + 'permissionId': 'user', + 'permissionName': '用户管理', + 'actions': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"import","defaultCheck":false,"describe":"导入"},{"action":"get","defaultCheck":false,"describe":"详情"},{"action":"edit","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"},{"action":"export","defaultCheck":false,"describe":"导出"}]', + 'actionEntitySet': [{ + 'action': 'add', + 'describe': '新增', + 'defaultCheck': false + }, + { + 'action': 'import', + 'describe': '导入', + 'defaultCheck': false + }, + { + 'action': 'get', + 'describe': '详情', + 'defaultCheck': false + }, + { + 'action': 'edit', + 'describe': '修改', + 'defaultCheck': false + }, + { + 'action': 'delete', + 'describe': '删除', + 'defaultCheck': false + }, + { + 'action': 'export', + 'describe': '导出', + 'defaultCheck': false + } + ], + 'actionList': ['add', 'get'], + 'dataAccess': null + } + ] + }, + { + 'id': 'svip', + 'name': 'SVIP', + 'describe': '超级会员', + 'status': 1, + 'creatorId': 'system', + 'createTime': 1532417744846, + 'deleted': 0, + 'permissions': [{ + 'roleId': 'admin', + 'permissionId': 'comment', + 'permissionName': '评论管理', + 'actions': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"query","defaultCheck":false,"describe":"查询"},{"action":"get","defaultCheck":false,"describe":"详情"},{"action":"edit","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"}]', + 'actionEntitySet': [{ + 'action': 'add', + 'describe': '新增', + 'defaultCheck': false + }, + { + 'action': 'query', + 'describe': '查询', + 'defaultCheck': false + }, + { + 'action': 'get', + 'describe': '详情', + 'defaultCheck': false + }, + { + 'action': 'edit', + 'describe': '修改', + 'defaultCheck': false + }, + { + 'action': 'delete', + 'describe': '删除', + 'defaultCheck': false + } + ], + 'actionList': ['add', 'get', 'delete'], + 'dataAccess': null + }, + { + 'roleId': 'admin', + 'permissionId': 'member', + 'permissionName': '会员管理', + 'actions': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"query","defaultCheck":false,"describe":"查询"},{"action":"get","defaultCheck":false,"describe":"详情"},{"action":"edit","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"}]', + 'actionEntitySet': [{ + 'action': 'add', + 'describe': '新增', + 'defaultCheck': false + }, + { + 'action': 'query', + 'describe': '查询', + 'defaultCheck': false + }, + { + 'action': 'get', + 'describe': '详情', + 'defaultCheck': false + } + ], + 'actionList': ['add', 'query', 'get'], + 'dataAccess': null + }, + { + 'roleId': 'admin', + 'permissionId': 'menu', + 'permissionName': '菜单管理', + 'actions': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"import","defaultCheck":false,"describe":"导入"},{"action":"get","defaultCheck":false,"describe":"详情"},{"action":"edit","defaultCheck":false,"describe":"修改"}]', + 'actionEntitySet': [{ + 'action': 'add', + 'describe': '新增', + 'defaultCheck': false + }, + { + 'action': 'import', + 'describe': '导入', + 'defaultCheck': false + }, + { + 'action': 'get', + 'describe': '详情', + 'defaultCheck': false + } + ], + 'actionList': ['add', 'get'], + 'dataAccess': null + }, + { + 'roleId': 'admin', + 'permissionId': 'order', + 'permissionName': '订单管理', + 'actions': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"query","defaultCheck":false,"describe":"查询"},{"action":"get","defaultCheck":false,"describe":"详情"},{"action":"edit","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"}]', + 'actionEntitySet': [{ + 'action': 'add', + 'describe': '新增', + 'defaultCheck': false + }, + { + 'action': 'query', + 'describe': '查询', + 'defaultCheck': false + }, + { + 'action': 'get', + 'describe': '详情', + 'defaultCheck': false + }, + { + 'action': 'edit', + 'describe': '修改', + 'defaultCheck': false + } + ], + 'actionList': ['add', 'query'], + 'dataAccess': null + }, + { + 'roleId': 'admin', + 'permissionId': 'permission', + 'permissionName': '权限管理', + 'actions': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"get","defaultCheck":false,"describe":"详情"},{"action":"edit","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"}]', + 'actionEntitySet': [{ + 'action': 'add', + 'describe': '新增', + 'defaultCheck': false + }, + { + 'action': 'get', + 'describe': '详情', + 'defaultCheck': false + }, + { + 'action': 'edit', + 'describe': '修改', + 'defaultCheck': false + } + ], + 'actionList': ['add', 'get', 'edit'], + 'dataAccess': null + }, + { + 'roleId': 'admin', + 'permissionId': 'role', + 'permissionName': '角色管理', + 'actions': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"get","defaultCheck":false,"describe":"详情"},{"action":"edit","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"}]', + 'actionEntitySet': [{ + 'action': 'add', + 'describe': '新增', + 'defaultCheck': false + }, + { + 'action': 'edit', + 'describe': '修改', + 'defaultCheck': false + }, + { + 'action': 'delete', + 'describe': '删除', + 'defaultCheck': false + } + ], + 'actionList': null, + 'dataAccess': null + }, + { + 'roleId': 'admin', + 'permissionId': 'test', + 'permissionName': '测试权限', + 'actions': '[]', + 'actionEntitySet': [], + 'actionList': ['add', 'edit'], + 'dataAccess': null + }, + { + 'roleId': 'admin', + 'permissionId': 'user', + 'permissionName': '用户管理', + 'actions': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"import","defaultCheck":false,"describe":"导入"},{"action":"get","defaultCheck":false,"describe":"详情"},{"action":"edit","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"},{"action":"export","defaultCheck":false,"describe":"导出"}]', + 'actionEntitySet': [{ + 'action': 'add', + 'describe': '新增', + 'defaultCheck': false + }, + { + 'action': 'import', + 'describe': '导入', + 'defaultCheck': false + }, + { + 'action': 'get', + 'describe': '详情', + 'defaultCheck': false + }, + { + 'action': 'edit', + 'describe': '修改', + 'defaultCheck': false + } + ], + 'actionList': ['add'], + 'dataAccess': null + } + ] + }, + { + 'id': 'user', + 'name': '普通会员', + 'describe': '普通用户,只能查询', + 'status': 1, + 'creatorId': 'system', + 'createTime': 1497160610259, + 'deleted': 0, + 'permissions': [{ + 'roleId': 'user', + 'permissionId': 'comment', + 'permissionName': '评论管理', + 'actions': '[{"action":"query","defaultCheck":false,"describe":"查询"},{"action":"get","defaultCheck":false,"describe":"详情"}]', + 'actionEntitySet': [{ + 'action': 'query', + 'describe': '查询', + 'defaultCheck': false + }, + { + 'action': 'get', + 'describe': '详情', + 'defaultCheck': false + } + ], + 'actionList': ['query'], + 'dataAccess': null + }, + + { + 'roleId': 'user', + 'permissionId': 'marketing', + 'permissionName': '营销管理', + 'actions': '[]', + 'actionEntitySet': [], + 'actionList': null, + 'dataAccess': null + }, + { + 'roleId': 'user', + 'permissionId': 'member', + 'permissionName': '会员管理', + 'actions': '[{"action":"query","defaultCheck":false,"describe":"查询"},{"action":"get","defaultCheck":false,"describe":"详情"}]', + 'actionEntitySet': [{ + 'action': 'query', + 'describe': '查询', + 'defaultCheck': false + }, + { + 'action': 'get', + 'describe': '详情', + 'defaultCheck': false + } + ], + 'actionList': null, + 'dataAccess': null + }, + { + 'roleId': 'user', + 'permissionId': 'menu', + 'permissionName': '菜单管理', + 'actions': '[]', + 'actionEntitySet': [], + 'actionList': null, + 'dataAccess': null + }, + + { + 'roleId': 'user', + 'permissionId': 'order', + 'permissionName': '订单管理', + 'actions': '[{"action":"query","defaultCheck":false,"describe":"查询"},{"action":"get","defaultCheck":false,"describe":"详情"}]', + 'actionEntitySet': [{ + 'action': 'query', + 'describe': '查询', + 'defaultCheck': false + }, + { + 'action': 'get', + 'describe': '详情', + 'defaultCheck': false + } + ], + 'actionList': null, + 'dataAccess': null + }, + { + 'roleId': 'user', + 'permissionId': 'permission', + 'permissionName': '权限管理', + 'actions': '[]', + 'actionEntitySet': [], + 'actionList': null, + 'dataAccess': null + }, + { + 'roleId': 'user', + 'permissionId': 'role', + 'permissionName': '角色管理', + 'actions': '[]', + 'actionEntitySet': [], + 'actionList': null, + 'dataAccess': null + }, + + { + 'roleId': 'user', + 'permissionId': 'test', + 'permissionName': '测试权限', + 'actions': '[]', + 'actionEntitySet': [], + 'actionList': null, + 'dataAccess': null + }, + { + 'roleId': 'user', + 'permissionId': 'user', + 'permissionName': '用户管理', + 'actions': '[]', + 'actionEntitySet': [], + 'actionList': null, + 'dataAccess': null + } + ] + } + ], + 'pageSize': 10, + 'pageNo': 0, + 'totalPage': 1, + 'totalCount': 5 + }) +} + +const permissionNoPager = () => { + return builder([{ + 'id': 'marketing', + 'name': '营销管理', + 'describe': null, + 'status': 1, + 'actionData': '[{"action":"query","defaultCheck":false,"describe":"查询"},{"action":"get","defaultCheck":false,"describe":"详情"},{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"edit","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"}]', + 'sptDaTypes': null, + 'optionalFields': null, + 'parents': null, + 'type': null, + 'deleted': 0, + 'actions': [ + 'add', + 'query', + 'get', + 'edit', + 'delete' + ] + }, + { + 'id': 'member', + 'name': '会员管理', + 'describe': null, + 'status': 1, + 'actionData': '[{"action":"query","defaultCheck":false,"describe":"查询"},{"action":"get","defaultCheck":false,"describe":"详情"},{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"edit","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"}]', + 'sptDaTypes': null, + 'optionalFields': '[]', + 'parents': null, + 'type': 'default', + 'deleted': 0, + 'actions': [ + 'add', + 'query', + 'get', + 'edit', + 'delete' + ] + }, + { + 'id': 'menu', + 'name': '菜单管理', + 'describe': null, + 'status': 1, + 'actionData': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"import","defaultCheck":false,"describe":"导入"},{"action":"get","defaultCheck":false,"describe":"查询"},{"action":"edit","defaultCheck":false,"describe":"修改"}]', + 'sptDaTypes': null, + 'optionalFields': '[]', + 'parents': null, + 'type': 'default', + 'deleted': 0, + 'actions': [ + 'add', + 'import', + 'get', + 'edit' + ] + }, + { + 'id': 'order', + 'name': '订单管理', + 'describe': null, + 'status': 1, + 'actionData': '[{"action":"query","defaultCheck":false,"describe":"查询"},{"action":"get","defaultCheck":false,"describe":"详情"},{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"edit","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"}]', + 'sptDaTypes': null, + 'optionalFields': '[]', + 'parents': null, + 'type': 'default', + 'deleted': 0, + 'actions': [ + 'add', + 'query', + 'get', + 'edit', + 'delete' + ] + }, + { + 'id': 'permission', + 'name': '权限管理', + 'describe': null, + 'status': 1, + 'actionData': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"get","defaultCheck":false,"describe":"查询"},{"action":"edit","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"}]', + 'sptDaTypes': null, + 'optionalFields': '[]', + 'parents': null, + 'type': 'default', + 'deleted': 0, + 'actions': [ + 'add', + 'get', + 'edit', + 'delete' + ] + }, + { + 'id': 'role', + 'name': '角色管理', + 'describe': null, + 'status': 1, + 'actionData': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"get","defaultCheck":false,"describe":"查询"},{"action":"edit","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"}]', + 'sptDaTypes': null, + 'optionalFields': '[]', + 'parents': null, + 'type': 'default', + 'deleted': 0, + 'actions': [ + 'add', + 'get', + 'edit', + 'delete' + ] + }, + { + 'id': 'test', + 'name': '测试权限', + 'describe': null, + 'status': 1, + 'actionData': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"get","defaultCheck":false,"describe":"详情"}]', + 'sptDaTypes': null, + 'optionalFields': '[]', + 'parents': null, + 'type': 'default', + 'deleted': 0, + 'actions': [ + 'add', + 'get' + ] + }, + { + 'id': 'user', + 'name': '用户管理', + 'describe': null, + 'status': 1, + 'actionData': '[{"action":"query","defaultCheck":false,"describe":"查询"},{"action":"get","defaultCheck":false,"describe":"详情"},{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"edit","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"},{"action":"import","defaultCheck":false,"describe":"导入"},{"action":"export","defaultCheck":false,"describe":"导出"}]', + 'sptDaTypes': null, + 'optionalFields': '[]', + 'parents': null, + 'type': 'default', + 'deleted': 0, + 'actions': [ + 'add', + 'get' + ] + } + ]) +} + +const permissions = () => { + return builder({ + 'data': [{ + 'id': 'marketing', + 'name': '营销管理', + 'describe': null, + 'status': 1, + 'actionData': '[{"action":"query","defaultCheck":false,"describe":"查询"},{"action":"get","defaultCheck":false,"describe":"详情"},{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"edit","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"}]', + 'sptDaTypes': null, + 'optionalFields': null, + 'parents': null, + 'type': null, + 'deleted': 0, + 'actions': [ + 'add', + 'query', + 'get', + 'edit', + 'delete' + ] + }, + { + 'id': 'member', + 'name': '会员管理', + 'describe': null, + 'status': 1, + 'actionData': '[{"action":"query","defaultCheck":false,"describe":"查询"},{"action":"get","defaultCheck":false,"describe":"详情"},{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"edit","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"}]', + 'sptDaTypes': null, + 'optionalFields': '[]', + 'parents': null, + 'type': 'default', + 'deleted': 0, + 'actions': [ + 'add', + 'query', + 'get', + 'edit', + 'delete' + ] + }, + { + 'id': 'menu', + 'name': '菜单管理', + 'describe': null, + 'status': 1, + 'actionData': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"import","defaultCheck":false,"describe":"导入"},{"action":"get","defaultCheck":false,"describe":"查询"},{"action":"edit","defaultCheck":false,"describe":"修改"}]', + 'sptDaTypes': null, + 'optionalFields': '[]', + 'parents': null, + 'type': 'default', + 'deleted': 0, + 'actions': [ + 'add', + 'import', + 'get', + 'edit' + ] + }, + { + 'id': 'order', + 'name': '订单管理', + 'describe': null, + 'status': 1, + 'actionData': '[{"action":"query","defaultCheck":false,"describe":"查询"},{"action":"get","defaultCheck":false,"describe":"详情"},{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"edit","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"}]', + 'sptDaTypes': null, + 'optionalFields': '[]', + 'parents': null, + 'type': 'default', + 'deleted': 0, + 'actions': [ + 'add', + 'query', + 'get', + 'edit', + 'delete' + ] + }, + { + 'id': 'permission', + 'name': '权限管理', + 'describe': null, + 'status': 1, + 'actionData': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"get","defaultCheck":false,"describe":"查询"},{"action":"edit","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"}]', + 'sptDaTypes': null, + 'optionalFields': '[]', + 'parents': null, + 'type': 'default', + 'deleted': 0, + 'actions': [ + 'add', + 'get', + 'edit', + 'delete' + ] + }, + { + 'id': 'role', + 'name': '角色管理', + 'describe': null, + 'status': 1, + 'actionData': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"get","defaultCheck":false,"describe":"查询"},{"action":"edit","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"}]', + 'sptDaTypes': null, + 'optionalFields': '[]', + 'parents': null, + 'type': 'default', + 'deleted': 0, + 'actions': [ + 'add', + 'get', + 'edit', + 'delete' + ] + }, + { + 'id': 'test', + 'name': '测试权限', + 'describe': null, + 'status': 1, + 'actionData': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"get","defaultCheck":false,"describe":"详情"}]', + 'sptDaTypes': null, + 'optionalFields': '[]', + 'parents': null, + 'type': 'default', + 'deleted': 0, + 'actions': [ + 'add', + 'get' + ] + }, + { + 'id': 'user', + 'name': '用户管理', + 'describe': null, + 'status': 1, + 'actionData': '[{"action":"add","describe":"新增","defaultCheck":false},{"action":"get","describe":"查询","defaultCheck":false}]', + 'sptDaTypes': null, + 'optionalFields': '[]', + 'parents': null, + 'type': 'default', + 'deleted': 0, + 'actions': [ + 'add', + 'get' + ] + } + ], + 'pageSize': 10, + 'pageNo': 0, + 'totalPage': 1, + 'totalCount': 5 + }) +} + +Mock.mock(/\/org\/tree/, 'get', orgTree) +Mock.mock(/\/role/, 'get', role) +Mock.mock(/\/permission\/no-pager/, 'get', permissionNoPager) +Mock.mock(/\/permission/, 'get', permissions) diff --git a/_web/src/mock/services/tagCloud.js b/_web/src/mock/services/tagCloud.js new file mode 100644 index 00000000..63a2e06d --- /dev/null +++ b/_web/src/mock/services/tagCloud.js @@ -0,0 +1,9 @@ +import Mock from 'mockjs2' +import { builder } from '../util' + +// +const tagCloudData = () => { + return builder([{ 'value': 9, 'name': 'AntV' }, { 'value': 8, 'name': 'F2' }, { 'value': 8, 'name': 'G2' }, { 'value': 8, 'name': 'G6' }, { 'value': 8, 'name': 'DataSet' }, { 'value': 8, 'name': '墨者学院' }, { 'value': 6, 'name': 'Analysis' }, { 'value': 6, 'name': 'Data Mining' }, { 'value': 6, 'name': 'Data Vis' }, { 'value': 6, 'name': 'Design' }, { 'value': 6, 'name': 'Grammar' }, { 'value': 6, 'name': 'Graphics' }, { 'value': 6, 'name': 'Graph' }, { 'value': 6, 'name': 'Hierarchy' }, { 'value': 6, 'name': 'Labeling' }, { 'value': 6, 'name': 'Layout' }, { 'value': 6, 'name': 'Quantitative' }, { 'value': 6, 'name': 'Relation' }, { 'value': 6, 'name': 'Statistics' }, { 'value': 6, 'name': '可视化' }, { 'value': 6, 'name': '数据' }, { 'value': 6, 'name': '数据可视化' }, { 'value': 4, 'name': 'Arc Diagram' }, { 'value': 4, 'name': 'Bar Chart' }, { 'value': 4, 'name': 'Canvas' }, { 'value': 4, 'name': 'Chart' }, { 'value': 4, 'name': 'DAG' }, { 'value': 4, 'name': 'DG' }, { 'value': 4, 'name': 'Facet' }, { 'value': 4, 'name': 'Geo' }, { 'value': 4, 'name': 'Line' }, { 'value': 4, 'name': 'MindMap' }, { 'value': 4, 'name': 'Pie' }, { 'value': 4, 'name': 'Pizza Chart' }, { 'value': 4, 'name': 'Punch Card' }, { 'value': 4, 'name': 'SVG' }, { 'value': 4, 'name': 'Sunburst' }, { 'value': 4, 'name': 'Tree' }, { 'value': 4, 'name': 'UML' }, { 'value': 3, 'name': 'Chart' }, { 'value': 3, 'name': 'View' }, { 'value': 3, 'name': 'Geom' }, { 'value': 3, 'name': 'Shape' }, { 'value': 3, 'name': 'Scale' }, { 'value': 3, 'name': 'Animate' }, { 'value': 3, 'name': 'Global' }, { 'value': 3, 'name': 'Slider' }, { 'value': 3, 'name': 'Connector' }, { 'value': 3, 'name': 'Transform' }, { 'value': 3, 'name': 'Util' }, { 'value': 3, 'name': 'DomUtil' }, { 'value': 3, 'name': 'MatrixUtil' }, { 'value': 3, 'name': 'PathUtil' }, { 'value': 3, 'name': 'G' }, { 'value': 3, 'name': '2D' }, { 'value': 3, 'name': '3D' }, { 'value': 3, 'name': 'Line' }, { 'value': 3, 'name': 'Area' }, { 'value': 3, 'name': 'Interval' }, { 'value': 3, 'name': 'Schema' }, { 'value': 3, 'name': 'Edge' }, { 'value': 3, 'name': 'Polygon' }, { 'value': 3, 'name': 'Heatmap' }, { 'value': 3, 'name': 'Render' }, { 'value': 3, 'name': 'Tooltip' }, { 'value': 3, 'name': 'Axis' }, { 'value': 3, 'name': 'Guide' }, { 'value': 3, 'name': 'Coord' }, { 'value': 3, 'name': 'Legend' }, { 'value': 3, 'name': 'Path' }, { 'value': 3, 'name': 'Helix' }, { 'value': 3, 'name': 'Theta' }, { 'value': 3, 'name': 'Rect' }, { 'value': 3, 'name': 'Polar' }, { 'value': 3, 'name': 'Dsv' }, { 'value': 3, 'name': 'Csv' }, { 'value': 3, 'name': 'Tsv' }, { 'value': 3, 'name': 'GeoJSON' }, { 'value': 3, 'name': 'TopoJSON' }, { 'value': 3, 'name': 'Filter' }, { 'value': 3, 'name': 'Map' }, { 'value': 3, 'name': 'Pick' }, { 'value': 3, 'name': 'Rename' }, { 'value': 3, 'name': 'Filter' }, { 'value': 3, 'name': 'Map' }, { 'value': 3, 'name': 'Pick' }, { 'value': 3, 'name': 'Rename' }, { 'value': 3, 'name': 'Reverse' }, { 'value': 3, 'name': 'sort' }, { 'value': 3, 'name': 'Subset' }, { 'value': 3, 'name': 'Partition' }, { 'value': 3, 'name': 'Imputation' }, { 'value': 3, 'name': 'Fold' }, { 'value': 3, 'name': 'Aggregate' }, { 'value': 3, 'name': 'Proportion' }, { 'value': 3, 'name': 'Histogram' }, { 'value': 3, 'name': 'Quantile' }, { 'value': 3, 'name': 'Treemap' }, { 'value': 3, 'name': 'Hexagon' }, { 'value': 3, 'name': 'Binning' }, { 'value': 3, 'name': 'kernel' }, { 'value': 3, 'name': 'Regression' }, { 'value': 3, 'name': 'Density' }, { 'value': 3, 'name': 'Sankey' }, { 'value': 3, 'name': 'Voronoi' }, { 'value': 3, 'name': 'Projection' }, { 'value': 3, 'name': 'Centroid' }, { 'value': 3, 'name': 'H5' }, { 'value': 3, 'name': 'Mobile' }, { 'value': 3, 'name': 'K线图' }, { 'value': 3, 'name': '关系图' }, { 'value': 3, 'name': '烛形图' }, { 'value': 3, 'name': '股票图' }, { 'value': 3, 'name': '直方图' }, { 'value': 3, 'name': '金字塔图' }, { 'value': 3, 'name': '分面' }, { 'value': 3, 'name': '南丁格尔玫瑰图' }, { 'value': 3, 'name': '饼图' }, { 'value': 3, 'name': '线图' }, { 'value': 3, 'name': '点图' }, { 'value': 3, 'name': '散点图' }, { 'value': 3, 'name': '子弹图' }, { 'value': 3, 'name': '柱状图' }, { 'value': 3, 'name': '仪表盘' }, { 'value': 3, 'name': '气泡图' }, { 'value': 3, 'name': '漏斗图' }, { 'value': 3, 'name': '热力图' }, { 'value': 3, 'name': '玉玦图' }, { 'value': 3, 'name': '直方图' }, { 'value': 3, 'name': '矩形树图' }, { 'value': 3, 'name': '箱形图' }, { 'value': 3, 'name': '色块图' }, { 'value': 3, 'name': '螺旋图' }, { 'value': 3, 'name': '词云' }, { 'value': 3, 'name': '词云图' }, { 'value': 3, 'name': '雷达图' }, { 'value': 3, 'name': '面积图' }, { 'value': 3, 'name': '马赛克图' }, { 'value': 3, 'name': '盒须图' }, { 'value': 3, 'name': '坐标轴' }, { 'value': 3, 'name': '' }, { 'value': 3, 'name': 'Jacques Bertin' }, { 'value': 3, 'name': 'Leland Wilkinson' }, { 'value': 3, 'name': 'William Playfair' }, { 'value': 3, 'name': '关联' }, { 'value': 3, 'name': '分布' }, { 'value': 3, 'name': '区间' }, { 'value': 3, 'name': '占比' }, { 'value': 3, 'name': '地图' }, { 'value': 3, 'name': '时间' }, { 'value': 3, 'name': '比较' }, { 'value': 3, 'name': '流程' }, { 'value': 3, 'name': '趋势' }, { 'value': 2, 'name': '亦叶' }, { 'value': 2, 'name': '再飞' }, { 'value': 2, 'name': '完白' }, { 'value': 2, 'name': '巴思' }, { 'value': 2, 'name': '张初尘' }, { 'value': 2, 'name': '御术' }, { 'value': 2, 'name': '有田' }, { 'value': 2, 'name': '沉鱼' }, { 'value': 2, 'name': '玉伯' }, { 'value': 2, 'name': '画康' }, { 'value': 2, 'name': '祯逸' }, { 'value': 2, 'name': '绝云' }, { 'value': 2, 'name': '罗宪' }, { 'value': 2, 'name': '萧庆' }, { 'value': 2, 'name': '董珊珊' }, { 'value': 2, 'name': '陆沉' }, { 'value': 2, 'name': '顾倾' }, { 'value': 2, 'name': 'Domo' }, { 'value': 2, 'name': 'GPL' }, { 'value': 2, 'name': 'PAI' }, { 'value': 2, 'name': 'SPSS' }, { 'value': 2, 'name': 'SYSTAT' }, { 'value': 2, 'name': 'Tableau' }, { 'value': 2, 'name': 'D3' }, { 'value': 2, 'name': 'Vega' }, { 'value': 2, 'name': '统计图表' }]) +} + +Mock.mock(/\/data\/antv\/tag-cloud/, 'get', tagCloudData) diff --git a/_web/src/mock/services/user.js b/_web/src/mock/services/user.js new file mode 100644 index 00000000..8666a1bf --- /dev/null +++ b/_web/src/mock/services/user.js @@ -0,0 +1,770 @@ +import Mock from 'mockjs2' +import { builder } from '../util' + +const info = (options) => { + console.log('options', options) + const userInfo = { + 'id': '4291d7da9005377ec9aec4a71ea837f', + 'name': '天野远子', + 'username': 'admin', + 'password': '', + 'avatar': '/avatar2.jpg', + 'status': 1, + 'telephone': '', + 'lastLoginIp': '27.154.74.117', + 'lastLoginTime': 1534837621348, + 'creatorId': 'admin', + 'createTime': 1497160610259, + 'merchantCode': 'TLif2btpzg079h15bk', + 'deleted': 0, + 'roleId': 'admin', + 'role': {} + } + // role + const roleObj = { + 'id': 'admin', + 'name': '管理员', + 'describe': '拥有所有权限', + 'status': 1, + 'creatorId': 'system', + 'createTime': 1497160610259, + 'deleted': 0, + 'permissions': [{ + 'roleId': 'admin', + 'permissionId': 'dashboard', + 'permissionName': '仪表盘', + 'actions': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"query","defaultCheck":false,"describe":"查询"},{"action":"get","defaultCheck":false,"describe":"详情"},{"action":"update","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"}]', + 'actionEntitySet': [{ + 'action': 'add', + 'describe': '新增', + 'defaultCheck': false + }, { + 'action': 'query', + 'describe': '查询', + 'defaultCheck': false + }, { + 'action': 'get', + 'describe': '详情', + 'defaultCheck': false + }, { + 'action': 'update', + 'describe': '修改', + 'defaultCheck': false + }, { + 'action': 'delete', + 'describe': '删除', + 'defaultCheck': false + }], + 'actionList': null, + 'dataAccess': null + }, { + 'roleId': 'admin', + 'permissionId': 'exception', + 'permissionName': '异常页面权限', + 'actions': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"query","defaultCheck":false,"describe":"查询"},{"action":"get","defaultCheck":false,"describe":"详情"},{"action":"update","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"}]', + 'actionEntitySet': [{ + 'action': 'add', + 'describe': '新增', + 'defaultCheck': false + }, { + 'action': 'query', + 'describe': '查询', + 'defaultCheck': false + }, { + 'action': 'get', + 'describe': '详情', + 'defaultCheck': false + }, { + 'action': 'update', + 'describe': '修改', + 'defaultCheck': false + }, { + 'action': 'delete', + 'describe': '删除', + 'defaultCheck': false + }], + 'actionList': null, + 'dataAccess': null + }, { + 'roleId': 'admin', + 'permissionId': 'result', + 'permissionName': '结果权限', + 'actions': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"query","defaultCheck":false,"describe":"查询"},{"action":"get","defaultCheck":false,"describe":"详情"},{"action":"update","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"}]', + 'actionEntitySet': [{ + 'action': 'add', + 'describe': '新增', + 'defaultCheck': false + }, { + 'action': 'query', + 'describe': '查询', + 'defaultCheck': false + }, { + 'action': 'get', + 'describe': '详情', + 'defaultCheck': false + }, { + 'action': 'update', + 'describe': '修改', + 'defaultCheck': false + }, { + 'action': 'delete', + 'describe': '删除', + 'defaultCheck': false + }], + 'actionList': null, + 'dataAccess': null + }, { + 'roleId': 'admin', + 'permissionId': 'profile', + 'permissionName': '详细页权限', + 'actions': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"query","defaultCheck":false,"describe":"查询"},{"action":"get","defaultCheck":false,"describe":"详情"},{"action":"update","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"}]', + 'actionEntitySet': [{ + 'action': 'add', + 'describe': '新增', + 'defaultCheck': false + }, { + 'action': 'query', + 'describe': '查询', + 'defaultCheck': false + }, { + 'action': 'get', + 'describe': '详情', + 'defaultCheck': false + }, { + 'action': 'update', + 'describe': '修改', + 'defaultCheck': false + }, { + 'action': 'delete', + 'describe': '删除', + 'defaultCheck': false + }], + 'actionList': null, + 'dataAccess': null + }, { + 'roleId': 'admin', + 'permissionId': 'table', + 'permissionName': '表格权限', + 'actions': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"import","defaultCheck":false,"describe":"导入"},{"action":"get","defaultCheck":false,"describe":"详情"},{"action":"update","defaultCheck":false,"describe":"修改"}]', + 'actionEntitySet': [{ + 'action': 'add', + 'describe': '新增', + 'defaultCheck': false + }, { + 'action': 'import', + 'describe': '导入', + 'defaultCheck': false + }, { + 'action': 'get', + 'describe': '详情', + 'defaultCheck': false + }, { + 'action': 'update', + 'describe': '修改', + 'defaultCheck': false + }], + 'actionList': null, + 'dataAccess': null + }, { + 'roleId': 'admin', + 'permissionId': 'form.vue', + 'permissionName': '表单权限', + 'actions': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"get","defaultCheck":false,"describe":"详情"},{"action":"query","defaultCheck":false,"describe":"查询"},{"action":"update","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"}]', + 'actionEntitySet': [{ + 'action': 'add', + 'describe': '新增', + 'defaultCheck': false + }, { + 'action': 'get', + 'describe': '详情', + 'defaultCheck': false + }, { + 'action': 'query', + 'describe': '查询', + 'defaultCheck': false + }, { + 'action': 'update', + 'describe': '修改', + 'defaultCheck': false + }, { + 'action': 'delete', + 'describe': '删除', + 'defaultCheck': false + }], + 'actionList': null, + 'dataAccess': null + }, { + 'roleId': 'admin', + 'permissionId': 'order', + 'permissionName': '订单管理', + 'actions': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"query","defaultCheck":false,"describe":"查询"},{"action":"get","defaultCheck":false,"describe":"详情"},{"action":"update","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"}]', + 'actionEntitySet': [{ + 'action': 'add', + 'describe': '新增', + 'defaultCheck': false + }, { + 'action': 'query', + 'describe': '查询', + 'defaultCheck': false + }, { + 'action': 'get', + 'describe': '详情', + 'defaultCheck': false + }, { + 'action': 'update', + 'describe': '修改', + 'defaultCheck': false + }, { + 'action': 'delete', + 'describe': '删除', + 'defaultCheck': false + }], + 'actionList': null, + 'dataAccess': null + }, { + 'roleId': 'admin', + 'permissionId': 'permission', + 'permissionName': '权限管理', + 'actions': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"get","defaultCheck":false,"describe":"详情"},{"action":"update","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"}]', + 'actionEntitySet': [{ + 'action': 'add', + 'describe': '新增', + 'defaultCheck': false + }, { + 'action': 'get', + 'describe': '详情', + 'defaultCheck': false + }, { + 'action': 'update', + 'describe': '修改', + 'defaultCheck': false + }, { + 'action': 'delete', + 'describe': '删除', + 'defaultCheck': false + }], + 'actionList': null, + 'dataAccess': null + }, { + 'roleId': 'admin', + 'permissionId': 'role', + 'permissionName': '角色管理', + 'actions': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"get","defaultCheck":false,"describe":"详情"},{"action":"update","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"}]', + 'actionEntitySet': [{ + 'action': 'add', + 'describe': '新增', + 'defaultCheck': false + }, { + 'action': 'get', + 'describe': '详情', + 'defaultCheck': false + }, { + 'action': 'update', + 'describe': '修改', + 'defaultCheck': false + }, { + 'action': 'delete', + 'describe': '删除', + 'defaultCheck': false + }], + 'actionList': null, + 'dataAccess': null + }, { + 'roleId': 'admin', + 'permissionId': 'table', + 'permissionName': '桌子管理', + 'actions': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"get","defaultCheck":false,"describe":"详情"},{"action":"query","defaultCheck":false,"describe":"查询"},{"action":"update","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"}]', + 'actionEntitySet': [{ + 'action': 'add', + 'describe': '新增', + 'defaultCheck': false + }, { + 'action': 'get', + 'describe': '详情', + 'defaultCheck': false + }, { + 'action': 'query', + 'describe': '查询', + 'defaultCheck': false + }, { + 'action': 'update', + 'describe': '修改', + 'defaultCheck': false + }, { + 'action': 'delete', + 'describe': '删除', + 'defaultCheck': false + }], + 'actionList': null, + 'dataAccess': null + }, { + 'roleId': 'admin', + 'permissionId': 'user', + 'permissionName': '用户管理', + 'actions': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"import","defaultCheck":false,"describe":"导入"},{"action":"get","defaultCheck":false,"describe":"详情"},{"action":"update","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"},{"action":"export","defaultCheck":false,"describe":"导出"}]', + 'actionEntitySet': [{ + 'action': 'add', + 'describe': '新增', + 'defaultCheck': false + }, { + 'action': 'import', + 'describe': '导入', + 'defaultCheck': false + }, { + 'action': 'get', + 'describe': '详情', + 'defaultCheck': false + }, { + 'action': 'update', + 'describe': '修改', + 'defaultCheck': false + }, { + 'action': 'delete', + 'describe': '删除', + 'defaultCheck': false + }, { + 'action': 'export', + 'describe': '导出', + 'defaultCheck': false + }], + 'actionList': null, + 'dataAccess': null + }] + } + + roleObj.permissions.push({ + 'roleId': 'admin', + 'permissionId': 'support', + 'permissionName': '超级模块', + 'actions': '[{"action":"add","defaultCheck":false,"describe":"新增"},{"action":"import","defaultCheck":false,"describe":"导入"},{"action":"get","defaultCheck":false,"describe":"详情"},{"action":"update","defaultCheck":false,"describe":"修改"},{"action":"delete","defaultCheck":false,"describe":"删除"},{"action":"export","defaultCheck":false,"describe":"导出"}]', + 'actionEntitySet': [{ + 'action': 'add', + 'describe': '新增', + 'defaultCheck': false + }, { + 'action': 'import', + 'describe': '导入', + 'defaultCheck': false + }, { + 'action': 'get', + 'describe': '详情', + 'defaultCheck': false + }, { + 'action': 'update', + 'describe': '修改', + 'defaultCheck': false + }, { + 'action': 'delete', + 'describe': '删除', + 'defaultCheck': false + }, { + 'action': 'export', + 'describe': '导出', + 'defaultCheck': false + }], + 'actionList': null, + 'dataAccess': null + }) + + userInfo.role = roleObj + return builder(userInfo) +} + +const userNav = (options) => { + const nav = [ + // dashboard + { + 'name': 'dashboard', + 'parentId': 0, + 'id': 1, + 'meta': { + 'icon': 'dashboard', + 'title': '仪表盘77', + 'show': true + }, + 'component': 'RouteView', + 'redirect': '/dashboard/workplace' + }, + { + 'name': 'workplace', + 'parentId': 1, + 'id': 7, + 'meta': { + 'title': '工作台', + 'show': true + }, + 'component': 'Workplace' + }, + { + 'name': 'monitor', + 'path': 'https://www.baidu.com/', + 'parentId': 1, + 'id': 3, + 'meta': { + 'title': '监控页(外部)', + 'target': '_blank', + 'show': true + } + }, + { + 'name': 'Analysis', + 'parentId': 1, + 'id': 2, + 'meta': { + 'title': '分析页', + 'show': true + }, + 'component': 'Analysis', + 'path': '/dashboard/analysis' + }, + { + 'name': 'tests', + 'parentId': 1, + 'id': 8, + 'meta': { + 'title': '测试功能', + 'show': true + }, + 'component': 'TestWork' + }, + + // form + { + 'name': 'form.vue', + 'parentId': 0, + 'id': 10, + 'meta': { + 'icon': 'form.vue', + 'title': '表单页' + }, + 'redirect': '/form/base-form', + 'component': 'PageView' + }, + { + 'name': 'basic-form', + 'parentId': 10, + 'id': 6, + 'meta': { + 'title': '基础表单' + }, + 'component': 'BasicForm' + }, + { + 'name': 'step-form', + 'parentId': 10, + 'id': 5, + 'meta': { + 'title': '分步表单' + }, + 'component': 'StepForm' + }, + { + 'name': 'advanced-form', + 'parentId': 10, + 'id': 4, + 'meta': { + 'title': '高级表单' + }, + 'component': 'AdvanceForm' + }, + + // list + { + 'name': 'list', + 'parentId': 0, + 'id': 10010, + 'meta': { + 'icon': 'table', + 'title': '列表页', + 'show': true + }, + 'redirect': '/list/table-list', + 'component': 'PageView' + }, + { + 'name': 'table-list', + 'parentId': 10010, + 'id': 10011, + 'path': '/list/table-list/:pageNo([1-9]\\d*)?', + 'meta': { + 'title': '查询表格', + 'show': true + }, + 'component': 'TableList' + }, + { + 'name': 'basic-list', + 'parentId': 10010, + 'id': 10012, + 'meta': { + 'title': '标准列表', + 'show': true + }, + 'component': 'StandardList' + }, + { + 'name': 'card', + 'parentId': 10010, + 'id': 10013, + 'meta': { + 'title': '卡片列表', + 'show': true + }, + 'component': 'CardList' + }, + { + 'name': 'search', + 'parentId': 10010, + 'id': 10014, + 'meta': { + 'title': '搜索列表', + 'show': true + }, + 'redirect': '/list/search/article', + 'component': 'SearchLayout' + }, + { + 'name': 'article', + 'parentId': 10014, + 'id': 10015, + 'meta': { + 'title': '搜索列表(文章)', + 'show': true + }, + 'component': 'SearchArticles' + }, + { + 'name': 'project', + 'parentId': 10014, + 'id': 10016, + 'meta': { + 'title': '搜索列表(项目)', + 'show': true + }, + 'component': 'SearchProjects' + }, + { + 'name': 'application', + 'parentId': 10014, + 'id': 10017, + 'meta': { + 'title': '搜索列表(应用)', + 'show': true + }, + 'component': 'SearchApplications' + }, + + // profile + { + 'name': 'profile', + 'parentId': 0, + 'id': 10018, + 'meta': { + 'title': '详情页', + 'icon': 'profile', + 'show': true + }, + 'redirect': '/profile/basic', + 'component': 'RouteView' + }, + { + 'name': 'basic', + 'parentId': 10018, + 'id': 10019, + 'meta': { + 'title': '基础详情页', + 'show': true + }, + 'component': 'ProfileBasic' + }, + { + 'name': 'advanced', + 'parentId': 10018, + 'id': 10020, + 'meta': { + 'title': '高级详情页', + 'show': true + }, + 'component': 'ProfileAdvanced' + }, + + // result + { + 'name': 'result', + 'parentId': 0, + 'id': 10021, + 'meta': { + 'title': '结果页', + 'icon': 'check-circle-o', + 'show': true + }, + 'redirect': '/result/success', + 'component': 'PageView' + }, + { + 'name': 'success', + 'parentId': 10021, + 'id': 10022, + 'meta': { + 'title': '成功', + 'hiddenHeaderContent': true, + 'show': true + }, + 'component': 'ResultSuccess' + }, + { + 'name': 'fail', + 'parentId': 10021, + 'id': 10023, + 'meta': { + 'title': '失败', + 'hiddenHeaderContent': true, + 'show': true + }, + 'component': 'ResultFail' + }, + + // Exception + { + 'name': 'exception', + 'parentId': 0, + 'id': 10024, + 'meta': { + 'title': '异常页', + 'icon': 'warning', + 'show': true + }, + 'redirect': '/exception/403', + 'component': 'RouteView' + }, + { + 'name': '403', + 'parentId': 10024, + 'id': 10025, + 'meta': { + 'title': '403', + 'show': true + }, + 'component': 'Exception403' + }, + { + 'name': '404', + 'parentId': 10024, + 'id': 10026, + 'meta': { + 'title': '404', + 'show': true + }, + 'component': 'Exception404' + }, + { + 'name': '500', + 'parentId': 10024, + 'id': 10027, + 'meta': { + 'title': '500', + 'show': true + }, + 'component': 'Exception500' + }, + + // account + { + 'name': 'account', + 'parentId': 0, + 'id': 10028, + 'meta': { + 'title': '个人页', + 'icon': 'user', + 'show': true + }, + 'redirect': '/account/center', + 'component': 'RouteView' + }, + { + 'name': 'center', + 'parentId': 10028, + 'id': 10029, + 'meta': { + 'title': '个人中心', + 'show': true + }, + 'component': 'AccountCenter' + }, + // 特殊三级菜单 + { + 'name': 'settings', + 'parentId': 10028, + 'id': 10030, + 'meta': { + 'title': '个人设置', + 'hideHeader': true, + 'hideChildren': true, + 'show': true + }, + 'redirect': '/account/settings/base', + 'component': 'AccountSettings' + }, + { + 'name': 'BaseSettings', + 'path': '/account/settings/base', + 'parentId': 10030, + 'id': 10031, + 'meta': { + 'title': '基本设置', + 'show': false + }, + 'component': 'BaseSettings' + }, + { + 'name': 'SecuritySettings', + 'path': '/account/settings/security', + 'parentId': 10030, + 'id': 10032, + 'meta': { + 'title': '安全设置', + 'show': false + }, + 'component': 'SecuritySettings' + }, + { + 'name': 'CustomSettings', + 'path': '/account/settings/custom', + 'parentId': 10030, + 'id': 10033, + 'meta': { + 'title': '个性化设置', + 'show': false + }, + 'component': 'CustomSettings' + }, + { + 'name': 'BindingSettings', + 'path': '/account/settings/binding', + 'parentId': 10030, + 'id': 10034, + 'meta': { + 'title': '账户绑定', + 'show': false + }, + 'component': 'BindingSettings' + }, + { + 'name': 'NotificationSettings', + 'path': '/account/settings/notification', + 'parentId': 10030, + 'id': 10034, + 'meta': { + 'title': '新消息通知', + 'show': false + }, + 'component': 'NotificationSettings' + } + ] + const json = builder(nav) + console.log('json', json) + return json +} + +Mock.mock(/\/api\/user\/info/, 'get', info) +Mock.mock(/\/api\/user\/nav/, 'get', userNav) diff --git a/_web/src/mock/util.js b/_web/src/mock/util.js new file mode 100644 index 00000000..a4be0360 --- /dev/null +++ b/_web/src/mock/util.js @@ -0,0 +1,38 @@ +const responseBody = { + message: '', + timestamp: 0, + result: null, + code: 0 +} + +export const builder = (data, message, code = 0, headers = {}) => { + responseBody.result = data + if (message !== undefined && message !== null) { + responseBody.message = message + } + if (code !== undefined && code !== 0) { + responseBody.code = code + responseBody._status = code + } + if (headers !== null && typeof headers === 'object' && Object.keys(headers).length > 0) { + responseBody._headers = headers + } + responseBody.timestamp = new Date().getTime() + return responseBody +} + +export const getQueryParameters = (options) => { + const url = options.url + const search = url.split('?')[1] + if (!search) { + return {} + } + return JSON.parse('{"' + decodeURIComponent(search) + .replace(/"/g, '\\"') + .replace(/&/g, '","') + .replace(/=/g, '":"') + '"}') +} + +export const getBody = (options) => { + return options.body && JSON.parse(options.body) +} diff --git a/_web/src/permission.js b/_web/src/permission.js new file mode 100644 index 00000000..5de7ac61 --- /dev/null +++ b/_web/src/permission.js @@ -0,0 +1,113 @@ +import Vue from 'vue' +import router from './router' +import store from './store' + +import NProgress from 'nprogress' // progress bar +import '@/components/NProgress/nprogress.less' // progress bar custom style +import { setDocumentTitle, domTitle } from '@/utils/domUtil' +import { ACCESS_TOKEN, ALL_APPS_MENU } from '@/store/mutation-types' + +import { Modal, notification } from 'ant-design-vue' // NProgress Configuration +import { timeFix } from '@/utils/util'/// es/notification +NProgress.configure({ showSpinner: false }) +const whiteList = ['login', 'register', 'registerResult'] // no redirect whitelist +// 无默认首页的情况 +const defaultRoutePath = '/welcome' + +router.beforeEach((to, from, next) => { + NProgress.start() // start progress bar + to.meta && (typeof to.meta.title !== 'undefined' && setDocumentTitle(`${to.meta.title} - ${domTitle}`)) + if (Vue.ls.get(ACCESS_TOKEN)) { + /* has token */ + if (to.path === '/user/login') { + next({ path: defaultRoutePath }) + NProgress.done() + } else { + if (store.getters.roles.length === 0) { + store + .dispatch('GetInfo') + .then(res => { + if (res.menus.length < 1) { + Modal.error({ + title: '提示:', + content: '无菜单权限,请联系管理员', + okText: '确定', + onOk: () => { + store.dispatch('Logout').then(() => { + window.location.reload() + }) + } + }) + return + } + // eslint-disable-next-line camelcase + const all_app_menu = Vue.ls.get(ALL_APPS_MENU) + let antDesignmenus + // eslint-disable-next-line camelcase + if (all_app_menu == null) { + const applocation = [] + res.apps.forEach(item => { + const apps = { 'code': '', 'name': '', 'active': '', 'menu': '' } + if (item.active) { + apps.code = item.code + apps.name = item.name + apps.active = item.active + apps.menu = res.menus + antDesignmenus = res.menus + } else { + apps.code = item.code + apps.name = item.name + apps.active = item.active + apps.menu = '' + } + applocation.push(apps) + }) + Vue.ls.set(ALL_APPS_MENU, applocation, 7 * 24 * 60 * 60 * 1000) + // 延迟 1 秒显示欢迎信息 + setTimeout(() => { + notification.success({ + message: '欢迎', + description: `${timeFix()},欢迎回来` + }) + }, 1000) + } else { + antDesignmenus = Vue.ls.get(ALL_APPS_MENU)[0].menu + } + store.dispatch('GenerateRoutes', { antDesignmenus }).then(() => { + // 动态添加可访问路由表 + router.addRoutes(store.getters.addRouters) + // 请求带有 redirect 重定向时,登录自动重定向到该地址 + const redirect = decodeURIComponent(from.query.redirect || to.path) + if (to.path === redirect) { + next({ path: redirect }) + // hack方法 确保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record + next({ ...to, replace: true }) + } else { + // 跳转到目的路由 + next({ path: redirect }) + } + }) + }) + .catch(() => { + store.dispatch('Logout').then(() => { + next({ path: '/user/login', query: { redirect: to.fullPath } }) + }) + }) + } else { + next() + } + } + } else { + if (whiteList.includes(to.name)) { + // 在免登录白名单,直接进入 + next() + } else { + next({ path: '/user/login', query: { redirect: to.fullPath } }) + NProgress.done() // if current page is login will not trigger afterEach hook, so manually handle it + } + } +}) + +router.afterEach(() => { + NProgress.done() // finish progress bar +}) diff --git a/_web/src/router/generator-routers.js b/_web/src/router/generator-routers.js new file mode 100644 index 00000000..4106ec6e --- /dev/null +++ b/_web/src/router/generator-routers.js @@ -0,0 +1,261 @@ + +import { BasicLayout, BlankLayout, PageView, RouteView, Iframe } from '@/layouts' + +// 前端路由表 +const constantRouterComponents = { + // 基础页面 layout 必须引入 + BasicLayout: BasicLayout, + BlankLayout: BlankLayout, + RouteView: RouteView, + PageView: PageView, + Iframe: Iframe, + '403': () => import('@/views/system/exception/403'), + '404': () => import('@/views/system/exception/404'), + '500': () => import('@/views/system/exception/500'), + + 'Workplace': () => import('@/views/system/dashboard/Workplace'), + // account + 'AccountCenter': () => import('@/views/system/account/center/Index'), + 'AccountSettings': () => import('@/views/system/account/settings/Index'), + 'BaseSettings': () => import('@/views/system/account/settings/BaseSetting'), + 'SecuritySettings': () => import('@/views/system/account/settings/Security'), + 'CustomSettings': () => import('@/views/system/account/settings/Custom'), + 'BindingSettings': () => import('@/views/system/account/settings/Binding'), + 'NotificationSettings': () => import('@/views/system/account/settings/Notification'), + + // 默认首页 + 'Console': () => import('@/views/system/index/welcome') +} + +// 前端未找到页面路由(固定不用改)、原来为 /404 +const notFoundRouter = { + path: '*', redirect: '/welcome', hidden: true +} +// 个人中心页面 +const userAccount = [ + // account + { + 'name': 'account', + 'pid': 0, + 'id': 10028, + 'meta': { + 'title': '个人页', + 'icon': 'user', + 'show': false + }, + 'redirect': '/account/center', + 'component': 'RouteView' + }, + { + 'name': 'center', + 'pid': 10028, + 'id': 10029, + 'meta': { + 'title': '个人中心', + 'show': false + }, + 'component': 'AccountCenter' + }, + // 特殊三级菜单 + { + 'name': 'settings', + 'pid': '10028', + 'id': '10030', + 'meta': { + 'title': '个人设置', + 'hideHeader': true, + 'hideChildren': true, + 'show': false + }, + 'redirect': '/account/settings/base', + 'component': 'AccountSettings' + }, + { + 'name': 'BaseSettings', + 'path': '/account/settings/base', + 'pid': 10030, + 'id': 10031, + 'meta': { + 'title': '基本设置', + 'show': false + }, + 'component': 'BaseSettings' + }, + { + 'name': 'SecuritySettings', + 'path': '/account/settings/security', + 'pid': 10030, + 'id': 10032, + 'meta': { + 'title': '安全设置', + 'show': false + }, + 'component': 'SecuritySettings' + }, + { + 'name': 'CustomSettings', + 'path': '/account/settings/custom', + 'pid': 10030, + 'id': 10033, + 'meta': { + 'title': '个性化设置', + 'show': false + }, + 'component': 'CustomSettings' + }, + { + 'name': 'BindingSettings', + 'path': '/account/settings/binding', + 'pid': 10030, + 'id': 10034, + 'meta': { + 'title': '账户绑定', + 'show': false + }, + 'component': 'BindingSettings' + }, + { + 'name': 'NotificationSettings', + 'path': '/account/settings/notification', + 'pid': 10030, + 'id': 10034, + 'meta': { + 'title': '新消息通知', + 'show': false + }, + 'component': 'NotificationSettings' + }, + { + 'name': 'Console', + 'path': '/welcome', + 'pid': 0, + 'id': 183183, + 'meta': { + 'title': '首页', + 'show': false + }, + 'component': 'Console' + } + +] + +// 根级菜单 +const rootRouter = { + key: '', + name: 'MenuIndex.vue', + path: '', + component: 'BasicLayout', + redirect: '/welcome', + meta: { + title: '首页' + }, + children: [] +} + +/** + * 动态生成菜单 + * @param data + * @returns {Promise} + */ +export const generatorDynamicRouter = (data) => { + return new Promise((resolve, reject) => { + const resNav = data.antDesignmenus + const menuNav = [] + const childrenNav = [] + // 后端数据, 根级树数组, 根级 PID + listToTree(resNav, childrenNav, 0) + + /** + * 增加静态网页 + */ + listToTree(userAccount, childrenNav, 0) + rootRouter.children = childrenNav + menuNav.push(rootRouter) + const routers = generator(menuNav) + routers.push(notFoundRouter) + resolve(routers) + }).catch(err => { + // reject('加载菜单失败') + return Promise.reject(err) + }) +} + +/** + * 格式化树形结构数据 生成 vue-router 层级路由表 + * + * @param routerMap + * @param parent + * @returns {*} + */ +export const generator = (routerMap, parent) => { + return routerMap.map(item => { + // eslint-disable-next-line no-unused-vars + const { title, show, hideChildren, hiddenHeaderContent, target, icon, link } = item.meta || {} + const currentRouter = { + // 如果路由设置了 path,则作为默认 path,否则 路由地址 动态拼接生成如 /dashboard/workplace + path: item.path || `${parent && parent.path || ''}/${item.key}`, + // 路由名称,建议唯一 + name: item.name || item.key || '', + // 该路由对应页面的 组件 :方案1 + // component: constantRouterComponents[item.component || item.key], + // 该路由对应页面的 组件 :方案2 (动态加载) + component: (constantRouterComponents[item.component || item.key]) || (() => import(`@/views/${item.component}`)), + // meta: 页面标题, 菜单图标, 页面权限(供指令权限用,可去掉) + meta: { + title: title, + icon: icon || undefined, + // hiddenHeaderContent: hiddenHeaderContent, + target: target, + link: link + } + } + // 是否设置了隐藏菜单 + if (show === false) { + currentRouter.hidden = true + } + // 是否设置了隐藏子菜单 + if (hideChildren) { + currentRouter.hideChildrenInMenu = true + } + // 为了防止出现后端返回结果不规范,处理有可能出现拼接出两个 反斜杠 + if (!currentRouter.path.startsWith('http')) { + currentRouter.path = currentRouter.path.replace('//', '/') + } + // 重定向 + item.redirect && (currentRouter.redirect = item.redirect) + // 是否有子菜单,并递归处理 + if (item.children && item.children.length > 0) { + // Recursion + currentRouter.children = generator(item.children, currentRouter) + } + return currentRouter + }) +} + +/** + * 数组转树形结构 + * @param list 源数组 + * @param tree 树 + * @param parentId 父ID + */ +const listToTree = (list, tree, parentId) => { + list.forEach(item => { + // 判断是否为父级菜单 + // eslint-disable-next-line eqeqeq + if (item.pid == parentId) { + const child = { + ...item, + key: item.key || item.name, + children: [] + } + // 迭代 list, 找到当前菜单相符合的所有子菜单 + listToTree(list, child.children, item.id) + // 删掉不存在 children 值的属性 + if (child.children.length <= 0) { + delete child.children + } + // 加入到树中 + tree.push(child) + } + }) +} diff --git a/_web/src/router/index.js b/_web/src/router/index.js new file mode 100644 index 00000000..dd727723 --- /dev/null +++ b/_web/src/router/index.js @@ -0,0 +1,19 @@ +import Vue from 'vue' +import Router from 'vue-router' +import { constantRouterMap } from '@/config/router.config' + +// hack router push callback +const originalPush = Router.prototype.push +Router.prototype.push = function push (location, onResolve, onReject) { + if (onResolve || onReject) return originalPush.call(this, location, onResolve, onReject) + return originalPush.call(this, location).catch(err => err) +} + +Vue.use(Router) + +export default new Router({ + mode: 'history', + base: process.env.BASE_URL, + scrollBehavior: () => ({ y: 0 }), + routes: constantRouterMap +}) diff --git a/_web/src/store/getters.js b/_web/src/store/getters.js new file mode 100644 index 00000000..69929b90 --- /dev/null +++ b/_web/src/store/getters.js @@ -0,0 +1,18 @@ +const getters = { + device: state => state.app.device, + theme: state => state.app.theme, + color: state => state.app.color, + token: state => state.user.token, + avatar: state => state.user.avatar, + nickname: state => state.user.name, + welcome: state => state.user.welcome, + roles: state => state.user.roles, + buttons: state => state.user.buttons, + admintype: state => state.user.admintype, + userInfo: state => state.user.info, + addRouters: state => state.permission.addRouters, + multiTab: state => state.app.multiTab, + lang: state => state.i18n.lang +} + +export default getters diff --git a/_web/src/store/index.js b/_web/src/store/index.js new file mode 100644 index 00000000..687d21b2 --- /dev/null +++ b/_web/src/store/index.js @@ -0,0 +1,32 @@ +import Vue from 'vue' +import Vuex from 'vuex' + +import app from './modules/app' +import user from './modules/user' + +// default router permission control +// import permission from './modules/permission' + +// dynamic router permission control (Experimental) +import permission from './modules/async-router' +import getters from './getters' + +Vue.use(Vuex) + +export default new Vuex.Store({ + modules: { + app, + user, + permission + }, + state: { + + }, + mutations: { + + }, + actions: { + + }, + getters +}) diff --git a/_web/src/store/modules/app.js b/_web/src/store/modules/app.js new file mode 100644 index 00000000..373a97eb --- /dev/null +++ b/_web/src/store/modules/app.js @@ -0,0 +1,122 @@ +import Vue from 'vue' +import { + SIDEBAR_TYPE, + DEFAULT_THEME, + DEFAULT_LAYOUT_MODE, + DEFAULT_COLOR, + DEFAULT_COLOR_WEAK, + DEFAULT_FIXED_HEADER, + DEFAULT_FIXED_SIDEMENU, + DEFAULT_FIXED_HEADER_HIDDEN, + DEFAULT_CONTENT_WIDTH_TYPE, + DEFAULT_MULTI_TAB +} from '@/store/mutation-types' + +const app = { + state: { + sidebar: true, + device: 'desktop', + theme: '', + layout: '', + contentWidth: '', + fixedHeader: false, + fixSiderbar: false, + autoHideHeader: false, + color: null, + weak: false, + multiTab: true + }, + mutations: { + SET_SIDEBAR_TYPE: (state, type) => { + state.sidebar = type + Vue.ls.set(SIDEBAR_TYPE, type) + }, + CLOSE_SIDEBAR: (state) => { + Vue.ls.set(SIDEBAR_TYPE, true) + state.sidebar = false + }, + TOGGLE_DEVICE: (state, device) => { + state.device = device + }, + TOGGLE_THEME: (state, theme) => { + // setStore('_DEFAULT_THEME', theme) + Vue.ls.set(DEFAULT_THEME, theme) + state.theme = theme + }, + TOGGLE_LAYOUT_MODE: (state, layout) => { + Vue.ls.set(DEFAULT_LAYOUT_MODE, layout) + state.layout = layout + }, + TOGGLE_FIXED_HEADER: (state, fixed) => { + Vue.ls.set(DEFAULT_FIXED_HEADER, fixed) + state.fixedHeader = fixed + }, + TOGGLE_FIXED_SIDERBAR: (state, fixed) => { + Vue.ls.set(DEFAULT_FIXED_SIDEMENU, fixed) + state.fixSiderbar = fixed + }, + TOGGLE_FIXED_HEADER_HIDDEN: (state, show) => { + Vue.ls.set(DEFAULT_FIXED_HEADER_HIDDEN, show) + state.autoHideHeader = show + }, + TOGGLE_CONTENT_WIDTH: (state, type) => { + Vue.ls.set(DEFAULT_CONTENT_WIDTH_TYPE, type) + state.contentWidth = type + }, + TOGGLE_COLOR: (state, color) => { + Vue.ls.set(DEFAULT_COLOR, color) + state.color = color + }, + TOGGLE_WEAK: (state, flag) => { + Vue.ls.set(DEFAULT_COLOR_WEAK, flag) + state.weak = flag + }, + TOGGLE_MULTI_TAB: (state, bool) => { + Vue.ls.set(DEFAULT_MULTI_TAB, bool) + state.multiTab = bool + } + }, + actions: { + setSidebar ({ commit }, type) { + commit('SET_SIDEBAR_TYPE', type) + }, + CloseSidebar ({ commit }) { + commit('CLOSE_SIDEBAR') + }, + ToggleDevice ({ commit }, device) { + commit('TOGGLE_DEVICE', device) + }, + ToggleTheme ({ commit }, theme) { + commit('TOGGLE_THEME', theme) + }, + ToggleLayoutMode ({ commit }, mode) { + commit('TOGGLE_LAYOUT_MODE', mode) + }, + ToggleFixedHeader ({ commit }, fixedHeader) { + if (!fixedHeader) { + commit('TOGGLE_FIXED_HEADER_HIDDEN', false) + } + commit('TOGGLE_FIXED_HEADER', fixedHeader) + }, + ToggleFixSiderbar ({ commit }, fixSiderbar) { + commit('TOGGLE_FIXED_SIDERBAR', fixSiderbar) + }, + ToggleFixedHeaderHidden ({ commit }, show) { + commit('TOGGLE_FIXED_HEADER_HIDDEN', show) + }, + ToggleContentWidth ({ commit }, type) { + commit('TOGGLE_CONTENT_WIDTH', type) + }, + ToggleColor ({ commit }, color) { + commit('TOGGLE_COLOR', color) + }, + ToggleWeak ({ commit }, weakFlag) { + commit('TOGGLE_WEAK', weakFlag) + }, + ToggleMultiTab ({ commit }, bool) { + commit('TOGGLE_MULTI_TAB', bool) + } + } +} + +export default app diff --git a/_web/src/store/modules/async-router.js b/_web/src/store/modules/async-router.js new file mode 100644 index 00000000..4491e06a --- /dev/null +++ b/_web/src/store/modules/async-router.js @@ -0,0 +1,33 @@ +/** + * 向后端请求用户的菜单,动态生成路由 + */ +import { constantRouterMap } from '@/config/router.config' +import { generatorDynamicRouter } from '@/router/generator-routers' + +const permission = { + state: { + routers: constantRouterMap, + addRouters: [] + }, + mutations: { + SET_ROUTERS: (state, routers) => { + state.addRouters = routers + state.routers = constantRouterMap.concat(routers) + } + }, + actions: { + GenerateRoutes ({ commit }, data) { + return new Promise(resolve => { + generatorDynamicRouter(data).then(routers => { + commit('SET_ROUTERS', routers) + resolve() + }) + }).catch(err => { + // eslint-disable-next-line no-undef + reject(err) + }) + } + } +} + +export default permission diff --git a/_web/src/store/modules/permission.js b/_web/src/store/modules/permission.js new file mode 100644 index 00000000..0e5e5c3e --- /dev/null +++ b/_web/src/store/modules/permission.js @@ -0,0 +1,77 @@ +import { asyncRouterMap, constantRouterMap } from '@/config/router.config' + +/** + * 过滤账户是否拥有某一个权限,并将菜单从加载列表移除 + * + * @param permission + * @param route + * @returns {boolean} + */ +function hasPermission (permission, route) { + // if (route.meta && route.meta.permission) { + // let flag = false + // for (let i = 0, len = permission.length; i < len; i++) { + // flag = route.meta.permission.includes(permission[i]) + // if (flag) { + // return true + // } + // } + // return false + // } + return true +} + +/** + * 单账户多角色时,使用该方法可过滤角色不存在的菜单 + * + * @param roles + * @param route + * @returns {*} + */ +// eslint-disable-next-line +function hasRole(roles, route) { + if (route.meta && route.meta.roles) { + return route.meta.roles.includes(roles.id) + } else { + return true + } +} + +function filterAsyncRouter (routerMap, roles) { + const accessedRouters = routerMap.filter(route => { + if (hasPermission(roles.permissionList, route)) { + if (route.children && route.children.length) { + route.children = filterAsyncRouter(route.children, roles) + } + return true + } + return false + }) + return accessedRouters +} + +const permission = { + state: { + routers: constantRouterMap, + addRouters: [] + }, + mutations: { + SET_ROUTERS: (state, routers) => { + state.addRouters = routers + state.routers = constantRouterMap.concat(routers) + } + }, + actions: { + GenerateRoutes ({ commit }, data) { + return new Promise(resolve => { + const { roles } = data + const accessedRouters = filterAsyncRouter(asyncRouterMap, roles) + // console.log('动态获取到的菜单列表:'+JSON.stringify(accessedRouters)) + commit('SET_ROUTERS', accessedRouters) + resolve() + }) + } + } +} + +export default permission diff --git a/_web/src/store/modules/user.js b/_web/src/store/modules/user.js new file mode 100644 index 00000000..0382b32d --- /dev/null +++ b/_web/src/store/modules/user.js @@ -0,0 +1,172 @@ +import Vue from 'vue' +import { login, getLoginUser, logout } from '@/api/modular/system/loginManage' +import { sysDictTypeTree } from '@/api/modular/system/dictManage' +import { sysMenuChange } from '@/api/modular/system/menuManage' +import { ACCESS_TOKEN, ALL_APPS_MENU, DICT_TYPE_TREE_DATA } from '@/store/mutation-types' + +import { welcome } from '@/utils/util' +import store from '../index' +import router from '../../router' + +const user = { + state: { + token: '', + name: '', + welcome: '', + avatar: '', + buttons: [], // 按钮权限 + admintype: '', // 是否是超管 + roles: [], + info: {} + }, + + mutations: { + SET_TOKEN: (state, token) => { + state.token = token + }, + SET_NAME: (state, { name, welcome }) => { + state.name = name + state.welcome = welcome + }, + SET_AVATAR: (state, avatar) => { + state.avatar = avatar + }, + SET_ROLES: (state, roles) => { + state.roles = roles + }, + SET_INFO: (state, info) => { + state.info = info + }, + SET_BUTTONS: (state, buttons) => { + state.buttons = buttons + }, + SET_ADMINTYPE: (state, admintype) => { + state.admintype = admintype + } + }, + + actions: { + // 登录 + Login ({ commit }, userInfo) { + return new Promise((resolve, reject) => { + login(userInfo).then(response => { + if (!response.success) { + reject(response.message) + return + } + const result = response.data + Vue.ls.set(ACCESS_TOKEN, result, 7 * 24 * 60 * 60 * 1000) + commit('SET_TOKEN', result) + resolve() + // eslint-disable-next-line handle-callback-err + }).catch(error => { + // eslint-disable-next-line prefer-promise-reject-errors + reject('后端未启动或代理错误') + }) + }) + }, + + // 获取用户信息 + GetInfo ({ commit }) { + return new Promise((resolve, reject) => { + getLoginUser().then(response => { + if (response.success) { + const data = response.data + commit('SET_ADMINTYPE', data.adminType) + commit('SET_ROLES', 1) + commit('SET_BUTTONS', data.permissions) + commit('SET_INFO', data) + commit('SET_NAME', { name: data.name, welcome: welcome() }) + if (data.avatar != null) { + commit('SET_AVATAR', process.env.VUE_APP_API_BASE_URL + '/sysFileInfo/preview?id=' + data.avatar) + } + resolve(data) + } else { + // eslint-disable-next-line no-undef + reject(new Error(data.message)) + } + }).catch(error => { + reject(error) + }) + }) + }, + + // 登出 + Logout ({ commit, state }) { + return new Promise((resolve) => { + logout(state.token).then(() => { + resolve() + }).catch(() => { + resolve() + }).finally(() => { + commit('SET_TOKEN', '') + commit('SET_ROLES', []) + commit('SET_BUTTONS', []) + commit('SET_ADMINTYPE', '') + Vue.ls.remove(ACCESS_TOKEN) + Vue.ls.remove(ALL_APPS_MENU) + Vue.ls.remove(DICT_TYPE_TREE_DATA) + }) + }) + }, + + // 加载所有字典数据 + dictTypeData () { + return new Promise((resolve, reject) => { + sysDictTypeTree().then((data) => { + if (data.success) { + const result = data.data + Vue.ls.set(DICT_TYPE_TREE_DATA, result) + resolve() + } else { + // eslint-disable-next-line no-undef + reject(new Error(data.message)) + } + }).catch(error => { + reject(error) + }) + }) + }, + + // 切换应用菜单 + MenuChange ({ commit }, application) { + return new Promise((resolve) => { + sysMenuChange({ application: application.code }).then((res) => { + const apps = { 'code': '', 'name': '', 'active': '', 'menu': '' } + apps.active = true + apps.menu = res.data + // eslint-disable-next-line camelcase + const all_app_menu = Vue.ls.get(ALL_APPS_MENU) + // eslint-disable-next-line camelcase + const new_false_all_app_menu = [] + // 先去除所有默认的,以为此时切换的即将成为前端缓存默认的应用 + all_app_menu.forEach(item => { + if (item.active) { + item.active = false + } + new_false_all_app_menu.push(item) + }) + // 此时缓存中全部都是不默认的应用 + Vue.ls.set(ALL_APPS_MENU, new_false_all_app_menu) + apps.name = application.name + apps.code = application.code + const applocationR = [] + applocationR.push(apps) + Vue.ls.set(ALL_APPS_MENU, applocationR) + resolve(res) + const antDesignmenus = res.data + store.dispatch('GenerateRoutes', { antDesignmenus }).then(() => { + router.addRoutes(store.getters.addRouters) + }) + // 切换应用刷新整体界面,暂且取消 + // window.location.reload() + }).catch(() => { + resolve() + }) + }) + } + + } +} + +export default user diff --git a/_web/src/store/mutation-types.js b/_web/src/store/mutation-types.js new file mode 100644 index 00000000..819c3125 --- /dev/null +++ b/_web/src/store/mutation-types.js @@ -0,0 +1,18 @@ +export const ACCESS_TOKEN = 'Access-Token' +export const SIDEBAR_TYPE = 'SIDEBAR_TYPE' +export const ALL_APPS_MENU = 'ALL_APPS_MENU' +export const DEFAULT_THEME = 'DEFAULT_THEME' +export const DEFAULT_LAYOUT_MODE = 'DEFAULT_LAYOUT_MODE' +export const DEFAULT_COLOR = 'DEFAULT_COLOR' +export const DEFAULT_COLOR_WEAK = 'DEFAULT_COLOR_WEAK' +export const DEFAULT_FIXED_HEADER = 'DEFAULT_FIXED_HEADER' +export const DEFAULT_FIXED_SIDEMENU = 'DEFAULT_FIXED_SIDEMENU' +export const DEFAULT_FIXED_HEADER_HIDDEN = 'DEFAULT_FIXED_HEADER_HIDDEN' +export const DEFAULT_CONTENT_WIDTH_TYPE = 'DEFAULT_CONTENT_WIDTH_TYPE' +export const DEFAULT_MULTI_TAB = 'DEFAULT_MULTI_TAB' +export const DICT_TYPE_TREE_DATA = 'DICT_TYPE_TREE_DATA' + +export const CONTENT_WIDTH_TYPE = { + Fluid: 'Fluid', + Fixed: 'Fixed' +} diff --git a/_web/src/utils/applocation.js b/_web/src/utils/applocation.js new file mode 100644 index 00000000..30fdc289 --- /dev/null +++ b/_web/src/utils/applocation.js @@ -0,0 +1,11 @@ +import store from '@/store' + +/** + * 缓存中的已选中应用 + * + * @author yubaoshan + * @date 2020/06/27 02:34 + */ +export function sysApplication () { + return store.getters.applocation +} diff --git a/_web/src/utils/axios.js b/_web/src/utils/axios.js new file mode 100644 index 00000000..3b91f6b5 --- /dev/null +++ b/_web/src/utils/axios.js @@ -0,0 +1,35 @@ +const VueAxios = { + vm: {}, + // eslint-disable-next-line no-unused-vars + install (Vue, instance) { + if (this.installed) { + return + } + this.installed = true + + if (!instance) { + // eslint-disable-next-line no-console + console.error('You have to install axios') + return + } + + Vue.axios = instance + + Object.defineProperties(Vue.prototype, { + axios: { + get: function get () { + return instance + } + }, + $http: { + get: function get () { + return instance + } + } + }) + } +} + +export { + VueAxios +} diff --git a/_web/src/utils/device.js b/_web/src/utils/device.js new file mode 100644 index 00000000..0f350f36 --- /dev/null +++ b/_web/src/utils/device.js @@ -0,0 +1,33 @@ +import enquireJs from 'enquire.js' + +export const DEVICE_TYPE = { + DESKTOP: 'desktop', + TABLET: 'tablet', + MOBILE: 'mobile' +} + +export const deviceEnquire = function (callback) { + const matchDesktop = { + match: () => { + callback && callback(DEVICE_TYPE.DESKTOP) + } + } + + const matchLablet = { + match: () => { + callback && callback(DEVICE_TYPE.TABLET) + } + } + + const matchMobile = { + match: () => { + callback && callback(DEVICE_TYPE.MOBILE) + } + } + + // screen and (max-width: 1087.99px) + enquireJs + .register('screen and (max-width: 576px)', matchMobile) + .register('screen and (min-width: 576px) and (max-width: 1199px)', matchLablet) + .register('screen and (min-width: 1200px)', matchDesktop) +} diff --git a/_web/src/utils/domUtil.js b/_web/src/utils/domUtil.js new file mode 100644 index 00000000..47996707 --- /dev/null +++ b/_web/src/utils/domUtil.js @@ -0,0 +1,19 @@ +export const setDocumentTitle = function (title) { + document.title = title + const ua = navigator.userAgent + // eslint-disable-next-line + const regex = /\bMicroMessenger\/([\d\.]+)/ + if (regex.test(ua) && /ip(hone|od|ad)/i.test(ua)) { + const i = document.createElement('iframe') + i.src = '/favicon.ico' + i.style.display = 'none' + i.onload = function () { + setTimeout(function () { + i.remove() + }, 9) + } + document.body.appendChild(i) + } +} + +export const domTitle = 'XiaoNuo' diff --git a/_web/src/utils/filter.js b/_web/src/utils/filter.js new file mode 100644 index 00000000..09b629f6 --- /dev/null +++ b/_web/src/utils/filter.js @@ -0,0 +1,91 @@ +import Vue from 'vue' +import { DICT_TYPE_TREE_DATA } from '@/store/mutation-types' +import moment from 'moment' +import 'moment/locale/zh-cn' +moment.locale('zh-cn') + +Vue.filter('NumberFormat', function (value) { + if (!value) { + return '0' + } + const intPartFormat = value.toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,') // 将整数部分逢三一断 + return intPartFormat +}) + +Vue.filter('dayjs', function (dataStr, pattern = 'YYYY-MM-DD HH:mm:ss') { + return moment(dataStr).format(pattern) +}) + +Vue.filter('moment', function (dataStr, pattern = 'YYYY-MM-DD HH:mm:ss') { + return moment(dataStr).format(pattern) +}) + +/** + * 金额格式化 ,使用方法:{{ val | Fmoney }} + * + * @author yubaoshan + * @date 2020-9-15 15:02:20 + */ +Vue.filter('Fmoney', function (val) { + // eslint-disable-next-line no-useless-escape + val = val.toString().replace(/\$|\,/g, '') + if (isNaN(val)) { + val = '0' + } + // eslint-disable-next-line eqeqeq + const sign = (val == (val = Math.abs(val))) + val = Math.floor(val * 100 + 0.50000000001) + let cents = val % 100 + val = Math.floor(val / 100).toString() + if (cents < 10) { + cents = '0' + cents + } + // eslint-disable-next-line no-undef + for (let i = 0; i < Math.floor((val.length - (1 + i)) / 3); I++) { + val = val.substring(0, val.length - (4 * i + 3)) + ',' + val.substring(val.length - (4 * i + 3)) + } + return (((sign) ? '' : '-') + val + '.' + cents) +}) + +/** + * 翻译使用方法,直接返回翻译后的name {{ code | dictType(value) }} + * + * @author yubaoshan + * @date 2020-9-15 15:02:20 + */ +Vue.filter('dictType', function (code, value) { + const dictTypeTree = Vue.ls.get(DICT_TYPE_TREE_DATA) + if (dictTypeTree === undefined) { + return '需重新登录' + } + // eslint-disable-next-line eqeqeq + const tree = dictTypeTree.filter(item => item.code == code)[0].children + if (tree === undefined || tree.length === 0) { + return '无此字典' + } + // eslint-disable-next-line eqeqeq + const values = tree.filter(item => item.code == value) + if (values.length === undefined || values.length === 0) { + return '无此字典' + } + return values[0].name +}) + +/** + * 获取某个code下字典的列表,多用于字典下拉框,使用方法:{{ code | dictData }} + * + * @author yubaoshan + * @date 2020-9-19 22:40:22 + */ +Vue.filter('dictData', function (code) { + const dictTypeTree = Vue.ls.get(DICT_TYPE_TREE_DATA) + if (dictTypeTree === undefined) { + return [] + } + // eslint-disable-next-line eqeqeq + const tree = dictTypeTree.filter(item => item.code == code)[0].children + if (tree === undefined) { + return [] + } + return tree +}) diff --git a/_web/src/utils/helper/permission.js b/_web/src/utils/helper/permission.js new file mode 100644 index 00000000..f0f6a32c --- /dev/null +++ b/_web/src/utils/helper/permission.js @@ -0,0 +1,51 @@ +export const PERMISSION_ENUM = { + 'add': { key: 'add', label: '新增' }, + 'delete': { key: 'delete', label: '删除' }, + 'edit': { key: 'edit', label: '修改' }, + 'query': { key: 'query', label: '查询' }, + 'get': { key: 'get', label: '详情' }, + 'enable': { key: 'enable', label: '启用' }, + 'disable': { key: 'disable', label: '禁用' }, + 'import': { key: 'import', label: '导入' }, + 'export': { key: 'export', label: '导出' } +} + +function plugin (Vue) { + if (plugin.installed) { + return + } + + !Vue.prototype.$auth && Object.defineProperties(Vue.prototype, { + $auth: { + get () { + const _this = this + return (permissions) => { + const [permission, action] = permissions.split('.') + const permissionList = _this.$store.getters.roles.permissions + return permissionList.find((val) => { + return val.permissionId === permission + }).actionList.findIndex((val) => { + return val === action + }) > -1 + } + } + } + }) + + !Vue.prototype.$enum && Object.defineProperties(Vue.prototype, { + $enum: { + get () { + // const _this = this; + return (val) => { + let result = PERMISSION_ENUM + val && val.split('.').forEach(v => { + result = result && result[v] || null + }) + return result + } + } + } + }) +} + +export default plugin diff --git a/_web/src/utils/mixin.js b/_web/src/utils/mixin.js new file mode 100644 index 00000000..217732d2 --- /dev/null +++ b/_web/src/utils/mixin.js @@ -0,0 +1,76 @@ +// import Vue from 'vue' +import { deviceEnquire, DEVICE_TYPE } from '@/utils/device' +import { mapState } from 'vuex' + +// const mixinsComputed = Vue.config.optionMergeStrategies.computed +// const mixinsMethods = Vue.config.optionMergeStrategies.methods + +const mixin = { + computed: { + ...mapState({ + layoutMode: state => state.app.layout, + navTheme: state => state.app.theme, + primaryColor: state => state.app.color, + colorWeak: state => state.app.weak, + fixedHeader: state => state.app.fixedHeader, + fixSiderbar: state => state.app.fixSiderbar, + fixSidebar: state => state.app.fixSiderbar, + contentWidth: state => state.app.contentWidth, + autoHideHeader: state => state.app.autoHideHeader, + sidebarOpened: state => state.app.sidebar, + multiTab: state => state.app.multiTab + }) + }, + methods: { + isTopMenu () { + return this.layoutMode === 'topmenu' + }, + isSideMenu () { + return !this.isTopMenu() + } + } +} + +const mixinDevice = { + computed: { + ...mapState({ + device: state => state.app.device + }) + }, + methods: { + isMobile () { + return this.device === DEVICE_TYPE.MOBILE + }, + isDesktop () { + return this.device === DEVICE_TYPE.DESKTOP + }, + isTablet () { + return this.device === DEVICE_TYPE.TABLET + } + } +} + +const AppDeviceEnquire = { + mounted () { + const { $store } = this + deviceEnquire(deviceType => { + switch (deviceType) { + case DEVICE_TYPE.DESKTOP: + $store.commit('TOGGLE_DEVICE', 'desktop') + $store.dispatch('setSidebar', true) + break + case DEVICE_TYPE.TABLET: + $store.commit('TOGGLE_DEVICE', 'tablet') + $store.dispatch('setSidebar', false) + break + case DEVICE_TYPE.MOBILE: + default: + $store.commit('TOGGLE_DEVICE', 'mobile') + $store.dispatch('setSidebar', true) + break + } + }) + } +} + +export { mixin, AppDeviceEnquire, mixinDevice } diff --git a/_web/src/utils/permissions.js b/_web/src/utils/permissions.js new file mode 100644 index 00000000..ce0376fd --- /dev/null +++ b/_web/src/utils/permissions.js @@ -0,0 +1,26 @@ +import store from '@/store' + +export function actionToObject (json) { + try { + return JSON.parse(json) + } catch (e) { + console.log('err', e.message) + } + return [] +} + +/** + * 控制按钮是否显示 + * + * @author yubaoshan + * @date 2020/06/27 02:34 + */ +export function hasBtnPermission (permission) { + const myBtns = store.getters.buttons + const admintype = store.getters.admintype + // eslint-disable-next-line eqeqeq + if (admintype == '1') { + return true + } + return myBtns.indexOf(permission) > -1 +} diff --git a/_web/src/utils/request.js b/_web/src/utils/request.js new file mode 100644 index 00000000..b59a59e8 --- /dev/null +++ b/_web/src/utils/request.js @@ -0,0 +1,94 @@ +import Vue from 'vue' +import axios from 'axios' +import store from '@/store' +import { message, Modal, notification } from 'ant-design-vue' /// es/notification +import { VueAxios } from './axios' +import { ACCESS_TOKEN } from '@/store/mutation-types' + +// 创建 axios 实例 +const service = axios.create({ + baseURL: '/api', // api base_url + timeout: 6000 // 请求超时时间 +}) + +const err = (error) => { + if (error.response) { + const data = error.response.data + const token = Vue.ls.get(ACCESS_TOKEN) + + if (error.response.status === 403) { + console.log('服务器403啦,要重新登录!') + notification.error({ + message: 'Forbidden', + description: data.message + }) + } + if (error.response.status === 500) { + if (data.message.length > 0) { + message.error(data.message) + } + } + if (error.response.status === 401 && !(data.result && data.result.isLogin)) { + notification.error({ + message: 'Unauthorized', + description: 'Authorization verification failed' + }) + if (token) { + store.dispatch('Logout').then(() => { + setTimeout(() => { + window.location.reload() + }, 1500) + }) + } + } + } + return Promise.reject(error) +} + +// request interceptor +service.interceptors.request.use(config => { + const token = Vue.ls.get(ACCESS_TOKEN) + if (token) { + config.headers['Authorization'] = 'Bearer ' + token + } + return config +}, err) + +/** + * response interceptor + * 所有请求统一返回 + */ +service.interceptors.response.use((response) => { + if (response.request.responseType === 'blob') { + return response + } + const code = response.data.code + if (code === 1011006 || code === 1011007 || code === 1011008 || code === 1011009) { + Modal.error({ + title: '提示:', + content: response.data.message, + okText: '重新登录', + onOk: () => { + Vue.ls.remove(ACCESS_TOKEN) + window.location.reload() + } + }) + } else if (code === 1013002 || code === 1016002 || code === 1015002) { + message.error(response.data.message) + return response.data + } else { + return response.data + } +}, err) + +const installer = { + vm: {}, + install (Vue) { + Vue.use(VueAxios, service) + } +} + +export { + installer as VueAxios, + service as axios +} diff --git a/_web/src/utils/routeConvert.js b/_web/src/utils/routeConvert.js new file mode 100644 index 00000000..e88b0d6d --- /dev/null +++ b/_web/src/utils/routeConvert.js @@ -0,0 +1,30 @@ +import cloneDeep from 'lodash.clonedeep' + +export function convertRoutes (nodes) { + if (!nodes) return null + + nodes = cloneDeep(nodes) + + let queue = Array.isArray(nodes) ? nodes.concat() : [nodes] + + while (queue.length) { + const levelSize = queue.length + + for (let i = 0; i < levelSize; i++) { + const node = queue.shift() + + if (!node.children || !node.children.length) continue + + node.children.forEach(child => { + // 转化相对路径 + if (child.path[0] !== '/' && !child.path.startsWith('http')) { + child.path = node.path.replace(/(\w*)[/]*$/, `$1/${child.path}`) + } + }) + + queue = queue.concat(node.children) + } + } + + return nodes +} diff --git a/_web/src/utils/util.js b/_web/src/utils/util.js new file mode 100644 index 00000000..311f7461 --- /dev/null +++ b/_web/src/utils/util.js @@ -0,0 +1,67 @@ +export function timeFix () { + const time = new Date() + const hour = time.getHours() + return hour < 9 ? '早上好' : hour <= 11 ? '上午好' : hour <= 13 ? '中午好' : hour < 20 ? '下午好' : '晚上好' +} + +export function welcome () { + const arr = ['休息一会儿吧', '准备吃什么呢?', '要不要打一把 LOL', '我猜你可能累了'] + const index = Math.floor(Math.random() * arr.length) + return arr[index] +} + +/** + * 触发 window.resize + */ +export function triggerWindowResizeEvent () { + const event = document.createEvent('HTMLEvents') + event.initEvent('resize', true, true) + event.eventType = 'message' + window.dispatchEvent(event) +} + +export function handleScrollHeader (callback) { + let timer = 0 + + let beforeScrollTop = window.pageYOffset + callback = callback || function () {} + window.addEventListener( + 'scroll', + event => { + clearTimeout(timer) + timer = setTimeout(() => { + let direction = 'up' + const afterScrollTop = window.pageYOffset + const delta = afterScrollTop - beforeScrollTop + if (delta === 0) { + return false + } + direction = delta > 0 ? 'down' : 'up' + callback(direction) + beforeScrollTop = afterScrollTop + }, 50) + }, + false + ) +} + +export function isIE () { + const bw = window.navigator.userAgent + const compare = (s) => bw.indexOf(s) >= 0 + const ie11 = (() => 'ActiveXObject' in window)() + return compare('MSIE') || ie11 +} + +/** + * Remove loading animate + * @param id parent element id or class + * @param timeout + */ +export function removeLoadingAnimate (id = '', timeout = 1500) { + if (id === '') { + return + } + setTimeout(() => { + document.body.removeChild(document.getElementById(id)) + }, timeout) +} diff --git a/_web/src/utils/utils.less b/_web/src/utils/utils.less new file mode 100644 index 00000000..ba75a67f --- /dev/null +++ b/_web/src/utils/utils.less @@ -0,0 +1,50 @@ +.textOverflow() { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + word-break: break-all; +} + +.textOverflowMulti(@line: 3, @bg: #fff) { + position: relative; + max-height: @line * 1.5em; + margin-right: -1em; + padding-right: 1em; + overflow: hidden; + line-height: 1.5em; + text-align: justify; + &::before { + position: absolute; + right: 14px; + bottom: 0; + padding: 0 1px; + background: @bg; + content: '...'; + } + &::after { + position: absolute; + right: 14px; + width: 1em; + height: 1em; + margin-top: 0.2em; + background: white; + content: ''; + } +} + +// mixins for clearfix +// ------------------------ +.clearfix() { + zoom: 1; + &::before, + &::after { + display: table; + content: ' '; + } + &::after { + clear: both; + height: 0; + font-size: 0; + visibility: hidden; + } +} \ No newline at end of file diff --git a/_web/src/views/404.vue b/_web/src/views/404.vue new file mode 100644 index 00000000..8c1d8a18 --- /dev/null +++ b/_web/src/views/404.vue @@ -0,0 +1,15 @@ + + + + + diff --git a/_web/src/views/Home.vue b/_web/src/views/Home.vue new file mode 100644 index 00000000..f67c95f5 --- /dev/null +++ b/_web/src/views/Home.vue @@ -0,0 +1,215 @@ + + + + + diff --git a/_web/src/views/main/README.md b/_web/src/views/main/README.md new file mode 100644 index 00000000..fadf99a4 --- /dev/null +++ b/_web/src/views/main/README.md @@ -0,0 +1 @@ +/** 您的业务接口文件全写在此文件夹下面,升级底座直接迁移代码即可 **/ diff --git a/_web/src/views/system/README.md b/_web/src/views/system/README.md new file mode 100644 index 00000000..46aab4d5 --- /dev/null +++ b/_web/src/views/system/README.md @@ -0,0 +1 @@ +/** 此文件夹下代码尽量不要动,底座升级直接覆盖替换 **/ diff --git a/_web/src/views/system/account/center/Index.vue b/_web/src/views/system/account/center/Index.vue new file mode 100644 index 00000000..bb1a1cdc --- /dev/null +++ b/_web/src/views/system/account/center/Index.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/_web/src/views/system/account/center/page/App.vue b/_web/src/views/system/account/center/page/App.vue new file mode 100644 index 00000000..853aeab7 --- /dev/null +++ b/_web/src/views/system/account/center/page/App.vue @@ -0,0 +1,113 @@ + + + + + diff --git a/_web/src/views/system/account/center/page/Article.vue b/_web/src/views/system/account/center/page/Article.vue new file mode 100644 index 00000000..a53d23ca --- /dev/null +++ b/_web/src/views/system/account/center/page/Article.vue @@ -0,0 +1,63 @@ + + + + + diff --git a/_web/src/views/system/account/center/page/Project.vue b/_web/src/views/system/account/center/page/Project.vue new file mode 100644 index 00000000..145232fb --- /dev/null +++ b/_web/src/views/system/account/center/page/Project.vue @@ -0,0 +1,109 @@ + + + + + diff --git a/_web/src/views/system/account/center/page/index.js b/_web/src/views/system/account/center/page/index.js new file mode 100644 index 00000000..b579b6a3 --- /dev/null +++ b/_web/src/views/system/account/center/page/index.js @@ -0,0 +1,5 @@ +import AppPage from './App' +import ArticlePage from './Article' +import ProjectPage from './Project' + +export { AppPage, ArticlePage, ProjectPage } diff --git a/_web/src/views/system/account/settings/AvatarModal.vue b/_web/src/views/system/account/settings/AvatarModal.vue new file mode 100644 index 00000000..289c9d03 --- /dev/null +++ b/_web/src/views/system/account/settings/AvatarModal.vue @@ -0,0 +1,183 @@ + + + + diff --git a/_web/src/views/system/account/settings/BaseSetting.vue b/_web/src/views/system/account/settings/BaseSetting.vue new file mode 100644 index 00000000..c7b11cf2 --- /dev/null +++ b/_web/src/views/system/account/settings/BaseSetting.vue @@ -0,0 +1,216 @@ + + + + + diff --git a/_web/src/views/system/account/settings/Binding.vue b/_web/src/views/system/account/settings/Binding.vue new file mode 100644 index 00000000..cbea7fc0 --- /dev/null +++ b/_web/src/views/system/account/settings/Binding.vue @@ -0,0 +1,25 @@ + + + + + diff --git a/_web/src/views/system/account/settings/Custom.vue b/_web/src/views/system/account/settings/Custom.vue new file mode 100644 index 00000000..c235570f --- /dev/null +++ b/_web/src/views/system/account/settings/Custom.vue @@ -0,0 +1,75 @@ + + + diff --git a/_web/src/views/system/account/settings/Index.vue b/_web/src/views/system/account/settings/Index.vue new file mode 100644 index 00000000..8db2efb6 --- /dev/null +++ b/_web/src/views/system/account/settings/Index.vue @@ -0,0 +1,155 @@ + + + + + diff --git a/_web/src/views/system/account/settings/Notification.vue b/_web/src/views/system/account/settings/Notification.vue new file mode 100644 index 00000000..cbea7fc0 --- /dev/null +++ b/_web/src/views/system/account/settings/Notification.vue @@ -0,0 +1,25 @@ + + + + + diff --git a/_web/src/views/system/account/settings/Security.vue b/_web/src/views/system/account/settings/Security.vue new file mode 100644 index 00000000..2d3b6509 --- /dev/null +++ b/_web/src/views/system/account/settings/Security.vue @@ -0,0 +1,70 @@ + + + + + diff --git a/_web/src/views/system/account/settings/securityItem/updPwd.vue b/_web/src/views/system/account/settings/securityItem/updPwd.vue new file mode 100644 index 00000000..a3bbcb17 --- /dev/null +++ b/_web/src/views/system/account/settings/securityItem/updPwd.vue @@ -0,0 +1,115 @@ + + + diff --git a/_web/src/views/system/app/addForm.vue b/_web/src/views/system/app/addForm.vue new file mode 100644 index 00000000..513f0305 --- /dev/null +++ b/_web/src/views/system/app/addForm.vue @@ -0,0 +1,99 @@ + + + diff --git a/_web/src/views/system/app/editForm.vue b/_web/src/views/system/app/editForm.vue new file mode 100644 index 00000000..e36a7037 --- /dev/null +++ b/_web/src/views/system/app/editForm.vue @@ -0,0 +1,116 @@ + + + diff --git a/_web/src/views/system/app/index.vue b/_web/src/views/system/app/index.vue new file mode 100644 index 00000000..2efcd458 --- /dev/null +++ b/_web/src/views/system/app/index.vue @@ -0,0 +1,218 @@ +/* eslint-disable eqeqeq */ + + + + diff --git a/_web/src/views/system/config/addForm.vue b/_web/src/views/system/config/addForm.vue new file mode 100644 index 00000000..9ca74ab3 --- /dev/null +++ b/_web/src/views/system/config/addForm.vue @@ -0,0 +1,140 @@ + + + diff --git a/_web/src/views/system/config/editForm.vue b/_web/src/views/system/config/editForm.vue new file mode 100644 index 00000000..fcb91dc8 --- /dev/null +++ b/_web/src/views/system/config/editForm.vue @@ -0,0 +1,171 @@ + + + diff --git a/_web/src/views/system/config/index.vue b/_web/src/views/system/config/index.vue new file mode 100644 index 00000000..624d9386 --- /dev/null +++ b/_web/src/views/system/config/index.vue @@ -0,0 +1,200 @@ + + + + diff --git a/_web/src/views/system/dashboard/Analysis.vue b/_web/src/views/system/dashboard/Analysis.vue new file mode 100644 index 00000000..6df9244d --- /dev/null +++ b/_web/src/views/system/dashboard/Analysis.vue @@ -0,0 +1,407 @@ + + + + + diff --git a/_web/src/views/system/dashboard/Monitor.vue b/_web/src/views/system/dashboard/Monitor.vue new file mode 100644 index 00000000..2b9c6c1c --- /dev/null +++ b/_web/src/views/system/dashboard/Monitor.vue @@ -0,0 +1,15 @@ + + + + + diff --git a/_web/src/views/system/dashboard/TestWork.vue b/_web/src/views/system/dashboard/TestWork.vue new file mode 100644 index 00000000..ae80f932 --- /dev/null +++ b/_web/src/views/system/dashboard/TestWork.vue @@ -0,0 +1,117 @@ + + + + + diff --git a/_web/src/views/system/dashboard/Workplace.vue b/_web/src/views/system/dashboard/Workplace.vue new file mode 100644 index 00000000..b0770b72 --- /dev/null +++ b/_web/src/views/system/dashboard/Workplace.vue @@ -0,0 +1,526 @@ + + + + + diff --git a/_web/src/views/system/dict/addForm.vue b/_web/src/views/system/dict/addForm.vue new file mode 100644 index 00000000..94dad704 --- /dev/null +++ b/_web/src/views/system/dict/addForm.vue @@ -0,0 +1,106 @@ + + + diff --git a/_web/src/views/system/dict/dictdata/addForm.vue b/_web/src/views/system/dict/dictdata/addForm.vue new file mode 100644 index 00000000..2dce343c --- /dev/null +++ b/_web/src/views/system/dict/dictdata/addForm.vue @@ -0,0 +1,123 @@ + + + diff --git a/_web/src/views/system/dict/dictdata/editForm.vue b/_web/src/views/system/dict/dictdata/editForm.vue new file mode 100644 index 00000000..a6bfeb1d --- /dev/null +++ b/_web/src/views/system/dict/dictdata/editForm.vue @@ -0,0 +1,137 @@ + + + diff --git a/_web/src/views/system/dict/dictdata/index.vue b/_web/src/views/system/dict/dictdata/index.vue new file mode 100644 index 00000000..ebac8bef --- /dev/null +++ b/_web/src/views/system/dict/dictdata/index.vue @@ -0,0 +1,200 @@ + + + + + diff --git a/_web/src/views/system/dict/editForm.vue b/_web/src/views/system/dict/editForm.vue new file mode 100644 index 00000000..49ee823c --- /dev/null +++ b/_web/src/views/system/dict/editForm.vue @@ -0,0 +1,128 @@ + + + diff --git a/_web/src/views/system/dict/index.vue b/_web/src/views/system/dict/index.vue new file mode 100644 index 00000000..77b0d827 --- /dev/null +++ b/_web/src/views/system/dict/index.vue @@ -0,0 +1,197 @@ + + + + + diff --git a/_web/src/views/system/email/index.vue b/_web/src/views/system/email/index.vue new file mode 100644 index 00000000..73f33092 --- /dev/null +++ b/_web/src/views/system/email/index.vue @@ -0,0 +1,189 @@ + + + + + diff --git a/_web/src/views/system/exception/403.vue b/_web/src/views/system/exception/403.vue new file mode 100644 index 00000000..ffc3799c --- /dev/null +++ b/_web/src/views/system/exception/403.vue @@ -0,0 +1,17 @@ + + + + + diff --git a/_web/src/views/system/exception/404.vue b/_web/src/views/system/exception/404.vue new file mode 100644 index 00000000..16f767f4 --- /dev/null +++ b/_web/src/views/system/exception/404.vue @@ -0,0 +1,17 @@ + + + + + diff --git a/_web/src/views/system/exception/500.vue b/_web/src/views/system/exception/500.vue new file mode 100644 index 00000000..cc5d7ab1 --- /dev/null +++ b/_web/src/views/system/exception/500.vue @@ -0,0 +1,17 @@ + + + + + diff --git a/_web/src/views/system/file/detailForm.vue b/_web/src/views/system/file/detailForm.vue new file mode 100644 index 00000000..f25b7197 --- /dev/null +++ b/_web/src/views/system/file/detailForm.vue @@ -0,0 +1,99 @@ + + diff --git a/_web/src/views/system/file/index.vue b/_web/src/views/system/file/index.vue new file mode 100644 index 00000000..2673c04c --- /dev/null +++ b/_web/src/views/system/file/index.vue @@ -0,0 +1,256 @@ + + + diff --git a/_web/src/views/system/file/previewForm.vue b/_web/src/views/system/file/previewForm.vue new file mode 100644 index 00000000..f125b93c --- /dev/null +++ b/_web/src/views/system/file/previewForm.vue @@ -0,0 +1,60 @@ + + diff --git a/_web/src/views/system/index/welcome.vue b/_web/src/views/system/index/welcome.vue new file mode 100644 index 00000000..a5c75754 --- /dev/null +++ b/_web/src/views/system/index/welcome.vue @@ -0,0 +1,15 @@ + + + + + diff --git a/_web/src/views/system/log/oplog/details.vue b/_web/src/views/system/log/oplog/details.vue new file mode 100644 index 00000000..c7ddd8df --- /dev/null +++ b/_web/src/views/system/log/oplog/details.vue @@ -0,0 +1,137 @@ + + diff --git a/_web/src/views/system/log/oplog/index.vue b/_web/src/views/system/log/oplog/index.vue new file mode 100644 index 00000000..a00f1b0a --- /dev/null +++ b/_web/src/views/system/log/oplog/index.vue @@ -0,0 +1,206 @@ + + + diff --git a/_web/src/views/system/log/vislog/details.vue b/_web/src/views/system/log/vislog/details.vue new file mode 100644 index 00000000..697c7d8f --- /dev/null +++ b/_web/src/views/system/log/vislog/details.vue @@ -0,0 +1,57 @@ + + diff --git a/_web/src/views/system/log/vislog/index.vue b/_web/src/views/system/log/vislog/index.vue new file mode 100644 index 00000000..fba9d8ff --- /dev/null +++ b/_web/src/views/system/log/vislog/index.vue @@ -0,0 +1,207 @@ + + + diff --git a/_web/src/views/system/machine/index.vue b/_web/src/views/system/machine/index.vue new file mode 100644 index 00000000..0500b2d4 --- /dev/null +++ b/_web/src/views/system/machine/index.vue @@ -0,0 +1,139 @@ + + + + + diff --git a/_web/src/views/system/menu/addForm.vue b/_web/src/views/system/menu/addForm.vue new file mode 100644 index 00000000..30cad95b --- /dev/null +++ b/_web/src/views/system/menu/addForm.vue @@ -0,0 +1,567 @@ + + + diff --git a/_web/src/views/system/menu/editForm.vue b/_web/src/views/system/menu/editForm.vue new file mode 100644 index 00000000..714b24ee --- /dev/null +++ b/_web/src/views/system/menu/editForm.vue @@ -0,0 +1,627 @@ + + + diff --git a/_web/src/views/system/menu/index.vue b/_web/src/views/system/menu/index.vue new file mode 100644 index 00000000..db91301b --- /dev/null +++ b/_web/src/views/system/menu/index.vue @@ -0,0 +1,188 @@ +/* eslint-disable */ + + + + diff --git a/_web/src/views/system/notice/addForm.vue b/_web/src/views/system/notice/addForm.vue new file mode 100644 index 00000000..e6e41ea3 --- /dev/null +++ b/_web/src/views/system/notice/addForm.vue @@ -0,0 +1,213 @@ + + + diff --git a/_web/src/views/system/notice/detailForm.vue b/_web/src/views/system/notice/detailForm.vue new file mode 100644 index 00000000..dc837b06 --- /dev/null +++ b/_web/src/views/system/notice/detailForm.vue @@ -0,0 +1,60 @@ + + diff --git a/_web/src/views/system/notice/editForm.vue b/_web/src/views/system/notice/editForm.vue new file mode 100644 index 00000000..604df460 --- /dev/null +++ b/_web/src/views/system/notice/editForm.vue @@ -0,0 +1,240 @@ + + + diff --git a/_web/src/views/system/notice/index.vue b/_web/src/views/system/notice/index.vue new file mode 100644 index 00000000..bd823ca6 --- /dev/null +++ b/_web/src/views/system/notice/index.vue @@ -0,0 +1,206 @@ + + + diff --git a/_web/src/views/system/noticeReceived/detailForm.vue b/_web/src/views/system/noticeReceived/detailForm.vue new file mode 100644 index 00000000..00340ce4 --- /dev/null +++ b/_web/src/views/system/noticeReceived/detailForm.vue @@ -0,0 +1,75 @@ + + + + diff --git a/_web/src/views/system/noticeReceived/index.vue b/_web/src/views/system/noticeReceived/index.vue new file mode 100644 index 00000000..a99bc553 --- /dev/null +++ b/_web/src/views/system/noticeReceived/index.vue @@ -0,0 +1,169 @@ + + + + + diff --git a/_web/src/views/system/onlineUser/index.vue b/_web/src/views/system/onlineUser/index.vue new file mode 100644 index 00000000..c3c33621 --- /dev/null +++ b/_web/src/views/system/onlineUser/index.vue @@ -0,0 +1,127 @@ + + + diff --git a/_web/src/views/system/org/addForm.vue b/_web/src/views/system/org/addForm.vue new file mode 100644 index 00000000..f037dc1b --- /dev/null +++ b/_web/src/views/system/org/addForm.vue @@ -0,0 +1,149 @@ + + + diff --git a/_web/src/views/system/org/editForm.vue b/_web/src/views/system/org/editForm.vue new file mode 100644 index 00000000..029d4e1f --- /dev/null +++ b/_web/src/views/system/org/editForm.vue @@ -0,0 +1,171 @@ + + + diff --git a/_web/src/views/system/org/index.vue b/_web/src/views/system/org/index.vue new file mode 100644 index 00000000..998eeae4 --- /dev/null +++ b/_web/src/views/system/org/index.vue @@ -0,0 +1,219 @@ + + + + + diff --git a/_web/src/views/system/pos/addForm.vue b/_web/src/views/system/pos/addForm.vue new file mode 100644 index 00000000..765eb756 --- /dev/null +++ b/_web/src/views/system/pos/addForm.vue @@ -0,0 +1,106 @@ + + + diff --git a/_web/src/views/system/pos/editForm.vue b/_web/src/views/system/pos/editForm.vue new file mode 100644 index 00000000..2fe56718 --- /dev/null +++ b/_web/src/views/system/pos/editForm.vue @@ -0,0 +1,129 @@ + + + diff --git a/_web/src/views/system/pos/index.vue b/_web/src/views/system/pos/index.vue new file mode 100644 index 00000000..4d3b8f60 --- /dev/null +++ b/_web/src/views/system/pos/index.vue @@ -0,0 +1,155 @@ + + + + + diff --git a/_web/src/views/system/role/addForm.vue b/_web/src/views/system/role/addForm.vue new file mode 100644 index 00000000..faa9f10e --- /dev/null +++ b/_web/src/views/system/role/addForm.vue @@ -0,0 +1,106 @@ + + + diff --git a/_web/src/views/system/role/editForm.vue b/_web/src/views/system/role/editForm.vue new file mode 100644 index 00000000..58513f93 --- /dev/null +++ b/_web/src/views/system/role/editForm.vue @@ -0,0 +1,128 @@ + + + diff --git a/_web/src/views/system/role/index.vue b/_web/src/views/system/role/index.vue new file mode 100644 index 00000000..37a9b0df --- /dev/null +++ b/_web/src/views/system/role/index.vue @@ -0,0 +1,164 @@ + + + + + diff --git a/_web/src/views/system/role/roleMenuForm.vue b/_web/src/views/system/role/roleMenuForm.vue new file mode 100644 index 00000000..bdcacd66 --- /dev/null +++ b/_web/src/views/system/role/roleMenuForm.vue @@ -0,0 +1,154 @@ + + + diff --git a/_web/src/views/system/role/roleOrgForm.vue b/_web/src/views/system/role/roleOrgForm.vue new file mode 100644 index 00000000..61f6235c --- /dev/null +++ b/_web/src/views/system/role/roleOrgForm.vue @@ -0,0 +1,197 @@ + + + diff --git a/_web/src/views/system/sms/index.vue b/_web/src/views/system/sms/index.vue new file mode 100644 index 00000000..04d6d82d --- /dev/null +++ b/_web/src/views/system/sms/index.vue @@ -0,0 +1,173 @@ + + + + + diff --git a/_web/src/views/system/timers/addForm.vue b/_web/src/views/system/timers/addForm.vue new file mode 100644 index 00000000..9927aa5c --- /dev/null +++ b/_web/src/views/system/timers/addForm.vue @@ -0,0 +1,126 @@ + + + diff --git a/_web/src/views/system/timers/editForm.vue b/_web/src/views/system/timers/editForm.vue new file mode 100644 index 00000000..ea8ef52e --- /dev/null +++ b/_web/src/views/system/timers/editForm.vue @@ -0,0 +1,151 @@ + + + diff --git a/_web/src/views/system/timers/index.vue b/_web/src/views/system/timers/index.vue new file mode 100644 index 00000000..e177bc93 --- /dev/null +++ b/_web/src/views/system/timers/index.vue @@ -0,0 +1,205 @@ + + + diff --git a/_web/src/views/system/user/addForm.vue b/_web/src/views/system/user/addForm.vue new file mode 100644 index 00000000..cb36da38 --- /dev/null +++ b/_web/src/views/system/user/addForm.vue @@ -0,0 +1,467 @@ + + + diff --git a/_web/src/views/system/user/editForm.vue b/_web/src/views/system/user/editForm.vue new file mode 100644 index 00000000..a204c5db --- /dev/null +++ b/_web/src/views/system/user/editForm.vue @@ -0,0 +1,493 @@ +/* eslint-disable vue/no-template-shadow */ + + diff --git a/_web/src/views/system/user/index.vue b/_web/src/views/system/user/index.vue new file mode 100644 index 00000000..0606b278 --- /dev/null +++ b/_web/src/views/system/user/index.vue @@ -0,0 +1,328 @@ + + + + + diff --git a/_web/src/views/system/user/userOrgForm.vue b/_web/src/views/system/user/userOrgForm.vue new file mode 100644 index 00000000..8c839dc7 --- /dev/null +++ b/_web/src/views/system/user/userOrgForm.vue @@ -0,0 +1,150 @@ + + + diff --git a/_web/src/views/system/user/userRoleForm.vue b/_web/src/views/system/user/userRoleForm.vue new file mode 100644 index 00000000..8aaf363f --- /dev/null +++ b/_web/src/views/system/user/userRoleForm.vue @@ -0,0 +1,116 @@ + + + diff --git a/_web/src/views/userLoginReg/Login.vue b/_web/src/views/userLoginReg/Login.vue new file mode 100644 index 00000000..1ceec988 --- /dev/null +++ b/_web/src/views/userLoginReg/Login.vue @@ -0,0 +1,311 @@ + + + + + diff --git a/_web/src/views/userLoginReg/Register.vue b/_web/src/views/userLoginReg/Register.vue new file mode 100644 index 00000000..2b202649 --- /dev/null +++ b/_web/src/views/userLoginReg/Register.vue @@ -0,0 +1,322 @@ + + + + + diff --git a/_web/src/views/userLoginReg/RegisterResult.vue b/_web/src/views/userLoginReg/RegisterResult.vue new file mode 100644 index 00000000..5a807e08 --- /dev/null +++ b/_web/src/views/userLoginReg/RegisterResult.vue @@ -0,0 +1,50 @@ + + + + + diff --git a/_web/tests/unit/.eslintrc.js b/_web/tests/unit/.eslintrc.js new file mode 100644 index 00000000..958d51ba --- /dev/null +++ b/_web/tests/unit/.eslintrc.js @@ -0,0 +1,5 @@ +module.exports = { + env: { + jest: true + } +} diff --git a/_web/vue.config.js b/_web/vue.config.js new file mode 100644 index 00000000..0bd9a55d --- /dev/null +++ b/_web/vue.config.js @@ -0,0 +1,114 @@ +const path = require('path') +const webpack = require('webpack') +const createThemeColorReplacerPlugin = require('./config/plugin.config') + +function resolve (dir) { + return path.join(__dirname, dir) +} + +const isProd = process.env.NODE_ENV === 'production' + +const assetsCDN = { + // webpack build externals + externals: { + vue: 'Vue', + 'vue-router': 'VueRouter', + vuex: 'Vuex', + axios: 'axios' + }, + css: [], + // https://unpkg.com/browse/vue@2.6.10/ + js: [ + '//cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.min.js', + '//cdn.jsdelivr.net/npm/vue-router@3.1.3/dist/vue-router.min.js', + '//cdn.jsdelivr.net/npm/vuex@3.1.1/dist/vuex.min.js', + '//cdn.jsdelivr.net/npm/axios@0.19.0/dist/axios.min.js' + ] +} + +// vue.config.js +const vueConfig = { + configureWebpack: { + // webpack plugins + plugins: [ + // Ignore all locale files of moment.js + new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/) + ], + // if prod, add externals + externals: isProd ? assetsCDN.externals : {} + }, + + chainWebpack: (config) => { + config.resolve.alias + .set('@$', resolve('src')) + + const svgRule = config.module.rule('svg') + svgRule.uses.clear() + svgRule + .oneOf('inline') + .resourceQuery(/inline/) + .use('vue-svg-icon-loader') + .loader('vue-svg-icon-loader') + .end() + .end() + .oneOf('external') + .use('file-loader') + .loader('file-loader') + .options({ + name: 'assets/[name].[hash:8].[ext]' + }) + + // if prod is on + // assets require on cdn + if (isProd) { + config.plugin('html').tap(args => { + args[0].cdn = assetsCDN + return args + }) + } + }, + + css: { + loaderOptions: { + less: { + modifyVars: { + 'primary-color': '#1890FF', + 'layout-color': '#1890FF', + 'border-radius-base': '2px' + }, + // DO NOT REMOVE THIS LINE + javascriptEnabled: true + } + } + }, + + devServer: { + port: 81, + proxy: { + '/api': { + target: process.env.VUE_APP_API_BASE_URL, + ws: false, + changeOrigin: true, + pathRewrite: { + '^/api': '' // 需要rewrite的, + } + } + } + }, + + // disable source map in production + productionSourceMap: false, + lintOnSave: undefined, + // babel-loader no-ignore node_modules/* + transpileDependencies: [] +} + +// preview.pro.loacg.com only do not use in your production; +if (process.env.VUE_APP_PREVIEW === 'true') { + // eslint-disable-next-line no-labels + // runtimeCompiler: true, + // add `ThemeColorReplacer` plugin to webpack plugins + vueConfig.configureWebpack.plugins.push(createThemeColorReplacerPlugin()) +} + +module.exports = vueConfig diff --git a/_web/webstorm.config.js b/_web/webstorm.config.js new file mode 100644 index 00000000..91174556 --- /dev/null +++ b/_web/webstorm.config.js @@ -0,0 +1,3 @@ +'use strict' +const webpackConfig = require('@vue/cli-service/webpack.config.js') +module.exports = webpackConfig diff --git a/pom.xml b/pom.xml new file mode 100644 index 00000000..9adab4d7 --- /dev/null +++ b/pom.xml @@ -0,0 +1,256 @@ + + + 4.0.0 + + + org.springframework.boot + spring-boot-starter-parent + 2.3.1.RELEASE + + + cn.xiaonuo + xiaonuo-vue + 1.1.0 + + xiaonuo-vue + xiaonuo-vue版本 + + pom + + + xiaonuo-base + xiaonuo-main + + + + UTF-8 + UTF-8 + 8.0.17 + 1.1.21 + 3.3.2 + 1.2.70 + 0.9.1 + 5.3.7 + 1.18.12 + 2.9.2 + 1.9.6 + 4.2.0 + 4.2.0 + 6.4.3 + 1.15.6 + 3.8.0 + 5.6.23 + 4.4.6 + 4.17.6 + 3.1.57 + + + + + + + + + com.baomidou + mybatis-plus-boot-starter + ${mp.version} + + + + + mysql + mysql-connector-java + ${mysql-connector-java.version} + + + + + com.alibaba + druid + ${druid.version} + + + + + io.jsonwebtoken + jjwt + ${jwt.version} + + + + + com.alibaba + fastjson + ${fastjson.version} + + + + + cn.hutool + hutool-all + ${hutool.version} + + + + + org.projectlombok + lombok + ${lombok.versin} + + + + + io.springfox + springfox-swagger2 + ${swagger.version} + + + io.springfox + springfox-swagger-ui + ${swagger.version} + + + com.github.xiaoymin + swagger-bootstrap-ui + ${swagger.bootstrap.ui.version} + + + + + cn.afterturn + easypoi-base + ${easypoi.version} + + + + + org.jodconverter + jodconverter-core + ${jodconverter.version} + + + org.jodconverter + jodconverter-local + ${jodconverter.version} + + + org.jodconverter + jodconverter-spring-boot-starter + ${jodconverter.version} + + + org.libreoffice + ridl + ${libreoffice.version} + + + + + me.zhyd.oauth + JustAuth + ${justauth.version} + + + + + com.aliyun.oss + aliyun-sdk-oss + ${aliyun.oss.version} + + + + + com.qcloud + cos_api + ${qcloud.oss.version} + + + + + com.aliyun + aliyun-java-sdk-core + ${aliyun.sms.sdk.version} + + + com.aliyun + aliyun-java-sdk-ecs + ${aliyun.sms.esc.version} + + + + + com.tencentcloudapi + tencentcloud-sdk-java + ${qcloud.sms.sdk.version} + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + ${java.version} + ${java.version} + + + + org.apache.maven.plugins + maven-resources-plugin + + + @ + + false + + + + + + src/main/webapp + false + + + src/main/resources + true + + + src/main/java + + **/*.xml + + + + + + + + local + + local + + + true + + + + dev + + dev + + + + prod + + prod + + + + + diff --git a/xiaonuo-base/README.md b/xiaonuo-base/README.md new file mode 100644 index 00000000..e47621ab --- /dev/null +++ b/xiaonuo-base/README.md @@ -0,0 +1 @@ +** 此模块大家尽量不要动,升级的时候只要将XiaoNuo的包覆盖此模块即可 ** diff --git a/xiaonuo-base/pom.xml b/xiaonuo-base/pom.xml new file mode 100644 index 00000000..74a1749b --- /dev/null +++ b/xiaonuo-base/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + + + cn.xiaonuo + xiaonuo-vue + 1.1.0 + ../pom.xml + + + xiaonuo-base + + pom + + + xiaonuo-core + xiaonuo-system + + + diff --git a/xiaonuo-base/xiaonuo-core/README.md b/xiaonuo-base/xiaonuo-core/README.md new file mode 100644 index 00000000..10004527 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/README.md @@ -0,0 +1,3 @@ +** 本模块是其他模块都会引用的模块,存放一些通用的工具类,枚举类,实体等 ** + +** 工具类能用hutool的用hutool不要自己封装 ** \ No newline at end of file diff --git a/xiaonuo-base/xiaonuo-core/pom.xml b/xiaonuo-base/xiaonuo-core/pom.xml new file mode 100644 index 00000000..7a80434c --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/pom.xml @@ -0,0 +1,142 @@ + + + 4.0.0 + + + cn.xiaonuo + xiaonuo-base + 1.1.0 + ../pom.xml + + + xiaonuo-core + + jar + + + + + + org.springframework.boot + spring-boot-starter-validation + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-aop + + + + + org.springframework.boot + spring-boot-starter-security + + + + + mysql + mysql-connector-java + + + + + com.alibaba + druid + + + + + com.baomidou + mybatis-plus-boot-starter + + + + + cn.hutool + hutool-all + + + + + org.projectlombok + lombok + + + + + com.alibaba + fastjson + + + + + cn.afterturn + easypoi-base + + + + + org.jodconverter + jodconverter-core + + + org.jodconverter + jodconverter-local + + + org.jodconverter + jodconverter-spring-boot-starter + + + org.libreoffice + ridl + + + + + me.zhyd.oauth + JustAuth + + + + + com.aliyun.oss + aliyun-sdk-oss + + + + + com.qcloud + cos_api + + + + + com.aliyun + aliyun-java-sdk-core + + + com.aliyun + aliyun-java-sdk-ecs + + + + + com.tencentcloudapi + tencentcloud-sdk-java + + + + + ${project.artifactId} + + diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/annotion/BusinessLog.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/annotion/BusinessLog.java new file mode 100644 index 00000000..b1dafeeb --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/annotion/BusinessLog.java @@ -0,0 +1,51 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.annotion; + +import com.cn.xiaonuo.core.enums.LogAnnotionOpTypeEnum; + +import java.lang.annotation.*; + +/** + * 标记需要做业务日志的方法 + * + * @author yubaoshan + * @date 2017/3/31 12:46 + */ +@Inherited +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD}) +public @interface BusinessLog { + + /** + * 业务的名称,例如:"修改菜单" + */ + String title() default ""; + + /** + * 业务操作类型枚举 + */ + LogAnnotionOpTypeEnum opType() default LogAnnotionOpTypeEnum.OTHER; +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/annotion/DataScope.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/annotion/DataScope.java new file mode 100644 index 00000000..3a8bd667 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/annotion/DataScope.java @@ -0,0 +1,39 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.annotion; + +import java.lang.annotation.*; + +/** + * 数据权限注解 + * + * @author xuyuxiang + * @date 2020/3/28 17:16 + */ +@Inherited +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD}) +public @interface DataScope { +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/annotion/ExpEnumType.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/annotion/ExpEnumType.java new file mode 100644 index 00000000..464b70aa --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/annotion/ExpEnumType.java @@ -0,0 +1,56 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.annotion; + +import java.lang.annotation.*; + +/** + * 标识在ExceptionEnum类上,用来标识类级别异常枚举编码 + *

+ * 异常枚举编码由3部分组成,如下: + *

+ * 模块编码(2位) + 分类编码(4位) + 具体项编码(至少1位) + *

+ * 模块编码和分类编码在ExpEnumCodeConstant类中声明 + * + * @author yubaoshan + * @date 2020/6/19 20:46 + */ +@Inherited +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE}) +public @interface ExpEnumType { + + /** + * 模块编码 + */ + int module() default 99; + + /** + * 分类编码 + */ + int kind() default 9999; + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/annotion/Permission.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/annotion/Permission.java new file mode 100644 index 00000000..46e05ad1 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/annotion/Permission.java @@ -0,0 +1,53 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.annotion; + +import com.cn.xiaonuo.core.enums.LogicTypeEnum; +import com.cn.xiaonuo.core.enums.LogicTypeEnum; + +import java.lang.annotation.*; + +/** + * 权限注解,用于检查权限 + * 使用方式:@Permission表示检查是否有权限访问该资源 + * + * @author xuyuxiang + * @date 2020/3/11 14:44 + */ +@Inherited +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD}) +public @interface Permission { + + /** + * 加上此注解表示需要有该资源url的才可以访问, 默认值为空,即该url,如果设置了值,则表示有该角色才可以访问 + */ + String[] value() default {}; + + /** + * 逻辑枚举,默认或 + */ + LogicTypeEnum logicType() default LogicTypeEnum.OR; +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/annotion/Wrapper.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/annotion/Wrapper.java new file mode 100644 index 00000000..6e56dd40 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/annotion/Wrapper.java @@ -0,0 +1,48 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.annotion; + +import com.cn.xiaonuo.core.pojo.base.wrapper.BaseWrapper; +import com.cn.xiaonuo.core.pojo.base.wrapper.BaseWrapper; + +import java.lang.annotation.*; + +/** + * 结果包装的注解,一般用在Controller层,给最后响应结果做包装 + * + * @author xuyuxiang + * @date 2020/7/24 17:10 + */ +@Inherited +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD}) +public @interface Wrapper { + + /** + * 具体包装类 + */ + Class>[] value(); + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/cache/CacheOperator.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/cache/CacheOperator.java new file mode 100644 index 00000000..2e1b275c --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/cache/CacheOperator.java @@ -0,0 +1,118 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.cache; + +import java.util.Collection; +import java.util.Map; + +/** + * 缓存操作的基础接口,可以实现不同种缓存实现 + *

+ * 泛型为cache的值类class类型 + * + * @author yubaoshan + * @date 2020/7/8 22:02 + */ +public interface CacheOperator { + + /** + * 添加缓存 + * + * @param key 键 + * @param value 值 + * @author yubaoshan + * @date 2020/7/8 22:06 + */ + void put(String key, T value); + + /** + * 添加缓存(带过期时间,单位是秒) + * + * @param key 键 + * @param value 值 + * @param timeoutSeconds 过期时间,单位秒 + * @author yubaoshan + * @date 2020/7/8 22:07 + */ + void put(String key, T value, Long timeoutSeconds); + + /** + * 通过缓存key获取缓存 + * + * @param key 键 + * @return 值 + * @author yubaoshan + * @date 2020/7/8 22:08 + */ + Object get(String key); + + /** + * 删除缓存 + * + * @param key 键,多个 + * @author yubaoshan + * @date 2020/7/8 22:09 + */ + void remove(String... key); + + /** + * 获得缓存的所有key列表(不带common prefix的) + * + * @return key列表 + * @author yubaoshan + * @date 2020/7/8 22:11 + */ + Collection getAllKeys(); + + /** + * 获得缓存的所有值列表 + * + * @return 值列表 + * @author yubaoshan + * @date 2020/7/8 22:11 + */ + Collection getAllValues(); + + /** + * 获取所有的key,value + * + * @return 键值map + * @author yubaoshan + * @date 2020/7/8 22:11 + */ + Map getAllKeyValues(); + + /** + * 通用缓存的前缀,用于区分不同业务 + *

+ * 如果带了前缀,所有的缓存在添加的时候,key都会带上这个前缀 + * + * @return 缓存前缀 + * @author yubaoshan + * @date 2020/7/9 11:06 + */ + String getCommonKeyPrefix(); + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/consts/AopSortConstant.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/consts/AopSortConstant.java new file mode 100644 index 00000000..fe24e901 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/consts/AopSortConstant.java @@ -0,0 +1,72 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.consts; + +/** + * aop顺序的常量 + *

+ * 顺序越小越靠前 + * + * @author yubaoshan + * @date 2020/4/10 15:33 + */ +public interface AopSortConstant { + + /** + * 全局异常拦截器 + */ + int GLOBAL_EXP_HANDLER_AOP = -120; + + /** + * 结果包装的aop + */ + int WRAPPER_AOP = -110; + + /** + * 接口资源权限校验 + */ + int PERMISSION_AOP = -100; + + /** + * 数据范围AOP + */ + int DATA_SCOPE_AOP = -50; + + /** + * 多租户的aop + */ + int TENANT_EXCHANGE_AOP = -10; + + /** + * 多数据源切换的aop + */ + int MULTI_DATA_SOURCE_AOP = 1; + + /** + * 业务日志的AOP + */ + int BUSINESS_LOG_AOP = 100; + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/consts/CommonConstant.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/consts/CommonConstant.java new file mode 100644 index 00000000..6a32b6da --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/consts/CommonConstant.java @@ -0,0 +1,109 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.consts; + +/** + * 通用常量 + * + * @author xuyuxiang + * @date 2020/3/11 16:51 + */ +public interface CommonConstant { + + /** + * id + */ + String ID = "id"; + + /** + * 名称 + */ + String NAME = "name"; + + /** + * 编码 + */ + String CODE = "code"; + + /** + * 值 + */ + String VALUE = "value"; + + /** + * 默认标识状态的字段名称 + */ + String STATUS = "status"; + + /** + * 默认逻辑删除的状态值 + */ + String DEFAULT_LOGIC_DELETE_VALUE = "2"; + + /** + * 用户代理 + */ + String USER_AGENT = "User-Agent"; + + /** + * 请求头token表示 + */ + String AUTHORIZATION = "Authorization"; + + /** + * token名称 + */ + String TOKEN_NAME = "token"; + + /** + * token类型 + */ + String TOKEN_TYPE_BEARER = "Bearer"; + + /** + * 首页提示语 + */ + String INDEX_TIPS = "Welcome To XiaoNuo"; + + /** + * 未知标识 + */ + String UNKNOWN = "Unknown"; + + /** + * 默认包名 + */ + String DEFAULT_PACKAGE_NAME = "com.cn.xiaonuo"; + + /** + * 默认密码 + */ + String DEFAULT_PASSWORD = "123456"; + + /** + * 请求号在header中的唯一标识 + */ + String REQUEST_NO_HEADER_NAME = "Request-No"; +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/consts/ExpEnumConstant.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/consts/ExpEnumConstant.java new file mode 100644 index 00000000..c116c516 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/consts/ExpEnumConstant.java @@ -0,0 +1,89 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.consts; + +/** + * 异常枚举编码构成常量 + *

+ * 异常枚举编码由3部分组成,如下: + *

+ * 模块编码(2位) + 分类编码(4位) + 具体项编码(至少1位) + *

+ * 模块编码和分类编码在ExpEnumCodeConstant类中声明 + * + * @author yubaoshan + * @date 2020/6/19 20:46 + */ +public interface ExpEnumConstant { + + /** + * 模块分类编码(2位) + *

+ * xiaonuo-core模块异常枚举编码 + */ + int XIAONUO_CORE_MODULE_EXP_CODE = 10; + + /* 分类编码(4位) */ + /** + * 认证异常枚举 + */ + int AUTH_EXCEPTION_ENUM = 1100; + + /** + * 参数校验异常枚举 + */ + int PARAM_EXCEPTION_ENUM = 1200; + + /** + * 授权和鉴权异常的枚举 + */ + int PERMISSION_EXCEPTION_ENUM = 1300; + + /** + * 请求方法相关异常枚举 + */ + int REQUEST_METHOD_EXCEPTION_ENUM = 1400; + + /** + * 请求类型相关异常枚举 + */ + int REQUEST_TYPE_EXCEPTION_ENUM = 1500; + + /** + * 服务器内部相关异常枚举 + */ + int SERVER_EXCEPTION_ENUM = 1600; + + /** + * 状态相关异常枚举 + */ + int STATUS_EXCEPTION_ENUM = 1700; + + /** + * 包装相关异常枚举 + */ + int WRAPPER_EXCEPTION_ENUM = 1800; + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/consts/MediaTypeConstant.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/consts/MediaTypeConstant.java new file mode 100644 index 00000000..f9287227 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/consts/MediaTypeConstant.java @@ -0,0 +1,99 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.consts; + +/** + * 常用媒体类型常量 + * + * @author xuyuxiang + * @date 2020/7/9 14:14 + */ +public interface MediaTypeConstant { + + /** + * 图片jpg格式 + */ + String IMG_JPG = "jpg"; + + /** + * 图片png格式 + */ + String IMG_PNG = "png"; + + /** + * 图片jpeg格式 + */ + String IMG_JPEG = "jpeg"; + + /** + * 图片tif格式 + */ + String IMG_TIF = "tif"; + + /** + * 图片gif格式 + */ + String IMG_GIF = "gif"; + + /** + * 图片bmp格式 + */ + String IMG_BMP = "bmp"; + + /** + * 文档txt格式 + */ + String DOC_TXT = "txt"; + + /** + * 文档doc格式 + */ + String DOC_DOC = "doc"; + + /** + * 文档docx格式 + */ + String DOC_DOCX = "docx"; + + /** + * 文档xls格式 + */ + String DOC_XLS = "xls"; + + /** + * 文档xlsx格式 + */ + String DOC_XLSX = "xlsx"; + + /** + * 文档ppt格式 + */ + String DOC_PPT = "ppt"; + + /** + * 文档pptx格式 + */ + String DOC_PPTX = "pptx"; +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/consts/SpringSecurityConstant.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/consts/SpringSecurityConstant.java new file mode 100644 index 00000000..4f9a85c9 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/consts/SpringSecurityConstant.java @@ -0,0 +1,68 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.consts; + +/** + * SpringSecurity相关常量 + * + * @author xuyuxiang + * @date 2020/3/18 17:49 + */ +public interface SpringSecurityConstant { + + /** + * 放开权限校验的接口 + */ + String[] NONE_SECURITY_URL_PATTERNS = { + + //前端的 + "/favicon.ico", + + //swagger相关的 + "/doc.html", + "/webjars/**", + "/swagger-resources/**", + "/v2/api-docs", + "/v2/api-docs-ext", + "/configuration/ui", + "/configuration/security", + + //后端的 + "/", + "/login", + "/logout", + "/oauth/**", + + //文件的 + "/sysFileInfo/upload", + "/sysFileInfo/download", + "/sysFileInfo/preview", + + //druid的 + "/druid/**", + + }; + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/consts/SymbolConstant.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/consts/SymbolConstant.java new file mode 100644 index 00000000..fe9401ab --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/consts/SymbolConstant.java @@ -0,0 +1,90 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.consts; + +/** + * 符号常量 + * + * @author xuyuxiang + * @date 2020/3/16 12:05 + */ +public interface SymbolConstant { + + String PERIOD = "."; + + String COMMA = ","; + + String COLON = ":"; + + String SEMICOLON = ";"; + + String EXCLAMATION_MARK = "!"; + + String QUESTION_MARK = "?"; + + String HYPHEN = "-"; + + String ASTERISK = "*"; + + String APOSTROPHE = "`"; + + String DASH = "-"; + + String UNDER_SCORE = "_"; + + String SINGLE_QUOTATION_MARK = "'"; + + String DOUBLE_QUOTATION_MARK = "\""; + + String LEFT_ROUND_BRACKETS = "("; + + String RIGHT_ROUND_BRACKETS = ")"; + + String LEFT_SQUARE_BRACKETS = "["; + + String RIGHT_SQUARE_BRACKETS = "]"; + + String LEFT_ANGLE_BRACKETS = "<"; + + String RIGHT_ANGLE_BRACKETS = ">"; + + String LEFT_CURLY_BRACKETS = "{"; + + String RIGHT_CURLY_BRACKETS = "}"; + + String DOLLAR = "$"; + + String PERCENT = "%"; + + String LEFT_DIVIDE = "/"; + + String RIGHT_DIVIDE = "\\"; + + String LEFT_DOUBLE_DIVIDE = "//"; + + String RIGHT_DOUBLE_DIVIDE = "\\\\"; + + String EQUAL = "="; +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/context/constant/ConstantContext.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/context/constant/ConstantContext.java new file mode 100644 index 00000000..104c4ade --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/context/constant/ConstantContext.java @@ -0,0 +1,78 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.context.constant; + +import cn.hutool.core.lang.Dict; +import cn.hutool.core.util.ObjectUtil; + +/** + * 系统参数配置容器 + * + * @author yubaoshan + * @date 2019/6/20 13:37 + */ +public class ConstantContext { + + /** + * 所有的常量,可以增删改查 + */ + private static final Dict CONSTANTS_HOLDER = Dict.create(); + + /** + * 添加系统常量 + * + * @author yubaoshan + * @date 2020/6/20 22:32 + */ + public static void putConstant(String code, Object value) { + if (ObjectUtil.hasEmpty(code, value)) { + return; + } + CONSTANTS_HOLDER.put(code, value); + } + + /** + * 删除常量,系统常量无法删除,在sysConfig已判断 + * + * @author yubaoshan + * @date 2020/6/20 22:32 + */ + public static void deleteConstant(String code) { + if (ObjectUtil.hasEmpty(code)) { + return; + } + CONSTANTS_HOLDER.remove(code); + } + + /** + * 获取系统常量本身 + * + * @author yubaoshan + * @date 2020/6/20 22:32 + */ + public static Dict me() { + return CONSTANTS_HOLDER; + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/context/constant/ConstantContextHolder.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/context/constant/ConstantContextHolder.java new file mode 100644 index 00000000..3ce36e66 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/context/constant/ConstantContextHolder.java @@ -0,0 +1,393 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.context.constant; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.RandomUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.log.Log; +import com.cn.xiaonuo.core.consts.CommonConstant; +import com.cn.xiaonuo.core.consts.SymbolConstant; +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.core.pojo.email.EmailConfigs; +import com.cn.xiaonuo.core.pojo.oauth.OauthConfigs; +import com.cn.xiaonuo.core.pojo.sms.AliyunSmsConfigs; +import com.cn.xiaonuo.core.pojo.sms.TencentSmsConfigs; + +import java.util.List; + +import static com.cn.xiaonuo.core.exception.enums.ServerExceptionEnum.CONSTANT_EMPTY; + +/** + * 系统参数配置获取 + * + * @author xuyuxiang + * @date 2020/4/14 15:34 + */ +public class ConstantContextHolder { + + private static final Log log = Log.get(); + + /** + * 获取租户功能是否开启 + * + * @author xuyuxiang + * @date 2020/9/3 + */ + public static Boolean getTenantOpenFlag() { + return getSysConfigWithDefault("XIAONUO_TENANT_OPEN", Boolean.class, false); + } + + /** + * 获取druid监控的密码 + * + * @author yubaoshan + * @date 2020/7/8 9:53 + */ + public static String getDruidMonitorPassword() { + return getSysConfigWithDefault("XIAONUO_DRUID_PASSWORD", String.class, RandomUtil.randomString(10)); + } + + /** + * 获取druid的账号 + * + * @author yubaoshan + * @date 2020/7/8 9:53 + */ + public static String getDruidMonitorUsername() { + return getSysConfigWithDefault("XIAONUO_DRUID_USERNAME", String.class, RandomUtil.randomString(10)); + } + + /** + * 获取放开xss过滤的接口 + * + * @author yubaoshan + * @date 2020/6/20 22:13 + */ + public static List getUnXssFilterUrl() { + String xiaoNuoUnXssFilterUrl = getSysConfigWithDefault("XIAONUO_UN_XSS_FILTER_URL", String.class, null); + if (ObjectUtil.isEmpty(xiaoNuoUnXssFilterUrl)) { + return CollectionUtil.newArrayList(); + } else { + return CollectionUtil.toList(xiaoNuoUnXssFilterUrl.split(SymbolConstant.COMMA)); + } + } + + /** + * 获取演示环境开关是否开启,默认为false + * + * @author yubaoshan + * @date 2020/6/20 22:13 + */ + public static Boolean getDemoEnvFlag() { + return getSysConfigWithDefault("XIAONUO_DEMO_ENV_FLAG", Boolean.class, false); + } + + /** + * 邮件的配置 + * + * @author yubaoshan + * @date 2020/6/19 18:08 + */ + public static EmailConfigs getEmailConfigs() { + String host = getSysConfig("XIAONUO_EMAIL_HOST", String.class, true); + String username = getSysConfig("XIAONUO_EMAIL_USERNAME", String.class, true); + String password = getSysConfig("XIAONUO_EMAIL_PASSWORD", String.class, true); + Integer port = getSysConfig("XIAONUO_EMAIL_PORT", Integer.class, true); + String from = getSysConfig("XIAONUO_EMAIL_FROM", String.class, true); + Boolean ssl = getSysConfig("XIAONUO_EMAIL_SSL", Boolean.class, true); + + EmailConfigs emailConfigs = new EmailConfigs(); + emailConfigs.setHost(host); + emailConfigs.setUser(username); + emailConfigs.setPass(password); + emailConfigs.setPort(port); + emailConfigs.setFrom(from); + emailConfigs.setSslEnable(ssl); + return emailConfigs; + } + + /** + * 获取腾讯云短信的配置 + * + * @author yubaoshan + * @date 2020/6/19 18:08 + */ + public static TencentSmsConfigs getTencentSmsConfigs() { + String xiaoNuoTencentSmsSecretId = getSysConfig("XIAONUO_TENCENT_SMS_SECRET_ID", String.class, true); + String xiaoNuoTencentSmsSecretKey = getSysConfig("XIAONUO_TENCENT_SMS_SECRET_KEY", String.class, true); + String xiaoNuoTencentSmsSdkAppId = getSysConfig("XIAONUO_TENCENT_SMS_SDK_APP_ID", String.class, true); + String xiaoNuoTencentSmsSign = getSysConfig("XIAONUO_TENCENT_SMS_SIGN", String.class, true); + + TencentSmsConfigs tencentSmsConfigs = new TencentSmsConfigs(); + tencentSmsConfigs.setSecretId(xiaoNuoTencentSmsSecretId); + tencentSmsConfigs.setSecretKey(xiaoNuoTencentSmsSecretKey); + tencentSmsConfigs.setSdkAppId(xiaoNuoTencentSmsSdkAppId); + tencentSmsConfigs.setSign(xiaoNuoTencentSmsSign); + return tencentSmsConfigs; + } + + /** + * 获取阿里云短信的配置 + * + * @author yubaoshan + * @date 2020/6/19 18:08 + */ + public static AliyunSmsConfigs getAliyunSmsConfigs() { + String xiaoNuoSmsAccesskeyId = getSysConfig("XIAONUO_ALIYUN_SMS_ACCESSKEY_ID", String.class, true); + String xiaoNuoSmsAccesskeySecret = getSysConfig("XIAONUO_ALIYUN_SMS_ACCESSKEY_SECRET", String.class, true); + String xiaoNuoSmsSignName = getSysConfig("XIAONUO_ALIYUN_SMS_SIGN_NAME", String.class, true); + String xiaoNuoSmsLoginTemplateCode = getSysConfig("XIAONUO_ALIYUN_SMS_LOGIN_TEMPLATE_CODE", String.class, true); + String xiaoNuoSmsInvalidateMinutes = getSysConfig("XIAONUO_ALIYUN_SMS_INVALIDATE_MINUTES", String.class, true); + + AliyunSmsConfigs aliyunSmsProperties = new AliyunSmsConfigs(); + aliyunSmsProperties.setAccessKeyId(xiaoNuoSmsAccesskeyId); + aliyunSmsProperties.setAccessKeySecret(xiaoNuoSmsAccesskeySecret); + aliyunSmsProperties.setSignName(xiaoNuoSmsSignName); + aliyunSmsProperties.setLoginTemplateCode(xiaoNuoSmsLoginTemplateCode); + aliyunSmsProperties.setInvalidateMinutes(Convert.toInt(xiaoNuoSmsInvalidateMinutes)); + return aliyunSmsProperties; + } + + /** + * 获取jwt密钥,默认是32位随机字符串 + * + * @author yubaoshan + * @date 2020/6/19 18:08 + */ + public static String getJwtSecret() { + return getSysConfigWithDefault("XIAONUO_JWT_SECRET", String.class, RandomUtil.randomString(32)); + } + + /** + * 获取默认密码 + * + * @author yubaoshan + * @date 2020/6/19 18:08 + */ + public static String getDefaultPassWord() { + return getSysConfigWithDefault("XIAONUO_DEFAULT_PASSWORD", String.class, CommonConstant.DEFAULT_PASSWORD); + } + + /** + * 获取会话过期时间,默认2小时 + * + * @author yubaoshan + * @date 2020/7/9 16:18 + */ + public static Long getSessionTokenExpireSec() { + return getSysConfigWithDefault("XIAONUO_SESSION_EXPIRE", Long.class, 2 * 60 * 60L); + } + + /** + * 获取token过期时间(单位:秒) + *

+ * 默认时间1天 + * + * @author xuyuxiang + * @date 2020/6/19 18:08 + */ + public static Long getTokenExpireSec() { + return getSysConfigWithDefault("XIAONUO_TOKEN_EXPIRE", Long.class, 86400L); + } + + /** + * 获取自定义的windows环境本地文件上传路径 + * + * @author xuyuxiang + * @date 2020/6/19 18:09 + */ + public static String getDefaultFileUploadPathForWindows() { + return getSysConfigWithDefault("XIAONUO_FILE_UPLOAD_PATH_FOR_WINDOWS", String.class, ""); + } + + /** + * 获取自定义的linux环境本地文件上传路径 + * + * @author xuyuxiang + * @date 2020/6/19 18:09 + */ + public static String getDefaultFileUploadPathForLinux() { + return getSysConfigWithDefault("XIAONUO_FILE_UPLOAD_PATH_FOR_LINUX", String.class, ""); + } + + /** + * 获取是否允许单用户登陆的开关, 默认为false + * + * @author xuyuxiang + * @date 2020/6/19 18:09 + */ + public static Boolean getEnableSingleLogin() { + return getSysConfigWithDefault("XIAONUO_ENABLE_SINGLE_LOGIN", Boolean.class, false); + } + + /** + * 获取阿里云定位接口 + * + * @author xuyuxiang + * @date 2020/7/20 9:20 + **/ + public static String getIpGeoApi() { + return getSysConfig("XIAONUO_IP_GEO_API", String.class, false); + } + + /** + * 获取阿里云定位appCode + * + * @author xuyuxiang + * @date 2020/7/20 10:33 + **/ + public static String getIpGeoAppCode() { + return getSysConfig("XIAONUO_IP_GEO_APP_CODE", String.class, false); + } + + /** + * 获取Oauth码云第三方登录的配置 + * + * @author xuyuxiang + * @date 2020/7/28 17:16 + **/ + public static OauthConfigs getGiteeOauthConfigs() { + String xiaoNuoClientId = getSysConfig("XIAONUO_OAUTH_GITEE_CLIENT_ID", String.class, true); + String xiaoNuoClientSecret = getSysConfig("XIAONUO_OAUTH_GITEE_CLIENT_SECRET", String.class, true); + String xiaoNuoRedirectUri = getSysConfig("XIAONUO_OAUTH_GITEE_REDIRECT_URI", String.class, true); + + OauthConfigs oauthConfigs = new OauthConfigs(); + oauthConfigs.setClientId(xiaoNuoClientId); + oauthConfigs.setClientSecret(xiaoNuoClientSecret); + oauthConfigs.setRedirectUri(xiaoNuoRedirectUri); + return oauthConfigs; + } + + /** + * 获取OauthGithub第三方登录的配置 + * + * @author xuyuxiang + * @date 2020/7/28 17:16 + **/ + public static OauthConfigs getGithubOauthConfigs() { + String xiaoNuoClientId = getSysConfig("XIAONUO_OAUTH_GITHUB_CLIENT_ID", String.class, true); + String xiaoNuoClientSecret = getSysConfig("XIAONUO_OAUTH_GITHUB_CLIENT_SECRET", String.class, true); + String xiaoNuoRedirectUri = getSysConfig("XIAONUO_OAUTH_GITHUB_REDIRECT_URI", String.class, true); + + OauthConfigs oauthConfigs = new OauthConfigs(); + oauthConfigs.setClientId(xiaoNuoClientId); + oauthConfigs.setClientSecret(xiaoNuoClientSecret); + oauthConfigs.setRedirectUri(xiaoNuoRedirectUri); + return oauthConfigs; + } + + /** + * 获取是否允许Oauth用户登陆的开关, 默认为false + * + * @author xuyuxiang + * @date 2020/7/28 16:37 + **/ + public static Boolean getEnableOauthLogin() { + return getSysConfigWithDefault("XIAONUO_ENABLE_OAUTH_LOGIN", Boolean.class, false); + } + + /** + * 获取前端项目的地址 + * + * @author xuyuxiang + * @date 2020/7/29 14:08 + **/ + public static String getWebUrl() { + return getSysConfig("XIAONUO_WEB_URL", String.class, true); + } + + /** + * 获取支付宝支付成功转发地址 + * + * @author xuyuxiang + * @date 2020/7/29 14:08 + **/ + public static String getAlipayReturnUrl() { + return getSysConfig("XIAONUO_ALIPAY_RETURN_URL", String.class, true); + } + + /** + * 获取config表中的配置,如果为空返回默认值 + * + * @param configCode 变量名称,对应sys_config表中的code + * @param clazz 返回变量值的类型 + * @param defaultValue 如果结果为空返回此默认值 + * @author yubaoshan + * @date 2020/6/20 22:03 + */ + public static T getSysConfigWithDefault(String configCode, Class clazz, T defaultValue) { + String configValue = ConstantContext.me().getStr(configCode); + if (ObjectUtil.isEmpty(configValue)) { + // 将默认值加入到缓存常量 + log.warn(">>> 系统配置sys_config表中存在空项,configCode为:{},系统采用默认值:{}", configCode, defaultValue); + ConstantContext.me().put(configCode, defaultValue); + return defaultValue; + } else { + try { + return Convert.convert(clazz, configValue); + } catch (Exception e) { + return defaultValue; + } + } + } + + /** + * 获取config表中的配置,如果为空,是否抛出异常 + * + * @param configCode 变量名称,对应sys_config表中的code + * @param clazz 返回变量值的类型 + * @param nullThrowExp 若为空是否抛出异常 + * @author yubaoshan + * @date 2020/6/20 22:03 + */ + public static T getSysConfig(String configCode, Class clazz, Boolean nullThrowExp) { + String configValue = ConstantContext.me().getStr(configCode); + if (ObjectUtil.isEmpty(configValue)) { + if (nullThrowExp) { + String format = StrUtil.format(">>> 系统配置sys_config表中存在空项,configCode为:{}", configCode); + log.error(format); + throw new ServiceException(CONSTANT_EMPTY.getCode(), format); + } else { + return null; + } + } else { + try { + return Convert.convert(clazz, configValue); + } catch (Exception e) { + if (nullThrowExp) { + String format = StrUtil.format(">>> 系统配置sys_config表中存在格式错误的值,configCode={},configValue={}", configCode, configValue); + log.error(format); + throw new ServiceException(CONSTANT_EMPTY.getCode(), format); + } else { + return null; + } + } + } + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/context/group/RequestGroupContext.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/context/group/RequestGroupContext.java new file mode 100644 index 00000000..224b27df --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/context/group/RequestGroupContext.java @@ -0,0 +1,67 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.context.group; + +/** + * 保存控制器的方法上的校验group class + * + * @author yubaoshan + * @date 2020/6/21 20:17 + */ +public class RequestGroupContext { + + private static final ThreadLocal> GROUP_CLASS_HOLDER = new ThreadLocal<>(); + + /** + * 设置临时的group class + * + * @author yubaoshan + * @date 2020/6/21 20:17 + */ + public static void set(Class groupValue) { + GROUP_CLASS_HOLDER.set(groupValue); + } + + /** + * 获取临时缓存的group class + * + * @author yubaoshan + * @date 2020/6/21 20:17 + */ + public static Class get() { + return GROUP_CLASS_HOLDER.get(); + } + + /** + * 清除临时缓存的group class + * + * @author yubaoshan + * @date 2020/6/21 20:17 + */ + public static void clear() { + GROUP_CLASS_HOLDER.remove(); + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/context/group/RequestParamIdContext.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/context/group/RequestParamIdContext.java new file mode 100644 index 00000000..113d8e4f --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/context/group/RequestParamIdContext.java @@ -0,0 +1,69 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.context.group; + +/** + * 临时保存参数id字段值,用于唯一性校验 + *

+ * 注意:如果要用@TableUniqueValue这个校验,必须得主键的字段名是id,否则会校验失败 + * + * @author yubaoshan + * @date 2020/6/21 20:17 + */ +public class RequestParamIdContext { + + private static final ThreadLocal PARAM_ID_HOLDER = new ThreadLocal<>(); + + /** + * 设置id + * + * @author yubaoshan + * @date 2020/6/21 20:17 + */ + public static void set(Long id) { + PARAM_ID_HOLDER.set(id); + } + + /** + * 获取id + * + * @author yubaoshan + * @date 2020/6/21 20:17 + */ + public static Long get() { + return PARAM_ID_HOLDER.get(); + } + + /** + * 清除缓存id + * + * @author yubaoshan + * @date 2020/6/21 20:17 + */ + public static void clear() { + PARAM_ID_HOLDER.remove(); + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/context/login/LoginContext.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/context/login/LoginContext.java new file mode 100644 index 00000000..73274510 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/context/login/LoginContext.java @@ -0,0 +1,169 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.context.login; + +import com.cn.xiaonuo.core.pojo.login.SysLoginUser; +import com.cn.xiaonuo.core.pojo.login.SysLoginUser; + +import java.util.List; + +/** + * 登录用户上下文 + * + * @author xuyuxiang + * @date 2020/3/13 12:16 + */ +public interface LoginContext { + + /** + * 获取当前登录用户 + * + * @return 当前登录用户信息 + * @author xuyuxiang + * @date 2020/3/13 14:40 + */ + SysLoginUser getSysLoginUser(); + + /** + * 获取当前登录用户,如未登录,则返回null,不抛异常 + * + * @return 当前登录用户信息 + * @author xuyuxiang + * @date 2020/3/13 14:40 + */ + SysLoginUser getSysLoginUserWithoutException(); + + /** + * 获取当前登录用户的id + * + * @return 当前登录用户的id + * @author xuyuxiang + * @date 2020/3/18 19:25 + */ + Long getSysLoginUserId(); + + /** + * 判断用户是否登录 + * + * @return 是否登录,true是,false否 + * @author xuyuxiang + * @date 2020/3/18 19:22 + */ + boolean hasLogin(); + + /** + * 获取当前登录用户的账户 + * + * @return 当前登陆用户的账户account + * @author xuyuxiang + * @date 2020/3/19 20:37 + */ + String getSysLoginUserAccount(); + + /** + * 判断当前登录用户是否有某资源的访问权限 + * + * @param requestUri 请求的url + * @return 是否有访问权限,true是,false否 + * @author xuyuxiang + * @date 2020/3/23 8:48 + */ + boolean hasPermission(String requestUri); + + /** + * 判断当前登录用户是否包含某个角色 + * + * @param roleCode 角色编码 + * @return 是否包含该角色,true是,false否 + * @author xuyuxiang + * @date 2020/3/23 8:53 + */ + boolean hasRole(String roleCode); + + /** + * 判断当前登录用户是否包含任意一个角色 + * + * @param roleCodes 角色集合,逗号拼接 + * @return 是否包含任一角色,true是,false否 + * @author xuyuxiang + * @date 2020/3/23 8:54 + */ + boolean hasAnyRole(String roleCodes); + + /** + * 判断当前登录用户是否是超级管理员 + * + * @return 当前登录用户是否是超级管理员 + * @author xuyuxiang + * @date 2020/3/23 17:50 + */ + boolean isSuperAdmin(); + + /** + * 判断当前登录用户是否包含所有角色 + * + * @param roleCodes 角色集合,逗号拼接 + * @return 是否包含所有角色,true是,false否 + * @author xuyuxiang + * @date 2020/4/5 10:28 + */ + boolean hasAllRole(String roleCodes); + + /** + * 获取当前登录用户的数据范围集合(组织机构id集合) + * + * @return 数据范围集合(组织机构id集合) + * @author xuyuxiang + * @date 2020/4/5 17:20 + */ + List getLoginUserDataScopeIdList(); + + /** + * 获取当前登录用户的组织机构id + * + * @return 当前登录用户的组织机构id + * @author xuyuxiang + * @date 2020/4/5 18:31 + */ + Long getSysLoginUserOrgId(); + + /** + * 获取当前登录用户的角色id集合 + * + * @return 当前登录用户角色id集合 + * @author xuyuxiang + * @date 2020/4/20 16:04 + */ + List getLoginUserRoleIds(); + + /** + * 获取最新的用户信息,用于修改之后前端获取 + * + * @return 最新的用户信息 + * @author xuyuxiang + * @date 2020/9/20 15:18 + **/ + SysLoginUser getSysLoginUserUpToDate(); +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/context/login/LoginContextHolder.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/context/login/LoginContextHolder.java new file mode 100644 index 00000000..e8574b20 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/context/login/LoginContextHolder.java @@ -0,0 +1,41 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.context.login; + +import cn.hutool.extra.spring.SpringUtil; + +/** + * 当前登录用户信息获取的接口 + * + * @author xuyuxiang + * @date 2020/3/13 12:21 + */ +public class LoginContextHolder { + + public static LoginContext me() { + return SpringUtil.getBean(LoginContext.class); + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/context/param/RequestParamContext.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/context/param/RequestParamContext.java new file mode 100644 index 00000000..e3bb6e65 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/context/param/RequestParamContext.java @@ -0,0 +1,89 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.context.param; + +import cn.hutool.core.lang.Dict; + +/** + * 临时保存http请求的参数 + *

+ * 可以保存@RequestBody的可以保存parameter方式传参的 + * + * @author xuyuxiang + * @date 2020/8/20 + */ +public class RequestParamContext { + + private static final ThreadLocal CONTEXT_HOLDER = new ThreadLocal<>(); + + /** + * 保存请求参数 + * + * @author yubaoshan + * @date 2020/6/21 20:17 + */ + public static void set(Dict requestParam) { + CONTEXT_HOLDER.set(requestParam); + } + + /** + * 保存请求参数 + * + * @author yubaoshan + * @date 2020/6/21 20:17 + */ + public static void setObject(Object requestParam) { + + if (requestParam == null) { + return; + } + + if (requestParam instanceof Dict) { + CONTEXT_HOLDER.set((Dict) requestParam); + } else { + CONTEXT_HOLDER.set(Dict.parse(requestParam)); + } + } + + /** + * 获取请求参数 + * + * @author yubaoshan + * @date 2020/6/21 20:17 + */ + public static Dict get() { + return CONTEXT_HOLDER.get(); + } + + /** + * 清除请求参数 + * + * @author yubaoshan + * @date 2020/6/21 20:17 + */ + public static void clear() { + CONTEXT_HOLDER.remove(); + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/context/requestno/RequestNoContext.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/context/requestno/RequestNoContext.java new file mode 100644 index 00000000..5511c91a --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/context/requestno/RequestNoContext.java @@ -0,0 +1,66 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.context.requestno; + +/** + * 临时保存当前请求号 + * + * @author yubaoshan + * @date 2020/6/21 20:17 + */ +public class RequestNoContext { + + private static final ThreadLocal CONTEXT_HOLDER = new ThreadLocal<>(); + + /** + * 保存请求号 + * + * @author yubaoshan + * @date 2020/6/21 20:17 + */ + public static void set(String requestNo) { + CONTEXT_HOLDER.set(requestNo); + } + + /** + * 获取请求号 + * + * @author yubaoshan + * @date 2020/6/21 20:17 + */ + public static String get() { + return CONTEXT_HOLDER.get(); + } + + /** + * 清除请求号 + * + * @author yubaoshan + * @date 2020/6/21 20:17 + */ + public static void clear() { + CONTEXT_HOLDER.remove(); + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/context/resources/ApiResourceContext.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/context/resources/ApiResourceContext.java new file mode 100644 index 00000000..1a20125b --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/context/resources/ApiResourceContext.java @@ -0,0 +1,93 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.context.resources; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; + +import java.util.Set; + +/** + * 存放本系统所有@RequestMapping的Url + * + * @author yubaoshan + * @date 2020/6/21 17:32 + */ +public class ApiResourceContext { + + /** + * 所有资源的url + */ + private static final Set API_URLS = CollectionUtil.newHashSet(); + + /** + * 添加一批url + * + * @author yubaoshan + * @date 2020/6/21 17:35 + */ + public static void addBatchUrls(Set urls) { + if (ObjectUtil.isEmpty(urls)) { + return; + } + API_URLS.addAll(urls); + } + + /** + * 添加url + * + * @author yubaoshan + * @date 2020/6/21 17:35 + */ + public static void addUrl(String url) { + if (ObjectUtil.isEmpty(url)) { + return; + } + API_URLS.add(url); + } + + /** + * 删除url + * + * @author yubaoshan + * @date 2020/6/21 17:35 + */ + public static void deleteUrl(String url) { + if (ObjectUtil.isEmpty(url)) { + return; + } + API_URLS.remove(url); + } + + /** + * 获取系统的所有url + * + * @author yubaoshan + * @date 2020/6/21 17:36 + */ + public static Set getApiUrls() { + return API_URLS; + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/context/system/SystemContext.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/context/system/SystemContext.java new file mode 100644 index 00000000..31a6ad9d --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/context/system/SystemContext.java @@ -0,0 +1,144 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.context.system; + +import cn.hutool.core.lang.Dict; +import com.cn.xiaonuo.core.pojo.base.validate.UniqueValidateParam; +import com.cn.xiaonuo.core.pojo.login.SysLoginUser; +import com.cn.xiaonuo.core.pojo.base.validate.UniqueValidateParam; +import com.cn.xiaonuo.core.pojo.login.SysLoginUser; + +import java.util.List; + +/** + * 系统相关上下文接口,在system模块实现,用于某些模块不能引用system模块时,通过此方式调用system相关功能 + * + * @author xuyuxiang + * @date 2020/5/6 14:52 + */ +public interface SystemContext { + + /** + * 根据用户id获取姓名 + * + * @param userId 用户id + * @return 用户姓名 + * @author xuyuxiang + * @date 2020/5/6 14:57 + */ + String getNameByUserId(Long userId); + + /** + * 根据角色id获取角色名称 + * + * @param roleId 角色id + * @return 角色名称 + * @author xuyuxiang + * @date 2020/5/22 15:55 + */ + String getNameByRoleId(Long roleId); + + /** + * 根据token获取登录用户信息 + * + * @param token token + * @return 登录用户信息 + * @author xuyuxiang + * @date 2020/3/13 11:59 + */ + SysLoginUser getLoginUserByToken(String token); + + /** + * 根据用户账号模糊搜索系统用户列表 + * + * @param account 账号 + * @return 增强版hashMap,格式:[{"id:":123, "firstName":"张三"}] + * @author xuyuxiang + * @date 2020/6/1 15:12 + */ + List listUser(String account); + + /** + * 根据角色名模糊搜索系统角色列表 + * + * @param name 角色名 + * @return 增强版hashMap,格式:[{"id:":123, "name":"总经理"}] + * @author xuyuxiang + * @date 2020/6/1 15:13 + */ + List listRole(String name); + + /** + * 根据id判断是否是用户 + * + * @param userOrRoleId 用户或角色id + * @return true是 false否 + * @author xuyuxiang + * @date 2020/8/4 20:56 + */ + boolean isUser(Long userOrRoleId); + + /** + * 根据id判断是否是角色 + * + * @param userOrRoleId 用户或角色id + * @return true是 false否 + * @author xuyuxiang + * @date 2020/8/4 20:56 + */ + boolean isRole(Long userOrRoleId); + + /** + * 根据字典类型获取字典的code值 + * + * @param dictTypeCodes 字典类型编码值 + * @return 字典的code值 + * @author xuyuxiang + * @date 2020/8/9 14:18 + */ + List getDictCodesByDictTypeCode(String... dictTypeCodes); + + /** + * 校验某个表中,某一列是否存在重复的值 + *

+ * 一般用于唯一code校验 + * + * @param uniqueValidateParam 被校验的参数 + * @return true-是唯一的值,false-不是唯一的 + * @author xuyuxiang + * @date 2020/8/9 21:41 + */ + boolean tableUniValueFlag(UniqueValidateParam uniqueValidateParam); + + /** + * 获取系统用户id集合 + * + * @return 用户id集合 + * @author xuyuxiang + * @date 2020/9/11 17:53 + **/ + List getAllUserIdList(); + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/context/system/SystemContextHolder.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/context/system/SystemContextHolder.java new file mode 100644 index 00000000..631e41cb --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/context/system/SystemContextHolder.java @@ -0,0 +1,41 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.context.system; + +import cn.hutool.extra.spring.SpringUtil; + +/** + * 使用system模块相关功能的接口 + * + * @author xuyuxiang + * @date 2020/5/6 14:56 + */ +public class SystemContextHolder { + + public static SystemContext me() { + return SpringUtil.getBean(SystemContext.class); + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/dbs/CurrentDataSourceContext.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/dbs/CurrentDataSourceContext.java new file mode 100644 index 00000000..a5987fea --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/dbs/CurrentDataSourceContext.java @@ -0,0 +1,43 @@ +package com.cn.xiaonuo.core.dbs; + +/** + * datasource的上下文 + * + * @author xuyuxiang + * @date 2020/8/24 + */ +public class CurrentDataSourceContext { + + private static final ThreadLocal CONTEXT_HOLDER = new ThreadLocal<>(); + + /** + * 设置数据源类型 + * + * @param dataSourceType 数据库类型 + * @date 2020/8/24 + */ + public static void setDataSourceType(String dataSourceType) { + CONTEXT_HOLDER.set(dataSourceType); + } + + /** + * 获取数据源类型 + * + * @author xuyuxiang + * @date 2020/8/24 + */ + public static String getDataSourceType() { + return CONTEXT_HOLDER.get(); + } + + /** + * 清除数据源类型 + * + * @author xuyuxiang + * @date 2020/8/24 + */ + public static void clearDataSourceType() { + CONTEXT_HOLDER.remove(); + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/email/MailSender.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/email/MailSender.java new file mode 100644 index 00000000..5c737451 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/email/MailSender.java @@ -0,0 +1,30 @@ +package com.cn.xiaonuo.core.email; + + +import com.cn.xiaonuo.core.email.modular.model.SendMailParam; + +/** + * 邮件收发统一接口 + * + * @author xuyuxiang + * @date 2018-07-08-下午3:26 + */ +public interface MailSender { + + /** + * 发送普通邮件 + * + * @author xuyuxiang + * @date 2018/7/8 下午3:34 + */ + void sendMail(SendMailParam sendMailParam); + + /** + * 发送html的邮件 + * + * @author xuyuxiang + * @date 2020/6/9 22:58 + */ + void sendMailHtml(SendMailParam sendMailParam); + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/email/modular/SimpleMailSender.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/email/modular/SimpleMailSender.java new file mode 100644 index 00000000..e320f8f9 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/email/modular/SimpleMailSender.java @@ -0,0 +1,72 @@ +package com.cn.xiaonuo.core.email.modular; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.extra.mail.MailAccount; +import cn.hutool.extra.mail.MailUtil; +import com.cn.xiaonuo.core.email.MailSender; +import com.cn.xiaonuo.core.email.modular.exception.MailSendException; +import com.cn.xiaonuo.core.email.modular.model.SendMailParam; + +/** + * 邮件发送器 + * + * @author xuyuxiang + * @date 2020/6/9 22:54 + */ +public class SimpleMailSender implements MailSender { + + /** + * 邮件配置 + */ + private final MailAccount mailAccount; + + public SimpleMailSender(MailAccount mailAccount) { + this.mailAccount = mailAccount; + } + + @Override + public void sendMail(SendMailParam sendMailParam) { + + //校验发送邮件的参数 + assertSendMailParams(sendMailParam); + + //spring发送邮件 + MailUtil.send(mailAccount, CollUtil.newArrayList(sendMailParam.getTo()), sendMailParam.getTitle(), sendMailParam.getContent(), false); + } + + @Override + public void sendMailHtml(SendMailParam sendMailParam) { + + //校验发送邮件的参数 + assertSendMailParams(sendMailParam); + + //spring发送邮件 + MailUtil.send(mailAccount, CollUtil.newArrayList(sendMailParam.getTo()), sendMailParam.getTitle(), sendMailParam.getContent(), true); + } + + /** + * 校验发送邮件的请求参数 + * + * @author xuyuxiang + * @date 2018/7/8 下午6:41 + */ + private void assertSendMailParams(SendMailParam sendMailParam) { + if (sendMailParam == null) { + throw new MailSendException(400, "请求参数为空"); + } + + if (ObjectUtil.isEmpty(sendMailParam.getTo())) { + throw new MailSendException(400, "收件人邮箱为空"); + } + + if (ObjectUtil.isEmpty(sendMailParam.getTitle())) { + throw new MailSendException(400, "邮件标题为空"); + } + + if (ObjectUtil.isEmpty(sendMailParam.getContent())) { + throw new MailSendException(400, "邮件内容为空"); + } + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/email/modular/exception/MailSendException.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/email/modular/exception/MailSendException.java new file mode 100644 index 00000000..7ce2d1e7 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/email/modular/exception/MailSendException.java @@ -0,0 +1,24 @@ +package com.cn.xiaonuo.core.email.modular.exception; + +import lombok.Getter; + +/** + * 邮件发送异常 + * + * @author xuyuxiang + * @date 2018-07-06-下午3:00 + */ +@Getter +public class MailSendException extends RuntimeException { + + private final Integer code; + + private final String errorMessage; + + public MailSendException(Integer code, String errorMessage) { + super(errorMessage); + this.code = code; + this.errorMessage = errorMessage; + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/email/modular/model/SendMailParam.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/email/modular/model/SendMailParam.java new file mode 100644 index 00000000..061b2c82 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/email/modular/model/SendMailParam.java @@ -0,0 +1,28 @@ +package com.cn.xiaonuo.core.email.modular.model; + +import lombok.Data; + +/** + * 发送邮件的请求参数 + * + * @author xuyuxiang + * @date 2018-07-05 21:19 + */ +@Data +public class SendMailParam { + + /** + * 发送给某人的邮箱 + */ + private String to; + + /** + * 邮件标题 + */ + private String title; + + /** + * 邮件内容 + */ + private String content; +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/enums/CommonStatusEnum.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/enums/CommonStatusEnum.java new file mode 100644 index 00000000..829e7d23 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/enums/CommonStatusEnum.java @@ -0,0 +1,80 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.enums; + +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.core.exception.enums.StatusExceptionEnum; +import lombok.Getter; + +/** + * 公共状态 + * + * @author yubaoshan + * @date 2017/1/22 12:14 + */ +@Getter +public enum CommonStatusEnum { + + /** + * 正常 + */ + ENABLE(0, "正常"), + + /** + * 停用 + */ + DISABLE(1, "停用"), + + /** + * 删除 + */ + DELETED(2, "删除"); + + private final Integer code; + + private final String message; + + CommonStatusEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + /** + * 检查请求参数的状态是否正确 + * + * @author yubaoshan + * @date 2020/4/30 22:43 + */ + public static void validateStatus(Integer code) { + if (code == null) { + throw new ServiceException(StatusExceptionEnum.REQUEST_EMPTY); + } + if (ENABLE.getCode().equals(code) || DISABLE.getCode().equals(code)) { + return; + } + throw new ServiceException(StatusExceptionEnum.NOT_WRITE_STATUS); + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/enums/DbIdEnum.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/enums/DbIdEnum.java new file mode 100644 index 00000000..5f862d46 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/enums/DbIdEnum.java @@ -0,0 +1,69 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.enums; + +import lombok.Getter; + +/** + * 不同数据库类型的枚举 + *

+ * 用于标识mapping.xml中不同数据库的标识 + * + * @author yubaoshan + * @date 2020/6/20 21:08 + */ +@Getter +public enum DbIdEnum { + + /** + * mysql + */ + MYSQL("mysql", "mysql"), + + /** + * pgsql + */ + PG_SQL("pgsql", "postgresql"), + + /** + * oracle + */ + ORACLE("oracle", "oracle"), + + /** + * mssql + */ + MS_SQL("mssql", "sqlserver"); + + private final String code; + + private final String name; + + DbIdEnum(String code, String name) { + this.code = code; + this.name = name; + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/enums/DocumentFormatEnum.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/enums/DocumentFormatEnum.java new file mode 100644 index 00000000..b51a0d6c --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/enums/DocumentFormatEnum.java @@ -0,0 +1,106 @@ +package com.cn.xiaonuo.core.enums; + +import org.jodconverter.document.DefaultDocumentFormatRegistry; +import org.jodconverter.document.DocumentFormat; + +import java.io.IOException; +import java.io.InputStream; + +/** + * 文档类型枚举 + * + * @author xuyuxiang + * @date 2020/7/6 15:00 + */ +public enum DocumentFormatEnum { + + /** + * 文档doc格式 + */ + DOC { + @Override + public DocumentFormat getFormFormat() { + return DefaultDocumentFormatRegistry.DOC; + } + }, + + /** + * 文档docx格式 + */ + DOCX { + @Override + public DocumentFormat getFormFormat() { + return DefaultDocumentFormatRegistry.DOCX; + } + }, + + /** + * 演示文稿ppt格式 + */ + PPT { + @Override + public DocumentFormat getFormFormat() { + return DefaultDocumentFormatRegistry.PPT; + } + }, + + /** + * 演示文稿pptx格式 + */ + PPTX { + @Override + public DocumentFormat getFormFormat() { + return DefaultDocumentFormatRegistry.PPTX; + } + }, + + /** + * 电子表格xls格式 + */ + XLS { + @Override + public DocumentFormat getFormFormat() { + return DefaultDocumentFormatRegistry.XLS; + } + + @Override + public DocumentFormat getTargetFormat() { + return DefaultDocumentFormatRegistry.HTML; + } + }, + + /** + * 电子表格xlsx格式 + */ + XLSX { + @Override + public DocumentFormat getFormFormat() { + return DefaultDocumentFormatRegistry.XLSX; + } + + @Override + public DocumentFormat getTargetFormat() { + return DefaultDocumentFormatRegistry.HTML; + } + }, + + /** + * 文本txt格式 + */ + TXT { + @Override + public DocumentFormat getFormFormat() { + return DefaultDocumentFormatRegistry.TXT; + } + }; + + public InputStream getInputStream(InputStream inputStream) throws IOException { + return inputStream; + } + + public abstract DocumentFormat getFormFormat(); + + public DocumentFormat getTargetFormat() { + return DefaultDocumentFormatRegistry.PDF; + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/enums/LogAnnotionOpTypeEnum.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/enums/LogAnnotionOpTypeEnum.java new file mode 100644 index 00000000..c38b7a1c --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/enums/LogAnnotionOpTypeEnum.java @@ -0,0 +1,107 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.enums; + +import lombok.Getter; + +/** + * 日志注解操作类型枚举 + * + * @author xuyuxiang + * @date 2020/3/16 17:45 + */ +@Getter +public enum LogAnnotionOpTypeEnum { + + /** + * 其它 + */ + OTHER, + + /** + * 增加 + */ + ADD, + + /** + * 删除 + */ + DELETE, + + /** + * 编辑 + */ + EDIT, + + /** + * 更新 + */ + UPDATE, + + /** + * 查询 + */ + QUERY, + + /** + * 详情 + */ + DETAIL, + + /** + * 树 + */ + TREE, + + /** + * 导入 + */ + IMPORT, + + /** + * 导出 + */ + EXPORT, + + /** + * 授权 + */ + GRANT, + + /** + * 强退 + */ + FORCE, + + /** + * 清空 + */ + CLEAN, + + /** + * 修改状态 + */ + CHANGE_STATUS +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/enums/LogicTypeEnum.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/enums/LogicTypeEnum.java new file mode 100644 index 00000000..2cb1f2b0 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/enums/LogicTypeEnum.java @@ -0,0 +1,44 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.enums; + +/** + * 逻辑枚举 + * + * @author xuyuxiang + * @date 2020/4/5 10:23 + */ +public enum LogicTypeEnum { + + /** + * 与 + */ + AND, + + /** + * 或 + */ + OR +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/enums/YesOrNotEnum.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/enums/YesOrNotEnum.java new file mode 100644 index 00000000..b938a107 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/enums/YesOrNotEnum.java @@ -0,0 +1,57 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.enums; + +import lombok.Getter; + +/** + * 是或否的枚举 + * + * @author yubaoshan + * @date 2020/4/13 22:59 + */ +@Getter +public enum YesOrNotEnum { + + /** + * 是 + */ + Y("Y", "是"), + + /** + * 否 + */ + N("N", "否"); + + private final String code; + + private final String message; + + YesOrNotEnum(String code, String message) { + this.code = code; + this.message = message; + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/AuthException.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/AuthException.java new file mode 100644 index 00000000..b69fa04f --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/AuthException.java @@ -0,0 +1,54 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.exception; + +import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum; +import lombok.Getter; + +/** + * 认证相关的异常 + *

+ * 认证和鉴权的区别: + *

+ * 认证可以证明你能登录系统,认证的过程是校验token的过程 + * 鉴权可以证明你有系统的哪些权限,鉴权的过程是校验角色是否包含某些接口的权限 + * + * @author xuyuxiang + * @date 2020/3/12 9:55 + */ +@Getter +public class AuthException extends RuntimeException { + + private final Integer code; + + private final String errorMessage; + + public AuthException(AbstractBaseExceptionEnum exception) { + super(exception.getMessage()); + this.code = exception.getCode(); + this.errorMessage = exception.getMessage(); + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/DemoException.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/DemoException.java new file mode 100644 index 00000000..faa0a657 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/DemoException.java @@ -0,0 +1,46 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.exception; + +import lombok.Getter; + +/** + * 演示环境,无法操作的异常 + * + * @author yubaoshan + * @date 2020/5/5 12:22 + */ +@Getter +public class DemoException extends ServiceException { + + private static final int DEMO_EXP_CODE = 14000; + + private static final String DEMO_EXP_ERROR_MESSAGE = "演示环境,无法操作!"; + + public DemoException() { + super(DEMO_EXP_CODE, DEMO_EXP_ERROR_MESSAGE); + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/LibreOfficeException.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/LibreOfficeException.java new file mode 100644 index 00000000..432cd274 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/LibreOfficeException.java @@ -0,0 +1,46 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.exception; + +import lombok.Getter; + +/** + * LibreOffice相关异常 + * + * @author xuyuxiang + * @date 2020/7/7 11:08 + */ +@Getter +public class LibreOfficeException extends ServiceException { + + private static final int LIBRE_OFFICE_EXP_CODE = 15000; + + private static final String LIBRE_OFFICE_EXP_ERROR_MESSAGE = "LibreOffice初始化异常,请检查LibreOffice是否启动!"; + + public LibreOfficeException() { + super(LIBRE_OFFICE_EXP_CODE, LIBRE_OFFICE_EXP_ERROR_MESSAGE); + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/PermissionException.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/PermissionException.java new file mode 100644 index 00000000..ffbb7472 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/PermissionException.java @@ -0,0 +1,55 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.exception; + +import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum; +import lombok.Getter; + +/** + * 授权和鉴权异常 + *

+ * 认证和鉴权的区别: + *

+ * 认证可以证明你能登录系统,认证的过程是校验token的过程 + * 鉴权可以证明你有系统的哪些权限,鉴权的过程是校验角色是否包含某些接口的权限 + * 也包含当前用户是否有操作该数据的权限 + * + * @author yubaoshan + * @date 2019/7/18 22:18 + */ +@Getter +public class PermissionException extends RuntimeException { + + private final Integer code; + + private final String errorMessage; + + public PermissionException(AbstractBaseExceptionEnum exception) { + super(exception.getMessage()); + this.code = exception.getCode(); + this.errorMessage = exception.getMessage(); + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/RequestMethodException.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/RequestMethodException.java new file mode 100644 index 00000000..9ae798a8 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/RequestMethodException.java @@ -0,0 +1,48 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.exception; + +import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum; +import lombok.Getter; + +/** + * 请求方法异常 + * + * @author xuyuxiang + * @date 2020/3/11 15:35 + */ +@Getter +public class RequestMethodException extends RuntimeException { + + private final Integer code; + + private final String errorMessage; + + public RequestMethodException(AbstractBaseExceptionEnum exception) { + super(exception.getMessage()); + this.code = exception.getCode(); + this.errorMessage = exception.getMessage(); + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/ServiceException.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/ServiceException.java new file mode 100644 index 00000000..80923f99 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/ServiceException.java @@ -0,0 +1,56 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.exception; + +import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 业务异常 + * + * @author xuyuxiang + * @date 2020/4/8 15:54 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class ServiceException extends RuntimeException { + + private Integer code; + + private String errorMessage; + + public ServiceException(Integer code, String errorMessage) { + super(errorMessage); + this.code = code; + this.errorMessage = errorMessage; + } + + public ServiceException(AbstractBaseExceptionEnum exception) { + super(exception.getMessage()); + this.code = exception.getCode(); + this.errorMessage = exception.getMessage(); + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/enums/AuthExceptionEnum.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/enums/AuthExceptionEnum.java new file mode 100644 index 00000000..623221ff --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/enums/AuthExceptionEnum.java @@ -0,0 +1,110 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.exception.enums; + +import com.cn.xiaonuo.core.annotion.ExpEnumType; +import com.cn.xiaonuo.core.consts.ExpEnumConstant; +import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum; +import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory; + +/** + * 认证相关的异常的枚举 + *

+ * 认证和鉴权的区别: + *

+ * 认证可以证明你能登录系统,认证的过程是校验token的过程 + * 鉴权可以证明你有系统的哪些权限,鉴权的过程是校验角色是否包含某些接口的权限 + * + * @author yubaoshan + * @date 2019/7/18 22:22 + */ +@ExpEnumType(module = ExpEnumConstant.XIAONUO_CORE_MODULE_EXP_CODE, kind = ExpEnumConstant.AUTH_EXCEPTION_ENUM) +public enum AuthExceptionEnum implements AbstractBaseExceptionEnum { + + /** + * 账号或密码为空 + */ + ACCOUNT_PWD_EMPTY(1, "账号或密码为空,请检查account或password参数"), + + /** + * 账号密码错误 + */ + ACCOUNT_PWD_ERROR(2, "账号或密码错误,请检查account或password参数"), + + /** + * 验证码错误 + */ + VALID_CODE_ERROR(3, "验证码错误,请检查captcha参数"), + + /** + * 请求token为空 + */ + REQUEST_TOKEN_EMPTY(4, "请求token为空,请携带token访问本接口"), + + /** + * token格式不正确,token请以Bearer开头 + */ + NOT_VALID_TOKEN_TYPE(5, "token格式不正确,token请以Bearer开头,并且Bearer后边带一个空格"), + + /** + * 请求token错误 + */ + REQUEST_TOKEN_ERROR(6, "请求token错误"), + + /** + * 账号被冻结 + */ + ACCOUNT_FREEZE_ERROR(7, "账号被冻结,请联系管理员"), + + /** + * 登录已过期 + */ + LOGIN_EXPIRED(8, "登录已过期,请重新登录"), + + /** + * 无登录用户 + */ + NO_LOGIN_USER(9, "无登录用户"); + + private final Integer code; + + private final String message; + + AuthExceptionEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return ExpEnumCodeFactory.getExpEnumCode(this.getClass(), code); + } + + @Override + public String getMessage() { + return message; + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/enums/ParamExceptionEnum.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/enums/ParamExceptionEnum.java new file mode 100644 index 00000000..fc6bc0d7 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/enums/ParamExceptionEnum.java @@ -0,0 +1,64 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.exception.enums; + +import com.cn.xiaonuo.core.annotion.ExpEnumType; +import com.cn.xiaonuo.core.consts.ExpEnumConstant; +import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum; +import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory; + +/** + * 参数校验异常枚举 + * + * @author xuyuxiang + * @date 2020/3/25 20:11 + */ +@ExpEnumType(module = ExpEnumConstant.XIAONUO_CORE_MODULE_EXP_CODE, kind = ExpEnumConstant.PARAM_EXCEPTION_ENUM) +public enum ParamExceptionEnum implements AbstractBaseExceptionEnum { + + /** + * 参数错误 + */ + PARAM_ERROR(1, "参数错误"); + + private final Integer code; + + private final String message; + + ParamExceptionEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return ExpEnumCodeFactory.getExpEnumCode(this.getClass(), code); + } + + @Override + public String getMessage() { + return message; + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/enums/PermissionExceptionEnum.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/enums/PermissionExceptionEnum.java new file mode 100644 index 00000000..77075658 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/enums/PermissionExceptionEnum.java @@ -0,0 +1,83 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.exception.enums; + +import com.cn.xiaonuo.core.annotion.ExpEnumType; +import com.cn.xiaonuo.core.consts.ExpEnumConstant; +import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum; +import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory; +import com.cn.xiaonuo.core.annotion.ExpEnumType; +import com.cn.xiaonuo.core.consts.ExpEnumConstant; +import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory; + +/** + * 授权和鉴权异常的枚举 + *

+ * 认证和鉴权的区别: + *

+ * 认证可以证明你能登录系统,认证的过程是校验token的过程 + * 鉴权可以证明你有系统的哪些权限,鉴权的过程是校验角色是否包含某些接口的权限 + * + * @author xuyuxiang + * @date 2020/3/12 10:14 + */ +@ExpEnumType(module = ExpEnumConstant.XIAONUO_CORE_MODULE_EXP_CODE, kind = ExpEnumConstant.PERMISSION_EXCEPTION_ENUM) +public enum PermissionExceptionEnum implements AbstractBaseExceptionEnum { + + /** + * 资源路径不存在 + */ + URL_NOT_EXIST(1, "资源路径不存在,请检查请求地址"), + + /** + * 没有权限访问资源 + */ + NO_PERMISSION(2, "没有权限访问资源,请联系管理员"), + + /** + * 没有权限操作该数据 + */ + NO_PERMISSION_OPERATE(3, "没有权限操作该数据,请联系管理员"); + + private final Integer code; + + private final String message; + + PermissionExceptionEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return ExpEnumCodeFactory.getExpEnumCode(this.getClass(), code); + } + + @Override + public String getMessage() { + return message; + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/enums/RequestMethodExceptionEnum.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/enums/RequestMethodExceptionEnum.java new file mode 100644 index 00000000..db2a55e8 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/enums/RequestMethodExceptionEnum.java @@ -0,0 +1,73 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.exception.enums; + +import com.cn.xiaonuo.core.annotion.ExpEnumType; +import com.cn.xiaonuo.core.consts.ExpEnumConstant; +import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum; +import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory; +import com.cn.xiaonuo.core.annotion.ExpEnumType; +import com.cn.xiaonuo.core.consts.ExpEnumConstant; +import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory; + +/** + * 请求方法相关异常枚举 + * + * @author xuyuxiang + * @date 2020/3/11 15:33 + */ +@ExpEnumType(module = ExpEnumConstant.XIAONUO_CORE_MODULE_EXP_CODE, kind = ExpEnumConstant.REQUEST_METHOD_EXCEPTION_ENUM) +public enum RequestMethodExceptionEnum implements AbstractBaseExceptionEnum { + + /** + * 不支持该请求方法,请求方法应为POST + */ + REQUEST_METHOD_IS_POST(1, "不支持该请求方法,请求方法应为POST"), + + /** + * 不支持该请求方法,请求方法应为GET + */ + REQUEST_METHOD_IS_GET(2, "不支持该请求方法,请求方法应为GET"); + + private final Integer code; + + private final String message; + + RequestMethodExceptionEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return ExpEnumCodeFactory.getExpEnumCode(this.getClass(), code); + } + + @Override + public String getMessage() { + return message; + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/enums/RequestTypeExceptionEnum.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/enums/RequestTypeExceptionEnum.java new file mode 100644 index 00000000..ea25e3b2 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/enums/RequestTypeExceptionEnum.java @@ -0,0 +1,73 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.exception.enums; + +import com.cn.xiaonuo.core.annotion.ExpEnumType; +import com.cn.xiaonuo.core.consts.ExpEnumConstant; +import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum; +import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory; +import com.cn.xiaonuo.core.annotion.ExpEnumType; +import com.cn.xiaonuo.core.consts.ExpEnumConstant; +import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory; + +/** + * 请求类型相关异常枚举 + * + * @author xuyuxiang + * @date 2020/4/2 15:42 + */ +@ExpEnumType(module = ExpEnumConstant.XIAONUO_CORE_MODULE_EXP_CODE, kind = ExpEnumConstant.REQUEST_TYPE_EXCEPTION_ENUM) +public enum RequestTypeExceptionEnum implements AbstractBaseExceptionEnum { + + /** + * 参数传递格式不支持 + */ + REQUEST_TYPE_IS_JSON(1, "参数传递格式不支持,请使用JSON格式传参"), + + /** + * 请求JSON参数格式不正确 + */ + REQUEST_JSON_ERROR(2, "请求JSON参数格式不正确,请检查参数格式"); + + private final Integer code; + + private final String message; + + RequestTypeExceptionEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return ExpEnumCodeFactory.getExpEnumCode(this.getClass(), code); + } + + @Override + public String getMessage() { + return message; + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/enums/ServerExceptionEnum.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/enums/ServerExceptionEnum.java new file mode 100644 index 00000000..9c2ad4cc --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/enums/ServerExceptionEnum.java @@ -0,0 +1,78 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.exception.enums; + +import com.cn.xiaonuo.core.annotion.ExpEnumType; +import com.cn.xiaonuo.core.consts.ExpEnumConstant; +import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum; +import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory; +import com.cn.xiaonuo.core.annotion.ExpEnumType; +import com.cn.xiaonuo.core.consts.ExpEnumConstant; +import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory; + +/** + * 服务器内部相关异常枚举 + * + * @author xuyuxiang + * @date 2020/3/18 19:19 + */ +@ExpEnumType(module = ExpEnumConstant.XIAONUO_CORE_MODULE_EXP_CODE, kind = ExpEnumConstant.SERVER_EXCEPTION_ENUM) +public enum ServerExceptionEnum implements AbstractBaseExceptionEnum { + + /** + * 当前请求参数为空或数据缺失 + */ + REQUEST_EMPTY(1, "当前请求参数为空或数据缺失,请联系管理员"), + + /** + * 服务器出现未知异常 + */ + SERVER_ERROR(2, "服务器出现异常,请联系管理员"), + + /** + * 常量获取存在空值 + */ + CONSTANT_EMPTY(3, "常量获取存在空值,请检查sys_config中是否配置"); + + private final Integer code; + + private final String message; + + ServerExceptionEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return ExpEnumCodeFactory.getExpEnumCode(this.getClass(), code); + } + + @Override + public String getMessage() { + return message; + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/enums/StatusExceptionEnum.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/enums/StatusExceptionEnum.java new file mode 100644 index 00000000..00d3b6cb --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/enums/StatusExceptionEnum.java @@ -0,0 +1,78 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.exception.enums; + +import com.cn.xiaonuo.core.annotion.ExpEnumType; +import com.cn.xiaonuo.core.consts.ExpEnumConstant; +import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum; +import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory; +import com.cn.xiaonuo.core.annotion.ExpEnumType; +import com.cn.xiaonuo.core.consts.ExpEnumConstant; +import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory; + +/** + * 状态枚举 + * + * @author yubaoshan + * @date 2020/4/30 22:45 + */ +@ExpEnumType(module = ExpEnumConstant.XIAONUO_CORE_MODULE_EXP_CODE, kind = ExpEnumConstant.STATUS_EXCEPTION_ENUM) +public enum StatusExceptionEnum implements AbstractBaseExceptionEnum { + + /** + * 请求状态值为空 + */ + REQUEST_EMPTY(1, "请求状态值为空"), + + /** + * 请求状值为非正确状态值 + */ + NOT_WRITE_STATUS(2, "请求状态值不合法"), + + /** + * 更新状态失败,试图更新被删除的记录 + */ + UPDATE_STATUS_ERROR(3, "更新状态失败,您试图更新被删除的记录"); + + private final Integer code; + + private final String message; + + StatusExceptionEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return ExpEnumCodeFactory.getExpEnumCode(this.getClass(), code); + } + + @Override + public String getMessage() { + return message; + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/enums/WrapperExceptionEnum.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/enums/WrapperExceptionEnum.java new file mode 100644 index 00000000..6f3e8372 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/enums/WrapperExceptionEnum.java @@ -0,0 +1,78 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.exception.enums; + +import com.cn.xiaonuo.core.annotion.ExpEnumType; +import com.cn.xiaonuo.core.consts.ExpEnumConstant; +import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum; +import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory; +import com.cn.xiaonuo.core.annotion.ExpEnumType; +import com.cn.xiaonuo.core.consts.ExpEnumConstant; +import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory; + +/** + * 对象包装异常 + * + * @author xuyuxiang + * @date 2020/7/24 14:36 + */ +@ExpEnumType(module = ExpEnumConstant.XIAONUO_CORE_MODULE_EXP_CODE, kind = ExpEnumConstant.WRAPPER_EXCEPTION_ENUM) +public enum WrapperExceptionEnum implements AbstractBaseExceptionEnum { + + /** + * 被包装的值不能是基本类型 + */ + BASIC_TYPE_ERROR(1, "被包装的值不能是基本类型"), + + /** + * 获取转化字段的值异常 + */ + TRANSFER_FILED_VALUE_ERROR(2, "获取转化字段的值异常"), + + /** + * 字段包装转化异常 + */ + TRANSFER_ERROR(3, "字段包装转化异常"); + + private final Integer code; + + private final String message; + + WrapperExceptionEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return ExpEnumCodeFactory.getExpEnumCode(this.getClass(), code); + } + + @Override + public String getMessage() { + return message; + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/enums/abs/AbstractBaseExceptionEnum.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/enums/abs/AbstractBaseExceptionEnum.java new file mode 100644 index 00000000..4b11a7b3 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/exception/enums/abs/AbstractBaseExceptionEnum.java @@ -0,0 +1,53 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.exception.enums.abs; + +/** + * 异常枚举格式规范 + * + * @author yubaoshan + * @date 2017/12/17 22:22 + */ +public interface AbstractBaseExceptionEnum { + + /** + * 获取异常的状态码 + * + * @return 状态码 + * @author yubaoshan + * @date 2020/7/9 14:28 + */ + Integer getCode(); + + /** + * 获取异常的提示信息 + * + * @return 提示信息 + * @author yubaoshan + * @date 2020/7/9 14:28 + */ + String getMessage(); + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/factory/ExpEnumCodeFactory.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/factory/ExpEnumCodeFactory.java new file mode 100644 index 00000000..225d2ac3 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/factory/ExpEnumCodeFactory.java @@ -0,0 +1,54 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.factory; + +import com.cn.xiaonuo.core.annotion.ExpEnumType; + +/** + * 异常枚举code值快速创建 + * + * @author yubaoshan + * @date 2020/6/19 21:30 + */ +public class ExpEnumCodeFactory { + + public static Integer getExpEnumCode(Class clazz, int code) { + + // 默认的异常响应码 + Integer defaultCode = Integer.valueOf("" + 99 + 9999 + 9); + + if (clazz == null) { + return defaultCode; + } else { + ExpEnumType expEnumType = clazz.getAnnotation(ExpEnumType.class); + if (expEnumType == null) { + return defaultCode; + } + return Integer.valueOf("" + expEnumType.module() + expEnumType.kind() + code); + } + + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/factory/PageFactory.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/factory/PageFactory.java new file mode 100644 index 00000000..7ebae420 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/factory/PageFactory.java @@ -0,0 +1,80 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.factory; + +import cn.hutool.core.util.ObjectUtil; +import com.cn.xiaonuo.core.util.HttpServletUtil; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; + +import javax.servlet.http.HttpServletRequest; + + +/** + * 默认分页参数构建 + * + * @author yubaoshan + * @date 2017/11/15 13:52 + */ +public class PageFactory { + + /** + * 每页大小(默认20) + */ + private static final String PAGE_SIZE_PARAM_NAME = "pageSize"; + + /** + * 第几页(从1开始) + */ + private static final String PAGE_NO_PARAM_NAME = "pageNo"; + + /** + * 默认分页,在使用时PageFactory.defaultPage会自动获取pageSize和pageNo参数 + * + * @author xuyuxiang + * @date 2020/3/30 16:42 + */ + public static Page defaultPage() { + + int pageSize = 20; + int pageNo = 1; + + HttpServletRequest request = HttpServletUtil.getRequest(); + + //每页条数 + String pageSizeString = request.getParameter(PAGE_SIZE_PARAM_NAME); + if (ObjectUtil.isNotEmpty(pageSizeString)) { + pageSize = Integer.parseInt(pageSizeString); + } + + //第几页 + String pageNoString = request.getParameter(PAGE_NO_PARAM_NAME); + if (ObjectUtil.isNotEmpty(pageNoString)) { + pageNo = Integer.parseInt(pageNoString); + } + + return new Page<>(pageNo, pageSize); + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/factory/TreeBuildFactory.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/factory/TreeBuildFactory.java new file mode 100644 index 00000000..49001a8b --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/factory/TreeBuildFactory.java @@ -0,0 +1,128 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.factory; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import com.cn.xiaonuo.core.pojo.base.node.BaseTreeNode; +import com.cn.xiaonuo.core.pojo.base.node.BaseTreeNode; +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 默认递归工具类,用于遍历有父子关系的节点,例如菜单树,字典树等等 + * + * @author xuyuxiang + * @date 2020/4/5 14:17 + */ +@Data +public class TreeBuildFactory { + + /** + * 顶级节点的父节点id(默认0) + */ + private Long rootParentId = 0L; + + /** + * 树节点构造 + * + * @author xuyuxiang + * @date 2020/4/5 14:09 + */ + public List doTreeBuild(List nodes) { + + //具体构建的过程 + List buildComplete = this.executeBuilding(nodes); + + //构建之后的处理工作 + return this.afterBuild(buildComplete); + } + + /** + * 查询子节点集合 + * + * @author xuyuxiang + * @date 2020/4/5 14:10 + */ + private void buildChildNodes(List totalNodes, T node, List childNodeLists) { + if (ObjectUtil.hasEmpty(totalNodes, node)) { + return; + } + List nodeSubLists = this.getSubChildLevelOne(totalNodes, node); + if (ObjectUtil.isNotEmpty(nodeSubLists)) { + nodeSubLists.forEach(t -> this.buildChildNodes(totalNodes, t, CollectionUtil.newArrayList())); + } + childNodeLists.addAll(nodeSubLists); + node.setChildren(childNodeLists); + } + + /** + * 获取子一级节点的集合 + * + * @author xuyuxiang + * @date 2020/4/5 14:12 + */ + private List getSubChildLevelOne(List list, T node) { + List nodeList = CollectionUtil.newArrayList(); + if (ObjectUtil.isNotEmpty(list)) { + list.forEach(t -> { + if (t.getPid().equals(node.getId())) { + nodeList.add(t); + } + }); + } + return nodeList; + } + + /** + * 执行构造 + * + * @author xuyuxiang + * @date 2020/4/5 14:13 + */ + private List executeBuilding(List nodes) { + nodes.forEach(t -> this.buildChildNodes(nodes, t, CollectionUtil.newArrayList())); + return nodes; + } + + /** + * 构造之后 + * + * @author xuyuxiang + * @date 2020/4/5 14:13 + */ + private List afterBuild(List nodes) { + //去掉所有的二级节点 + ArrayList results = CollectionUtil.newArrayList(); + nodes.forEach(t -> { + if (rootParentId.equals(t.getPid())) { + results.add(t); + } + }); + return results; + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/file/FileOperator.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/file/FileOperator.java new file mode 100644 index 00000000..a964f1ed --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/file/FileOperator.java @@ -0,0 +1,147 @@ +package com.cn.xiaonuo.core.file; + + +import com.cn.xiaonuo.core.file.common.enums.BucketAuthEnum; + +import java.io.InputStream; + +/** + * 文件操纵者(内网操作) + *

+ * 如果存在未包含的操作,可以调用getClient()自行获取client进行操作 + * + * @author xuyuxiang + * @date 2018-06-27-下午12:37 + */ +public interface FileOperator { + + /** + * 初始化操作的客户端 + * + * @author xuyuxiang + * @date 2020/5/23 2:32 下午 + */ + void initClient(); + + /** + * 销毁操作的客户端 + * + * @author xuyuxiang + * @date 2020/5/23 2:32 下午 + */ + void destroyClient(); + + /** + * 获取操作的客户端 + * + * @author xuyuxiang + * @date 2020/5/23 2:58 下午 + */ + Object getClient(); + + /** + * 查询存储桶是否存在 + *

+ * 例如:传入参数examplebucket-1250000000,返回true代表存在此桶 + * + * @author xuyuxiang + * @date 2020/5/23 2:29 下午 + */ + boolean doesBucketExist(String bucketName); + + /** + * 设置预定义策略 + *

+ * 预定义策略如公有读、公有读写、私有读 + * + * @author xuyuxiang + * @date 2020/5/23 3:02 下午 + */ + void setBucketAcl(String bucketName, BucketAuthEnum bucketAuthEnum); + + /** + * 判断是否存在文件 + * + * @param bucketName 桶名称 + * @param key 唯一标示id,例如a.txt, doc/a.txt + * @author xuyuxiang + * @date 2018/6/27 下午1:14 + */ + boolean isExistingFile(String bucketName, String key); + + /** + * 存储文件 + * + * @param bucketName 桶名称 + * @param key 唯一标示id,例如a.txt, doc/a.txt + * @param bytes 文件字节数组 + * @author xuyuxiang + * @date 2018/6/27 下午1:16 + */ + void storageFile(String bucketName, String key, byte[] bytes); + + /** + * 存储文件(存放到指定的bucket里边) + * + * @param bucketName 桶名称 + * @param key 唯一标示id,例如a.txt, doc/a.txt + * @param inputStream 文件流 + * @author xuyuxiang + * @date 2018年10月19日13:20:37 + */ + void storageFile(String bucketName, String key, InputStream inputStream); + + /** + * 获取某个bucket下的文件字节 + * + * @param bucketName 桶名称 + * @param key 唯一标示id,例如a.txt, doc/a.txt + * @author xuyuxiang + * @date 2018/6/27 下午1:15 + */ + byte[] getFileBytes(String bucketName, String key); + + /** + * 文件访问权限管理 + * + * @param bucketName 桶名称 + * @param key 唯一标示id,例如a.txt, doc/a.txt + * @param bucketAuthEnum 文件权限 + * @author xuyuxiang + * @date 2020/5/23 5:30 下午 + */ + void setFileAcl(String bucketName, String key, BucketAuthEnum bucketAuthEnum); + + /** + * 拷贝文件 + * + * @param originBucketName 源文件桶 + * @param originFileKey 源文件名称 + * @param newBucketName 新文件桶 + * @param newFileKey 新文件名称 + * @author xuyuxiang + * @date 2020/5/23 6:09 下午 + */ + void copyFile(String originBucketName, String originFileKey, String newBucketName, String newFileKey); + + /** + * 获取文件的下载地址(带鉴权的),生成外网地址 + * + * @param bucketName 文件桶 + * @param key 文件唯一标识 + * @author xuyuxiang + * @date 2018/7/7 上午11:27 + */ + String getFileAuthUrl(String bucketName, String key, Long timeoutMillis); + + /** + * 删除文件 + * + * @param bucketName 文件桶 + * @param key 文件唯一标识 + * @author xuyuxiang + * @date 2020/9/18 + */ + void deleteFile(String bucketName, String key); + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/file/common/enums/BucketAuthEnum.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/file/common/enums/BucketAuthEnum.java new file mode 100644 index 00000000..b62cdee6 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/file/common/enums/BucketAuthEnum.java @@ -0,0 +1,26 @@ +package com.cn.xiaonuo.core.file.common.enums; + +/** + * 桶的权限策略枚举 + * + * @author xuyuxiang + * @date 2020-05-23-3:03 下午 + */ +public enum BucketAuthEnum { + + /** + * 私有的(仅有 owner 可以读写) + */ + PRIVATE, + + /** + * 公有读,私有写( owner 可以读写, 其他客户可以读) + */ + PUBLIC_READ, + + /** + * 公共读写(即所有人都可以读写,慎用) + */ + PUBLIC_READ_WRITE + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/file/common/exp/FileServiceException.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/file/common/exp/FileServiceException.java new file mode 100644 index 00000000..572c7810 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/file/common/exp/FileServiceException.java @@ -0,0 +1,18 @@ +package com.cn.xiaonuo.core.file.common.exp; + +import lombok.Getter; + +/** + * 文件操作业务异常 + * + * @author xuyuxiang + * @date 2020-05-23-2:42 下午 + */ +@Getter +public class FileServiceException extends RuntimeException { + + public FileServiceException(String message) { + super(message); + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/file/modular/aliyun/AliyunFileOperator.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/file/modular/aliyun/AliyunFileOperator.java new file mode 100644 index 00000000..a09fca8d --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/file/modular/aliyun/AliyunFileOperator.java @@ -0,0 +1,189 @@ +package com.cn.xiaonuo.core.file.modular.aliyun; + +import cn.hutool.core.io.IoUtil; +import com.aliyun.oss.ClientException; +import com.aliyun.oss.OSS; +import com.aliyun.oss.OSSClientBuilder; +import com.aliyun.oss.OSSException; +import com.aliyun.oss.model.CannedAccessControlList; +import com.aliyun.oss.model.OSSObject; +import com.aliyun.oss.model.PutObjectRequest; +import com.cn.xiaonuo.core.file.FileOperator; +import com.cn.xiaonuo.core.file.common.enums.BucketAuthEnum; +import com.cn.xiaonuo.core.file.modular.aliyun.exp.AliyunFileServiceException; +import com.cn.xiaonuo.core.file.modular.aliyun.prop.AliyunOssProperties; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.net.URL; +import java.util.Date; + +/** + * 阿里云文件操作 + * + * @author xuyuxiang + * @date 2020/5/25 2:33 下午 + */ +public class AliyunFileOperator implements FileOperator { + + /** + * 阿里云文件操作客户端 + */ + private OSS ossClient; + + /** + * 阿里云oss的配置 + */ + private final AliyunOssProperties aliyunOssProperties; + + public AliyunFileOperator(AliyunOssProperties aliyunOssProperties) { + this.aliyunOssProperties = aliyunOssProperties; + this.initClient(); + } + + @Override + public void initClient() { + String endpoint = aliyunOssProperties.getEndPoint(); + String accessKeyId = aliyunOssProperties.getAccessKeyId(); + String accessKeySecret = aliyunOssProperties.getAccessKeySecret(); + + // 创建OSSClient实例。 + ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); + } + + @Override + public void destroyClient() { + ossClient.shutdown(); + } + + @Override + public Object getClient() { + return ossClient; + } + + @Override + public boolean doesBucketExist(String bucketName) { + try { + return ossClient.doesBucketExist(bucketName); + } catch (OSSException e) { + throw new AliyunFileServiceException(e); + } catch (ClientException e) { + throw new AliyunFileServiceException(e); + } + } + + @Override + public void setBucketAcl(String bucketName, BucketAuthEnum bucketAuthEnum) { + try { + if (bucketAuthEnum.equals(BucketAuthEnum.PRIVATE)) { + ossClient.setBucketAcl(bucketName, CannedAccessControlList.Private); + } else if (bucketAuthEnum.equals(BucketAuthEnum.PUBLIC_READ)) { + ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead); + } else if (bucketAuthEnum.equals(BucketAuthEnum.PUBLIC_READ_WRITE)) { + ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicReadWrite); + } + } catch (OSSException e) { + throw new AliyunFileServiceException(e); + } catch (ClientException e) { + throw new AliyunFileServiceException(e); + } + } + + @Override + public boolean isExistingFile(String bucketName, String key) { + try { + return ossClient.doesObjectExist(bucketName, key); + } catch (OSSException e) { + throw new AliyunFileServiceException(e); + } catch (ClientException e) { + throw new AliyunFileServiceException(e); + } + } + + @Override + public void storageFile(String bucketName, String key, byte[] bytes) { + try { + ossClient.putObject(bucketName, key, new ByteArrayInputStream(bytes)); + } catch (OSSException e) { + throw new AliyunFileServiceException(e); + } catch (ClientException e) { + throw new AliyunFileServiceException(e); + } + } + + @Override + public void storageFile(String bucketName, String key, InputStream inputStream) { + try { + PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, inputStream); + ossClient.putObject(putObjectRequest); + } catch (OSSException e) { + throw new AliyunFileServiceException(e); + } catch (ClientException e) { + throw new AliyunFileServiceException(e); + } + } + + @Override + public byte[] getFileBytes(String bucketName, String key) { + InputStream objectContent = null; + try { + OSSObject ossObject = ossClient.getObject(bucketName, key); + objectContent = ossObject.getObjectContent(); + return IoUtil.readBytes(objectContent); + } catch (OSSException e) { + throw new AliyunFileServiceException(e); + } catch (ClientException e) { + throw new AliyunFileServiceException(e); + } finally { + IoUtil.close(objectContent); + } + + } + + @Override + public void setFileAcl(String bucketName, String key, BucketAuthEnum bucketAuthEnum) { + try { + if (bucketAuthEnum.equals(BucketAuthEnum.PRIVATE)) { + ossClient.setObjectAcl(bucketName, key, CannedAccessControlList.Private); + } else if (bucketAuthEnum.equals(BucketAuthEnum.PUBLIC_READ)) { + ossClient.setObjectAcl(bucketName, key, CannedAccessControlList.PublicRead); + } else if (bucketAuthEnum.equals(BucketAuthEnum.PUBLIC_READ_WRITE)) { + ossClient.setObjectAcl(bucketName, key, CannedAccessControlList.PublicReadWrite); + } + } catch (OSSException e) { + throw new AliyunFileServiceException(e); + } catch (ClientException e) { + throw new AliyunFileServiceException(e); + } + } + + @Override + public void copyFile(String originBucketName, String originFileKey, String newBucketName, String newFileKey) { + try { + ossClient.copyObject(originBucketName, originFileKey, newBucketName, newFileKey); + } catch (OSSException e) { + throw new AliyunFileServiceException(e); + } catch (ClientException e) { + throw new AliyunFileServiceException(e); + } + } + + @Override + public String getFileAuthUrl(String bucketName, String key, Long timeoutMillis) { + try { + Date expiration = new Date(new Date().getTime() + timeoutMillis); + URL url = ossClient.generatePresignedUrl(bucketName, key, expiration); + return url.toString(); + } catch (OSSException e) { + throw new AliyunFileServiceException(e); + } catch (ClientException e) { + throw new AliyunFileServiceException(e); + } + } + + @Override + public void deleteFile(String bucketName, String key) { + ossClient.deleteObject(bucketName, key); + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/file/modular/aliyun/exp/AliyunFileServiceException.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/file/modular/aliyun/exp/AliyunFileServiceException.java new file mode 100644 index 00000000..91fafaf2 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/file/modular/aliyun/exp/AliyunFileServiceException.java @@ -0,0 +1,46 @@ +package com.cn.xiaonuo.core.file.modular.aliyun.exp; + +import com.aliyun.oss.ClientException; +import com.aliyun.oss.OSSException; +import lombok.Getter; + +/** + * 腾讯文件操作异常 + * + * @author xuyuxiang + * @date 2020-05-23-2:42 下午 + */ +@Getter +public class AliyunFileServiceException extends RuntimeException { + + /** + * 客户端异常 + *

+ * 是由于客户端原因导致无法和服务端完成正常的交互而导致的失败,如客户端无法连接到服务端,无法解析服务端返回的数据 + */ + private ClientException clientException; + + /** + * 服务端异常 + *

+ * 用于指交互正常完成,但是操作失败的场景 + *

+ * 例如客户端访问一个不存在 Bucket,删除一个不存在的文件,没有权限进行某个操作, 服务端故障异常等 + */ + private OSSException ossException; + + public AliyunFileServiceException(String message) { + super(message); + } + + public AliyunFileServiceException(ClientException clientException) { + super(clientException.getMessage()); + this.clientException = clientException; + } + + public AliyunFileServiceException(OSSException ossException) { + super(ossException.getMessage()); + this.ossException = ossException; + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/file/modular/aliyun/prop/AliyunOssProperties.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/file/modular/aliyun/prop/AliyunOssProperties.java new file mode 100644 index 00000000..e6f64c45 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/file/modular/aliyun/prop/AliyunOssProperties.java @@ -0,0 +1,31 @@ +package com.cn.xiaonuo.core.file.modular.aliyun.prop; + +import lombok.Data; + +/** + * 腾讯云cos文件存储配置 + * + * @author xuyuxiang + * @date 2020/5/22 6:56 下午 + */ +@Data +public class AliyunOssProperties { + + /** + * 默认北京,内网 + *

+ * https://help.aliyun.com/document_detail/31837.html?spm=a2c4g.11186623.2.17.467f45dcjB4WQQ#concept-zt4-cvy-5db + */ + private String endPoint = "http://oss-cn-beijing.aliyuncs.com"; + + /** + * 秘钥id + */ + private String accessKeyId; + + /** + * 秘钥secret + */ + private String accessKeySecret; + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/file/modular/local/LocalFileOperator.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/file/modular/local/LocalFileOperator.java new file mode 100644 index 00000000..200f092f --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/file/modular/local/LocalFileOperator.java @@ -0,0 +1,157 @@ +package com.cn.xiaonuo.core.file.modular.local; + +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.system.SystemUtil; +import com.cn.xiaonuo.core.file.FileOperator; +import com.cn.xiaonuo.core.file.common.enums.BucketAuthEnum; +import com.cn.xiaonuo.core.file.common.exp.FileServiceException; +import com.cn.xiaonuo.core.file.modular.local.prop.LocalFileProperties; + +import java.io.File; +import java.io.InputStream; + +/** + * 阿里云文件操作 + * + * @author xuyuxiang + * @date 2020/5/25 2:33 下午 + */ +public class LocalFileOperator implements FileOperator { + + private final LocalFileProperties localFileProperties; + + private String currentSavePath = ""; + + public LocalFileOperator(LocalFileProperties localFileProperties) { + this.localFileProperties = localFileProperties; + initClient(); + } + + @Override + public void initClient() { + if (SystemUtil.getOsInfo().isWindows()) { + String savePathWindows = localFileProperties.getLocalFileSavePathWin(); + if (!FileUtil.exist(savePathWindows)) { + FileUtil.mkdir(savePathWindows); + } + currentSavePath = savePathWindows; + } else { + String savePathLinux = localFileProperties.getLocalFileSavePathLinux(); + if (!FileUtil.exist(savePathLinux)) { + FileUtil.mkdir(savePathLinux); + } + currentSavePath = savePathLinux; + } + } + + @Override + public void destroyClient() { + // empty + } + + @Override + public Object getClient() { + // empty + return null; + } + + @Override + public boolean doesBucketExist(String bucketName) { + String absolutePath = currentSavePath + File.separator + bucketName; + return FileUtil.exist(absolutePath); + } + + @Override + public void setBucketAcl(String bucketName, BucketAuthEnum bucketAuthEnum) { + // empty + } + + @Override + public boolean isExistingFile(String bucketName, String key) { + String absoluteFile = currentSavePath + File.separator + bucketName + File.separator + key; + return FileUtil.exist(absoluteFile); + } + + @Override + public void storageFile(String bucketName, String key, byte[] bytes) { + + // 判断bucket存在不存在 + String bucketPath = currentSavePath + File.separator + bucketName; + if (!FileUtil.exist(bucketPath)) { + FileUtil.mkdir(bucketPath); + } + + // 存储文件 + String absoluteFile = currentSavePath + File.separator + bucketName + File.separator + key; + FileUtil.writeBytes(bytes, absoluteFile); + } + + @Override + public void storageFile(String bucketName, String key, InputStream inputStream) { + + // 判断bucket存在不存在 + String bucketPath = currentSavePath + File.separator + bucketName; + if (!FileUtil.exist(bucketPath)) { + FileUtil.mkdir(bucketPath); + } + + // 存储文件 + String absoluteFile = currentSavePath + File.separator + bucketName + File.separator + key; + FileUtil.writeFromStream(inputStream, absoluteFile); + } + + @Override + public byte[] getFileBytes(String bucketName, String key) { + + // 判断文件存在不存在 + String absoluteFile = currentSavePath + File.separator + bucketName + File.separator + key; + if (!FileUtil.exist(absoluteFile)) { + String message = StrUtil.format("文件不存在,bucket={},key={}", bucketName, key); + throw new FileServiceException(message); + } else { + return FileUtil.readBytes(absoluteFile); + } + } + + @Override + public void setFileAcl(String bucketName, String key, BucketAuthEnum bucketAuthEnum) { + // empty + } + + @Override + public void copyFile(String originBucketName, String originFileKey, String newBucketName, String newFileKey) { + + // 判断文件存在不存在 + String originFile = currentSavePath + File.separator + originBucketName + File.separator + originFileKey; + if (!FileUtil.exist(originFile)) { + String message = StrUtil.format("源文件不存在,bucket={},key={}", originBucketName, originFileKey); + throw new FileServiceException(message); + } else { + + // 拷贝文件 + String destFile = currentSavePath + File.separator + newBucketName + File.separator + newFileKey; + FileUtil.copy(originFile, destFile, true); + } + } + + @Override + public String getFileAuthUrl(String bucketName, String key, Long timeoutMillis) { + // empty + return null; + } + + @Override + public void deleteFile(String bucketName, String key) { + + // 判断文件存在不存在 + String file = currentSavePath + File.separator + bucketName + File.separator + key; + if (!FileUtil.exist(file)) { + return; + } + + // 删除文件 + FileUtil.del(file); + + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/file/modular/local/prop/LocalFileProperties.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/file/modular/local/prop/LocalFileProperties.java new file mode 100644 index 00000000..63404eea --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/file/modular/local/prop/LocalFileProperties.java @@ -0,0 +1,24 @@ +package com.cn.xiaonuo.core.file.modular.local.prop; + +import lombok.Data; + +/** + * 本地文件存储配置 + * + * @author xuyuxiang + * @date 2020/6/7 22:30 + */ +@Data +public class LocalFileProperties { + + /** + * 本地文件存储位置(linux) + */ + private String localFileSavePathLinux = "/tmp/tempFilePath"; + + /** + * 本地文件存储位置(windows) + */ + private String localFileSavePathWin = "D:\\tempFilePath"; + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/file/modular/tencent/TenFileOperator.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/file/modular/tencent/TenFileOperator.java new file mode 100644 index 00000000..6f263d14 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/file/modular/tencent/TenFileOperator.java @@ -0,0 +1,238 @@ +package com.cn.xiaonuo.core.file.modular.tencent; + +import cn.hutool.core.io.IoUtil; +import com.cn.xiaonuo.core.file.FileOperator; +import com.cn.xiaonuo.core.file.common.enums.BucketAuthEnum; +import com.cn.xiaonuo.core.file.modular.tencent.exp.TencentFileServiceException; +import com.cn.xiaonuo.core.file.modular.tencent.prop.TenCosProperties; +import com.qcloud.cos.COSClient; +import com.qcloud.cos.ClientConfig; +import com.qcloud.cos.auth.BasicCOSCredentials; +import com.qcloud.cos.auth.COSCredentials; +import com.qcloud.cos.exception.CosClientException; +import com.qcloud.cos.exception.CosServiceException; +import com.qcloud.cos.http.HttpMethodName; +import com.qcloud.cos.model.*; +import com.qcloud.cos.region.Region; +import com.qcloud.cos.transfer.TransferManager; +import com.qcloud.cos.transfer.TransferManagerConfiguration; + +import javax.activation.MimetypesFileTypeMap; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.net.URL; +import java.util.Date; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * 腾讯云内网文件操作 + * + * @author xuyuxiang + * @date 2020-05-22-6:51 下午 + */ +public class TenFileOperator implements FileOperator { + + private final TenCosProperties tenCosProperties; + + private COSClient cosClient; + + private TransferManager transferManager; + + public TenFileOperator(TenCosProperties tenCosProperties) { + this.tenCosProperties = tenCosProperties; + initClient(); + } + + @Override + public void initClient() { + + // 1.初始化用户身份信息 + String secretId = tenCosProperties.getSecretId(); + String secretKey = tenCosProperties.getSecretKey(); + COSCredentials cred = new BasicCOSCredentials(secretId, secretKey); + + // 2.设置 bucket 的区域, COS 地域的简称请参照 https://cloud.tencent.com/document/product/436/6224 + Region region = new Region(tenCosProperties.getRegionId()); + ClientConfig clientConfig = new ClientConfig(region); + + // 3.生成 cos 客户端。 + cosClient = new COSClient(cred, clientConfig); + + // 4.线程池大小,建议在客户端与 COS 网络充足(例如使用腾讯云的 CVM,同地域上传 COS)的情况下,设置成16或32即可,可较充分的利用网络资源 + // 对于使用公网传输且网络带宽质量不高的情况,建议减小该值,避免因网速过慢,造成请求超时。 + ExecutorService threadPool = Executors.newFixedThreadPool(32); + + // 5.传入一个 threadpool, 若不传入线程池,默认 TransferManager 中会生成一个单线程的线程池。 + transferManager = new TransferManager(cosClient, threadPool); + + // 6.设置高级接口的分块上传阈值和分块大小为10MB + TransferManagerConfiguration transferManagerConfiguration = new TransferManagerConfiguration(); + transferManagerConfiguration.setMultipartUploadThreshold(10 * 1024 * 1024); + transferManagerConfiguration.setMinimumUploadPartSize(10 * 1024 * 1024); + transferManager.setConfiguration(transferManagerConfiguration); + } + + @Override + public void destroyClient() { + cosClient.shutdown(); + } + + @Override + public Object getClient() { + return cosClient; + } + + @Override + public boolean doesBucketExist(String bucketName) { + try { + return cosClient.doesBucketExist(bucketName); + } catch (CosServiceException e) { + throw new TencentFileServiceException(e); + } catch (CosClientException e) { + throw new TencentFileServiceException(e); + } + } + + @Override + public void setBucketAcl(String bucketName, BucketAuthEnum bucketAuthEnum) { + try { + if (bucketAuthEnum.equals(BucketAuthEnum.PRIVATE)) { + cosClient.setBucketAcl(bucketName, CannedAccessControlList.Private); + } else if (bucketAuthEnum.equals(BucketAuthEnum.PUBLIC_READ)) { + cosClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead); + } else if (bucketAuthEnum.equals(BucketAuthEnum.PUBLIC_READ_WRITE)) { + cosClient.setBucketAcl(bucketName, CannedAccessControlList.PublicReadWrite); + } + } catch (CosServiceException e) { + throw new TencentFileServiceException(e); + } catch (CosClientException e) { + throw new TencentFileServiceException(e); + } + } + + @Override + public boolean isExistingFile(String bucketName, String key) { + try { + cosClient.getObjectMetadata(bucketName, key); + return true; + } catch (CosServiceException e) { + return false; + } + } + + @Override + public void storageFile(String bucketName, String key, byte[] bytes) { + // 根据文件名获取contentType + String contentType = "application/octet-stream"; + if (key.contains(".")) { + contentType = MimetypesFileTypeMap.getDefaultFileTypeMap().getContentType(key); + } + + // 上传文件 + ByteArrayInputStream byteArrayInputStream = null; + try { + byteArrayInputStream = new ByteArrayInputStream(bytes); + ObjectMetadata objectMetadata = new ObjectMetadata(); + objectMetadata.setContentType(contentType); + cosClient.putObject(bucketName, key, new ByteArrayInputStream(bytes), objectMetadata); + } catch (CosServiceException e) { + throw new TencentFileServiceException(e); + } catch (CosClientException e) { + throw new TencentFileServiceException(e); + } finally { + IoUtil.close(byteArrayInputStream); + } + + } + + @Override + public void storageFile(String bucketName, String key, InputStream inputStream) { + + // 根据文件名获取contentType + String contentType = "application/octet-stream"; + if (key.contains(".")) { + contentType = MimetypesFileTypeMap.getDefaultFileTypeMap().getContentType(key); + } + + // 上传文件 + try { + ObjectMetadata objectMetadata = new ObjectMetadata(); + objectMetadata.setContentType(contentType); + cosClient.putObject(bucketName, key, inputStream, objectMetadata); + } catch (CosServiceException e) { + throw new TencentFileServiceException(e); + } catch (CosClientException e) { + throw new TencentFileServiceException(e); + } finally { + IoUtil.close(inputStream); + } + } + + @Override + public byte[] getFileBytes(String bucketName, String key) { + COSObjectInputStream cosObjectInput = null; + try { + GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, key); + COSObject cosObject = cosClient.getObject(getObjectRequest); + cosObjectInput = cosObject.getObjectContent(); + return IoUtil.readBytes(cosObjectInput); + } catch (CosServiceException e) { + throw new TencentFileServiceException(e); + } catch (CosClientException e) { + throw new TencentFileServiceException(e); + } finally { + IoUtil.close(cosObjectInput); + } + } + + @Override + public void setFileAcl(String bucketName, String key, BucketAuthEnum bucketAuthEnum) { + if (bucketAuthEnum.equals(BucketAuthEnum.PRIVATE)) { + cosClient.setObjectAcl(bucketName, key, CannedAccessControlList.Private); + } else if (bucketAuthEnum.equals(BucketAuthEnum.PUBLIC_READ)) { + cosClient.setObjectAcl(bucketName, key, CannedAccessControlList.PublicRead); + } else if (bucketAuthEnum.equals(BucketAuthEnum.PUBLIC_READ_WRITE)) { + cosClient.setObjectAcl(bucketName, key, CannedAccessControlList.PublicReadWrite); + } + } + + @Override + public void copyFile(String originBucketName, String originFileKey, String newBucketName, String newFileKey) { + // 初始化拷贝参数 + Region srcBucketRegion = new Region(tenCosProperties.getRegionId()); + CopyObjectRequest copyObjectRequest = new CopyObjectRequest( + srcBucketRegion, originBucketName, originFileKey, newBucketName, newFileKey); + + // 拷贝对象 + try { + transferManager.copy(copyObjectRequest, cosClient, null); + } catch (CosServiceException e) { + throw new TencentFileServiceException(e); + } catch (CosClientException e) { + throw new TencentFileServiceException(e); + } + } + + @Override + public String getFileAuthUrl(String bucketName, String key, Long timeoutMillis) { + GeneratePresignedUrlRequest presignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, key, HttpMethodName.GET); + Date expirationDate = new Date(System.currentTimeMillis() + timeoutMillis); + presignedUrlRequest.setExpiration(expirationDate); + URL url = null; + try { + url = cosClient.generatePresignedUrl(presignedUrlRequest); + } catch (CosServiceException e) { + throw new TencentFileServiceException(e); + } catch (CosClientException e) { + throw new TencentFileServiceException(e); + } + return url.toString(); + } + + @Override + public void deleteFile(String bucketName, String key) { + cosClient.deleteObject(bucketName, key); + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/file/modular/tencent/exp/TencentFileServiceException.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/file/modular/tencent/exp/TencentFileServiceException.java new file mode 100644 index 00000000..ae08c2b5 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/file/modular/tencent/exp/TencentFileServiceException.java @@ -0,0 +1,46 @@ +package com.cn.xiaonuo.core.file.modular.tencent.exp; + +import com.qcloud.cos.exception.CosClientException; +import com.qcloud.cos.exception.CosServiceException; +import lombok.Getter; + +/** + * 腾讯文件操作异常 + * + * @author xuyuxiang + * @date 2020-05-23-2:42 下午 + */ +@Getter +public class TencentFileServiceException extends RuntimeException { + + /** + * 客户端异常 + *

+ * 是由于客户端原因导致无法和服务端完成正常的交互而导致的失败,如客户端无法连接到服务端,无法解析服务端返回的数据 + */ + private CosClientException cosClientException; + + /** + * 服务端异常 + *

+ * 用于指交互正常完成,但是操作失败的场景 + *

+ * 例如客户端访问一个不存在 Bucket,删除一个不存在的文件,没有权限进行某个操作, 服务端故障异常等 + */ + private CosServiceException cosServiceException; + + public TencentFileServiceException(String message) { + super(message); + } + + public TencentFileServiceException(CosClientException cosClientException) { + super(cosClientException.getMessage()); + this.cosClientException = cosClientException; + } + + public TencentFileServiceException(CosServiceException cosServiceException) { + super(cosServiceException.getMessage()); + this.cosServiceException = cosServiceException; + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/file/modular/tencent/prop/TenCosProperties.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/file/modular/tencent/prop/TenCosProperties.java new file mode 100644 index 00000000..d6891025 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/file/modular/tencent/prop/TenCosProperties.java @@ -0,0 +1,29 @@ +package com.cn.xiaonuo.core.file.modular.tencent.prop; + +import lombok.Data; + +/** + * 腾讯云cos文件存储配置 + * + * @author xuyuxiang + * @date 2020/5/22 6:56 下午 + */ +@Data +public class TenCosProperties { + + /** + * secretId + */ + private String secretId; + + /** + * secretKey + */ + private String secretKey; + + /** + * 地域id(默认北京) + */ + private String regionId = "ap-beijing"; + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/base/entity/BaseEntity.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/base/entity/BaseEntity.java new file mode 100644 index 00000000..875f1743 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/base/entity/BaseEntity.java @@ -0,0 +1,69 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.pojo.base.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 通用基础字段,需要此通用字段的实体可继承此类 + * + * @author xuyuxiang + * @date 2020/3/10 16:02 + */ +@Data +public class BaseEntity implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 创建时间 + */ + @TableField(fill = FieldFill.INSERT) + private Date createTime; + + /** + * 创建人 + */ + @TableField(fill = FieldFill.INSERT) + private Long createUser; + + /** + * 更新时间 + */ + @TableField(fill = FieldFill.UPDATE) + private Date updateTime; + + /** + * 更新人 + */ + @TableField(fill = FieldFill.UPDATE) + private Long updateUser; + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/base/node/BaseTreeNode.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/base/node/BaseTreeNode.java new file mode 100644 index 00000000..327c1384 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/base/node/BaseTreeNode.java @@ -0,0 +1,64 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.pojo.base.node; + +import java.util.List; + +/** + * 树节点接口 + * + * @author xuyuxiang + * @date 2020/4/5 14:07 + */ +public interface BaseTreeNode { + + + /** + * 获取节点id + * + * @return 节点id + * @author xuyuxiang + * @date 2020/7/9 18:36 + */ + Long getId(); + + /** + * 获取节点父id + * + * @return 节点父id + * @author xuyuxiang + * @date 2020/7/9 18:36 + */ + Long getPid(); + + /** + * 设置children + * + * @param children 子节点集合 + * @author xuyuxiang + * @date 2020/7/9 18:36 + */ + void setChildren(List children); +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/base/param/BaseParam.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/base/param/BaseParam.java new file mode 100644 index 00000000..7ecfa2c0 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/base/param/BaseParam.java @@ -0,0 +1,272 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.pojo.base.param; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 通用基础参数,相关实体参数校验可继承此类 + * + * @author xuyuxiang + * @date 2020/3/10 16:02 + */ +@Data +public class BaseParam implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 搜索值 + */ + private String searchValue; + + /** + * 数据权限 + */ + private List dataScope; + + /** + * 开始时间 + */ + private String searchBeginTime; + + /** + * 结束时间 + */ + private String searchEndTime; + + /** + * 状态(字典 0正常 1停用 2删除) + */ + private Integer searchStatus; + + /** + * 参数校验分组:分页 + */ + public @interface page { + } + + /** + * 参数校验分组:列表 + */ + public @interface list { + } + + /** + * 参数校验分组:下拉 + */ + public @interface dropDown { + } + + /** + * 参数校验分组:增加 + */ + public @interface add { + } + + /** + * 参数校验分组:编辑 + */ + public @interface edit { + } + + /** + * 参数校验分组:更新信息 + */ + public @interface updateInfo { + } + + /** + * 参数校验分组:修改密码 + */ + public @interface updatePwd { + } + + /** + * 参数校验分组:重置密码 + */ + public @interface resetPwd { + } + + /** + * 参数校验分组:修改头像 + */ + public @interface updateAvatar { + } + + /** + * 参数校验分组:删除 + */ + public @interface delete { + } + + /** + * 参数校验分组:详情 + */ + public @interface detail { + } + + /** + * 参数校验分组:授权角色 + */ + public @interface grantRole { + } + + /** + * 参数校验分组:授权菜单 + */ + public @interface grantMenu { + } + + /** + * 参数校验分组:授权数据 + */ + public @interface grantData { + } + + /** + * 参数校验分组:强退 + */ + public @interface force { + } + + /** + * 参数校验分组:停用 + */ + public @interface stop { + } + + /** + * 参数校验分组:启用 + */ + public @interface start { + } + + /** + * 参数校验分组:部署 + */ + public @interface deploy { + } + + /** + * 参数校验分组:挂起 + */ + public @interface suspend { + } + + /** + * 参数校验分组:激活 + */ + public @interface active { + } + + /** + * 参数校验分组:委托 + */ + public @interface entrust { + } + + /** + * 参数校验分组:转办 + */ + public @interface turn { + } + + /** + * 参数校验分组:追踪 + */ + public @interface trace { + } + + /** + * 参数校验分组:跳转 + */ + public @interface jump { + } + + /** + * 参数校验分组:提交 + */ + public @interface submit { + } + + /** + * 参数校验分组:退回 + */ + public @interface back { + } + + /** + * 参数校验分组:终止 + */ + public @interface end { + } + + /** + * 参数校验分组:导出 + */ + public @interface export { + } + + /** + * 参数校验分组:映射 + */ + public @interface mapping { + } + + /** + * 参数校验分组:切换 + */ + public @interface change { + } + + /** + * 参数校验分组:历史审批记录 + */ + public @interface commentHistory { + } + + /** + * 参数校验分组:修改状态 + */ + public @interface changeStatus { + } + + /** + * 参数校验分组:加签 + */ + public @interface addSign { + } + + /** + * 参数校验分组:减签 + */ + public @interface deleteSign { + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/base/validate/UniqueValidateParam.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/base/validate/UniqueValidateParam.java new file mode 100644 index 00000000..c9b01fbc --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/base/validate/UniqueValidateParam.java @@ -0,0 +1,56 @@ +package com.cn.xiaonuo.core.pojo.base.validate; + +import lombok.Builder; +import lombok.Data; + +/** + * 校验参数时用的方法参数 + * + * @author xuyuxiang + * @date 2020/8/17 21:43 + */ +@Data +@Builder +public class UniqueValidateParam { + + /** + * 表名称 + */ + String tableName; + + /** + * 列名称 + */ + String columnName; + + /** + * 被参数校验时候的字段的值 + */ + String value; + + /** + * 校验时,是否排除当前的记录 + */ + Boolean excludeCurrentRecord; + + /** + * 当前记录的主键id + */ + Long id; + + /** + * 排除所有被逻辑删除的记录的控制 + */ + Boolean excludeLogicDeleteItems; + + /** + * 逻辑删除的字段名 + */ + String logicDeleteFieldName; + + /** + * 逻辑删除的字段的值 + */ + String logicDeleteValue; + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/base/wrapper/BaseWrapper.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/base/wrapper/BaseWrapper.java new file mode 100644 index 00000000..4cd6e30a --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/base/wrapper/BaseWrapper.java @@ -0,0 +1,47 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.pojo.base.wrapper; + +import java.util.Map; + +/** + * 基础包装接口, + * + * @author xuyuxiang + * @date 2020/7/24 17:18 + */ +public interface BaseWrapper { + + /** + * 具体包装的过程 + * + * @param beWrappedModel 被包装的原始对象,可以是obj,list,page,PageResult + * @return 包装后增加的增量集合 + * @author xuyuxiang + * @date 2020/7/24 17:22 + */ + Map doWrap(T beWrappedModel); + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/druid/DruidProperties.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/druid/DruidProperties.java new file mode 100644 index 00000000..de79e949 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/druid/DruidProperties.java @@ -0,0 +1,174 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.pojo.druid; + +import cn.hutool.log.Log; +import com.cn.xiaonuo.core.enums.DbIdEnum; +import com.alibaba.druid.pool.DruidDataSource; +import lombok.Data; + +import java.sql.SQLException; +import java.util.Properties; + +/** + *

数据库数据源配置

+ *

说明:类中属性包含默认值的不要在这里修改,应该在"application.yml"中配置

+ * + * @author yubaoshan + * @date 2017/5/21 11:18 + */ +@Data +public class DruidProperties { + + private static final Log log = Log.get(); + + /** + * oracle校验语句 + */ + private final String ORACLE_VALIDATE_QUERY_SQL = "select 1 from dual"; + + /** + * postgresql校验语句 + */ + private final String POSTGRESQL_VALIDATE_QUERY_SQL = "select version()"; + + /** + * sqlserver校验语句 + */ + private final String SQLSERVER_VALIDATE_QUERY_SQL = "select 1"; + + /** + * mysql校验语句 + */ + private final String MYSQL_VALIDATE_QUERY_SQL = "select 1"; + + private String url; + + private String username; + + private String password; + + private String driverClassName; + + private Integer initialSize = 2; + + private Integer minIdle = 1; + + private Integer maxActive = 20; + + private Integer maxWait = 60000; + + private Integer timeBetweenEvictionRunsMillis = 60000; + + private Integer minEvictableIdleTimeMillis = 300000; + + private String validationQuery; + + private Boolean testWhileIdle = true; + + private Boolean testOnBorrow = true; + + private Boolean testOnReturn = true; + + private Boolean poolPreparedStatements = true; + + private Integer maxPoolPreparedStatementPerConnectionSize = 20; + + private String filters = "stat,wall"; + + private String dataSourceName; + + public void config(DruidDataSource dataSource) { + + dataSource.setUrl(url); + dataSource.setUsername(username); + dataSource.setPassword(password); + + dataSource.setDriverClassName(driverClassName); + //定义初始连接数 + dataSource.setInitialSize(initialSize); + //最小空闲 + dataSource.setMinIdle(minIdle); + //定义最大连接数 + dataSource.setMaxActive(maxActive); + //最长等待时间 + dataSource.setMaxWait(maxWait); + + //配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); + + //配置一个连接在池中最小生存的时间,单位是毫秒 + dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); + dataSource.setValidationQuery(getValidateQueryByUrl(url)); + dataSource.setTestWhileIdle(testWhileIdle); + dataSource.setTestOnBorrow(testOnBorrow); + dataSource.setTestOnReturn(testOnReturn); + + //打开PSCache,并且指定每个连接上PSCache的大小 + dataSource.setPoolPreparedStatements(poolPreparedStatements); + dataSource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize); + + try { + dataSource.setFilters(filters); + } catch (SQLException e) { + log.error(">>> 数据库连接池初始化异常:{}", e.getMessage()); + } + } + + public Properties createProperties() { + Properties properties = new Properties(); + properties.put("url", this.url); + properties.put("username", this.username); + properties.put("password", this.password); + properties.put("driverClassName", this.driverClassName); + properties.put("initialSize", this.initialSize); + properties.put("maxActive", this.maxActive); + properties.put("minIdle", this.minIdle); + properties.put("maxWait", this.maxWait); + properties.put("poolPreparedStatements", this.poolPreparedStatements); + properties.put("maxPoolPreparedStatementPerConnectionSize", this.maxPoolPreparedStatementPerConnectionSize); + properties.put("validationQuery", getValidateQueryByUrl(this.url)); + properties.put("testOnBorrow", this.testOnBorrow); + properties.put("testOnReturn", this.testOnReturn); + properties.put("testWhileIdle", this.testWhileIdle); + properties.put("timeBetweenEvictionRunsMillis", this.timeBetweenEvictionRunsMillis); + properties.put("minEvictableIdleTimeMillis", this.minEvictableIdleTimeMillis); + properties.put("filters", this.filters); + return properties; + } + + private String getValidateQueryByUrl(String url) { + if (url.contains(DbIdEnum.ORACLE.getName())) { + return ORACLE_VALIDATE_QUERY_SQL; + } else if (url.contains(DbIdEnum.PG_SQL.getName())) { + return POSTGRESQL_VALIDATE_QUERY_SQL; + } else if (url.contains(DbIdEnum.MS_SQL.getName())) { + return SQLSERVER_VALIDATE_QUERY_SQL; + } else { + return MYSQL_VALIDATE_QUERY_SQL; + } + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/email/EmailConfigs.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/email/EmailConfigs.java new file mode 100644 index 00000000..2edae5cb --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/email/EmailConfigs.java @@ -0,0 +1,68 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.pojo.email; + +import lombok.Data; + +/** + * 邮件的配置 + * + * @author yubaoshan + * @date 2020/6/9 23:16 + */ +@Data +public class EmailConfigs { + + /** + * host + */ + private String host; + + /** + * 邮箱用户名 + */ + private String user; + + /** + * 邮箱密码或者安全码 + */ + private String pass; + + /** + * 邮箱端口 + */ + private Integer port; + + /** + * 邮箱发件人 + */ + private String from; + + /** + * 使用 SSL安全连接 + */ + private Boolean sslEnable; + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/login/LoginEmpInfo.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/login/LoginEmpInfo.java new file mode 100644 index 00000000..a624fab0 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/login/LoginEmpInfo.java @@ -0,0 +1,69 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.pojo.login; + +import cn.hutool.core.lang.Dict; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 登录用户员工信息 + * + * @author xuyuxiang + * @date 2020/3/11 16:44 + */ +@Data +public class LoginEmpInfo implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 工号 + */ + private String jobNum; + + /** + * 所属机构id + */ + private Long orgId; + + /** + * 所属机构名称 + */ + private String orgName; + + /** + * 附属机构与职位信息 + */ + private List extOrgPos; + + /** + * 职位信息 + */ + private List positions; + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/login/SysLoginUser.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/login/SysLoginUser.java new file mode 100644 index 00000000..b5811e34 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/login/SysLoginUser.java @@ -0,0 +1,217 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.pojo.login; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.lang.Dict; +import cn.hutool.core.util.ObjectUtil; +import com.cn.xiaonuo.core.consts.CommonConstant; +import com.cn.xiaonuo.core.pojo.node.LoginMenuTreeNode; +import lombok.Data; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; + +/** + * 登录用户模型 + * + * @author xuyuxiang + * @date 2020/3/11 12:21 + */ +@Data +public class SysLoginUser implements UserDetails, Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + private Long id; + + /** + * 账号 + */ + private String account; + + /** + * 昵称 + */ + private String nickName; + + /** + * 姓名 + */ + private String name; + + /** + * 头像 + */ + private String avatar; + + /** + * 生日 + */ + private Date birthday; + + /** + * 性别(字典 1男 2女) + */ + private Integer sex; + + /** + * 邮箱 + */ + private String email; + + /** + * 手机 + */ + private String phone; + + /** + * 电话 + */ + private String tel; + + /** + * 管理员类型(0超级管理员 1非管理员) + */ + private Integer adminType; + + /** + * 最后登陆IP + */ + private String lastLoginIp; + + /** + * 最后登陆时间 + */ + private String lastLoginTime; + + /** + * 最后登陆地址 + */ + private String lastLoginAddress; + + /** + * 最后登陆所用浏览器 + */ + private String lastLoginBrowser; + + /** + * 最后登陆所用系统 + */ + private String lastLoginOs; + + /** + * 员工信息 + */ + private LoginEmpInfo loginEmpInfo; + + /** + * 具备应用信息 + */ + private List apps; + + /** + * 角色信息 + */ + private List roles; + + /** + * 权限信息 + */ + private List permissions; + + /** + * 登录菜单信息,AntDesign版本菜单 + */ + private List menus; + + /** + * 数据范围信息 + */ + private List dataScopes; + + /** + * 租户信息 + */ + private Dict tenants; + + /** + * 角色名称集合 + */ + @Override + public Collection getAuthorities() { + ArrayList grantedAuthorities = CollectionUtil.newArrayList(); + if (ObjectUtil.isNotEmpty(roles)) { + roles.forEach(dict -> { + String roleName = dict.getStr(CommonConstant.NAME); + XiaoNuoAuthority xiaoNuoAuthority = new XiaoNuoAuthority(roleName); + grantedAuthorities.add(xiaoNuoAuthority); + }); + } + return grantedAuthorities; + } + + @Override + public String getPassword() { + return null; + } + + @Override + public String getUsername() { + return this.account; + } + + @Override + public boolean isAccountNonExpired() { + //能生成loginUser就是jwt解析成功,没锁定 + return true; + } + + @Override + public boolean isAccountNonLocked() { + //能生成loginUser就是jwt解析成功,没锁定 + return true; + } + + @Override + public boolean isCredentialsNonExpired() { + //能生成loginUser就是jwt解析成功,没锁定 + return true; + } + + @Override + public boolean isEnabled() { + //能生成loginUser就是jwt解析成功,没锁定 + return true; + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/login/XiaoNuoAuthority.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/login/XiaoNuoAuthority.java new file mode 100644 index 00000000..cbe0a6ad --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/login/XiaoNuoAuthority.java @@ -0,0 +1,48 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.pojo.login; + +import lombok.AllArgsConstructor; +import lombok.Data; +import org.springframework.security.core.GrantedAuthority; + +/** + * 用来包装一下角色名称 + * + * @author yubaoshan + * @date 2020/4/10 13:08 + */ +@Data +@AllArgsConstructor +public class XiaoNuoAuthority implements GrantedAuthority { + + private String authority; + + @Override + public String getAuthority() { + return authority; + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/node/AntdBaseTreeNode.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/node/AntdBaseTreeNode.java new file mode 100644 index 00000000..0dde57d3 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/node/AntdBaseTreeNode.java @@ -0,0 +1,88 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.pojo.node; + +import com.cn.xiaonuo.core.pojo.base.node.BaseTreeNode; +import com.cn.xiaonuo.core.pojo.base.node.BaseTreeNode; +import lombok.Data; + +import java.util.List; + +/** + * antd通用前端树节点 + * + * @author yubaoshan + * @date 2020/6/9 12:42 + */ +@Data +public class AntdBaseTreeNode implements BaseTreeNode { + + /** + * 主键 + */ + private Long id; + + /** + * 父id + */ + private Long parentId; + + /** + * 名称 + */ + private String title; + + /** + * 值 + */ + private String value; + + /** + * 排序,越小优先级越高 + */ + private Integer weight; + + /** + * 子节点 + */ + private List children; + + /** + * 父id别名 + */ + @Override + public Long getPid() { + return this.parentId; + } + + /** + * 子节点 + */ + @Override + public void setChildren(List children) { + this.children = children; + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/node/CommonBaseTreeNode.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/node/CommonBaseTreeNode.java new file mode 100644 index 00000000..375c3bb0 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/node/CommonBaseTreeNode.java @@ -0,0 +1,91 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.pojo.node; + +import com.cn.xiaonuo.core.pojo.base.node.BaseTreeNode; +import com.cn.xiaonuo.core.pojo.base.node.BaseTreeNode; +import lombok.Data; + +import java.util.List; + +/** + * 通用树节点 + * + * @author xuyuxiang + * @date 2020/3/26 14:29 + */ +@Data +public class CommonBaseTreeNode implements BaseTreeNode { + + /** + * 节点id + */ + private Long id; + + /** + * 节点父id + */ + private Long pid; + + /** + * 节点名称 + */ + private String nodeName; + + /** + * 子节点集合 + */ + private List children; + + @Override + public Long getId() { + return this.id; + } + + @Override + public Long getPid() { + return this.pid; + } + + @Override + public void setChildren(List children) { + this.children = children; + } + + /*@Override + public String getNodeId() { + return this.nodeId; + } + + @Override + public String getNodeParentId() { + return this.nodeParentId; + } + + @Override + public void setChildrenNodes(List childrenNodes) { + this.childrenNodes = childrenNodes; + }*/ +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/node/LoginMenuTreeNode.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/node/LoginMenuTreeNode.java new file mode 100644 index 00000000..2a61fed8 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/node/LoginMenuTreeNode.java @@ -0,0 +1,111 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.pojo.node; + +import lombok.Data; + +/** + * 登录菜单 + * + * @author yubaoshan + * @date 2020/4/17 17:35 + */ +@Data +public class LoginMenuTreeNode { + + /** + * id + */ + private Long id; + + /** + * 父id + */ + private Long pid; + + /** + * 路由名称, 必须设置,且不能重名 + */ + private String name; + + /** + * 组件 + */ + private String component; + + /** + * 重定向地址, 访问这个路由时, 自定进行重定向 + */ + private String redirect; + + /** + * 路由元信息(路由附带扩展信息) + */ + private Meta meta; + + /** + * 路径 + */ + private String path; + + /** + * 控制路由和子路由是否显示在 sidebar + */ + private boolean hidden; + + /** + * 路由元信息内部类 + */ + @Data + public class Meta { + + /** + * 路由标题, 用于显示面包屑, 页面标题 *推荐设置 + */ + public String title; + + /** + * 图标 + */ + public String icon; + + /** + * 是否可见 + */ + public boolean show; + + /** + * 如需外部打开,增加:_blank + */ + public String target; + + /** + * 内链打开http链接 + */ + public String link; + + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/oauth/OauthConfigs.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/oauth/OauthConfigs.java new file mode 100644 index 00000000..68f645c5 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/oauth/OauthConfigs.java @@ -0,0 +1,52 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.pojo.oauth; + +import lombok.Data; + +/** + * Oauth第三方登录配置 + * + * @author xuyuxiang + * @date 2020/7/28 17:18 + **/ +@Data +public class OauthConfigs { + + /** + * clientId + */ + private String clientId; + + /** + * clientSecret + */ + private String clientSecret; + + /** + * 回调地址 + */ + private String redirectUri; +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/page/PageResult.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/page/PageResult.java new file mode 100644 index 00000000..5cacecf9 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/page/PageResult.java @@ -0,0 +1,118 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.pojo.page; + +import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.PageUtil; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 分页结果集 + * + * @author xuyuxiang + * @date 2020/3/30 15:44 + */ +@Data +public class PageResult implements Serializable { + + private static final long serialVersionUID = -1L; + + /** + * 默认分页彩虹展示数量 + */ + public static final int RAINBOW_NUM = 5; + + /** + * 第几页 + */ + private Integer pageNo = 1; + + /** + * 每页条数 + */ + private Integer pageSize = 20; + + /** + * 总页数 + */ + private Integer totalPage = 0; + + /** + * 总记录数 + */ + private Integer totalRows = 0; + + /** + * 结果集 + */ + private List rows; + + /** + * 分页彩虹 + */ + private int[] rainbow; + + public PageResult() { + } + + /** + * 将mybatis-plus的page转成自定义的PageResult,扩展了totalPage总页数,和rainBow彩虹条 + * + * @author xuyuxiang + * @date 2020/4/8 19:20 + */ + public PageResult(Page page) { + this.setRows(page.getRecords()); + this.setTotalRows(Convert.toInt(page.getTotal())); + this.setPageNo(Convert.toInt(page.getCurrent())); + this.setPageSize(Convert.toInt(page.getSize())); + this.setTotalPage(PageUtil.totalPage(Convert.toInt(page.getTotal()), + Convert.toInt(page.getSize()))); + this.setRainbow(PageUtil.rainbow(Convert.toInt(page.getCurrent()), + Convert.toInt(this.getTotalPage()), RAINBOW_NUM)); + } + + /** + * 将mybatis-plus的page转成自定义的PageResult,扩展了totalPage总页数,和rainBow彩虹条 + * 可单独设置rows + * + * @author xuyuxiang + * @date 2020/4/14 20:55 + */ + public PageResult(Page page, List t) { + this.setRows(t); + this.setTotalRows(Convert.toInt(page.getTotal())); + this.setPageNo(Convert.toInt(page.getCurrent())); + this.setPageSize(Convert.toInt(page.getSize())); + this.setTotalPage(PageUtil.totalPage(Convert.toInt(page.getTotal()), + Convert.toInt(page.getSize()))); + this.setRainbow(PageUtil.rainbow(Convert.toInt(page.getCurrent()), + Convert.toInt(this.getTotalPage()), RAINBOW_NUM)); + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/response/ErrorResponseData.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/response/ErrorResponseData.java new file mode 100644 index 00000000..6a1f2ad0 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/response/ErrorResponseData.java @@ -0,0 +1,56 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.pojo.response; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 失败响应结果 + * + * @author xuyuxiang + * @date 2020/3/30 15:05 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class ErrorResponseData extends ResponseData { + + /** + * 异常的具体类名称 + */ + private String exceptionClazz; + + ErrorResponseData(String message) { + super(false, DEFAULT_ERROR_CODE, message, null); + } + + public ErrorResponseData(Integer code, String message) { + super(false, code, message, null); + } + + ErrorResponseData(Integer code, String message, Object object) { + super(false, code, message, object); + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/response/ResponseData.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/response/ResponseData.java new file mode 100644 index 00000000..104d5257 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/response/ResponseData.java @@ -0,0 +1,99 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.pojo.response; + +import lombok.Data; + +/** + * 响应结果数据 + * + * @author xuyuxiang + * @date 2020/3/30 15:04 + */ +@Data +public class ResponseData { + + public static final String DEFAULT_SUCCESS_MESSAGE = "请求成功"; + + public static final String DEFAULT_ERROR_MESSAGE = "网络异常"; + + public static final Integer DEFAULT_SUCCESS_CODE = 200; + + public static final Integer DEFAULT_ERROR_CODE = 500; + + /** + * 请求是否成功 + */ + private Boolean success; + + /** + * 响应状态码 + */ + private Integer code; + + /** + * 响应信息 + */ + private String message; + + /** + * 响应对象 + */ + private Object data; + + public ResponseData() { + } + + public ResponseData(Boolean success, Integer code, String message, Object data) { + this.success = success; + this.code = code; + this.message = message; + this.data = data; + } + + public static SuccessResponseData success() { + return new SuccessResponseData(); + } + + public static SuccessResponseData success(Object object) { + return new SuccessResponseData(object); + } + + public static SuccessResponseData success(Integer code, String message, Object object) { + return new SuccessResponseData(code, message, object); + } + + public static ErrorResponseData error(String message) { + return new ErrorResponseData(message); + } + + public static ErrorResponseData error(Integer code, String message) { + return new ErrorResponseData(code, message); + } + + public static ErrorResponseData error(Integer code, String message, Object object) { + return new ErrorResponseData(code, message, object); + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/response/SuccessResponseData.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/response/SuccessResponseData.java new file mode 100644 index 00000000..74e74a18 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/response/SuccessResponseData.java @@ -0,0 +1,46 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.pojo.response; + +/** + * 成功响应结果 + * + * @author xuyuxiang + * @date 2020/3/30 15:04 + */ +public class SuccessResponseData extends ResponseData { + + public SuccessResponseData() { + super(true, DEFAULT_SUCCESS_CODE, DEFAULT_SUCCESS_MESSAGE, null); + } + + public SuccessResponseData(Object object) { + super(true, DEFAULT_SUCCESS_CODE, DEFAULT_SUCCESS_MESSAGE, object); + } + + public SuccessResponseData(Integer code, String message, Object object) { + super(true, code, message, object); + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/sms/AliyunSmsConfigs.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/sms/AliyunSmsConfigs.java new file mode 100644 index 00000000..03f4744f --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/sms/AliyunSmsConfigs.java @@ -0,0 +1,63 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.pojo.sms; + +import lombok.Data; + +/** + * 阿里云oss相关配置 + * + * @author yubaoshan + * @date 2018/6/27 13:20 + */ +@Data +public class AliyunSmsConfigs { + + /** + * accessKeyId + */ + private String accessKeyId; + + /** + * accessKeySecret + */ + private String accessKeySecret; + + /** + * 签名名称 + */ + private String signName; + + /** + * 登录验证码的模板 + */ + private String loginTemplateCode; + + /** + * 短信失效时间(分钟) + */ + private Integer invalidateMinutes = 2; + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/sms/TencentSmsConfigs.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/sms/TencentSmsConfigs.java new file mode 100644 index 00000000..56ce93f2 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/pojo/sms/TencentSmsConfigs.java @@ -0,0 +1,64 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.pojo.sms; + +import lombok.Data; + +/** + * 阿里云oss相关配置 + * + * @author yubaoshan + * @date 2018/6/27 13:20 + */ +@Data +public class TencentSmsConfigs { + + /** + * secretId + */ + private String secretId; + + /** + * secretKey + */ + private String secretKey; + + /** + * 应用控制台应用管理中的应用id + *

+ * 在 [短信控制台] 添加应用后生成的实际 SDKAppID,例如1400006666 + *

+ * 短信控制台:https://console.cloud.tencent.com/smsv2 + */ + private String sdkAppId; + + /** + * 签名,一般为中文名 + *

+ * 短信签名内容: 使用 UTF-8 编码,必须填写已审核通过的签名,可登录 [短信控制台] 查看签名信息 + */ + private String sign; + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/sms/SmsSender.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/sms/SmsSender.java new file mode 100644 index 00000000..1de7ac42 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/sms/SmsSender.java @@ -0,0 +1,26 @@ +package com.cn.xiaonuo.core.sms; + +import java.util.Map; + +/** + * 短信发送服务 + * + * @author xuyuxiang + * @date 2018-07-06-下午2:14 + */ +public interface SmsSender { + + /** + * 发送短信 + *

+ * 如果是腾讯云,params要用LinkedHashMap,保证顺序 + * + * @param phone 电话号码 + * @param templateCode 模板号码 + * @param params 模板里参数的集合 + * @author xuyuxiang + * @date 2018/7/6 下午2:32 + */ + void sendSms(String phone, String templateCode, Map params); + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/sms/modular/aliyun/AliyunSmsSender.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/sms/modular/aliyun/AliyunSmsSender.java new file mode 100644 index 00000000..6219f26b --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/sms/modular/aliyun/AliyunSmsSender.java @@ -0,0 +1,156 @@ +package com.cn.xiaonuo.core.sms.modular.aliyun; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.aliyuncs.CommonRequest; +import com.aliyuncs.CommonResponse; +import com.aliyuncs.DefaultAcsClient; +import com.aliyuncs.IAcsClient; +import com.aliyuncs.exceptions.ClientException; +import com.aliyuncs.profile.DefaultProfile; +import com.cn.xiaonuo.core.sms.SmsSender; +import com.cn.xiaonuo.core.sms.modular.aliyun.enums.AliyunSmsResultEnum; +import com.cn.xiaonuo.core.sms.modular.aliyun.exp.AliyunSmsException; +import com.cn.xiaonuo.core.sms.modular.aliyun.msign.MultiSignManager; +import com.cn.xiaonuo.core.sms.modular.aliyun.prop.AliyunSmsProperties; +import lombok.extern.slf4j.Slf4j; + +import java.util.Map; + +/** + * 阿里云短信发送服务 + * + * @author xuyuxiang + * @date 2018-07-06-下午2:15 + */ +@Slf4j +public class AliyunSmsSender implements SmsSender { + + private final MultiSignManager multiSignManager; + + private final AliyunSmsProperties aliyunSmsProperties; + + public AliyunSmsSender(MultiSignManager multiSignManager, AliyunSmsProperties aliyunSmsProperties) { + this.multiSignManager = multiSignManager; + this.aliyunSmsProperties = aliyunSmsProperties; + } + + @Override + public void sendSms(String phone, String templateCode, Map params) { + + log.info("开始发送阿里云短信,手机号是:" + phone + ",模板号是:" + templateCode + ",参数是:" + params); + + // 检验参数是否合法 + assertSendSmsParams(phone, templateCode, params, aliyunSmsProperties); + + // 初始化client profile + IAcsClient iAcsClient = initClient(); + + // 组装请求对象 + JSONObject smsRes = createSmsRequest(phone, templateCode, params, iAcsClient); + + // 如果返回ok则发送成功 + if (!AliyunSmsResultEnum.OK.getCode().equals(smsRes.getString("Code"))) { + + // 返回其他状态码根据情况抛出业务异常 + String code = AliyunSmsResultEnum.SYSTEM_ERROR.getCode(); + String errorMessage = AliyunSmsResultEnum.SYSTEM_ERROR.getMessage(); + for (AliyunSmsResultEnum smsExceptionEnum : AliyunSmsResultEnum.values()) { + if (smsExceptionEnum.getCode().equals(smsRes.getString("Code"))) { + code = smsExceptionEnum.getCode(); + errorMessage = smsExceptionEnum.getMessage(); + } + } + log.error("发送短信异常!code = " + code + ",message = " + errorMessage); + throw new AliyunSmsException(code, errorMessage); + } + } + + /** + * 初始化短信发送的客户端 + * + * @author xuyuxiang + * @date 2018/7/6 下午3:57 + */ + private IAcsClient initClient() { + final String accessKeyId = aliyunSmsProperties.getAccessKeyId(); + final String accessKeySecret = aliyunSmsProperties.getAccessKeySecret(); + + // 创建DefaultAcsClient实例并初始化 + DefaultProfile profile = DefaultProfile.getProfile(aliyunSmsProperties.getRegionId(), accessKeyId, accessKeySecret); + return new DefaultAcsClient(profile); + } + + /** + * 组装请求对象 + * + * @author xuyuxiang + * @date 2018/7/6 下午3:00 + */ + private JSONObject createSmsRequest(String phoneNumber, String templateCode, Map params, IAcsClient acsClient) { + CommonRequest request = new CommonRequest(); + request.setSysDomain(aliyunSmsProperties.getSmsDomain()); + request.setSysVersion(aliyunSmsProperties.getSmsVersion()); + request.setSysAction(aliyunSmsProperties.getSmsSendAction()); + + // 接收短信的手机号码 + request.putQueryParameter("PhoneNumbers", phoneNumber); + + // 短信签名名称。请在控制台签名管理页面签名名称一列查看(必须是已添加、并通过审核的短信签名)。 + request.putQueryParameter("SignName", this.getSmsSign(phoneNumber)); + + // 短信模板ID + request.putQueryParameter("TemplateCode", templateCode); + + // 短信模板变量对应的实际值,JSON格式。 + request.putQueryParameter("TemplateParam", JSON.toJSONString(params)); + + //请求失败这里会抛ClientException异常 + CommonResponse commonResponse; + try { + commonResponse = acsClient.getCommonResponse(request); + String data = commonResponse.getData(); + String jsonResult = data.replaceAll("'\'", ""); + log.info("获取到发送短信的响应结果!{}", jsonResult); + return JSON.parseObject(jsonResult); + } catch (ClientException e) { + log.error("初始化阿里云sms异常!可能是accessKey和secret错误!", e); + throw new AliyunSmsException(AliyunSmsResultEnum.INIT_SMS_CLIENT_ERROR.getCode(), + AliyunSmsResultEnum.INIT_SMS_CLIENT_ERROR.getMessage()); + } + } + + /** + * 校验发送短信的参数是否正确 + * + * @author xuyuxiang + * @date 2018/7/6 下午3:19 + */ + private void assertSendSmsParams(String phoneNumber, String templateCode, Map params, + AliyunSmsProperties aliyunSmsProperties) { + if (ObjectUtil.hasEmpty(phoneNumber, templateCode, params, aliyunSmsProperties)) { + log.error("阿里云短信发送异常!请求参数存在空!"); + throw new AliyunSmsException(AliyunSmsResultEnum.PARAM_NULL.getCode(), AliyunSmsResultEnum.PARAM_NULL.getMessage()); + } + } + + /** + * 获取sms发送的sign标识,参数phone是发送的手机号码 + * + * @author xuyuxiang + * @date 2018/8/13 21:23 + */ + private String getSmsSign(String phone) { + String signName = aliyunSmsProperties.getSignName(); + + // 如果是单个签名就用一个签名发 + if (!signName.contains(",")) { + log.info("发送短信,签名为:" + signName + ",电话为:" + phone); + return signName; + } else { + return multiSignManager.getSign(phone, signName); + } + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/sms/modular/aliyun/enums/AliyunSmsResultEnum.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/sms/modular/aliyun/enums/AliyunSmsResultEnum.java new file mode 100644 index 00000000..341d87c1 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/sms/modular/aliyun/enums/AliyunSmsResultEnum.java @@ -0,0 +1,124 @@ +package com.cn.xiaonuo.core.sms.modular.aliyun.enums; + + +import lombok.Getter; + +/** + * 短信发送异常相关枚举 + * + * @author xuyuxiang + * @date 2018/1/4 22:40 + */ +@Getter +public enum AliyunSmsResultEnum { + + + /** + * 初始化sms客户端错误,accessKey错误 + */ + INIT_SMS_CLIENT_ERROR("SMS_CLIENT_INIT_ERROR", "初始化sms客户端错误,accessKey错误"), + + /** + * 请求参数为空 + */ + PARAM_NULL("NULL", "请求参数为空"), + + /** + * 请求成功 + */ + OK("OK", "请求成功"), + + /** + * RAM权限DENY + */ + RAM_PERMISSION_DENY("isp.RAM_PERMISSION_DENY", "RAM权限DENY"), + + /** + * 产品未开通 + */ + PRODUCT_UNSUBSCRIBE("isv.PRODUCT_UNSUBSCRIBE", "产品未开通"), + + /** + * 账户不存在 + */ + ACCOUNT_NOT_EXISTS("isv.ACCOUNT_NOT_EXISTS", "账户不存在"), + + /** + * 账户异常 + */ + ACCOUNT_ABNORMAL("isv.ACCOUNT_ABNORMAL", "账户异常"), + + /** + * 短信模板不合法 + */ + SMS_TEMPLATE_ILLEGAL("isv.SMS_TEMPLATE_ILLEGAL", "短信模板不合法"), + + /** + * 短信签名不合法 + */ + SMS_SIGNATURE_ILLEGAL("isv.SMS_SIGNATURE_ILLEGAL", "短信签名不合法"), + + /** + * 参数异常 + */ + INVALID_PARAMETERS("isv.INVALID_PARAMETERS", "参数异常"), + + /** + * 系统错误 + */ + SYSTEM_ERROR("isp.SYSTEM_ERROR", "系统错误"), + + /** + * 非法手机号 + */ + MOBILE_NUMBER_ILLEGAL("isv.MOBILE_NUMBER_ILLEGAL", "非法手机号"), + + /** + * 手机号码数量超过限制 + */ + MOBILE_COUNT_OVER_LIMIT("isv.MOBILE_COUNT_OVER_LIMIT", "手机号码数量超过限制"), + + /** + * 模板缺少变量 + */ + TEMPLATE_MISSING_PARAMETERS("isv.TEMPLATE_MISSING_PARAMETERS", "模板缺少变量"), + + /** + * 发送短信过于频繁,请稍后再试 + */ + BUSINESS_LIMIT_CONTROL("isv.BUSINESS_LIMIT_CONTROL", "发送短信过于频繁,请稍后再试"), + + /** + * JSON参数不合法,只接受字符串值 + */ + INVALID_JSON_PARAM("isv.INVALID_JSON_PARAM", "JSON参数不合法,只接受字符串值"), + + /** + * 黑名单管控 + */ + BLACK_KEY_CONTROL_LIMIT("isv.BLACK_KEY_CONTROL_LIMIT", "黑名单管控"), + + /** + * 参数超出长度限制 + */ + PARAM_LENGTH_LIMIT("isv.PARAM_LENGTH_LIMIT", "参数超出长度限制"), + + /** + * 不支持URL + */ + PARAM_NOT_SUPPORT_URL("isv.PARAM_NOT_SUPPORT_URL", "不支持URL"), + + /** + * 账户余额不足 + */ + AMOUNT_NOT_ENOUGH("isv.AMOUNT_NOT_ENOUGH", "账户余额不足"); + + private String code; + + private final String message; + + AliyunSmsResultEnum(String code, String message) { + this.code = code; + this.message = message; + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/sms/modular/aliyun/exp/AliyunSmsException.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/sms/modular/aliyun/exp/AliyunSmsException.java new file mode 100644 index 00000000..e1b4fc03 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/sms/modular/aliyun/exp/AliyunSmsException.java @@ -0,0 +1,23 @@ +package com.cn.xiaonuo.core.sms.modular.aliyun.exp; + +import lombok.Getter; + +/** + * 短信发送异常 + * + * @author xuyuxiang + * @date 2018-07-06-下午3:00 + */ +@Getter +public class AliyunSmsException extends RuntimeException { + + private final String code; + + private final String errorMessage; + + public AliyunSmsException(String code, String errorMessage) { + super(errorMessage); + this.code = code; + this.errorMessage = errorMessage; + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/sms/modular/aliyun/msign/MultiSignManager.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/sms/modular/aliyun/msign/MultiSignManager.java new file mode 100644 index 00000000..40cb1723 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/sms/modular/aliyun/msign/MultiSignManager.java @@ -0,0 +1,22 @@ +package com.cn.xiaonuo.core.sms.modular.aliyun.msign; + +/** + * 多个签名的缓存管理,为了打破一个签名发送次数的限制 + * + * @author xuyuxiang + * @date 2018-09-21-上午10:47 + */ +public interface MultiSignManager { + + /** + * 获取签名 + * + * @param phone 电话 + * @param signName 发送短信用的签名,是一个以逗号隔开的字符串 + * @return 签名 + * @author xuyuxiang + * @date 2018/9/21 上午10:51 + */ + String getSign(String phone, String signName); + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/sms/modular/aliyun/msign/impl/MapBasedMultiSignManager.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/sms/modular/aliyun/msign/impl/MapBasedMultiSignManager.java new file mode 100644 index 00000000..c333a301 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/sms/modular/aliyun/msign/impl/MapBasedMultiSignManager.java @@ -0,0 +1,64 @@ +package com.cn.xiaonuo.core.sms.modular.aliyun.msign.impl; + +import cn.hutool.log.Log; +import com.cn.xiaonuo.core.sms.modular.aliyun.msign.MultiSignManager; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 获取缓存的map中的签名 + * + * @author xuyuxiang + * @date 2018-09-21-上午10:49 + */ +public class MapBasedMultiSignManager implements MultiSignManager { + + private static final Log log = Log.get(); + + private static final int CLEAR_COUNT = 1000; + + private final Map cacheMap = new ConcurrentHashMap<>(); + + @Override + public String getSign(String phone, String signName) { + + //先清除map + clearMap(); + + //分割签名数组 + String[] signNames = signName.split(","); + + //获取上次发送的时候用的哪个签名,这次换一个 + Object lastSignName = cacheMap.get(phone); + if (lastSignName == null) { + cacheMap.put(phone, signNames[0]); + log.info("发送短信,签名为:" + signNames[0] + ",电话为:" + phone); + return signNames[0]; + } else { + for (String name : signNames) { + if (!name.equals(lastSignName)) { + cacheMap.put(phone, name); + log.info("发送短信,签名为:" + name + ",电话为:" + phone); + return name; + } + } + cacheMap.put(phone, signNames[0]); + log.info("发送短信,签名为:" + signNames[0] + ",电话为:" + phone); + return signNames[0]; + } + } + + /** + * 每隔一段时间清除下map + * + * @author xuyuxiang + * @date 2018/9/21 上午10:57 + */ + private void clearMap() { + if (cacheMap.size() >= CLEAR_COUNT) { + cacheMap.clear(); + } + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/sms/modular/aliyun/prop/AliyunSmsProperties.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/sms/modular/aliyun/prop/AliyunSmsProperties.java new file mode 100644 index 00000000..b6f20798 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/sms/modular/aliyun/prop/AliyunSmsProperties.java @@ -0,0 +1,54 @@ +package com.cn.xiaonuo.core.sms.modular.aliyun.prop; + +import lombok.Data; + +/** + * 阿里云oss相关配置 + * + * @author xuyuxiang + * @date 2018-06-27-下午1:20 + */ +@Data +public class AliyunSmsProperties { + + /** + * accessKeyId + */ + private String accessKeyId; + + /** + * accessKeySecret + */ + private String accessKeySecret; + + /** + * 签名名称 + */ + private String signName; + + /** + * 短信失效时间(分钟) + */ + private Integer invalidateMinutes = 2; + + /** + * 地域id(阿里云sdk默认的,一般不用修改) + */ + private String regionId = "cn-hangzhou"; + + /** + * domain(阿里云sdk默认的,一般不用修改) + */ + private String smsDomain = "dysmsapi.aliyuncs.com"; + + /** + * version(阿里云sdk默认的,一般不用修改) + */ + private String smsVersion = "2017-05-25"; + + /** + * sms发送(阿里云sdk默认的,一般不用修改) + */ + private String smsSendAction = "SendSms"; + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/sms/modular/tencent/TencentSmsSender.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/sms/modular/tencent/TencentSmsSender.java new file mode 100644 index 00000000..37a7ab48 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/sms/modular/tencent/TencentSmsSender.java @@ -0,0 +1,89 @@ +package com.cn.xiaonuo.core.sms.modular.tencent; + +import cn.hutool.core.util.ArrayUtil; +import com.cn.xiaonuo.core.sms.SmsSender; +import com.cn.xiaonuo.core.sms.modular.tencent.exp.TencentSmsException; +import com.cn.xiaonuo.core.sms.modular.tencent.prop.TencentSmsProperties; +import com.tencentcloudapi.common.Credential; +import com.tencentcloudapi.common.exception.TencentCloudSDKException; +import com.tencentcloudapi.common.profile.ClientProfile; +import com.tencentcloudapi.common.profile.HttpProfile; +import com.tencentcloudapi.sms.v20190711.SmsClient; +import com.tencentcloudapi.sms.v20190711.models.SendSmsRequest; +import com.tencentcloudapi.sms.v20190711.models.SendSmsResponse; +import com.tencentcloudapi.sms.v20190711.models.SendStatus; + +import java.util.Collection; +import java.util.LinkedList; +import java.util.Map; + +/** + * 腾讯云短信发送 + * + * @author xuyuxiang + * @date 2020/5/24 17:58 + */ +public class TencentSmsSender implements SmsSender { + + private TencentSmsProperties tencentSmsProperties; + + public TencentSmsSender(TencentSmsProperties tencentSmsProperties) { + this.tencentSmsProperties = tencentSmsProperties; + } + + @Override + public void sendSms(String phone, String templateCode, Map params) { + try { + + // 实例化一个认证对象 + Credential cred = new Credential( + tencentSmsProperties.getSecretId(), tencentSmsProperties.getSecretKey()); + + // 实例化一个 http 选项,可选,无特殊需求时可以跳过 + HttpProfile httpProfile = new HttpProfile(); + ClientProfile clientProfile = new ClientProfile(); + clientProfile.setSignMethod("HmacSHA256"); + clientProfile.setHttpProfile(httpProfile); + + // 实例化 SMS 的 client 对象 + SmsClient client = new SmsClient(cred, "ap-guangzhou", clientProfile); + + // 构建请求参数 + SendSmsRequest req = new SendSmsRequest(); + + // 设置应用id + req.setSmsSdkAppid(tencentSmsProperties.getSdkAppId()); + + // 设置签名 + req.setSign(tencentSmsProperties.getSign()); + + // 设置模板id + req.setTemplateID(templateCode); + + // 默认发送一个手机短信 + String[] phoneNumbers = {"+86" + phone}; + req.setPhoneNumberSet(phoneNumbers); + + // 模板参数 + if (params != null && params.size() > 0) { + LinkedList strings = new LinkedList<>(); + Collection values = params.values(); + for (Object value : values) { + strings.add(value.toString()); + } + req.setTemplateParamSet(ArrayUtil.toArray(strings, String.class)); + } + + SendSmsResponse res = client.SendSms(req); + + SendStatus[] sendStatusSet = res.getSendStatusSet(); + if (sendStatusSet != null && sendStatusSet.length > 0) { + if (!sendStatusSet[0].getCode().equals("Ok")) { + throw new TencentSmsException(sendStatusSet[0].getCode(), sendStatusSet[0].getMessage()); + } + } + } catch (TencentCloudSDKException e) { + throw new TencentSmsException("500", e.getMessage()); + } + } +} \ No newline at end of file diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/sms/modular/tencent/exp/TencentSmsException.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/sms/modular/tencent/exp/TencentSmsException.java new file mode 100644 index 00000000..21fa29ec --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/sms/modular/tencent/exp/TencentSmsException.java @@ -0,0 +1,23 @@ +package com.cn.xiaonuo.core.sms.modular.tencent.exp; + +import lombok.Getter; + +/** + * 短信发送异常 + * + * @author xuyuxiang + * @date 2018-07-06-下午3:00 + */ +@Getter +public class TencentSmsException extends RuntimeException { + + private final String code; + + private final String errorMessage; + + public TencentSmsException(String code, String errorMessage) { + super(errorMessage); + this.code = code; + this.errorMessage = errorMessage; + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/sms/modular/tencent/prop/TencentSmsProperties.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/sms/modular/tencent/prop/TencentSmsProperties.java new file mode 100644 index 00000000..43967455 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/sms/modular/tencent/prop/TencentSmsProperties.java @@ -0,0 +1,40 @@ +package com.cn.xiaonuo.core.sms.modular.tencent.prop; + +import lombok.Data; + +/** + * 腾讯云短信配置 + * + * @author xuyuxiang + * @date 2020/5/24 18:01 + */ +@Data +public class TencentSmsProperties { + + /** + * secretId + */ + private String secretId; + + /** + * secretKey + */ + private String secretKey; + + /** + * 应用控制台应用管理中的应用id + *

+ * 在 [短信控制台] 添加应用后生成的实际 SDKAppID,例如1400006666 + *

+ * 短信控制台:https://console.cloud.tencent.com/smsv2 + */ + private String sdkAppId; + + /** + * 签名,一般为中文名 + *

+ * 短信签名内容: 使用 UTF-8 编码,必须填写已审核通过的签名,可登录 [短信控制台] 查看签名信息 + */ + private String sign; + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/tenant/consts/TenantConstants.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/tenant/consts/TenantConstants.java new file mode 100644 index 00000000..01b768ae --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/tenant/consts/TenantConstants.java @@ -0,0 +1,31 @@ +package com.cn.xiaonuo.core.tenant.consts; + +/** + * 租户的常量 + * + * @author xuyuxiang + * @date 2019-06-18-16:24 + */ +public interface TenantConstants { + + /** + * 租户数据源标识前缀 + */ + String TENANT_DB_PREFIX = "xiaonuo_tenant_db_"; + + /** + * 初始化租户的sql文件名称 + */ + String INIT_SQL_FILE_NAME = "tenant_init.sql"; + + /** + * 租户编码的字段名称 + */ + String TENANT_CODE = "tenantCode"; + + /** + * 租户对应的数据库编码字段名称 + */ + String TENANT_DB_NAME = "tenantDbName"; + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/tenant/consts/TenantExpEnumConstant.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/tenant/consts/TenantExpEnumConstant.java new file mode 100644 index 00000000..e235e1a6 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/tenant/consts/TenantExpEnumConstant.java @@ -0,0 +1,21 @@ +package com.cn.xiaonuo.core.tenant.consts; + +/** + * 多租户的异常编码规范 + * + * @author xuyuxiang + * @date 2020/9/3 + */ +public interface TenantExpEnumConstant { + + /** + * 模块分类编码(2位) + */ + int TENANT_MODULE_EXP_CODE = 60; + + /** + * 租户操作相关分类编码(4位) + */ + int TENANT_EXCEPTION_ENUM = 1100; + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/tenant/context/TenantCodeHolder.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/tenant/context/TenantCodeHolder.java new file mode 100644 index 00000000..0133164a --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/tenant/context/TenantCodeHolder.java @@ -0,0 +1,24 @@ +package com.cn.xiaonuo.core.tenant.context; + +/** + * 租户编码的临时存放 + * + * @author xuyuxiang + * @date 2019-06-19-14:08 + */ +public class TenantCodeHolder { + + private static final ThreadLocal TENANT_CODE_HOLDER = new ThreadLocal<>(); + + public static void put(String value) { + TENANT_CODE_HOLDER.set(value); + } + + public static String get() { + return TENANT_CODE_HOLDER.get(); + } + + public static void remove() { + TENANT_CODE_HOLDER.remove(); + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/tenant/context/TenantDbNameHolder.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/tenant/context/TenantDbNameHolder.java new file mode 100644 index 00000000..e0b20338 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/tenant/context/TenantDbNameHolder.java @@ -0,0 +1,24 @@ +package com.cn.xiaonuo.core.tenant.context; + +/** + * 租户对应的数据库的临时存放 + * + * @author xuyuxiang + * @date 2019-06-19-14:08 + */ +public class TenantDbNameHolder { + + private static final ThreadLocal DB_NAME_HOLDER = new ThreadLocal<>(); + + public static void put(String value) { + DB_NAME_HOLDER.set(value); + } + + public static String get() { + return DB_NAME_HOLDER.get(); + } + + public static void remove() { + DB_NAME_HOLDER.remove(); + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/tenant/entity/TenantInfo.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/tenant/entity/TenantInfo.java new file mode 100644 index 00000000..51c05c7e --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/tenant/entity/TenantInfo.java @@ -0,0 +1,71 @@ +package com.cn.xiaonuo.core.tenant.entity; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + *

+ * 租户表 + *

+ * + * @author yubaoshan + * @since 2019-06-16 + */ +@TableName("sys_tenant_info") +@Data +public class TenantInfo implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 租户名称 + */ + @TableField("name") + private String name; + + /** + * 租户的编码 + */ + @TableField("code") + private String code; + + /** + * 关联的数据库名称 + */ + @TableField("db_name") + private String dbName; + + /** + * 创建时间 + */ + @TableField(value = "create_time", fill = FieldFill.INSERT) + private Date createTime; + + /** + * 创建人 + */ + @TableField(value = "create_user", fill = FieldFill.INSERT) + private Long createUser; + + /** + * 更新时间 + */ + @TableField(value = "update_time", fill = FieldFill.UPDATE) + private Date updateTime; + + /** + * 更新人 + */ + @TableField(value = "update_user", fill = FieldFill.UPDATE) + private Long updateUser; + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/tenant/exception/TenantException.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/tenant/exception/TenantException.java new file mode 100644 index 00000000..41762725 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/tenant/exception/TenantException.java @@ -0,0 +1,18 @@ +package com.cn.xiaonuo.core.tenant.exception; + +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum; + +/** + * 多租户的异常 + * + * @author xuyuxiang + * @date 2020/9/3 + */ +public class TenantException extends ServiceException { + + public TenantException(AbstractBaseExceptionEnum exception) { + super(exception); + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/tenant/exception/enums/TenantExceptionEnum.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/tenant/exception/enums/TenantExceptionEnum.java new file mode 100644 index 00000000..879bc787 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/tenant/exception/enums/TenantExceptionEnum.java @@ -0,0 +1,56 @@ +package com.cn.xiaonuo.core.tenant.exception.enums; + +import com.cn.xiaonuo.core.annotion.ExpEnumType; +import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum; +import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory; +import com.cn.xiaonuo.core.tenant.consts.TenantExpEnumConstant; + +/** + * 多租户异常枚举 + * + * @author xuyuxiang + * @date 2020/8/24 + */ +@ExpEnumType(module = TenantExpEnumConstant.TENANT_MODULE_EXP_CODE, kind = TenantExpEnumConstant.TENANT_EXCEPTION_ENUM) +public enum TenantExceptionEnum implements AbstractBaseExceptionEnum { + + /** + * 更新租户的密码错误 + */ + UPDATE_TENANT_PASSWORD_ERROR(1, "更新租户的密码错误"), + + /** + * 多数据源模块未启用,找不到DatabaseInfoService + */ + DBS_MODULAR_NOT_ENABLE_ERROR(2, "多数据源模块未启用,找不到DatabaseInfoService"), + + /** + * 找不到该租户信息 + */ + CNAT_FIND_TENANT_ERROR(3, "找不到该租户信息"), + + /** + * 多租户模块未启用,找不到TenantInfoService + */ + TENANT_MODULE_NOT_ENABLE_ERROR(4, "多租户模块未启用,找不到TenantInfoService"); + + TenantExceptionEnum(int code, String message) { + this.code = code; + this.message = message; + } + + private final Integer code; + + private final String message; + + @Override + public Integer getCode() { + return ExpEnumCodeFactory.getExpEnumCode(this.getClass(), code); + } + + @Override + public String getMessage() { + return message; + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/tenant/params/TenantInfoParam.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/tenant/params/TenantInfoParam.java new file mode 100644 index 00000000..6bf50041 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/tenant/params/TenantInfoParam.java @@ -0,0 +1,54 @@ +package com.cn.xiaonuo.core.tenant.params; + +import com.cn.xiaonuo.core.pojo.base.param.BaseParam; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + *

+ * 租户表 + *

+ * + * @author yubaoshan + * @since 2019-06-16 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class TenantInfoParam extends BaseParam { + + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @NotNull(message = "id不能为空,请检查id参数", groups = {edit.class, delete.class, detail.class}) + private Long id; + + /** + * 租户名称 + */ + @NotBlank(message = "租户名称不能为空,请检查name参数", groups = {add.class, edit.class}) + private String name; + + /** + * 租户的编码 + */ + @NotBlank(message = "租户的编码不能为空,请检查code参数", groups = {add.class, edit.class}) + private String code; + + /** + * 租户管理员账号 + */ + @NotBlank(message = "租户管理员账号不能为空,请检查adminUsername参数", groups = {add.class}) + private String adminUsername; + + /** + * 租户管理员密码 + */ + @NotBlank(message = "租户管理员账号不能为空,请检查adminPassword参数", groups = {add.class}) + private String adminPassword; + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/tenant/service/TenantInfoService.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/tenant/service/TenantInfoService.java new file mode 100644 index 00000000..98a9e023 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/tenant/service/TenantInfoService.java @@ -0,0 +1,63 @@ +package com.cn.xiaonuo.core.tenant.service; + +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.core.tenant.entity.TenantInfo; +import com.cn.xiaonuo.core.tenant.params.TenantInfoParam; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + * 租户表 服务类 + * + * @author yubaoshan + * @since 2019-06-16 + */ +public interface TenantInfoService extends IService { + + /** + * 新增租户 + * + * @param param 添加参数 + * @author yubaoshan + * @date 2019-06-16 + */ + void add(TenantInfoParam param); + + /** + * 删除租户 + * + * @param param 删除参数 + * @author yubaoshan + * @date 2019-06-16 + */ + void delete(TenantInfoParam param); + + /** + * 更新租户 + * + * @param param 更新参数 + * @author yubaoshan + * @date 2019-06-16 + */ + void update(TenantInfoParam param); + + /** + * 分页查询租户列表 + * + * @param param 查询参数 + * @return 查询结果 + * @author xuyuxiang + * @date 2020/9/3 + */ + PageResult page(TenantInfoParam param); + + /** + * 获取租户信息,通过租户编码 + * + * @param code 租户编码 + * @return 租户信息 + * @author xuyuxiang + * @date 2019-06-19 14:17 + */ + TenantInfo getByCode(String code); + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/timer/TimerTaskRunner.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/timer/TimerTaskRunner.java new file mode 100644 index 00000000..3beacd80 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/timer/TimerTaskRunner.java @@ -0,0 +1,45 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.timer; + +/** + * 定时器执行者 + *

+ * 定时器都要实现本接口,并需要把实现类加入到spring容器中 + * + * @author yubaoshan + * @date 2020/6/28 21:28 + */ +public interface TimerTaskRunner { + + /** + * 任务执行的具体内容 + * + * @author yubaoshan + * @date 2020/6/28 21:29 + */ + void action(); + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/util/AopTargetUtil.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/util/AopTargetUtil.java new file mode 100644 index 00000000..d5d443b5 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/util/AopTargetUtil.java @@ -0,0 +1,88 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.util; + +import cn.hutool.log.Log; +import com.cn.xiaonuo.core.context.requestno.RequestNoContext; +import org.springframework.aop.framework.AdvisedSupport; +import org.springframework.aop.framework.AopProxy; +import org.springframework.aop.support.AopUtils; + +import java.lang.reflect.Field; + +/** + * 获取代理原始对象的工具 + * + * @author yubaoshan + * @date 2018/2/21 17:09 + */ +public class AopTargetUtil { + + private static final Log log = Log.get(); + + /** + * 获取被代理的对象本身 + * + * @author yubaoshan + * @date 2020/6/21 17:02 + */ + public static Object getTarget(Object proxy) { + + // 判断是不是代理对象,如果不是直接返回 + if (!AopUtils.isAopProxy(proxy)) { + return proxy; + } + + try { + if (AopUtils.isJdkDynamicProxy(proxy)) { + return getJdkDynamicProxyTargetObject(proxy); + } else { + return getCglibProxyTargetObject(proxy); + } + } catch (Exception e) { + log.error(">>> 获取代理对象异常,请求号为:{},具体信息为:{}", RequestNoContext.get(), e.getMessage()); + return null; + } + } + + private static Object getCglibProxyTargetObject(Object proxy) throws Exception { + Field h = proxy.getClass().getDeclaredField("CGLIB$CALLBACK_0"); + h.setAccessible(true); + Object dynamicAdvisedInterceptor = h.get(proxy); + Field advised = dynamicAdvisedInterceptor.getClass().getDeclaredField("advised"); + advised.setAccessible(true); + return ((AdvisedSupport) advised.get(dynamicAdvisedInterceptor)).getTargetSource().getTarget(); + } + + private static Object getJdkDynamicProxyTargetObject(Object proxy) throws Exception { + Field h = proxy.getClass().getSuperclass().getDeclaredField("h"); + h.setAccessible(true); + AopProxy aopProxy = (AopProxy) h.get(proxy); + Field advised = aopProxy.getClass().getDeclaredField("advised"); + advised.setAccessible(true); + return ((AdvisedSupport) advised.get(aopProxy)).getTargetSource().getTarget(); + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/util/HttpServletUtil.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/util/HttpServletUtil.java new file mode 100644 index 00000000..93aaf6b9 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/util/HttpServletUtil.java @@ -0,0 +1,72 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.util; + +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.core.exception.enums.ServerExceptionEnum; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * HttpServlet工具类,获取当前request和response + * + * @author xuyuxiang + * @date 2020/3/30 15:09 + */ +public class HttpServletUtil { + + /** + * 获取当前请求的request对象 + * + * @author xuyuxiang + * @date 2020/3/30 15:10 + */ + public static HttpServletRequest getRequest() { + ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + if (requestAttributes == null) { + throw new ServiceException(ServerExceptionEnum.REQUEST_EMPTY); + } else { + return requestAttributes.getRequest(); + } + } + + /** + * 获取当前请求的response对象 + * + * @author xuyuxiang + * @date 2020/3/30 15:10 + */ + public static HttpServletResponse getResponse() { + ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + if (requestAttributes == null) { + throw new ServiceException(ServerExceptionEnum.REQUEST_EMPTY); + } else { + return requestAttributes.getResponse(); + } + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/util/IpAddressUtil.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/util/IpAddressUtil.java new file mode 100644 index 00000000..4541a1d7 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/util/IpAddressUtil.java @@ -0,0 +1,108 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.util; + +import cn.hutool.core.net.NetUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.extra.servlet.ServletUtil; +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpUtil; +import cn.hutool.log.Log; +import com.cn.xiaonuo.core.consts.CommonConstant; +import com.cn.xiaonuo.core.consts.SymbolConstant; +import com.cn.xiaonuo.core.context.constant.ConstantContextHolder; +import com.cn.xiaonuo.core.context.requestno.RequestNoContext; +import com.alibaba.fastjson.JSONPath; + +import javax.servlet.http.HttpServletRequest; +import java.util.List; + +/** + * 根据ip地址定位工具类,使用高德地地图定位api + * + * @author xuyuxiang + * @date 2020/3/16 11:25 + */ +public class IpAddressUtil { + + private static final Log log = Log.get(); + + private static final String LOCAL_IP = "127.0.0.1"; + + private static final String LOCAL_REMOTE_HOST = "0:0:0:0:0:0:0:1"; + + /** + * 获取客户端ip + * + * @author xuyuxiang + * @date 2020/3/19 9:32 + */ + public static String getIp(HttpServletRequest request) { + if (ObjectUtil.isEmpty(request)) { + return LOCAL_IP; + } else { + String remoteHost = ServletUtil.getClientIP(request); + return LOCAL_REMOTE_HOST.equals(remoteHost) ? LOCAL_IP : remoteHost; + } + } + + /** + * 根据ip地址定位 + * + * @author xuyuxiang + * @date 2020/3/16 15:17 + */ + @SuppressWarnings("unchecked") + public static String getAddress(HttpServletRequest request) { + String resultJson = SymbolConstant.DASH; + + String ip = getIp(request); + + //如果是本地ip或局域网ip,则直接不查询 + if (ObjectUtil.isEmpty(ip) || NetUtil.isInnerIP(ip)) { + return resultJson; + } + + try { + //获取阿里云定位api接口 + String api = ConstantContextHolder.getIpGeoApi(); + //获取阿里云定位appCode + String appCode = ConstantContextHolder.getIpGeoAppCode(); + if (ObjectUtil.isAllNotEmpty(api, appCode)) { + String path = "$['data']['country','region','city','isp']"; + String appCodeSymbol = "APPCODE"; + HttpRequest http = HttpUtil.createGet(String.format(api, ip)); + http.header(CommonConstant.AUTHORIZATION, appCodeSymbol + " " + appCode); + resultJson = http.timeout(3000).execute().body(); + resultJson = String.join("", (List) JSONPath.read(resultJson, path)); + } + } catch (Exception e) { + resultJson = SymbolConstant.DASH; + log.error(">>> 根据ip定位异常,请求号为:{},具体信息为:{}", RequestNoContext.get(), e.getMessage()); + } + return resultJson; + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/util/JoinPointUtil.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/util/JoinPointUtil.java new file mode 100644 index 00000000..5a485afe --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/util/JoinPointUtil.java @@ -0,0 +1,73 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.util; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSON; +import org.aspectj.lang.JoinPoint; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * Spring切面工具类 + * + * @author xuyuxiang + * @date 2020/3/16 17:56 + */ +public class JoinPointUtil { + + /** + * 获取切面的参数json + * + * @author xuyuxiang + * @date 2020/3/16 17:57 + */ + public static String getArgsJsonString(JoinPoint joinPoint) { + StringBuilder argsJson = new StringBuilder(); + Object[] args = joinPoint.getArgs(); + for (Object arg : args) { + if (!isFilterObject(arg)) { + if (ObjectUtil.isNotNull(arg)) { + String jsonStr = JSON.toJSONString(arg); + argsJson.append(jsonStr).append(" "); + } + } + } + return argsJson.toString().trim(); + } + + /** + * 判断是否需要拼接参数,过滤掉HttpServletRequest,MultipartFile,HttpServletResponse等类型参数 + * + * @author xuyuxiang + * @date 2020/3/16 17:59 + */ + private static boolean isFilterObject(Object arg) { + return arg instanceof MultipartFile || arg instanceof HttpServletRequest || arg instanceof HttpServletResponse; + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/util/LibreOfficeUtil.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/util/LibreOfficeUtil.java new file mode 100644 index 00000000..9a1100d5 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/util/LibreOfficeUtil.java @@ -0,0 +1,113 @@ +package com.cn.xiaonuo.core.util; + +import cn.hutool.extra.spring.SpringUtil; +import cn.hutool.log.Log; +import com.cn.xiaonuo.core.consts.MediaTypeConstant; +import com.cn.xiaonuo.core.enums.DocumentFormatEnum; +import com.cn.xiaonuo.core.exception.LibreOfficeException; +import org.jodconverter.DocumentConverter; +import org.jodconverter.document.DocumentFormat; +import org.jodconverter.office.OfficeException; +import org.springframework.http.MediaType; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * LibreOffice工具类,用于将word,excel,ppt等格式文件转为pdf预览 + * + * @author xuyuxiang + * @date 2020/7/6 14:55 + */ +public class LibreOfficeUtil { + + private static final Log log = Log.get(); + + private static DocumentConverter documentConverter; + + private static void init() { + try { + documentConverter = SpringUtil.getBean(DocumentConverter.class); + } catch (Exception e) { + throw new LibreOfficeException(); + } + } + + /** + * 将文件流转换为PDF流 + * + * @param inputStream:输入流 + * @param outputStream:输入pdf流 + * @param fileSuffix:源文件后缀 + * @return 目标类型的contentType + * @author xuyuxiang + * @date 2020/7/6 15:02 + */ + public static void convertToPdf(InputStream inputStream, OutputStream outputStream, String fileSuffix) { + init(); + final DocumentFormatEnum documentFormatEnum = DocumentFormatEnum.valueOf(fileSuffix.toUpperCase()); + final DocumentFormat format = documentFormatEnum.getFormFormat(); + log.info(">>> 待转换的文档类型:{}", format); + final DocumentFormat targetFormat = documentFormatEnum.getTargetFormat(); + log.info(">>> 转换的目标文档类型:{}", targetFormat); + try { + final InputStream is = documentFormatEnum.getInputStream(inputStream); + documentConverter.convert(is).as(format).to(outputStream).as(targetFormat).execute(); + } catch (IOException | OfficeException e) { + e.printStackTrace(); + } + log.info(">>> 文件转换结束"); + } + + /** + * 根据文件后缀判断是否图片 + * + * @author xuyuxiang + * @date 2020/7/6 15:31 + */ + public static boolean isPic(String fileSuffix) { + return MediaTypeConstant.IMG_JPG.equals(fileSuffix) + || MediaTypeConstant.IMG_JPEG.equals(fileSuffix) + || MediaTypeConstant.IMG_PNG.equals(fileSuffix) + || MediaTypeConstant.IMG_GIF.equals(fileSuffix) + || MediaTypeConstant.IMG_TIF.equals(fileSuffix) + || MediaTypeConstant.IMG_BMP.equals(fileSuffix); + } + + /** + * 根据文件后缀判断是否文档 + * + * @author xuyuxiang + * @date 2020/7/6 15:31 + */ + public static boolean isDoc(String fileSuffix) { + return MediaTypeConstant.DOC_TXT.equals(fileSuffix) + || MediaTypeConstant.DOC_DOC.equals(fileSuffix) + || MediaTypeConstant.DOC_DOCX.equals(fileSuffix) + || MediaTypeConstant.DOC_XLS.equals(fileSuffix) + || MediaTypeConstant.DOC_XLSX.equals(fileSuffix) + || MediaTypeConstant.DOC_PPT.equals(fileSuffix) + || MediaTypeConstant.DOC_PPTX.equals(fileSuffix); + } + + /** + * 根据文件后缀获取转换目标类型 + * + * @author xuyuxiang + * @date 2020/7/6 17:03 + */ + public static String getTargetContentTypeBySuffix(String fileSuffix) { + //如果目标类型是pdf + if (MediaTypeConstant.DOC_TXT.equals(fileSuffix) + || MediaTypeConstant.DOC_DOC.equals(fileSuffix) + || MediaTypeConstant.DOC_DOCX.equals(fileSuffix) + || MediaTypeConstant.DOC_PPT.equals(fileSuffix) + || MediaTypeConstant.DOC_PPTX.equals(fileSuffix)) { + return MediaType.APPLICATION_PDF_VALUE; + } else { + //否则是html类型 + return MediaType.TEXT_HTML_VALUE; + } + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/util/PageUtil.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/util/PageUtil.java new file mode 100644 index 00000000..0594bc5c --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/util/PageUtil.java @@ -0,0 +1,37 @@ +package com.cn.xiaonuo.core.util; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.convert.Convert; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; + +import java.util.List; + +/** + * 分页工具类针对hutool分页的扩展 + * + * @author xuyuxiang + * @date 2020/9/19 10:30 + **/ +public class PageUtil extends cn.hutool.core.util.PageUtil{ + + /** + * 逻辑分页 + * + * @author xuyuxiang + * @date 2020/9/19 10:36 + **/ + public static List page(Page page, List list) { + setFirstPageNo(1); + int start = getStart(Convert.toInt(page.getCurrent()), Convert.toInt(page.getSize())); + int end = getEnd(Convert.toInt(page.getCurrent()), Convert.toInt(page.getSize())); + if(start > list.size()) { + return CollectionUtil.newArrayList(); + }else if(start > end) { + return CollectionUtil.newArrayList(); + } else if(end > list.size()) { + return list.subList(start, list.size()); + } else { + return list.subList(start, end); + } + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/util/PastTimeFormatUtil.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/util/PastTimeFormatUtil.java new file mode 100644 index 00000000..f3d39167 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/util/PastTimeFormatUtil.java @@ -0,0 +1,149 @@ +package com.cn.xiaonuo.core.util; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateTime; +import cn.hutool.core.date.DateUnit; +import cn.hutool.core.date.DateUtil; + +import java.util.Date; + +/** + * 过去时间格式化工具类 + * + * @author xuyuxiang + * @date 2020/8/6 14:29 + **/ +public class PastTimeFormatUtil { + + private static final long ONE_MINUTE_SECONDS = 60; + + private static final int BEFORE_DAWN_HOUR = 6; + + private static final int MORNING_END_HOUR = 12; + + private static final int NOON_END_HOUR = 13; + + private static final int AFTERNOON_END_HOUR = 18; + + private static final int NIGHT_END_HOUR = 24; + + /** + * 将日期格式化为仿微信的日期 + * + * @param date 要格式化的日期 + * @return 格式化结果 + * @author xuyuxiang + * @date 2020/8/6 11:41 + **/ + public static String formatPastTime(Date date) { + if (DateUtil.between(date, DateUtil.date(), DateUnit.SECOND, false) < 0) { + //今天之后的时间显示年月日时分 + return DateUtil.format(date, DatePattern.NORM_DATETIME_MINUTE_PATTERN); + } else { + //如果是今年 + if (DateUtil.thisYear() == DateUtil.year(date)) { + //如果是今天 + if (DateUtil.isSameDay(date, DateUtil.date())) { + //相差分钟数 + long betweenMinute = DateUtil.between(date, DateUtil.date(), DateUnit.MINUTE); + //如果在1小时之内 + if (betweenMinute < ONE_MINUTE_SECONDS) { + //一分钟之内,显示刚刚 + if (betweenMinute < 1) { + return "刚刚"; + } else { + //一分钟之外,显示xx分钟前 + return betweenMinute + "分钟前"; + } + } else { + //一小时之外,显示时分 + return getTodayHour(date) + " " + DateUtil.format(date, "HH:mm"); + } + } else if (DateUtil.isSameDay(date, DateUtil.yesterday())) { + //如果是昨天,显示昨天时分 + return "昨天 " + DateUtil.format(date, "HH:mm"); + } else if (isThisWeek(date)) { + //如果是本周 + String weekday; + //获取是本周的第几天 + int dayOfWeek = DateUtil.dayOfWeek(date) - 1; + switch (dayOfWeek) { + case 1: + weekday = "周一"; + break; + case 2: + weekday = "周二"; + break; + case 3: + weekday = "周三"; + break; + case 4: + weekday = "周四"; + break; + case 5: + weekday = "周五"; + break; + case 6: + weekday = "周六"; + break; + default: + weekday = "周日"; + break; + } + //显示本周时分 + return weekday + " " + DateUtil.format(date, "HH:mm"); + } else { + //否则显示月日时分 + return DateUtil.format(date, "MM-dd HH:mm"); + } + } else { + //本年之外显示年月日时分 + return DateUtil.format(date, DatePattern.NORM_DATETIME_MINUTE_PATTERN); + } + } + } + + /** + * 判断日期是否是本周 + * + * @param date 要判断的日期 + * @return boolean + * @author xuyuxiang + * @date 2020/8/6 12:10 + **/ + private static boolean isThisWeek(Date date) { + //获取本周开始时间 + DateTime beginOfWeek = DateUtil.beginOfWeek(DateUtil.date()); + //获取与本周开始时间相差的天数 + long betweenBegin = DateUtil.between(date, beginOfWeek, DateUnit.DAY, false) + 1; + //如果是同一天,或相差天数小于0,则是本周 + return DateUtil.isSameDay(date, beginOfWeek) || betweenBegin < 0; + } + + /** + * 根据今天日期获取早中晚 + * + * @author xuyuxiang + * @date 2020/8/6 14:42 + **/ + private static String getTodayHour(Date date) { + String result = ""; + int hour = DateUtil.hour(date, true); + if (hour >= 0 && hour <= BEFORE_DAWN_HOUR) { + result = "凌晨"; + } + if (hour > BEFORE_DAWN_HOUR && hour < MORNING_END_HOUR) { + result = "上午"; + } + if (hour == MORNING_END_HOUR) { + result = "中午"; + } + if (hour >= NOON_END_HOUR && hour <= AFTERNOON_END_HOUR) { + result = "下午"; + } + if (hour > AFTERNOON_END_HOUR && hour <= NIGHT_END_HOUR) { + result = "晚上"; + } + return result; + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/util/PoiUtil.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/util/PoiUtil.java new file mode 100644 index 00000000..4e759a67 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/util/PoiUtil.java @@ -0,0 +1,160 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.util; + +import cn.afterturn.easypoi.excel.ExcelExportUtil; +import cn.afterturn.easypoi.excel.ExcelImportUtil; +import cn.afterturn.easypoi.excel.entity.ExportParams; +import cn.afterturn.easypoi.excel.entity.ImportParams; +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.util.CharsetUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.log.Log; +import org.apache.poi.ss.usermodel.Workbook; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletResponse; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.URLEncoder; +import java.util.Collection; +import java.util.List; + +/** + * 简单导入导出工具类 + * + * @author xuyuxiang + * @date 2020/6/30 17:25 + */ +public class PoiUtil { + + private static final Log log = Log.get(); + + /** + * 使用流的方式导出excel + * + * @param excelName 要导出的文件名称,如Users.xls + * @param pojoClass Excel实体类 + * @param data 要导出的数据集合 + * @author xuyuxiang + * @date 2020/7/1 10:00 + */ + public static void exportExcelWithStream(String excelName, Class pojoClass, Collection data) { + try { + HttpServletResponse response = HttpServletUtil.getResponse(); + String fileName = URLEncoder.encode(excelName, CharsetUtil.UTF_8); + response.reset(); + response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\""); + response.setContentType("application/octet-stream;charset=UTF-8"); + ServletOutputStream outputStream = response.getOutputStream(); + Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), pojoClass, data); + workbook.write(outputStream); + outputStream.close(); + } catch (IOException e) { + log.error(">>> 导出数据异常:{}", e.getMessage()); + } + } + + /** + * 使用文件的方式导出excel + * + * @param filePath 文件路径,如 d:/demo/demo.xls + * @param pojoClass Excel实体类 + * @param data 要导出的数据集合 + * @author xuyuxiang + * @date 2020/7/1 9:58 + */ + public static void exportExcelWithFile(String filePath, Class pojoClass, Collection data) { + + try { + //先创建父文件夹 + FileUtil.mkParentDirs(filePath); + File file = FileUtil.file(filePath); + Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), pojoClass, data); + FileOutputStream fos = new FileOutputStream(file); + workbook.write(fos); + fos.close(); + } catch (IOException e) { + log.error(">>> 导出数据异常:{}", e.getMessage()); + } + + } + + /** + * 根据文件路径来导入Excel + * + * @param filePath 文件路径 + * @param titleRows 表标题的行数 + * @param headerRows 表头行数 + * @param pojoClass Excel实体类 + * @author xuyuxiang + * @date 2020/7/1 9:58 + */ + public static List importExcel(String filePath, Integer titleRows, Integer headerRows, Class pojoClass) { + //判断文件是否存在 + if (ObjectUtil.isEmpty(filePath)) { + return null; + } + ImportParams params = new ImportParams(); + params.setTitleRows(titleRows); + params.setHeadRows(headerRows); + List list = null; + try { + list = ExcelImportUtil.importExcel(new File(filePath), pojoClass, params); + } catch (Exception e) { + log.error(">>> 导入数据异常:{}", e.getMessage()); + } + return list; + } + + /** + * 根据接收的Excel文件来导入Excel,并封装成实体类 + * + * @param file 上传的文件 + * @param titleRows 表标题的行数 + * @param headerRows 表头行数 + * @param pojoClass Excel实体类 + * @author xuyuxiang + * @date 2020/7/1 9:57 + */ + public static List importExcel(MultipartFile file, Integer titleRows, Integer headerRows, Class pojoClass) { + if (ObjectUtil.isNull(file)) { + return null; + } + ImportParams params = new ImportParams(); + params.setTitleRows(titleRows); + params.setHeadRows(headerRows); + List list = null; + try { + list = ExcelImportUtil.importExcel(file.getInputStream(), pojoClass, params); + } catch (Exception e) { + log.error(">>> 导入数据异常:{}", e.getMessage()); + } + return list; + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/util/ResponseUtil.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/util/ResponseUtil.java new file mode 100644 index 00000000..e0aa1a6c --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/util/ResponseUtil.java @@ -0,0 +1,73 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.util; + +import cn.hutool.core.util.CharsetUtil; +import cn.hutool.http.ContentType; +import com.cn.xiaonuo.core.pojo.response.ErrorResponseData; +import com.alibaba.fastjson.JSON; +import com.cn.xiaonuo.core.pojo.response.ErrorResponseData; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * 响应工具类 + * + * @author xuyuxiang + * @date 2020/3/20 11:17 + */ +public class ResponseUtil { + + /** + * 响应异常,直接向前端写response,用于异常处理器捕获不到时手动抛出 + * + * @author xuyuxiang + * @date 2020/3/20 11:18 + */ + public static void responseExceptionError(HttpServletResponse response, + Integer code, + String message, + String exceptionClazz) throws IOException { + response.setCharacterEncoding(CharsetUtil.UTF_8); + response.setContentType(ContentType.JSON.toString()); + ErrorResponseData errorResponseData = new ErrorResponseData(code, message); + errorResponseData.setExceptionClazz(exceptionClazz); + String errorResponseJsonData = JSON.toJSONString(errorResponseData); + response.getWriter().write(errorResponseJsonData); + } + + /** + * 响应异常,向前端返回ErrorResponseData的json数据,用于全局异常处理器 + * + * @author xuyuxiang + * @date 2020/3/20 11:31 + */ + public static ErrorResponseData responseDataError(Integer code, String message, String exceptionClazz) { + ErrorResponseData errorResponseData = new ErrorResponseData(code, message); + errorResponseData.setExceptionClazz(exceptionClazz); + return errorResponseData; + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/util/UaUtil.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/util/UaUtil.java new file mode 100644 index 00000000..8d32abb6 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/util/UaUtil.java @@ -0,0 +1,96 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.util; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.extra.servlet.ServletUtil; +import cn.hutool.http.useragent.Browser; +import cn.hutool.http.useragent.UserAgent; +import cn.hutool.http.useragent.UserAgentUtil; +import com.cn.xiaonuo.core.consts.CommonConstant; +import com.cn.xiaonuo.core.consts.SymbolConstant; + +import javax.servlet.http.HttpServletRequest; + +/** + * 用户代理工具类 + * + * @author xuyuxiang + * @date 2020/3/19 14:52 + */ +public class UaUtil { + + /** + * 获取客户端浏览器 + * + * @author xuyuxiang + * @date 2020/3/19 14:53 + */ + public static String getBrowser(HttpServletRequest request) { + UserAgent userAgent = getUserAgent(request); + if (ObjectUtil.isEmpty(userAgent)) { + return SymbolConstant.DASH; + } else { + String browser = userAgent.getBrowser().toString(); + return CommonConstant.UNKNOWN.equals(browser) ? SymbolConstant.DASH : browser; + } + } + + /** + * 获取客户端操作系统 + * + * @author xuyuxiang + * @date 2020/3/19 14:53 + */ + public static String getOs(HttpServletRequest request) { + UserAgent userAgent = getUserAgent(request); + if (ObjectUtil.isEmpty(userAgent)) { + return SymbolConstant.DASH; + } else { + String os = userAgent.getOs().toString(); + return CommonConstant.UNKNOWN.equals(os) ? SymbolConstant.DASH : os; + } + } + + /** + * 获取请求代理头 + * + * @author xuyuxiang + * @date 2020/3/19 14:54 + */ + private static UserAgent getUserAgent(HttpServletRequest request) { + String userAgentStr = ServletUtil.getHeaderIgnoreCase(request, CommonConstant.USER_AGENT); + UserAgent userAgent = UserAgentUtil.parse(userAgentStr); + //判空 + if (ObjectUtil.isNotEmpty(userAgentStr)) { + //如果根本没获取到浏览器 + if (CommonConstant.UNKNOWN.equals(userAgent.getBrowser().getName())) { + //则将ua设置为浏览器 + userAgent.setBrowser(new Browser(userAgentStr, null, "")); + } + } + return userAgent; + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/date/DateValue.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/date/DateValue.java new file mode 100644 index 00000000..5c63e91a --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/date/DateValue.java @@ -0,0 +1,57 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.validation.date; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.*; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * 校验日期格式 yyyy-MM-dd + * + * @author xuyuxiang + * @date 2020/5/26 14:48 + */ +@Documented +@Constraint(validatedBy = DateValueValidator.class) +@Target({ElementType.FIELD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +public @interface DateValue { + + String message() default "日期格式不正确,正确格式应为yyyy-MM-dd"; + + Class[] groups() default {}; + + Class[] payload() default {}; + + @Target({ElementType.FIELD, ElementType.PARAMETER}) + @Retention(RUNTIME) + @Documented + @interface List { + DateValue[] value(); + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/date/DateValueValidator.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/date/DateValueValidator.java new file mode 100644 index 00000000..06bd08bf --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/date/DateValueValidator.java @@ -0,0 +1,59 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.validation.date; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; + +/** + * 校验日期格式 yyyy-MM-dd + * + * @author xuyuxiang + * @date 2020/5/26 14:48 + */ +public class DateValueValidator implements ConstraintValidator { + + @Override + public boolean isValid(String dateValue, ConstraintValidatorContext context) { + //为空则放过,因为在此校验之前会加入@NotNull或@NotBlank校验 + if (ObjectUtil.isEmpty(dateValue)) { + return true; + } + //长度不对直接返回 + if (dateValue.length() != DatePattern.NORM_DATE_PATTERN.length()) { + return false; + } + try { + DateUtil.parseDate(dateValue); + return true; + } catch (Exception e) { + return false; + } + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/dateordatetime/DateOrDateTimeValue.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/dateordatetime/DateOrDateTimeValue.java new file mode 100644 index 00000000..5f0cb72e --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/dateordatetime/DateOrDateTimeValue.java @@ -0,0 +1,57 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.validation.dateordatetime; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.*; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * 校验日期或时间格式 yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss + * + * @author xuyuxiang + * @date 2020/5/26 14:48 + */ +@Documented +@Constraint(validatedBy = DateOrDateTimeValueValidator.class) +@Target({ElementType.FIELD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +public @interface DateOrDateTimeValue { + + String message() default "日期或时间格式不正确,正确格式应为yyyy-MM-dd或yyyy-MM-dd HH:mm:ss"; + + Class[] groups() default {}; + + Class[] payload() default {}; + + @Target({ElementType.FIELD, ElementType.PARAMETER}) + @Retention(RUNTIME) + @Documented + @interface List { + DateOrDateTimeValue[] value(); + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/dateordatetime/DateOrDateTimeValueValidator.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/dateordatetime/DateOrDateTimeValueValidator.java new file mode 100644 index 00000000..d76a0e0d --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/dateordatetime/DateOrDateTimeValueValidator.java @@ -0,0 +1,65 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.validation.dateordatetime; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; + +/** + * 校验日期或时间格式 yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss + * + * @author xuyuxiang + * @date 2020/5/26 14:48 + */ +public class DateOrDateTimeValueValidator implements ConstraintValidator { + + @Override + public boolean isValid(String dateValue, ConstraintValidatorContext context) { + //为空则放过,因为在此校验之前会加入@NotNull或@NotBlank校验 + if (ObjectUtil.isEmpty(dateValue)) { + return true; + } + //长度不对直接返回 + if (dateValue.length() != DatePattern.NORM_DATE_PATTERN.length() && + dateValue.length() != DatePattern.NORM_DATETIME_PATTERN.length()) { + return false; + } + try { + DateUtil.parseDate(dateValue); + return true; + } catch (Exception dateParseException) { + try { + DateUtil.parseDateTime(dateValue); + return true; + } catch (Exception dateTimeParseException) { + return false; + } + } + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/dateormonth/DateOrMonthValue.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/dateormonth/DateOrMonthValue.java new file mode 100644 index 00000000..893802af --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/dateormonth/DateOrMonthValue.java @@ -0,0 +1,57 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.validation.dateormonth; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.*; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * 校验日期格式 yyyy-MM-dd 或 yyyy-MM + * + * @author xuyuxiang + * @date 2020/5/26 14:48 + */ +@Documented +@Constraint(validatedBy = DateOrMonthValueValidator.class) +@Target({ElementType.FIELD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +public @interface DateOrMonthValue { + + String message() default "日期格式不正确,正确格式应为yyyy-MM-dd或yyyy-MM"; + + Class[] groups() default {}; + + Class[] payload() default {}; + + @Target({ElementType.FIELD, ElementType.PARAMETER}) + @Retention(RUNTIME) + @Documented + @interface List { + DateOrMonthValue[] value(); + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/dateormonth/DateOrMonthValueValidator.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/dateormonth/DateOrMonthValueValidator.java new file mode 100644 index 00000000..88f1b07c --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/dateormonth/DateOrMonthValueValidator.java @@ -0,0 +1,67 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.validation.dateormonth; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; + +/** + * 校验日期格式 yyyy-MM-dd 或 yyyy-MM + * + * @author xuyuxiang + * @date 2020/5/26 14:48 + */ +public class DateOrMonthValueValidator implements ConstraintValidator { + + public static final String NORM_MONTH_PATTERN = "yyyy-MM"; + + @Override + public boolean isValid(String dateValue, ConstraintValidatorContext context) { + //为空则放过,因为在此校验之前会加入@NotNull或@NotBlank校验 + if (ObjectUtil.isEmpty(dateValue)) { + return true; + } + //长度不对直接返回 + if (dateValue.length() != DatePattern.NORM_DATE_PATTERN.length() && + dateValue.length() != NORM_MONTH_PATTERN.length()) { + return false; + } + try { + DateUtil.parseDate(dateValue); + return true; + } catch (Exception dateParseException) { + try { + DateUtil.parse(dateValue, NORM_MONTH_PATTERN); + return true; + } catch (Exception monthParseException) { + return false; + } + } + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/dateortime/DateOrTimeValue.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/dateortime/DateOrTimeValue.java new file mode 100644 index 00000000..5a6ddd9c --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/dateortime/DateOrTimeValue.java @@ -0,0 +1,57 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.validation.dateortime; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.*; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * 校验日期或时间格式 yyyy-MM-dd 或 HH:mm:ss + * + * @author xuyuxiang + * @date 2020/5/26 14:48 + */ +@Documented +@Constraint(validatedBy = DateOrTimeValueValidator.class) +@Target({ElementType.FIELD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +public @interface DateOrTimeValue { + + String message() default "日期或时间格式不正确,正确格式应为yyyy-MM-dd 或 HH:mm:ss"; + + Class[] groups() default {}; + + Class[] payload() default {}; + + @Target({ElementType.FIELD, ElementType.PARAMETER}) + @Retention(RUNTIME) + @Documented + @interface List { + DateOrTimeValue[] value(); + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/dateortime/DateOrTimeValueValidator.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/dateortime/DateOrTimeValueValidator.java new file mode 100644 index 00000000..845616f6 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/dateortime/DateOrTimeValueValidator.java @@ -0,0 +1,65 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.validation.dateortime; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; + +/** + * 校验日期或时间格式 yyyy-MM-dd 或 HH:mm:ss + * + * @author xuyuxiang + * @date 2020/5/26 14:48 + */ +public class DateOrTimeValueValidator implements ConstraintValidator { + + @Override + public boolean isValid(String dateValue, ConstraintValidatorContext context) { + //为空则放过,因为在此校验之前会加入@NotNull或@NotBlank校验 + if (ObjectUtil.isEmpty(dateValue)) { + return true; + } + //长度不对直接返回 + if (dateValue.length() != DatePattern.NORM_DATE_PATTERN.length() && + dateValue.length() != DatePattern.NORM_TIME_PATTERN.length()) { + return false; + } + try { + DateUtil.parseDate(dateValue); + return true; + } catch (Exception dateParseException) { + try { + DateUtil.parseTime(dateValue); + return true; + } catch (Exception timeParseException) { + return false; + } + } + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/datetime/DateTimeValue.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/datetime/DateTimeValue.java new file mode 100644 index 00000000..52c5e9a2 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/datetime/DateTimeValue.java @@ -0,0 +1,57 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.validation.datetime; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.*; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * 校验日期时间格式 yyyy-MM-dd HH:mm:ss + * + * @author xuyuxiang + * @date 2020/5/26 14:48 + */ +@Documented +@Constraint(validatedBy = DateTimeValueValidator.class) +@Target({ElementType.FIELD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +public @interface DateTimeValue { + + String message() default "日期时间格式不正确,正确格式应为yyyy-MM-dd HH:mm:ss"; + + Class[] groups() default {}; + + Class[] payload() default {}; + + @Target({ElementType.FIELD, ElementType.PARAMETER}) + @Retention(RUNTIME) + @Documented + @interface List { + DateTimeValue[] value(); + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/datetime/DateTimeValueValidator.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/datetime/DateTimeValueValidator.java new file mode 100644 index 00000000..734fd5ed --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/datetime/DateTimeValueValidator.java @@ -0,0 +1,59 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.validation.datetime; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; + +/** + * 校验日期时间格式 yyyy-MM-dd HH:mm:ss + * + * @author xuyuxiang + * @date 2020/5/26 14:48 + */ +public class DateTimeValueValidator implements ConstraintValidator { + + @Override + public boolean isValid(String dateTimeValue, ConstraintValidatorContext context) { + //为空则放过,因为在此校验之前会加入@NotNull或@NotBlank校验 + if (ObjectUtil.isEmpty(dateTimeValue)) { + return true; + } + //长度不对直接返回 + if (dateTimeValue.length() != DatePattern.NORM_DATETIME_PATTERN.length()) { + return false; + } + try { + DateUtil.parseDateTime(dateTimeValue); + return true; + } catch (Exception e) { + return false; + } + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/dict/DictValue.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/dict/DictValue.java new file mode 100644 index 00000000..dbac78c1 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/dict/DictValue.java @@ -0,0 +1,66 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.validation.dict; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.*; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * 检验值是否为字典值,验证sys_dict_data表中有没有相关的字典项 + *

+ * 本注解用的时候,一定要加dictType参数,用来表明验证的哪个字典类型中的值 + *

+ * dictType值来自数据库中sys_dict_type表的code值 + * + * @author yubaoshan + * @date 2020/4/14 23:49 + */ +@Documented +@Constraint(validatedBy = DictValueValidator.class) +@Target({ElementType.FIELD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +public @interface DictValue { + + String message() default "不正确的字典值,请检查数据库中是否录入该字典项"; + + Class[] groups() default {}; + + Class[] payload() default {}; + + /** + * 字典的类型 + */ + String[] dictType(); + + @Target({ElementType.FIELD, ElementType.PARAMETER}) + @Retention(RUNTIME) + @Documented + @interface List { + DictValue[] value(); + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/dict/DictValueValidator.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/dict/DictValueValidator.java new file mode 100644 index 00000000..af4753b5 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/dict/DictValueValidator.java @@ -0,0 +1,58 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.validation.dict; + +import com.cn.xiaonuo.core.context.system.SystemContextHolder; +import com.cn.xiaonuo.core.context.system.SystemContextHolder; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import java.util.List; + +/** + * 字典值校验 + * + * @author yubaoshan + * @date 2020/4/14 23:49 + */ +public class DictValueValidator implements ConstraintValidator { + + private String[] dictType; + + @Override + public void initialize(DictValue constraintAnnotation) { + this.dictType = constraintAnnotation.dictType(); + } + + @Override + public boolean isValid(String dictValue, ConstraintValidatorContext context) { + List dictCodes = SystemContextHolder.me().getDictCodesByDictTypeCode(dictType); + if (dictCodes != null && dictCodes.size() > 0) { + return dictCodes.contains(dictValue); + } else { + return false; + } + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/flag/FlagValue.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/flag/FlagValue.java new file mode 100644 index 00000000..d198e6b2 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/flag/FlagValue.java @@ -0,0 +1,62 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.validation.flag; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.*; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * 校验标识,只有Y和N两种状态的标识 + * + * @author yubaoshan + * @date 2020/4/14 23:49 + */ +@Documented +@Constraint(validatedBy = FlagValueValidator.class) +@Target({ElementType.FIELD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +public @interface FlagValue { + + String message() default "不正确的状态标识,请传递Y或者N"; + + Class[] groups() default {}; + + Class[] payload() default {}; + + /** + * 是否必填 + */ + boolean required() default true; + + @Target({ElementType.FIELD, ElementType.PARAMETER}) + @Retention(RUNTIME) + @Documented + @interface List { + FlagValue[] value(); + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/flag/FlagValueValidator.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/flag/FlagValueValidator.java new file mode 100644 index 00000000..ed896559 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/flag/FlagValueValidator.java @@ -0,0 +1,65 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.validation.flag; + +import cn.hutool.core.util.StrUtil; +import com.cn.xiaonuo.core.enums.YesOrNotEnum; +import com.cn.xiaonuo.core.enums.YesOrNotEnum; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; + +/** + * 校验标识,只有Y和N两种状态的标识 + * + * @author yubaoshan + * @date 2020/4/14 23:49 + */ +public class FlagValueValidator implements ConstraintValidator { + + private Boolean required; + + @Override + public void initialize(FlagValue constraintAnnotation) { + this.required = constraintAnnotation.required(); + } + + @Override + public boolean isValid(String flagValue, ConstraintValidatorContext context) { + + // 如果是必填的 + if (required) { + return YesOrNotEnum.Y.getCode().equals(flagValue) || YesOrNotEnum.N.getCode().equals(flagValue); + } else { + + //如果不是必填,可以为空 + if (StrUtil.isEmpty(flagValue)) { + return true; + } else { + return YesOrNotEnum.Y.getCode().equals(flagValue) || YesOrNotEnum.N.getCode().equals(flagValue); + } + } + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/month/MonthValue.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/month/MonthValue.java new file mode 100644 index 00000000..1253fe82 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/month/MonthValue.java @@ -0,0 +1,57 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.validation.month; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.*; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * 校验日期格式 yyyy-MM + * + * @author xuyuxiang + * @date 2020/5/26 14:48 + */ +@Documented +@Constraint(validatedBy = MonthValueValidator.class) +@Target({ElementType.FIELD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +public @interface MonthValue { + + String message() default "日期格式不正确,正确格式应为yyyy-MM"; + + Class[] groups() default {}; + + Class[] payload() default {}; + + @Target({ElementType.FIELD, ElementType.PARAMETER}) + @Retention(RUNTIME) + @Documented + @interface List { + MonthValue[] value(); + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/month/MonthValueValidator.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/month/MonthValueValidator.java new file mode 100644 index 00000000..0bc1de5f --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/month/MonthValueValidator.java @@ -0,0 +1,60 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.validation.month; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; + +/** + * 校验日期格式 yyyy-MM + * + * @author xuyuxiang + * @date 2020/5/26 14:48 + */ +public class MonthValueValidator implements ConstraintValidator { + + public static final String NORM_MONTH_PATTERN = "yyyy-MM"; + + @Override + public boolean isValid(String dateValue, ConstraintValidatorContext context) { + //为空则放过,因为在此校验之前会加入@NotNull或@NotBlank校验 + if (ObjectUtil.isEmpty(dateValue)) { + return true; + } + //长度不对直接返回 + if (dateValue.length() != NORM_MONTH_PATTERN.length()) { + return false; + } + try { + DateUtil.parse(dateValue, NORM_MONTH_PATTERN); + return true; + } catch (Exception e) { + return false; + } + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/mothordatetime/MonthOrDateTimeValue.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/mothordatetime/MonthOrDateTimeValue.java new file mode 100644 index 00000000..121cefb9 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/mothordatetime/MonthOrDateTimeValue.java @@ -0,0 +1,57 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.validation.mothordatetime; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.*; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * 校验日期格式 yyyy-MM 或 yyyy-MM-dd HH:mm:ss + * + * @author xuyuxiang + * @date 2020/5/26 14:48 + */ +@Documented +@Constraint(validatedBy = MonthOrDateTimeValueValidator.class) +@Target({ElementType.FIELD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +public @interface MonthOrDateTimeValue { + + String message() default "日期格式不正确,正确格式应为yyyy-MM或yyyy-MM-dd HH:mm:ss"; + + Class[] groups() default {}; + + Class[] payload() default {}; + + @Target({ElementType.FIELD, ElementType.PARAMETER}) + @Retention(RUNTIME) + @Documented + @interface List { + MonthOrDateTimeValue[] value(); + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/mothordatetime/MonthOrDateTimeValueValidator.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/mothordatetime/MonthOrDateTimeValueValidator.java new file mode 100644 index 00000000..f1e375aa --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/mothordatetime/MonthOrDateTimeValueValidator.java @@ -0,0 +1,67 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.validation.mothordatetime; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; + +/** + * 校验日期格式 yyyy-MM 或 yyyy-MM-dd HH:mm:ss + * + * @author xuyuxiang + * @date 2020/5/26 14:48 + */ +public class MonthOrDateTimeValueValidator implements ConstraintValidator { + + public static final String NORM_MONTH_PATTERN = "yyyy-MM"; + + @Override + public boolean isValid(String dateValue, ConstraintValidatorContext context) { + //为空则放过,因为在此校验之前会加入@NotNull或@NotBlank校验 + if (ObjectUtil.isEmpty(dateValue)) { + return true; + } + //长度不对直接返回 + if (dateValue.length() != DatePattern.NORM_DATETIME_PATTERN.length() && + dateValue.length() != NORM_MONTH_PATTERN.length()) { + return false; + } + try { + DateUtil.parseDateTime(dateValue); + return true; + } catch (Exception dateTimeParseException) { + try { + DateUtil.parse(dateValue, NORM_MONTH_PATTERN); + return true; + } catch (Exception monthParseException) { + return false; + } + } + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/time/TimeValue.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/time/TimeValue.java new file mode 100644 index 00000000..4e7ca5a4 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/time/TimeValue.java @@ -0,0 +1,57 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.validation.time; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.*; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * 校验日期格式 HH:mm:ss + * + * @author xuyuxiang + * @date 2020/5/26 14:48 + */ +@Documented +@Constraint(validatedBy = TimeValueValidator.class) +@Target({ElementType.FIELD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +public @interface TimeValue { + + String message() default "日期格式不正确,正确格式应为HH:mm:ss"; + + Class[] groups() default {}; + + Class[] payload() default {}; + + @Target({ElementType.FIELD, ElementType.PARAMETER}) + @Retention(RUNTIME) + @Documented + @interface List { + TimeValue[] value(); + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/time/TimeValueValidator.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/time/TimeValueValidator.java new file mode 100644 index 00000000..c1b551e6 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/time/TimeValueValidator.java @@ -0,0 +1,59 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.validation.time; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; + +/** + * 校验日期格式 HH:mm:ss + * + * @author xuyuxiang + * @date 2020/5/26 14:48 + */ +public class TimeValueValidator implements ConstraintValidator { + + @Override + public boolean isValid(String dateValue, ConstraintValidatorContext context) { + //为空则放过,因为在此校验之前会加入@NotNull或@NotBlank校验 + if (ObjectUtil.isEmpty(dateValue)) { + return true; + } + //长度不对直接返回 + if (dateValue.length() != DatePattern.NORM_TIME_PATTERN.length()) { + return false; + } + try { + DateUtil.parseTime(dateValue); + return true; + } catch (Exception e) { + return false; + } + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/unique/TableUniqueValue.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/unique/TableUniqueValue.java new file mode 100644 index 00000000..5be93285 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/unique/TableUniqueValue.java @@ -0,0 +1,88 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.validation.unique; + +import com.cn.xiaonuo.core.consts.CommonConstant; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.*; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * 验证表的的某个字段值是否在是唯一值 + * + * @author yubaoshan + * @date 2020/4/14 23:49 + */ +@Documented +@Constraint(validatedBy = TableUniqueValueValidator.class) +@Target({ElementType.FIELD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +public @interface TableUniqueValue { + + String message() default "库中存在重复编码,请更换该编码值"; + + Class[] groups() default {}; + + Class[] payload() default {}; + + /** + * 表名称,例如 sys_user + */ + String tableName(); + + /** + * 列名称,例如 user_code + */ + String columnName(); + + /** + * 是否开启状态校验,默认是关闭的 + *

+ * 关于为何开启状态校验: + *

+ * 若项目中某个表包含控制逻辑删除的字段,我们在进行唯一值校验的时候要排除这种状态的记录,所以需要用到这个功能 + */ + boolean excludeLogicDeleteItems() default false; + + /** + * 标识状态的字段名 + */ + String logicDeleteFieldName() default CommonConstant.STATUS; + + /** + * 逻辑删除的值(默认2是删除),用string是为了更通用 + */ + String logicDeleteValue() default CommonConstant.DEFAULT_LOGIC_DELETE_VALUE; + + @Target({ElementType.FIELD, ElementType.PARAMETER}) + @Retention(RUNTIME) + @Documented + @interface List { + TableUniqueValue[] value(); + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/unique/TableUniqueValueValidator.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/unique/TableUniqueValueValidator.java new file mode 100644 index 00000000..a9944829 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/validation/unique/TableUniqueValueValidator.java @@ -0,0 +1,127 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core.validation.unique; + +import cn.hutool.core.util.ObjectUtil; +import com.cn.xiaonuo.core.context.group.RequestGroupContext; +import com.cn.xiaonuo.core.context.group.RequestParamIdContext; +import com.cn.xiaonuo.core.context.system.SystemContextHolder; +import com.cn.xiaonuo.core.pojo.base.param.BaseParam; +import com.cn.xiaonuo.core.pojo.base.validate.UniqueValidateParam; +import com.cn.xiaonuo.core.context.group.RequestGroupContext; +import com.cn.xiaonuo.core.context.group.RequestParamIdContext; +import com.cn.xiaonuo.core.context.system.SystemContextHolder; +import com.cn.xiaonuo.core.pojo.base.param.BaseParam; +import com.cn.xiaonuo.core.pojo.base.validate.UniqueValidateParam; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; + +/** + * 验证表的的某个字段值是否在是唯一值 + * + * @author yubaoshan + * @date 2020/4/14 23:49 + */ +public class TableUniqueValueValidator implements ConstraintValidator { + + private String tableName; + + private String columnName; + + private boolean excludeLogicDeleteItems; + + private String logicDeleteFieldName; + + private String logicDeleteValue; + + @Override + public void initialize(TableUniqueValue constraintAnnotation) { + this.tableName = constraintAnnotation.tableName(); + this.columnName = constraintAnnotation.columnName(); + this.excludeLogicDeleteItems = constraintAnnotation.excludeLogicDeleteItems(); + this.logicDeleteFieldName = constraintAnnotation.logicDeleteFieldName(); + this.logicDeleteValue = constraintAnnotation.logicDeleteValue(); + } + + @Override + public boolean isValid(String fieldValue, ConstraintValidatorContext context) { + + if (ObjectUtil.isNull(fieldValue)) { + return true; + } + + Class validateGroupClass = RequestGroupContext.get(); + + // 如果属于add group,则校验库中所有行 + if (BaseParam.add.class.equals(validateGroupClass)) { + return SystemContextHolder.me().tableUniValueFlag(createAddParam(fieldValue)); + } + + // 如果属于edit group,校验时需要排除当前修改的这条记录 + if (BaseParam.edit.class.equals(validateGroupClass)) { + return SystemContextHolder.me().tableUniValueFlag(createEditParam(fieldValue)); + } + + // 默认校验所有的行 + return SystemContextHolder.me().tableUniValueFlag(createAddParam(fieldValue)); + } + + /** + * 创建校验新增的参数 + * + * @author xuyuxiang + * @date 2020/8/17 21:55 + */ + private UniqueValidateParam createAddParam(String fieldValue) { + return UniqueValidateParam.builder() + .tableName(tableName) + .columnName(columnName) + .value(fieldValue) + .excludeCurrentRecord(Boolean.FALSE) + .excludeLogicDeleteItems(excludeLogicDeleteItems) + .logicDeleteFieldName(logicDeleteFieldName) + .logicDeleteValue(logicDeleteValue).build(); + } + + /** + * 创建修改的参数校验 + * + * @author xuyuxiang + * @date 2020/8/17 21:56 + */ + private UniqueValidateParam createEditParam(String fieldValue) { + return UniqueValidateParam.builder() + .tableName(tableName) + .columnName(columnName) + .value(fieldValue) + .excludeCurrentRecord(Boolean.TRUE) + .id(RequestParamIdContext.get()) + .excludeLogicDeleteItems(excludeLogicDeleteItems) + .logicDeleteFieldName(logicDeleteFieldName) + .logicDeleteValue(logicDeleteValue).build(); + } + +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/web/XiaoNuoRequestResponseBodyMethodProcessor.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/web/XiaoNuoRequestResponseBodyMethodProcessor.java new file mode 100644 index 00000000..5df88b96 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/web/XiaoNuoRequestResponseBodyMethodProcessor.java @@ -0,0 +1,56 @@ +package com.cn.xiaonuo.core.web; + +import com.cn.xiaonuo.core.context.param.RequestParamContext; +import org.springframework.core.Conventions; +import org.springframework.core.MethodParameter; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.lang.Nullable; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.support.ModelAndViewContainer; +import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor; +import java.util.List; + +/** + * 拓展原有RequestResponseBodyMethodProcessor,只为缓存临时参数 + * + * @author xuyuxiang + * @date 2020/8/21 20:51 + */ +public class XiaoNuoRequestResponseBodyMethodProcessor extends RequestResponseBodyMethodProcessor { + + public XiaoNuoRequestResponseBodyMethodProcessor(List> converters) { + super(converters); + } + + @Override + public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer, + NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception { + + parameter = parameter.nestedIfOptional(); + Object arg = readWithMessageConverters(webRequest, parameter, parameter.getNestedGenericParameterType()); + + // 临时缓存一下@RequestBody注解上的参数 + RequestParamContext.setObject(arg); + + String name = Conventions.getVariableNameForParameter(parameter); + + if (binderFactory != null) { + WebDataBinder binder = binderFactory.createBinder(webRequest, arg, name); + if (arg != null) { + validateIfApplicable(binder, parameter); + if (binder.getBindingResult().hasErrors() && isBindExceptionRequired(binder, parameter)) { + throw new MethodArgumentNotValidException(parameter, binder.getBindingResult()); + } + } + if (mavContainer != null) { + mavContainer.addAttribute(BindingResult.MODEL_KEY_PREFIX + name, binder.getBindingResult()); + } + } + + return adaptArgumentIfNecessary(arg, parameter); + } +} diff --git a/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/web/package-info.java b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/web/package-info.java new file mode 100644 index 00000000..ea533af1 --- /dev/null +++ b/xiaonuo-base/xiaonuo-core/src/main/java/com/cn/xiaonuo/core/web/package-info.java @@ -0,0 +1,4 @@ +package com.cn.xiaonuo.core.web; +/** + * 此包存放的对spring mvc的一些拓展 + */ diff --git a/xiaonuo-base/xiaonuo-system/README.md b/xiaonuo-base/xiaonuo-system/README.md new file mode 100644 index 00000000..aec68cad --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/README.md @@ -0,0 +1 @@ +** 此模块可以尽量不要动,升级的时候只要将xiaonuo-base的模块覆盖即可 ** diff --git a/xiaonuo-base/xiaonuo-system/pom.xml b/xiaonuo-base/xiaonuo-system/pom.xml new file mode 100644 index 00000000..4ad775e8 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/pom.xml @@ -0,0 +1,93 @@ + + + 4.0.0 + + + cn.xiaonuo + xiaonuo-base + 1.1.0 + ../pom.xml + + + xiaonuo-system + + jar + + + + + + cn.xiaonuo + xiaonuo-core + 1.1.0 + + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.vintage + junit-vintage-engine + + + com.vaadin.external.google + android-json + + + + + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + + org.springframework.boot + spring-boot-starter-data-redis + true + + + io.lettuce + lettuce-core + + + + + redis.clients + jedis + true + + + + + io.jsonwebtoken + jjwt + + + + + io.springfox + springfox-swagger2 + + + io.springfox + springfox-swagger-ui + + + com.github.xiaoymin + swagger-bootstrap-ui + + + + + ${project.artifactId} + + diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/config/AopConfig.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/config/AopConfig.java new file mode 100644 index 00000000..ada184ba --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/config/AopConfig.java @@ -0,0 +1,90 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.config; + +import com.cn.xiaonuo.sys.core.aop.BusinessLogAop; +import com.cn.xiaonuo.sys.core.aop.DataScopeAop; +import com.cn.xiaonuo.sys.core.aop.PermissionAop; +import com.cn.xiaonuo.sys.core.aop.WrapperAop; +import com.cn.xiaonuo.sys.core.aop.BusinessLogAop; +import com.cn.xiaonuo.sys.core.aop.DataScopeAop; +import com.cn.xiaonuo.sys.core.aop.PermissionAop; +import com.cn.xiaonuo.sys.core.aop.WrapperAop; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 切面配置 + * + * @author xuyuxiang + * @date 2020/3/18 11:25 + */ +@Configuration +public class AopConfig { + + /** + * 日志切面 + * + * @author xuyuxiang + * @date 2020/3/20 14:10 + */ + @Bean + public BusinessLogAop businessLogAop() { + return new BusinessLogAop(); + } + + /** + * 权限切面 + * + * @author xuyuxiang + * @date 2020/3/23 17:36 + */ + @Bean + public PermissionAop permissionAop() { + return new PermissionAop(); + } + + /** + * 数据范围切面 + * + * @author xuyuxiang + * @date 2020/4/6 13:47 + */ + @Bean + public DataScopeAop dataScopeAop() { + return new DataScopeAop(); + } + + /** + * 结果包装的aop + * + * @author xuyuxiang + * @date 2020/7/24 22:18 + */ + @Bean + public WrapperAop wrapperAop() { + return new WrapperAop(); + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/config/CacheConfig.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/config/CacheConfig.java new file mode 100644 index 00000000..2ce0a588 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/config/CacheConfig.java @@ -0,0 +1,98 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.config; + +import cn.hutool.cache.CacheUtil; +import cn.hutool.cache.impl.TimedCache; +import com.cn.xiaonuo.core.context.constant.ConstantContextHolder; +import com.cn.xiaonuo.core.pojo.login.SysLoginUser; +import com.cn.xiaonuo.sys.core.cache.MappingCache; +import com.cn.xiaonuo.sys.core.cache.ResourceCache; +import com.cn.xiaonuo.sys.core.cache.UserCache; +import com.cn.xiaonuo.core.context.constant.ConstantContextHolder; +import com.cn.xiaonuo.core.pojo.login.SysLoginUser; +import com.cn.xiaonuo.sys.core.cache.MappingCache; +import com.cn.xiaonuo.sys.core.cache.ResourceCache; +import com.cn.xiaonuo.sys.core.cache.UserCache; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.Map; + +/** + * 缓存的配置,默认使用基于内存的缓存,如果分布式部署请更换为redis + * + * @author xuyuxiang + * @date 2020/7/9 11:43 + */ +@Configuration +public class CacheConfig { + + /** + * url资源的缓存,默认不过期 + * + * @author yubaoshan + * @date 2020/7/9 11:44 + */ + @Bean + public ResourceCache resourceCache() { + return new ResourceCache(); + } + + /** + * 登录用户的缓存,默认过期时间,根据系统sys_config中的常量决定 + * + * @author yubaoshan + * @date 2020/7/9 11:44 + */ + @Bean + public UserCache userCache() { + TimedCache timedCache = + CacheUtil.newTimedCache(ConstantContextHolder.getSessionTokenExpireSec() * 1000); + + // 定时清理缓存,间隔1秒 + timedCache.schedulePrune(1000); + + return new UserCache(timedCache); + } + + /** + * mapping映射缓存 + * + * @author xuyuxiang + * @date 2020/7/24 13:55 + */ + @Bean + public MappingCache mappingCache() { + TimedCache> timedCache = + CacheUtil.newTimedCache(2 * 60 * 1000); + + // 定时清理缓存,间隔1秒 + timedCache.schedulePrune(1000); + + return new MappingCache(timedCache); + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/config/DataSourceConfig.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/config/DataSourceConfig.java new file mode 100644 index 00000000..f3b9c0e5 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/config/DataSourceConfig.java @@ -0,0 +1,66 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.config; + +import cn.hutool.core.collection.CollectionUtil; +import com.cn.xiaonuo.core.context.constant.ConstantContextHolder; +import com.alibaba.druid.support.http.StatViewServlet; +import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import java.util.HashMap; + +/** + * Druid配置 + * + * @author yubaoshan + * @date 2017/5/20 21:58 + */ +@Configuration +// @Import(MultiDataSourceConfig.class) +public class DataSourceConfig { + + /** + * druid监控,配置StatViewServlet + * + * @author xuyuxiang + * @date 2020/6/28 16:03 + */ + @Bean + public ServletRegistrationBean druidServletRegistration() { + + // 设置servelet的参数 + HashMap statViewServletParams = CollectionUtil.newHashMap(); + statViewServletParams.put("resetEnable", "true"); + statViewServletParams.put("loginUsername", ConstantContextHolder.getDruidMonitorUsername()); + statViewServletParams.put("loginPassword", ConstantContextHolder.getDruidMonitorPassword()); + + ServletRegistrationBean registration = new ServletRegistrationBean<>(new StatViewServlet()); + registration.addUrlMappings("/druid/*"); + registration.setInitParameters(statViewServletParams); + return registration; + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/config/FileConfig.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/config/FileConfig.java new file mode 100644 index 00000000..5de88d11 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/config/FileConfig.java @@ -0,0 +1,72 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.config; + +import cn.hutool.core.util.ObjectUtil; +import com.cn.xiaonuo.core.context.constant.ConstantContextHolder; +import com.cn.xiaonuo.core.file.FileOperator; +import com.cn.xiaonuo.core.file.modular.local.LocalFileOperator; +import com.cn.xiaonuo.core.file.modular.local.prop.LocalFileProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 文件存储的配置 + *

+ * 默认激活本地文件存储 + * + * @author yubaoshan + * @date 2020/6/6 22:27 + */ +@Configuration +public class FileConfig { + + /** + * 默认文件存储的位置 + */ + public static final String DEFAULT_BUCKET = "defaultBucket"; + + /** + * 本地文件操作客户端 + * + * @author yubaoshan + * @date 2020/6/9 21:39 + */ + @Bean + public FileOperator fileOperator() { + LocalFileProperties localFileProperties = new LocalFileProperties(); + String fileUploadPathForWindows = ConstantContextHolder.getDefaultFileUploadPathForWindows(); + if (ObjectUtil.isNotEmpty(fileUploadPathForWindows)) { + localFileProperties.setLocalFileSavePathWin(fileUploadPathForWindows); + } + + String fileUploadPathForLinux = ConstantContextHolder.getDefaultFileUploadPathForLinux(); + if (ObjectUtil.isNotEmpty(fileUploadPathForLinux)) { + localFileProperties.setLocalFileSavePathLinux(fileUploadPathForLinux); + } + return new LocalFileOperator(localFileProperties); + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/config/MailSenderConfig.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/config/MailSenderConfig.java new file mode 100644 index 00000000..f4d96dcb --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/config/MailSenderConfig.java @@ -0,0 +1,59 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.config; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.extra.mail.MailAccount; +import com.cn.xiaonuo.core.context.constant.ConstantContextHolder; +import com.cn.xiaonuo.core.email.MailSender; +import com.cn.xiaonuo.core.email.modular.SimpleMailSender; +import com.cn.xiaonuo.core.pojo.email.EmailConfigs; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 邮件发送控制器 + * + * @author yubaoshan + * @date 2020/6/6 22:27 + */ +@Configuration +public class MailSenderConfig { + + /** + * 邮件发射器 + * + * @author yubaoshan + * @date 2020/6/9 23:13 + */ + @Bean + public MailSender mailSender() { + EmailConfigs emailConfigs = ConstantContextHolder.getEmailConfigs(); + MailAccount mailAccount = new MailAccount(); + BeanUtil.copyProperties(emailConfigs, mailAccount); + return new SimpleMailSender(mailAccount); + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/config/MybatisConfig.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/config/MybatisConfig.java new file mode 100644 index 00000000..b2115c57 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/config/MybatisConfig.java @@ -0,0 +1,92 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.config; + +import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; +import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; +import com.cn.xiaonuo.sys.core.mybatis.dbid.XiaoNuoDatabaseIdProvider; +import com.cn.xiaonuo.sys.core.mybatis.fieldfill.CustomMetaObjectHandler; +import com.cn.xiaonuo.sys.core.mybatis.sqlfilter.DemoProfileSqlInterceptor; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * mybatis扩展插件配置 + * + * @author xuyuxiang + * @date 2020/3/18 10:49 + */ +@Configuration +@MapperScan(basePackages = {"com.cn.xiaonuo.**.mapper"}) +public class MybatisConfig { + + /** + * mybatis-plus分页插件 + * + * @author xuyuxiang + * @date 2020/3/31 15:42 + */ + @Bean + public PaginationInterceptor paginationInterceptor() { + return new PaginationInterceptor(); + } + + /** + * 演示环境的sql拦截器 + *

+ * 演示环境只开放查询操作,其他都不允许 + * + * @author yubaoshan + * @date 2020/5/5 12:24 + */ + @Bean + public DemoProfileSqlInterceptor demoProfileSqlInterceptor() { + return new DemoProfileSqlInterceptor(); + } + + /** + * 自定义公共字段自动注入 + * + * @author xuyuxiang + * @date 2020/3/31 15:42 + */ + @Bean + public MetaObjectHandler metaObjectHandler() { + return new CustomMetaObjectHandler(); + } + + /** + * 数据库id选择器 + * + * @author yubaoshan + * @date 2020/6/20 21:23 + */ + @Bean + public XiaoNuoDatabaseIdProvider xiaoNuoDatabaseIdProvider() { + return new XiaoNuoDatabaseIdProvider(); + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/config/SmsSenderConfig.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/config/SmsSenderConfig.java new file mode 100644 index 00000000..d5c6a019 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/config/SmsSenderConfig.java @@ -0,0 +1,65 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.config; + +import cn.hutool.core.bean.BeanUtil; +import com.cn.xiaonuo.core.context.constant.ConstantContextHolder; +import com.cn.xiaonuo.core.pojo.sms.AliyunSmsConfigs; +import com.cn.xiaonuo.core.sms.SmsSender; +import com.cn.xiaonuo.core.sms.modular.aliyun.AliyunSmsSender; +import com.cn.xiaonuo.core.sms.modular.aliyun.msign.impl.MapBasedMultiSignManager; +import com.cn.xiaonuo.core.sms.modular.aliyun.prop.AliyunSmsProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 短信发送配置,短信发送的配置属性都在数据库的sys_config表中 + *

+ * 默认开启了阿里云的短信配置 + * + * @author yubaoshan + * @date 2020/6/6 22:27 + */ +@Configuration +public class SmsSenderConfig { + + /** + * 短信发送器(阿里云) + * + * @author yubaoshan + * @date 2020/6/6 22:30 + */ + @Bean + public SmsSender aliyunSmsSender() { + + // 从数据库配置读取阿里云配置 + AliyunSmsConfigs aliyunSmsConfigs = ConstantContextHolder.getAliyunSmsConfigs(); + AliyunSmsProperties aliyunSmsProperties = new AliyunSmsProperties(); + BeanUtil.copyProperties(aliyunSmsConfigs, aliyunSmsProperties); + + return new AliyunSmsSender(new MapBasedMultiSignManager(), aliyunSmsProperties); + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/config/SpringSecurityConfig.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/config/SpringSecurityConfig.java new file mode 100644 index 00000000..c68901e8 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/config/SpringSecurityConfig.java @@ -0,0 +1,117 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.config; + +import com.cn.xiaonuo.core.consts.SpringSecurityConstant; +import com.cn.xiaonuo.sys.core.filter.security.JwtAuthenticationTokenFilter; +import com.cn.xiaonuo.sys.core.filter.security.entrypoint.JwtAuthenticationEntryPoint; +import com.cn.xiaonuo.sys.modular.auth.service.impl.AuthServiceImpl; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; + +import javax.annotation.Resource; + +/** + * SpringSecurity配置 + * + * @author xuyuxiang + * @date 2020/3/18 10:54 + */ +@Configuration +public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { + + @Resource + private AuthServiceImpl authService; + + @Resource + private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter; + + @Resource + private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint; + + /** + * 开启跨域访问拦截器 + * + * @author yubaoshan + * @date 2020/4/29 9:50 + */ + @Bean + public CorsFilter corsFilter() { + CorsConfiguration corsConfiguration = new CorsConfiguration(); + corsConfiguration.addAllowedOrigin("*"); + corsConfiguration.addAllowedHeader("*"); + corsConfiguration.addAllowedMethod("*"); + + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + source.registerCorsConfiguration("/**", corsConfiguration); + return new CorsFilter(source); + } + + @Override + protected void configure(HttpSecurity httpSecurity) throws Exception { + + //开启模拟请求,比如API POST测试工具的测试,不开启时,API POST为报403错误 + httpSecurity.csrf().disable(); + + //开启跨域访问 + httpSecurity.cors(); + + //不使用默认退出,自定义退出 + httpSecurity.logout().disable(); + + //未授权时访问须授权的资源端点 + httpSecurity.exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint); + + //放开一些接口的权限校验 + for (String notAuthResource : SpringSecurityConstant.NONE_SECURITY_URL_PATTERNS) { + httpSecurity.authorizeRequests().antMatchers(notAuthResource).permitAll(); + } + + //其余的都需授权访问 + httpSecurity.authorizeRequests().anyRequest().authenticated(); + + //前置token过滤器 + httpSecurity.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); + + //用户详情service + httpSecurity.userDetailsService(authService); + + //全局不创建session + httpSecurity.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); + + //禁用页面缓存,返回的都是json + httpSecurity.headers() + .frameOptions().disable() + .cacheControl(); + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/config/SwaggerConfig.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/config/SwaggerConfig.java new file mode 100644 index 00000000..4a5dd951 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/config/SwaggerConfig.java @@ -0,0 +1,89 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.config; + +import cn.hutool.core.collection.CollectionUtil; +import com.github.xiaoymin.swaggerbootstrapui.annotations.EnableSwaggerBootstrapUI; +import io.swagger.annotations.ApiOperation; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.ParameterBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.schema.ModelRef; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.Contact; +import springfox.documentation.service.Parameter; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +import java.util.List; + +/** + * swagger配置 + * + * @author xuyuxiang + * @date 2020/3/11 15:05 + */ +@Configuration +@EnableSwagger2 +@EnableSwaggerBootstrapUI +public class SwaggerConfig { + + @Bean + public Docket createRestApi() { + Parameter parameter = new ParameterBuilder() + .name("Authorization") + .description("token令牌") + .modelRef(new ModelRef("string")) + .parameterType("header") + .required(false) + .build(); + + List parameters = CollectionUtil.newArrayList(); + parameters.add(parameter); + + return new Docket(DocumentationType.SWAGGER_2) + .apiInfo(apiInfo()) + .select() + .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) + .paths(PathSelectors.any()) + .build() + .globalOperationParameters(parameters); + } + + private ApiInfo apiInfo() { + return new ApiInfoBuilder() + .title("XiaoNuo Doc") + .description("XiaoNuo Doc文档") + .termsOfServiceUrl("https://www.xiaonuo.vip") + .contact(new Contact("xuyuxiang, yubaoshan", "https://www.xiaonuo.vip", "")) + .version("1.0") + .build(); + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/config/WebMvcConfig.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/config/WebMvcConfig.java new file mode 100644 index 00000000..7a566f2d --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/config/WebMvcConfig.java @@ -0,0 +1,157 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.config; + +import com.cn.xiaonuo.core.web.XiaoNuoRequestResponseBodyMethodProcessor; +import com.cn.xiaonuo.sys.core.error.XiaoNuoErrorAttributes; +import com.cn.xiaonuo.sys.core.filter.RequestNoFilter; +import com.cn.xiaonuo.sys.core.filter.xss.XssFilter; +import com.cn.xiaonuo.sys.core.validator.XiaoNuoValidator; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; +import javax.annotation.PostConstruct; +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * web配置 + * + * @author yubaoshan + * @date 2020/4/11 10:23 + */ +@Configuration +@Import({cn.hutool.extra.spring.SpringUtil.class}) +public class WebMvcConfig implements WebMvcConfigurer { + + /** + * 错误信息提示重写 + * + * @author yubaoshan + * @date 2020/4/14 22:27 + */ + @Bean + public XiaoNuoErrorAttributes xiaoNuoErrorAttributes() { + return new XiaoNuoErrorAttributes(); + } + + /** + * 静态资源映射 + * + * @author yubaoshan + * @date 2020/4/11 10:23 + */ + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + //swagger增强的静态资源映射 + registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/"); + registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); + //flowable设计器静态资源映射 + registry.addResourceHandler("/designer/**").addResourceLocations("classpath:/designer/"); + } + + /** + * xss过滤器 + * + * @author yubaoshan + * @date 2020/6/21 10:30 + */ + @Bean + public FilterRegistrationBean xssFilterFilterRegistrationBean() { + FilterRegistrationBean registration = new FilterRegistrationBean<>(new XssFilter()); + registration.addUrlPatterns("/*"); + return registration; + } + + /** + * 请求唯一编号生成器 + * + * @author yubaoshan + * @date 2020/6/21 10:30 + */ + @Bean + public FilterRegistrationBean requestNoFilterFilterRegistrationBean() { + FilterRegistrationBean registration = new FilterRegistrationBean<>(new RequestNoFilter()); + registration.addUrlPatterns("/*"); + return registration; + } + + /** + * json自定义序列化工具,long转string + * + * @author yubaoshan + * @date 2020/5/28 14:48 + */ + @Bean + public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() { + return jacksonObjectMapperBuilder -> + jacksonObjectMapperBuilder + .serializerByType(Long.class, ToStringSerializer.instance) + .serializerByType(Long.TYPE, ToStringSerializer.instance); + } + + /** + * 自定义的spring参数校验器,重写主要为了保存一些在自定义validator中读不到的属性 + * + * @author xuyuxiang + * @date 2020/8/12 20:18 + */ + @Bean + public XiaoNuoValidator xiaoNuoValidator() { + return new XiaoNuoValidator(); + } + + + /** + * 自定义的XiaoNuoRequestResponseBodyMethodProcessor,放在所有resolvers之前 + * + * @author xuyuxiang + * @date 2020/8/21 21:09 + */ + @Configuration + public static class MethodArgumentResolver { + + @Resource + private RequestMappingHandlerAdapter adapter; + + @PostConstruct + public void injectSelfMethodArgumentResolver() { + List argumentResolvers = new ArrayList<>(); + argumentResolvers.add(new XiaoNuoRequestResponseBodyMethodProcessor(adapter.getMessageConverters())); + argumentResolvers.addAll(Objects.requireNonNull(adapter.getArgumentResolvers())); + adapter.setArgumentResolvers(argumentResolvers); + } + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/aop/BusinessLogAop.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/aop/BusinessLogAop.java new file mode 100644 index 00000000..f1bedb9e --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/aop/BusinessLogAop.java @@ -0,0 +1,111 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.aop; + +import cn.hutool.core.util.ObjectUtil; +import com.cn.xiaonuo.core.annotion.BusinessLog; +import com.cn.xiaonuo.core.consts.AopSortConstant; +import com.cn.xiaonuo.core.consts.CommonConstant; +import com.cn.xiaonuo.core.context.login.LoginContextHolder; +import com.cn.xiaonuo.core.pojo.login.SysLoginUser; +import com.cn.xiaonuo.sys.core.log.LogManager; +import com.alibaba.fastjson.JSON; +import com.cn.xiaonuo.core.annotion.BusinessLog; +import com.cn.xiaonuo.core.consts.AopSortConstant; +import com.cn.xiaonuo.core.consts.CommonConstant; +import com.cn.xiaonuo.core.context.login.LoginContextHolder; +import com.cn.xiaonuo.core.pojo.login.SysLoginUser; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.AfterThrowing; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.core.annotation.Order; + +import java.lang.reflect.Method; + +/** + * 业务日志aop切面 + * + * @author xuyuxiang + * @date 2020/3/20 11:47 + */ +@Aspect +@Order(AopSortConstant.BUSINESS_LOG_AOP) +public class BusinessLogAop { + + /** + * 日志切入点 + * + * @author xuyuxiang + * @date 2020/3/23 17:10 + */ + @Pointcut("@annotation(com.cn.xiaonuo.core.annotion.BusinessLog)") + private void getLogPointCut() { + } + + /** + * 操作成功返回结果记录日志 + * + * @author xuyuxiang + * @date 2020/3/20 11:51 + */ + @AfterReturning(pointcut = "getLogPointCut()", returning = "result") + public void doAfterReturning(JoinPoint joinPoint, Object result) { + MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); + Method method = methodSignature.getMethod(); + BusinessLog businessLog = method.getAnnotation(BusinessLog.class); + SysLoginUser sysLoginUser = LoginContextHolder.me().getSysLoginUserWithoutException(); + String account = CommonConstant.UNKNOWN; + if(ObjectUtil.isNotNull(sysLoginUser)) { + account = sysLoginUser.getAccount(); + } + //异步记录日志 + LogManager.me().executeOperationLog( + businessLog, account, joinPoint, JSON.toJSONString(result)); + } + + /** + * 操作发生异常记录日志 + * + * @author xuyuxiang + * @date 2020/3/21 11:38 + */ + @AfterThrowing(pointcut = "getLogPointCut()", throwing = "exception") + public void doAfterThrowing(JoinPoint joinPoint, Exception exception) { + MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); + Method method = methodSignature.getMethod(); + BusinessLog businessLog = method.getAnnotation(BusinessLog.class); + SysLoginUser sysLoginUser = LoginContextHolder.me().getSysLoginUserWithoutException(); + String account = CommonConstant.UNKNOWN; + if(ObjectUtil.isNotNull(sysLoginUser)) { + account = sysLoginUser.getAccount(); + } + //异步记录日志 + LogManager.me().executeExceptionLog( + businessLog, account, joinPoint, exception); + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/aop/DataScopeAop.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/aop/DataScopeAop.java new file mode 100644 index 00000000..2cf9c369 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/aop/DataScopeAop.java @@ -0,0 +1,85 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.aop; + +import com.cn.xiaonuo.core.consts.AopSortConstant; +import com.cn.xiaonuo.core.context.login.LoginContextHolder; +import com.cn.xiaonuo.core.pojo.base.param.BaseParam; +import com.cn.xiaonuo.core.consts.AopSortConstant; +import com.cn.xiaonuo.core.context.login.LoginContextHolder; +import com.cn.xiaonuo.core.pojo.base.param.BaseParam; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.core.annotation.Order; + +import java.util.List; + +/** + * 数据权限切面 + * + * @author xuyuxiang + * @date 2020/3/28 17:16 + */ +@Aspect +@Order(AopSortConstant.DATA_SCOPE_AOP) +public class DataScopeAop { + + /** + * 数据范围切入点 + * + * @author xuyuxiang + * @date 2020/4/6 13:32 + */ + @Pointcut("@annotation(com.cn.xiaonuo.core.annotion.DataScope)") + private void getDataScopePointCut() { + } + + /** + * 执行数据范围过滤 + * + * @author xuyuxiang + * @date 2020/4/6 13:32 + */ + @Before("getDataScopePointCut()") + public void doDataScope(JoinPoint joinPoint) { + + //不是超级管理员时进行数据权限过滤 + if (!LoginContextHolder.me().isSuperAdmin()) { + Object[] args = joinPoint.getArgs(); + + //数据范围就是组织机构id集合 + List loginUserDataScopeIdList = LoginContextHolder.me().getLoginUserDataScopeIdList(); + BaseParam baseParam; + for (Object object : args) { + if (object instanceof BaseParam) { + baseParam = (BaseParam) object; + baseParam.setDataScope(loginUserDataScopeIdList); + } + } + } + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/aop/PermissionAop.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/aop/PermissionAop.java new file mode 100644 index 00000000..a6af6275 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/aop/PermissionAop.java @@ -0,0 +1,138 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.aop; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.log.Log; +import com.cn.xiaonuo.core.annotion.BusinessLog; +import com.cn.xiaonuo.core.annotion.Permission; +import com.cn.xiaonuo.core.consts.AopSortConstant; +import com.cn.xiaonuo.core.consts.SymbolConstant; +import com.cn.xiaonuo.core.context.login.LoginContextHolder; +import com.cn.xiaonuo.core.enums.LogicTypeEnum; +import com.cn.xiaonuo.core.exception.PermissionException; +import com.cn.xiaonuo.core.exception.enums.PermissionExceptionEnum; +import com.cn.xiaonuo.core.util.HttpServletUtil; +import com.cn.xiaonuo.sys.core.log.LogManager; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.core.annotation.Order; + +import javax.servlet.http.HttpServletRequest; +import java.lang.reflect.Method; + +/** + * 权限过滤Aop切面 + * + * @author xuyuxiang + * @date 2020/3/23 17:09 + */ +@Aspect +@Order(AopSortConstant.PERMISSION_AOP) +public class PermissionAop { + + private static final Log log = Log.get(); + + /** + * 权限切入点 + * + * @author xuyuxiang + * @date 2020/3/23 17:10 + */ + @Pointcut("@annotation(com.cn.xiaonuo.core.annotion.Permission)") + private void getPermissionPointCut() { + } + + /** + * 执行权限过滤 + * + * @author xuyuxiang + * @date 2020/3/23 17:14 + */ + @Before("getPermissionPointCut()") + public void doPermission(JoinPoint joinPoint) { + + // 如果是超级管理员,直接放过权限校验 + boolean isSuperAdmin = LoginContextHolder.me().isSuperAdmin(); + if (isSuperAdmin) { + return; + } + + // 如果不是超级管理员,则开始进行权限校验 + MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); + Method method = methodSignature.getMethod(); + Permission permission = method.getAnnotation(Permission.class); + + // 当前方法需要的角色集合 + String[] requireRoles = permission.value(); + + // 逻辑类型 + LogicTypeEnum logicTypeEnum = permission.logicType(); + + // 首先校验当前用户有没有 当前请求requestUri的权限 + HttpServletRequest request = HttpServletUtil.getRequest(); + boolean hasUriPermission = LoginContextHolder.me().hasPermission(request.getRequestURI()); + if (!hasUriPermission) { + this.executeNoPermissionExceptionLog(joinPoint, new PermissionException(PermissionExceptionEnum.NO_PERMISSION)); + throw new PermissionException(PermissionExceptionEnum.NO_PERMISSION); + } + + // 如果当前接口需要特定的角色权限,则校验参数上的特殊角色当前用户有没 + if (requireRoles.length != 0) { + boolean hasSpecialRolePermission = true; + if (LogicTypeEnum.AND.equals(logicTypeEnum)) { + hasSpecialRolePermission = LoginContextHolder.me().hasAllRole(StrUtil.join(SymbolConstant.COMMA, (Object) requireRoles)); + } else if (LogicTypeEnum.OR.equals(logicTypeEnum)) { + hasSpecialRolePermission = LoginContextHolder.me().hasAnyRole(StrUtil.join(SymbolConstant.COMMA, (Object) requireRoles)); + } else { + log.error(">>> permission注解逻辑枚举错误"); + } + if (!hasSpecialRolePermission) { + this.executeNoPermissionExceptionLog(joinPoint, new PermissionException(PermissionExceptionEnum.NO_PERMISSION)); + throw new PermissionException(PermissionExceptionEnum.NO_PERMISSION); + } + } + } + + /** + * 记录无权限异常日志 + * + * @author xuyuxiang + * @date 2020/3/24 11:14 + */ + private void executeNoPermissionExceptionLog(JoinPoint joinPoint, Exception exception) { + MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); + Method method = methodSignature.getMethod(); + BusinessLog businessLog = method.getAnnotation(BusinessLog.class); + + //异步记录日志 + LogManager.me().executeExceptionLog( + businessLog, LoginContextHolder.me().getSysLoginUserAccount(), joinPoint, exception); + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/aop/WrapperAop.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/aop/WrapperAop.java new file mode 100644 index 00000000..704879e6 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/aop/WrapperAop.java @@ -0,0 +1,248 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.aop; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.log.Log; +import com.cn.xiaonuo.core.annotion.Wrapper; +import com.cn.xiaonuo.core.consts.AopSortConstant; +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.core.exception.enums.WrapperExceptionEnum; +import com.cn.xiaonuo.core.pojo.base.wrapper.BaseWrapper; +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.core.pojo.response.ResponseData; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.cn.xiaonuo.core.annotion.Wrapper; +import com.cn.xiaonuo.core.consts.AopSortConstant; +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.core.exception.enums.WrapperExceptionEnum; +import com.cn.xiaonuo.core.pojo.base.wrapper.BaseWrapper; +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.core.pojo.response.ResponseData; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.core.annotation.Order; + +import java.lang.reflect.Array; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Map; + +/** + * controller结果包装的aop + * + * @author xuyuxiang + * @date 2020/7/24 17:42 + */ +@Aspect +@Order(AopSortConstant.WRAPPER_AOP) +public class WrapperAop { + + private static final Log log = Log.get(); + + /** + * 切入点 + * + * @author xuyuxiang + * @date 2020/7/24 17:42 + */ + @Pointcut("@annotation(com.cn.xiaonuo.core.annotion.Wrapper)") + private void wrapperPointcut() { + } + + /** + * 执行具体的包装过程 + * + * @author xuyuxiang + * @date 2020/7/24 17:44 + */ + @Around("wrapperPointcut()") + public Object doWrapper(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { + + // 直接执行原有业务逻辑 + Object proceedResult = proceedingJoinPoint.proceed(); + + return processWrapping(proceedingJoinPoint, proceedResult); + } + + /** + * 具体包装过程 + * + * @author xuyuxiang + * @date 2020/7/24 17:53 + */ + @SuppressWarnings("all") + private Object processWrapping(ProceedingJoinPoint proceedingJoinPoint, Object originResult) throws IllegalAccessException, InstantiationException { + + // 获取@Wrapper注解 + MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature(); + Method method = methodSignature.getMethod(); + Wrapper wrapperAnnotation = method.getAnnotation(Wrapper.class); + + // 获取注解上的处理类 + Class>[] baseWrapperClasses = wrapperAnnotation.value(); + + // 如果注解上的为空直接返回 + if (ObjectUtil.isEmpty(baseWrapperClasses)) { + return originResult; + } + + // 获取原有返回结果,如果不是ResponseData则不进行处理(需要遵守这个约定) + if (!(originResult instanceof ResponseData)) { + log.warn(">>> 当前请求的返回结果不是ResponseData类型,直接返回原值!"); + return originResult; + } + + // 获取ResponseData中的值 + ResponseData responseData = (ResponseData) originResult; + Object beWrapped = responseData.getData(); + + // 如果是基本类型,不进行加工处理 + if (ObjectUtil.isBasicType(beWrapped)) { + throw new ServiceException(WrapperExceptionEnum.BASIC_TYPE_ERROR); + } + + // 如果是Page类型 + if (beWrapped instanceof Page) { + + // 获取Page原有对象 + Page page = (Page) beWrapped; + + // 将page中所有records都包装一遍 + ArrayList> maps = new ArrayList<>(); + for (Object wrappedItem : page.getRecords()) { + maps.add(this.wrapPureObject(wrappedItem, baseWrapperClasses)); + } + + page.setRecords(maps); + responseData.setData(page); + } + + // 如果是PageResult类型 + else if (beWrapped instanceof PageResult) { + + // 获取PageResult原有对象 + PageResult pageResult = (PageResult) beWrapped; + + // 将PageResult中所有rows都包装一遍 + ArrayList> maps = new ArrayList<>(); + for (Object wrappedItem : pageResult.getRows()) { + maps.add(this.wrapPureObject(wrappedItem, baseWrapperClasses)); + } + + pageResult.setRows(maps); + responseData.setData(pageResult); + } + + // 如果是List类型 + else if (beWrapped instanceof Collection) { + + // 获取原有的List + Collection collection = (Collection) beWrapped; + + // 将page中所有records都包装一遍 + ArrayList> maps = new ArrayList<>(); + for (Object wrappedItem : collection) { + maps.add(this.wrapPureObject(wrappedItem, baseWrapperClasses)); + } + + responseData.setData(maps); + } + + // 如果是Array类型 + else if (ArrayUtil.isArray(beWrapped)) { + + // 获取原有的Array + Object[] objects = this.objToArray(beWrapped); + + // 将array中所有records都包装一遍 + ArrayList> maps = new ArrayList<>(); + for (Object wrappedItem : objects) { + maps.add(this.wrapPureObject(wrappedItem, baseWrapperClasses)); + } + + responseData.setData(maps); + } + + // 如果是Object类型 + else { + responseData.setData(this.wrapPureObject(beWrapped, baseWrapperClasses)); + } + + + return responseData; + } + + /** + * 原始对象包装成一个map的过程 + *

+ * 期间多次根据BaseWrapper接口方法执行包装过程 + * + * @author xuyuxiang + * @date 2020/7/24 21:40 + */ + @SuppressWarnings("all") + private Map wrapPureObject(Object originModel, Class>[] baseWrapperClasses) { + + // 首先将原始的对象转化为map + Map originMap = BeanUtil.beanToMap(originModel); + + // 经过多个包装类填充属性 + try { + for (Class> baseWrapperClass : baseWrapperClasses) { + BaseWrapper baseWrapper = baseWrapperClass.newInstance(); + Map incrementFieldsMap = baseWrapper.doWrap(originModel); + originMap.putAll(incrementFieldsMap); + } + } catch (Exception e) { + log.error(">>> 原始对象包装过程,字段转化异常:{}", e.getMessage()); + throw new ServiceException(WrapperExceptionEnum.TRANSFER_ERROR); + } + + return originMap; + } + + /** + * Object转为一个array,确保object为数组类型 + * + * @author xuyuxiang + * @date 2020/7/24 22:06 + */ + private Object[] objToArray(Object object) { + int length = Array.getLength(object); + Object[] result = new Object[length]; + for (int i = 0; i < result.length; i++) { + result[i] = Array.get(object, i); + } + return result; + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/cache/MappingCache.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/cache/MappingCache.java new file mode 100644 index 00000000..1d0b1f16 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/cache/MappingCache.java @@ -0,0 +1,65 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.cache; + +import cn.hutool.cache.impl.TimedCache; +import com.cn.xiaonuo.sys.core.cache.base.AbstractMemoryCacheOperator; + +import java.util.Map; + +/** + * mapping是映射,指业务id和业务名称的映射,或字典code和字典值的映射 + *

+ * mapping的含义: + * 指对接口响应字段转化(或完善)过程 + *

+ * 为什么要映射: + * 一般在查询类的方法,响应结果如果需要返回详细的一些名称信息 + * 则需要通过left join关联对应明细表或字典表,通过id或者code查到对应的中文名称,这样做效率不高 + *

+ * 结论: + * 利用缓存,将常用的字典或者业务id映射,保存起来 + * 一方面保证了查询速度,一方面简化了代码开发,不用写一些left join之类的sql + * + * @author xuyuxiang + * @date 2020/7/24 11:59 + */ +public class MappingCache extends AbstractMemoryCacheOperator> { + + /** + * 缓存的前缀标识 + */ + public static final String TRANSLATES_CACHE_PREFIX = "MAPPINGS_"; + + public MappingCache(TimedCache> timedCache) { + super(timedCache); + } + + @Override + public String getCommonKeyPrefix() { + return TRANSLATES_CACHE_PREFIX; + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/cache/OauthCache.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/cache/OauthCache.java new file mode 100644 index 00000000..e3f0ce82 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/cache/OauthCache.java @@ -0,0 +1,72 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.cache; + +import cn.hutool.cache.impl.CacheObj; +import cn.hutool.cache.impl.TimedCache; +import me.zhyd.oauth.cache.AuthCacheConfig; +import me.zhyd.oauth.cache.AuthStateCache; +import org.springframework.stereotype.Component; + +import java.util.Iterator; + +/** + * Oauth登录的缓存 + * + * @author xuyuxiang + * @date 2020/7/28 17:42 + **/ +@Component +public class OauthCache implements AuthStateCache { + + private final TimedCache timedCache = new TimedCache<>(AuthCacheConfig.timeout); + + @Override + public void cache(String key, String value) { + timedCache.put(key, value, AuthCacheConfig.timeout); + } + + @Override + public void cache(String key, String value, long timeoutSeconds) { + timedCache.put(key, value, AuthCacheConfig.timeout); + } + + @Override + public String get(String key) { + return timedCache.get(key); + } + + @Override + public boolean containsKey(String key) { + Iterator> cacheObjIterator = timedCache.cacheObjIterator(); + while (cacheObjIterator.hasNext()) { + String temKey = cacheObjIterator.next().getKey(); + if (temKey.equals(key)) { + return true; + } + } + return false; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/cache/ResourceCache.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/cache/ResourceCache.java new file mode 100644 index 00000000..e8d4c1e6 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/cache/ResourceCache.java @@ -0,0 +1,63 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.cache; + +import cn.hutool.core.collection.CollectionUtil; + +import java.util.Set; + +/** + * 项目资源的缓存,存储了项目所有的访问url + *

+ * 一般用在过滤器检测请求是否是项目没有的url + * + * @author yubaoshan + * @date 2020/7/9 11:03 + */ +public class ResourceCache { + + private final Set resourceCaches = CollectionUtil.newHashSet(); + + /** + * 获取所有缓存资源 + * + * @author yubaoshan + * @date 2020/7/9 13:52 + */ + public Set getAllResources() { + return resourceCaches; + } + + /** + * 直接缓存所有资源 + * + * @author yubaoshan + * @date 2020/7/9 13:52 + */ + public void putAllResources(Set resources) { + resourceCaches.addAll(resources); + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/cache/UserCache.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/cache/UserCache.java new file mode 100644 index 00000000..82016446 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/cache/UserCache.java @@ -0,0 +1,57 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.cache; + +import cn.hutool.cache.impl.TimedCache; +import com.cn.xiaonuo.core.pojo.login.SysLoginUser; +import com.cn.xiaonuo.sys.core.cache.base.AbstractMemoryCacheOperator; +import com.cn.xiaonuo.core.pojo.login.SysLoginUser; + +/** + * 登录用户的缓存,存储了当前登录的用户 + *

+ * 一般用于在线用户的查看和过滤器检测用户是否登录 + *

+ * key为用户的唯一id,value为LoginUser对象 + * + * @author yubaoshan + * @date 2020/7/9 11:02 + */ +public class UserCache extends AbstractMemoryCacheOperator { + + /** + * 登录用户缓存前缀 + */ + public static final String LOGIN_USER_CACHE_PREFIX = "LOGIN_USER_"; + + public UserCache(TimedCache timedCache) { + super(timedCache); + } + + @Override + public String getCommonKeyPrefix() { + return LOGIN_USER_CACHE_PREFIX; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/cache/base/AbstractMemoryCacheOperator.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/cache/base/AbstractMemoryCacheOperator.java new file mode 100644 index 00000000..5685c1be --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/cache/base/AbstractMemoryCacheOperator.java @@ -0,0 +1,105 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.cache.base; + +import cn.hutool.cache.impl.CacheObj; +import cn.hutool.cache.impl.TimedCache; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.cn.xiaonuo.core.cache.CacheOperator; + +import java.util.*; + +/** + * 基于内存的缓存封装 + * + * @author yubaoshan + * @date 2020/7/9 10:09 + */ +public abstract class AbstractMemoryCacheOperator implements CacheOperator { + + private final TimedCache timedCache; + + public AbstractMemoryCacheOperator(TimedCache timedCache) { + this.timedCache = timedCache; + } + + @Override + public void put(String key, T value) { + timedCache.put(getCommonKeyPrefix() + key, value); + } + + @Override + public void put(String key, T value, Long timeoutSeconds) { + timedCache.put(getCommonKeyPrefix() + key, value, timeoutSeconds * 1000); + } + + @Override + public T get(String key) { + // 如果用户在超时前调用了get(key)方法,会重头计算起始时间,false的作用就是不从头算 + return timedCache.get(getCommonKeyPrefix() + key, true); + } + + @Override + public void remove(String... key) { + if (key.length > 0) { + for (String itemKey : key) { + timedCache.remove(getCommonKeyPrefix() + itemKey); + } + } + } + + @Override + public Collection getAllKeys() { + Iterator> cacheObjIterator = timedCache.cacheObjIterator(); + ArrayList keys = CollectionUtil.newArrayList(); + while (cacheObjIterator.hasNext()) { + // 去掉缓存key的common prefix前缀 + String key = cacheObjIterator.next().getKey(); + keys.add(StrUtil.removePrefix(key, getCommonKeyPrefix())); + } + return keys; + } + + @Override + public Collection getAllValues() { + Iterator> cacheObjIterator = timedCache.cacheObjIterator(); + ArrayList values = CollectionUtil.newArrayList(); + while (cacheObjIterator.hasNext()) { + values.add(cacheObjIterator.next().getValue()); + } + return values; + } + + @Override + public Map getAllKeyValues() { + Collection allKeys = this.getAllKeys(); + HashMap results = CollectionUtil.newHashMap(); + for (String key : allKeys) { + results.put(key, this.get(key)); + } + return results; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/cache/base/AbstractRedisCacheOperator.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/cache/base/AbstractRedisCacheOperator.java new file mode 100644 index 00000000..50cc19a1 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/cache/base/AbstractRedisCacheOperator.java @@ -0,0 +1,106 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.cache.base; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.cn.xiaonuo.core.cache.CacheOperator; +import com.cn.xiaonuo.core.cache.CacheOperator; +import com.cn.xiaonuo.core.consts.SymbolConstant; +import org.springframework.data.redis.core.RedisTemplate; + +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +import static com.cn.xiaonuo.core.consts.SymbolConstant.ASTERISK; + +/** + * 基于redis的缓存封装 + * + * @author yubaoshan + * @date 2020/7/9 10:09 + */ +public abstract class AbstractRedisCacheOperator implements CacheOperator { + + private final RedisTemplate redisTemplate; + + public AbstractRedisCacheOperator(RedisTemplate redisTemplate) { + this.redisTemplate = redisTemplate; + } + + @Override + public void put(String key, T value) { + redisTemplate.boundValueOps(getCommonKeyPrefix() + key).set(value); + } + + @Override + public void put(String key, T value, Long timeoutSeconds) { + redisTemplate.boundValueOps(getCommonKeyPrefix() + key).set(value, timeoutSeconds, TimeUnit.SECONDS); + } + + @Override + public T get(String key) { + return redisTemplate.boundValueOps(getCommonKeyPrefix() + key).get(); + } + + @Override + public void remove(String... key) { + ArrayList keys = CollectionUtil.toList(key); + List withPrefixKeys = keys.stream().map(i -> getCommonKeyPrefix() + i).collect(Collectors.toList()); + redisTemplate.delete(withPrefixKeys); + } + + @Override + public Collection getAllKeys() { + Set keys = redisTemplate.keys(getCommonKeyPrefix() + SymbolConstant.ASTERISK); + if (keys != null) { + // 去掉缓存key的common prefix前缀 + return keys.stream().map(key -> StrUtil.removePrefix(key, getCommonKeyPrefix())).collect(Collectors.toSet()); + } else { + return CollectionUtil.newHashSet(); + } + } + + @Override + public Collection getAllValues() { + Set keys = redisTemplate.keys(getCommonKeyPrefix() + SymbolConstant.ASTERISK); + if (keys != null) { + return redisTemplate.opsForValue().multiGet(keys); + } else { + return CollectionUtil.newArrayList(); + } + } + + @Override + public Map getAllKeyValues() { + Collection allKeys = this.getAllKeys(); + HashMap results = CollectionUtil.newHashMap(); + for (String key : allKeys) { + results.put(key, this.get(key)); + } + return results; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/consts/SysExpEnumConstant.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/consts/SysExpEnumConstant.java new file mode 100644 index 00000000..9cf22d3c --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/consts/SysExpEnumConstant.java @@ -0,0 +1,124 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.consts; + +/** + * 系统管理异常枚举编码构成常量 + *

+ * 异常枚举编码由3部分组成,如下: + *

+ * 模块编码(2位) + 分类编码(4位) + 具体项编码(至少1位) + *

+ * 模块编码和分类编码在ExpEnumCodeConstant类中声明 + * + * @author yubaoshan + * @date 2020/6/19 20:46 + */ +public interface SysExpEnumConstant { + + /** + * 模块分类编码(2位) + *

+ * xiaonuo-system模块异常枚举编码 + */ + int XIAONUO_SYS_MODULE_EXP_CODE = 20; + + /* 分类编码(4位) */ + /** + * 系统应用相关异常枚举 + */ + int SYS_APP_EXCEPTION_ENUM = 1100; + + /** + * 系统参数配置相关异常枚举 + */ + int SYS_CONFIG_EXCEPTION_ENUM = 1200; + + /** + * 系统字典值相关异常枚举 + */ + int SYS_DICT_DATA_EXCEPTION_ENUM = 1300; + + /** + * 系统字典类型相关异常枚举 + */ + int SYS_DICT_TYPE_EXCEPTION_ENUM = 1400; + + /** + * 文件信息表相关枚举 + */ + int SYS_FILE_INFO_EXCEPTION_ENUM = 1500; + + /** + * 系统菜单相关异常枚举 + */ + int SYS_MENU_EXCEPTION_ENUM = 1600; + + /** + * 系统组织机构相关异常枚举 + */ + int SYS_ORG_EXCEPTION_ENUM = 1700; + + /** + * 系统职位相关异常枚举 + */ + int SYS_POS_EXCEPTION_ENUM = 1800; + + /** + * 系统角色相关异常枚举 + */ + int SYS_ROLE_EXCEPTION_ENUM = 1900; + + /** + * 系统用户相关异常枚举 + */ + int SYS_USER_EXCEPTION_ENUM = 2000; + + /** + * 系统通知公告相关异常枚举 + */ + int SYS_NOTICE_EXCEPTION_ENUM = 2100; + + /** + * 定时任务相关 + */ + int TIMER_EXCEPTION_ENUM = 2200; + + /** + * 邮件相关 + */ + int EMAIL_EXCEPTION_ENUM = 2300; + + /** + * 短信相关 + */ + int SMS_EXCEPTION_ENUM = 2400; + + /** + * Oauth登录相关 + */ + int OAUTH_EXCEPTION_ENUM = 2500; + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/context/SystemContextImpl.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/context/SystemContextImpl.java new file mode 100644 index 00000000..c3a1a416 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/context/SystemContextImpl.java @@ -0,0 +1,229 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.context; + +import cn.hutool.core.lang.Dict; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.log.Log; +import com.cn.xiaonuo.core.context.system.SystemContext; +import com.cn.xiaonuo.core.pojo.base.validate.UniqueValidateParam; +import com.cn.xiaonuo.core.pojo.login.SysLoginUser; +import com.cn.xiaonuo.sys.modular.auth.service.AuthService; +import com.cn.xiaonuo.sys.modular.dict.service.SysDictDataService; +import com.cn.xiaonuo.sys.modular.role.entity.SysRole; +import com.cn.xiaonuo.sys.modular.role.param.SysRoleParam; +import com.cn.xiaonuo.sys.modular.role.service.SysRoleService; +import com.cn.xiaonuo.sys.modular.user.entity.SysUser; +import com.cn.xiaonuo.sys.modular.user.param.SysUserParam; +import com.cn.xiaonuo.sys.modular.user.service.SysUserService; +import com.baomidou.mybatisplus.extension.toolkit.SqlRunner; +import com.cn.xiaonuo.core.context.system.SystemContext; +import com.cn.xiaonuo.core.pojo.base.validate.UniqueValidateParam; +import com.cn.xiaonuo.core.pojo.login.SysLoginUser; +import com.cn.xiaonuo.sys.modular.auth.service.AuthService; +import com.cn.xiaonuo.sys.modular.dict.service.SysDictDataService; +import com.cn.xiaonuo.sys.modular.role.entity.SysRole; +import com.cn.xiaonuo.sys.modular.role.param.SysRoleParam; +import com.cn.xiaonuo.sys.modular.role.service.SysRoleService; +import com.cn.xiaonuo.sys.modular.user.entity.SysUser; +import com.cn.xiaonuo.sys.modular.user.param.SysUserParam; +import com.cn.xiaonuo.sys.modular.user.service.SysUserService; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 系统相关上下文接口实现类 + * + * @author xuyuxiang + * @date 2020/5/6 14:59 + */ +@Component +public class SystemContextImpl implements SystemContext { + + Log log = Log.get(); + + @Resource + private AuthService authService; + + @Resource + private SysUserService sysUserService; + + @Resource + private SysRoleService sysRoleService; + + @Resource + private SysDictDataService sysDictDataService; + + @Override + public String getNameByUserId(Long userId) { + return sysUserService.getNameByUserId(userId); + } + + @Override + public String getNameByRoleId(Long roleId) { + return sysRoleService.getNameByRoleId(roleId); + } + + @Override + public SysLoginUser getLoginUserByToken(String token) { + return authService.getLoginUserByToken(token); + } + + @Override + public List listUser(String account) { + SysUserParam sysUserParam = new SysUserParam(); + if (ObjectUtil.isNotEmpty(account)) { + sysUserParam.setAccount(account); + } + return sysUserService.list(sysUserParam); + } + + @Override + public List listRole(String name) { + SysRoleParam sysRoleParam = new SysRoleParam(); + if (ObjectUtil.isNotEmpty(name)) { + sysRoleParam.setName(name); + } + return sysRoleService.list(sysRoleParam); + } + + @Override + public boolean isUser(Long userOrRoleId) { + SysUser sysUser = sysUserService.getById(userOrRoleId); + return !ObjectUtil.isNull(sysUser); + } + + @Override + public boolean isRole(Long userOrRoleId) { + SysRole sysRole = sysRoleService.getById(userOrRoleId); + return !ObjectUtil.isNull(sysRole); + } + + @Override + public List getDictCodesByDictTypeCode(String... dictTypeCodes) { + return sysDictDataService.getDictCodesByDictTypeCode(dictTypeCodes); + } + + @Override + public boolean tableUniValueFlag(UniqueValidateParam uniqueValidateParam) { + int resultCount = 0; + + // 参数校验 + paramValidate(uniqueValidateParam); + + // 不排除当前记录,不排除逻辑删除的内容 + if (!uniqueValidateParam.getExcludeCurrentRecord() + && !uniqueValidateParam.getExcludeLogicDeleteItems()) { + resultCount = SqlRunner.db().selectCount( + "select count(*) from " + uniqueValidateParam.getTableName() + " where " + uniqueValidateParam.getColumnName() + " = {0}", + uniqueValidateParam.getValue()); + } + + // 不排除当前记录,排除逻辑删除的内容 + if (!uniqueValidateParam.getExcludeCurrentRecord() + && uniqueValidateParam.getExcludeLogicDeleteItems()) { + resultCount = SqlRunner.db().selectCount( + "select count(*) from " + uniqueValidateParam.getTableName() + + " where " + uniqueValidateParam.getColumnName() + " = {0} " + + " and " + + "(" + uniqueValidateParam.getLogicDeleteFieldName() + " is null || " + + uniqueValidateParam.getLogicDeleteFieldName() + " <> " + uniqueValidateParam.getLogicDeleteValue() + ")", + uniqueValidateParam.getValue()); + } + + // 排除当前记录,不排除逻辑删除的内容 + if (uniqueValidateParam.getExcludeCurrentRecord() + && !uniqueValidateParam.getExcludeLogicDeleteItems()) { + + // id判空 + paramIdValidate(uniqueValidateParam); + + resultCount = SqlRunner.db().selectCount( + "select count(*) from " + uniqueValidateParam.getTableName() + + " where " + uniqueValidateParam.getColumnName() + " = {0} " + + " and id <> {1}", + uniqueValidateParam.getValue(), uniqueValidateParam.getId()); + } + + // 排除当前记录,排除逻辑删除的内容 + if (uniqueValidateParam.getExcludeCurrentRecord() + && uniqueValidateParam.getExcludeLogicDeleteItems()) { + + // id判空 + paramIdValidate(uniqueValidateParam); + + resultCount = SqlRunner.db().selectCount( + "select count(*) from " + uniqueValidateParam.getTableName() + + " where " + uniqueValidateParam.getColumnName() + " = {0} " + + " and id <> {1} " + + " and " + + "(" + uniqueValidateParam.getLogicDeleteFieldName() + " is null || " + + uniqueValidateParam.getLogicDeleteFieldName() + " <> " + uniqueValidateParam.getLogicDeleteValue() + ")", + uniqueValidateParam.getValue(), uniqueValidateParam.getId()); + } + + // 如果大于0,代表不是唯一的当前校验的值 + return resultCount <= 0; + } + + @Override + public List getAllUserIdList() { + return sysUserService.getAllUserIdList(); + } + + /** + * 几个参数的为空校验 + * + * @author xuyuxiang + * @date 2020/8/17 22:00 + */ + private void paramValidate(UniqueValidateParam uniqueValidateParam) { + if (StrUtil.isBlank(uniqueValidateParam.getTableName())) { + throw new IllegalArgumentException("当前table字段值唯一性校验失败,tableName为空"); + } + if (StrUtil.isBlank(uniqueValidateParam.getColumnName())) { + throw new IllegalArgumentException("当前table字段值唯一性校验失败,columnName为空"); + } + if (StrUtil.isBlank(uniqueValidateParam.getValue())) { + throw new IllegalArgumentException("当前table字段值唯一性校验失败,字段值value为空"); + } + } + + /** + * id参数的为空校验 + * + * @author xuyuxiang + * @date 2020/8/17 22:00 + */ + private void paramIdValidate(UniqueValidateParam uniqueValidateParam) { + if (uniqueValidateParam.getId() == null) { + throw new IllegalArgumentException("当前table字段值唯一性校验失败,id为空"); + } + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/AdminTypeEnum.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/AdminTypeEnum.java new file mode 100644 index 00000000..c5541f04 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/AdminTypeEnum.java @@ -0,0 +1,56 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.enums; + +import lombok.Getter; + +/** + * 管理员类型枚举 + * + * @author xuyuxiang + * @date 2020/4/5 10:23 + */ +@Getter +public enum AdminTypeEnum { + + /** + * 超级管理员 + */ + SUPER_ADMIN(1, "超级管理员"), + + /** + * 非管理员 + */ + NONE(2, "非管理员"); + + private final Integer code; + + private final String message; + + AdminTypeEnum(int code, String message) { + this.code = code; + this.message = message; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/DataScopeTypeEnum.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/DataScopeTypeEnum.java new file mode 100644 index 00000000..34f0921a --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/DataScopeTypeEnum.java @@ -0,0 +1,71 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.enums; + +import lombok.Getter; + +/** + * 数据范围类型枚举 + * + * @author xuyuxiang + * @date 2020/5/28 11:02 + */ +@Getter +public enum DataScopeTypeEnum { + + /** + * 全部数据 + */ + ALL(1, "全部数据"), + + /** + * 本部门及以下数据 + */ + DEPT_WITH_CHILD(2, "本部门及以下数据"), + + /** + * 本部门数据 + */ + DEPT(3, "本部门数据"), + + /** + * 仅本人数据 + */ + SELF(4, "仅本人数据"), + + /** + * 仅本人数据 + */ + DEFINE(5, "自定义数据"); + + private final Integer code; + + private final String message; + + DataScopeTypeEnum(Integer code, String message) { + this.code = code; + this.message = message; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/LogSuccessStatusEnum.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/LogSuccessStatusEnum.java new file mode 100644 index 00000000..9da88ef2 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/LogSuccessStatusEnum.java @@ -0,0 +1,56 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.enums; + +import lombok.Getter; + +/** + * 日志成功状态 + * + * @author xuyuxiang + * @date 2020/3/12 15:53 + */ +@Getter +public enum LogSuccessStatusEnum { + + /** + * 失败 + */ + FAIL("N", "失败"), + + /** + * 成功 + */ + SUCCESS("Y", "成功"); + + private final String code; + + private final String message; + + LogSuccessStatusEnum(String code, String message) { + this.code = code; + this.message = message; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/MenuOpenTypeEnum.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/MenuOpenTypeEnum.java new file mode 100644 index 00000000..b346ef7f --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/MenuOpenTypeEnum.java @@ -0,0 +1,66 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.enums; + +import lombok.Getter; + +/** + * 菜单类型枚举 + * + * @author xuyuxiang + * @date 2020/5/25 15:18 + */ +@Getter +public enum MenuOpenTypeEnum { + + /** + * 无 + */ + NONE(0, "无"), + + /** + * 组件 + */ + COMPONENT(1, "组件"), + + /** + * 内链 + */ + INNER(2, "内链"), + + /** + * 外链 + */ + OUTER(3, "外链"); + + private final Integer code; + + private final String message; + + MenuOpenTypeEnum(Integer code, String message) { + this.code = code; + this.message = message; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/MenuTypeEnum.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/MenuTypeEnum.java new file mode 100644 index 00000000..d74dae9f --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/MenuTypeEnum.java @@ -0,0 +1,61 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.enums; + +import lombok.Getter; + +/** + * 菜单类型枚举 + * + * @author xuyuxiang + * @date 2020/5/25 15:18 + */ +@Getter +public enum MenuTypeEnum { + + /** + * 目录 + */ + DIR(0, "目录"), + + /** + * 菜单 + */ + MENU(1, "菜单"), + + /** + * 按钮 + */ + BTN(2, "按钮"); + + private final Integer code; + + private final String message; + + MenuTypeEnum(Integer code, String message) { + this.code = code; + this.message = message; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/MenuWeightEnum.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/MenuWeightEnum.java new file mode 100644 index 00000000..b5c3f6b3 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/MenuWeightEnum.java @@ -0,0 +1,56 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.enums; + +import lombok.Getter; + +/** + * 菜单权重枚举 + * + * @author xuyuxiang + * @date 2020/5/27 17:07 + */ +@Getter +public enum MenuWeightEnum { + + /** + * 系统权重 + */ + SUPER_ADMIN_WEIGHT(1, "系统权重"), + + /** + * 业务权重 + */ + DEFAULT_WEIGHT(2, "业务权重"); + + private final Integer code; + + private final String name; + + MenuWeightEnum(Integer code, String name) { + this.code = code; + this.name = name; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/NoticeStatusEnum.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/NoticeStatusEnum.java new file mode 100644 index 00000000..d4880461 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/NoticeStatusEnum.java @@ -0,0 +1,67 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.enums; + +import lombok.Getter; + +/** + * 通知公告状态 + * + * @author xuyuxiang + * @date 2020/6/28 17:51 + */ +@Getter +public enum NoticeStatusEnum { + + /** + * 草稿 + */ + DRAFT(0, "草稿"), + + /** + * 发布 + */ + PUBLIC(1, "发布"), + + /** + * 撤回 + */ + CANCEL(2, "撤回"), + + /** + * 删除 + */ + DELETED(3, "删除"); + + private final Integer code; + + private final String message; + + NoticeStatusEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/NoticeUserStatusEnum.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/NoticeUserStatusEnum.java new file mode 100644 index 00000000..1ab017f3 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/NoticeUserStatusEnum.java @@ -0,0 +1,57 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.enums; + +import lombok.Getter; + +/** + * 通知公告用户状态 + * + * @author xuyuxiang + * @date 2020/6/29 11:02 + */ +@Getter +public enum NoticeUserStatusEnum { + + /** + * 未读 + */ + UNREAD(0, "未读"), + + /** + * 已读 + */ + READ(1, "已读"); + + private final Integer code; + + private final String message; + + NoticeUserStatusEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/OauthPlatformEnum.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/OauthPlatformEnum.java new file mode 100644 index 00000000..4565ed70 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/OauthPlatformEnum.java @@ -0,0 +1,57 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.enums; + +import lombok.Getter; + +/** + * Oauth登录授权平台的枚举 + * + * @author xuyuxiang + * @date 2020/7/28 16:46 + **/ +@Getter +public enum OauthPlatformEnum { + + /** + * 码云 + */ + GITEE("gitee", "码云"), + + /** + * github + */ + GITHUB("github", "github"); + + private final String code; + + private final String message; + + OauthPlatformEnum(String code, String message) { + this.code = code; + this.message = message; + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/OauthSexEnum.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/OauthSexEnum.java new file mode 100644 index 00000000..95cf6296 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/OauthSexEnum.java @@ -0,0 +1,61 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.enums; + +import lombok.Getter; + +/** + * Oauth用户性别枚举 + * + * @author xuyuxiang + * @date 2020/7/29 10:32 + **/ +@Getter +public enum OauthSexEnum { + + /** + * 男 + */ + MAN("1", "男"), + + /** + * 女 + */ + WOMAN("0", "女"), + + /** + * 未知 + */ + NONE("-1", "未知"); + + private final String code; + + private final String message; + + OauthSexEnum(String code, String message) { + this.code = code; + this.message = message; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/SexEnum.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/SexEnum.java new file mode 100644 index 00000000..c239fe54 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/SexEnum.java @@ -0,0 +1,61 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.enums; + +import lombok.Getter; + +/** + * 性别枚举 + * + * @author xuyuxiang + * @date 2020/5/28 10:51 + */ +@Getter +public enum SexEnum { + + /** + * 男 + */ + MAN(1, "男"), + + /** + * 女 + */ + WOMAN(2, "女"), + + /** + * 未知 + */ + NONE(3, "未知"); + + private final Integer code; + + private final String message; + + SexEnum(Integer code, String message) { + this.code = code; + this.message = message; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/VisLogTypeEnum.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/VisLogTypeEnum.java new file mode 100644 index 00000000..e355b63a --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/enums/VisLogTypeEnum.java @@ -0,0 +1,56 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.enums; + +import lombok.Getter; + +/** + * 访问日志类型枚举 + * + * @author xuyuxiang + * @date 2020/3/12 15:50 + */ +@Getter +public enum VisLogTypeEnum { + + /** + * 登录日志 + */ + LOGIN(1, "登录"), + + /** + * 退出日志 + */ + EXIT(2, "登出"); + + private final Integer code; + + private final String message; + + VisLogTypeEnum(Integer code, String message) { + this.code = code; + this.message = message; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/error/GlobalExceptionHandler.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/error/GlobalExceptionHandler.java new file mode 100644 index 00000000..cac96031 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/error/GlobalExceptionHandler.java @@ -0,0 +1,370 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.error; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.extra.servlet.ServletUtil; +import cn.hutool.log.Log; +import com.cn.xiaonuo.core.consts.AopSortConstant; +import com.cn.xiaonuo.core.consts.CommonConstant; +import com.cn.xiaonuo.core.consts.SymbolConstant; +import com.cn.xiaonuo.core.context.requestno.RequestNoContext; +import com.cn.xiaonuo.core.exception.AuthException; +import com.cn.xiaonuo.core.exception.DemoException; +import com.cn.xiaonuo.core.exception.PermissionException; +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.core.exception.enums.*; +import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum; +import com.cn.xiaonuo.core.pojo.response.ErrorResponseData; +import com.cn.xiaonuo.core.sms.modular.aliyun.exp.AliyunSmsException; +import com.cn.xiaonuo.core.sms.modular.tencent.exp.TencentSmsException; +import com.cn.xiaonuo.core.util.ResponseUtil; +import org.apache.ibatis.exceptions.PersistenceException; +import org.mybatis.spring.MyBatisSystemException; +import org.springframework.core.annotation.Order; +import org.springframework.http.HttpStatus; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.validation.BindException; +import org.springframework.validation.BindingResult; +import org.springframework.validation.ObjectError; +import org.springframework.web.HttpMediaTypeNotSupportedException; +import org.springframework.web.HttpRequestMethodNotSupportedException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.MissingServletRequestParameterException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.servlet.NoHandlerFoundException; + +import javax.servlet.http.HttpServletRequest; +import java.util.List; + +/** + * 全局异常处理器 + * + * @author xuyuxiang + * @date 2020/3/18 19:03 + */ +@Order(AopSortConstant.GLOBAL_EXP_HANDLER_AOP) +@ControllerAdvice +public class GlobalExceptionHandler { + + private static final Log log = Log.get(); + + /** + * 腾讯云短信发送异常 + * + * @author yubaoshan + * @date 2020/6/7 18:03 + */ + @ExceptionHandler(TencentSmsException.class) + @ResponseBody + public ErrorResponseData aliyunSmsException(TencentSmsException e) { + log.error(">>> 发送短信异常,请求号为:{},具体信息为:{}", RequestNoContext.get(), e.getErrorMessage()); + return renderJson(500, e.getErrorMessage()); + } + + /** + * 阿里云短信发送异常 + * + * @author yubaoshan + * @date 2020/6/7 18:03 + */ + @ExceptionHandler(AliyunSmsException.class) + @ResponseBody + public ErrorResponseData aliyunSmsException(AliyunSmsException e) { + log.error(">>> 发送短信异常,请求号为:{},具体信息为:{}", RequestNoContext.get(), e.getErrorMessage()); + return renderJson(500, e.getErrorMessage()); + } + + /** + * 请求参数缺失异常 + * + * @author yubaoshan + * @date 2020/6/7 18:03 + */ + @ExceptionHandler(MissingServletRequestParameterException.class) + @ResponseBody + public ErrorResponseData missParamException(MissingServletRequestParameterException e) { + log.error(">>> 请求参数异常,请求号为:{},具体信息为:{}", RequestNoContext.get(), e.getMessage()); + String parameterType = e.getParameterType(); + String parameterName = e.getParameterName(); + String message = StrUtil.format(">>> 缺少请求的参数{},类型为{}", parameterName, parameterType); + return renderJson(500, message); + } + + /** + * 拦截参数格式传递异常 + * + * @author xuyuxiang + * @date 2020/4/2 15:32 + */ + @ExceptionHandler(HttpMessageNotReadableException.class) + @ResponseBody + public ErrorResponseData httpMessageNotReadable(HttpMessageNotReadableException e) { + log.error(">>> 参数格式传递异常,请求号为:{},具体信息为:{}", RequestNoContext.get(), e.getMessage()); + return renderJson(RequestTypeExceptionEnum.REQUEST_JSON_ERROR); + } + + /** + * 拦截不支持媒体类型异常 + * + * @author xuyuxiang + * @date 2020/4/2 15:38 + */ + @ExceptionHandler(HttpMediaTypeNotSupportedException.class) + @ResponseBody + public ErrorResponseData httpMediaTypeNotSupport(HttpMediaTypeNotSupportedException e) { + log.error(">>> 参数格式传递异常,请求号为:{},具体信息为:{}", RequestNoContext.get(), e.getMessage()); + return renderJson(RequestTypeExceptionEnum.REQUEST_TYPE_IS_JSON); + } + + /** + * 拦截请求方法的异常 + * + * @author xuyuxiang + * @date 2020/3/18 19:14 + */ + @ExceptionHandler(HttpRequestMethodNotSupportedException.class) + @ResponseBody + public ErrorResponseData methodNotSupport(HttpServletRequest request) { + if (ServletUtil.isPostMethod(request)) { + log.error(">>> 请求方法异常,请求号为:{},具体信息为:{}", RequestNoContext.get(), RequestMethodExceptionEnum.REQUEST_METHOD_IS_GET.getMessage()); + return renderJson(RequestMethodExceptionEnum.REQUEST_METHOD_IS_GET); + } + if (ServletUtil.isGetMethod(request)) { + log.error(">>> 请求方法异常,请求号为:{},具体信息为:{}", RequestNoContext.get(), RequestMethodExceptionEnum.REQUEST_METHOD_IS_POST.getMessage()); + return renderJson(RequestMethodExceptionEnum.REQUEST_METHOD_IS_POST); + } + return null; + } + + /** + * 拦截资源找不到的运行时异常 + * + * @author xuyuxiang + * @date 2020/4/2 15:38 + */ + @ExceptionHandler(NoHandlerFoundException.class) + @ResponseStatus(HttpStatus.NOT_FOUND) + @ResponseBody + public ErrorResponseData notFound(NoHandlerFoundException e) { + log.error(">>> 资源不存在异常,请求号为:{},具体信息为:{}", RequestNoContext.get(), e.getMessage()); + return renderJson(PermissionExceptionEnum.URL_NOT_EXIST); + } + + /** + * 拦截参数校验错误异常,JSON传参 + * + * @author xuyuxiang + * @date 2020/4/2 15:38 + */ + @ExceptionHandler(MethodArgumentNotValidException.class) + @ResponseBody + public ErrorResponseData methodArgumentNotValidException(MethodArgumentNotValidException e) { + String argNotValidMessage = getArgNotValidMessage(e.getBindingResult()); + log.error(">>> 参数校验错误异常,请求号为:{},具体信息为:{}", RequestNoContext.get(), argNotValidMessage); + return renderJson(ParamExceptionEnum.PARAM_ERROR.getCode(), argNotValidMessage); + } + + /** + * 拦截参数校验错误异常 + * + * @author xuyuxiang + * @date 2020/3/18 19:41 + */ + @ExceptionHandler(BindException.class) + @ResponseBody + public ErrorResponseData paramError(BindException e) { + String argNotValidMessage = getArgNotValidMessage(e.getBindingResult()); + log.error(">>> 参数校验错误异常,请求号为:{},具体信息为:{}", RequestNoContext.get(), argNotValidMessage); + return renderJson(ParamExceptionEnum.PARAM_ERROR.getCode(), argNotValidMessage); + } + + /** + * 拦截认证失败异常 + * + * @author xuyuxiang + * @date 2020/3/18 19:41 + */ + @ExceptionHandler(AuthException.class) + @ResponseBody + public ErrorResponseData authFail(AuthException e) { + log.error(">>> 认证异常,请求号为:{},具体信息为:{}", RequestNoContext.get(), e.getMessage()); + return renderJson(e.getCode(), e.getErrorMessage()); + } + + /** + * 拦截权限异常 + * + * @author xuyuxiang + * @date 2020/3/18 19:41 + */ + @ExceptionHandler(PermissionException.class) + @ResponseBody + public ErrorResponseData noPermission(PermissionException e) { + log.error(">>> 权限异常,请求号为:{},具体信息为:{}", RequestNoContext.get(), e.getMessage()); + return renderJson(e.getCode(), e.getErrorMessage()); + } + + /** + * 拦截业务异常 + * + * @author xuyuxiang + * @date 2020/3/18 19:41 + */ + @ExceptionHandler(ServiceException.class) + @ResponseBody + public ErrorResponseData businessError(ServiceException e) { + log.error(">>> 业务异常,请求号为:{},具体信息为:{}", RequestNoContext.get(), e.getMessage()); + return renderJson(e.getCode(), e.getErrorMessage(), e); + } + + /** + * 拦截mybatis数据库操作的异常 + *

+ * 用在demo模式,拦截DemoException + * + * @author yubaoshan + * @date 2020/5/5 15:19 + */ + @ExceptionHandler(MyBatisSystemException.class) + @ResponseBody + public ErrorResponseData persistenceException(MyBatisSystemException e) { + log.error(">>> mybatis操作出现异常,请求号为:{},具体信息为:{}", RequestNoContext.get(), e.getMessage()); + Throwable cause = e.getCause(); + if (cause instanceof PersistenceException) { + Throwable secondCause = cause.getCause(); + if (secondCause instanceof DemoException) { + DemoException demoException = (DemoException) secondCause; + return ResponseUtil.responseDataError(demoException.getCode(), demoException.getErrorMessage(), e.getStackTrace()[0].toString()); + } + } + return ResponseUtil.responseDataError(ServerExceptionEnum.SERVER_ERROR.getCode(), ServerExceptionEnum.SERVER_ERROR.getMessage(), e.getStackTrace()[0].toString()); + } + + /** + * 拦截未知的运行时异常 + * + * @author xuyuxiang + * @date 2020/3/18 19:41 + */ + @ExceptionHandler(Throwable.class) + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) + @ResponseBody + public ErrorResponseData serverError(Throwable e) { + log.error(">>> 服务器运行异常,请求号为:{}", RequestNoContext.get()); + e.printStackTrace(); + return renderJson(e); + } + + /** + * 渲染异常json + * + * @author yubaoshan + * @date 2020/5/5 16:22 + */ + private ErrorResponseData renderJson(Integer code, String message) { + return renderJson(code, message, null); + } + + /** + * 渲染异常json + * + * @author yubaoshan + * @date 2020/5/5 16:22 + */ + private ErrorResponseData renderJson(AbstractBaseExceptionEnum baseExceptionEnum) { + return renderJson(baseExceptionEnum.getCode(), baseExceptionEnum.getMessage(), null); + } + + /** + * 渲染异常json + * + * @author yubaoshan + * @date 2020/5/5 16:22 + */ + private ErrorResponseData renderJson(Throwable throwable) { + return renderJson(((AbstractBaseExceptionEnum) ServerExceptionEnum.SERVER_ERROR).getCode(), + ((AbstractBaseExceptionEnum) ServerExceptionEnum.SERVER_ERROR).getMessage(), throwable); + } + + /** + * 渲染异常json + *

+ * 根据异常枚举和Throwable异常响应,异常信息响应堆栈第一行 + * + * @author yubaoshan + * @date 2020/5/5 16:22 + */ + private ErrorResponseData renderJson(Integer code, String message, Throwable e) { + if (ObjectUtil.isNotNull(e)) { + + //获取所有堆栈信息 + StackTraceElement[] stackTraceElements = e.getStackTrace(); + + //默认的异常类全路径为第一条异常堆栈信息的 + String exceptionClassTotalName = stackTraceElements[0].toString(); + + //遍历所有堆栈信息,找到com.cn.xiaonuo开头的第一条异常信息 + for (StackTraceElement stackTraceElement : stackTraceElements) { + if (stackTraceElement.toString().contains(CommonConstant.DEFAULT_PACKAGE_NAME)) { + exceptionClassTotalName = stackTraceElement.toString(); + break; + } + } + return ResponseUtil.responseDataError(code, message, exceptionClassTotalName); + } else { + return ResponseUtil.responseDataError(code, message, null); + } + } + + /** + * 获取请求参数不正确的提示信息 + *

+ * 多个信息,拼接成用逗号分隔的形式 + * + * @author yubaoshan + * @date 2020/5/5 16:50 + */ + private String getArgNotValidMessage(BindingResult bindingResult) { + if (bindingResult == null) { + return ""; + } + StringBuilder stringBuilder = new StringBuilder(); + + //多个错误用逗号分隔 + List allErrorInfos = bindingResult.getAllErrors(); + for (ObjectError error : allErrorInfos) { + stringBuilder.append(SymbolConstant.COMMA).append(error.getDefaultMessage()); + } + + //最终把首部的逗号去掉 + return StrUtil.removePrefix(stringBuilder.toString(), SymbolConstant.COMMA); + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/error/XiaoNuoErrorAttributes.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/error/XiaoNuoErrorAttributes.java new file mode 100644 index 00000000..f29322d3 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/error/XiaoNuoErrorAttributes.java @@ -0,0 +1,70 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.error; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.http.HttpStatus; +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.core.exception.enums.PermissionExceptionEnum; +import com.cn.xiaonuo.core.exception.enums.ServerExceptionEnum; +import com.cn.xiaonuo.core.pojo.response.ErrorResponseData; +import org.springframework.boot.web.error.ErrorAttributeOptions; +import org.springframework.boot.web.servlet.error.DefaultErrorAttributes; +import org.springframework.web.context.request.WebRequest; + +import java.util.Map; + +/** + * 将系统管理未知错误异常,输出格式重写为我们熟悉的响应格式 + * + * @author yubaoshan + * @date 2020/4/14 22:21 + */ +public class XiaoNuoErrorAttributes extends DefaultErrorAttributes { + + @Override + public Map getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions attributeOptions) { + + // 1.先获取spring默认的返回内容 + Map defaultErrorAttributes = super.getErrorAttributes(webRequest, attributeOptions); + + // 2.如果返回的异常是ServiceException,则按ServiceException响应的内容进行返回 + Throwable throwable = this.getError(webRequest); + if (throwable instanceof ServiceException) { + ServiceException serviceException = (ServiceException) throwable; + return BeanUtil.beanToMap(new ErrorResponseData(serviceException.getCode(), serviceException.getErrorMessage())); + } + + // 3.如果返回的是404 http状态码 + Integer status = (Integer) defaultErrorAttributes.get("status"); + if (status.equals(HttpStatus.HTTP_NOT_FOUND)) { + return BeanUtil.beanToMap(new ErrorResponseData(PermissionExceptionEnum.URL_NOT_EXIST.getCode(), PermissionExceptionEnum.URL_NOT_EXIST.getMessage())); + } + + // 4.无法确定的返回服务器异常 + return BeanUtil.beanToMap(new ErrorResponseData(ServerExceptionEnum.SERVER_ERROR.getCode(), ServerExceptionEnum.SERVER_ERROR.getMessage())); + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/filter/RequestNoFilter.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/filter/RequestNoFilter.java new file mode 100644 index 00000000..a7d455ae --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/filter/RequestNoFilter.java @@ -0,0 +1,67 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.filter; + + +import com.cn.xiaonuo.core.context.requestno.RequestNoContext; +import com.cn.xiaonuo.core.consts.CommonConstant; + +import javax.servlet.*; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.UUID; + +/** + * 对请求生成唯一编码 + * + * @author yubaoshan + * @date 2020/6/21 10:04 + */ +public class RequestNoFilter implements Filter { + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + try { + // 生成唯一请求号uuid + String requestNo = UUID.randomUUID().toString(); + + // 增加响应头的请求号 + HttpServletResponse httpServletResponse = (HttpServletResponse) response; + httpServletResponse.addHeader(CommonConstant.REQUEST_NO_HEADER_NAME, requestNo); + + // 临时存储 + RequestNoContext.set(requestNo); + + // 放开请求 + chain.doFilter(request, response); + + } finally { + // 清除临时存储的唯一编号 + RequestNoContext.clear(); + } + + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/filter/security/JwtAuthenticationTokenFilter.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/filter/security/JwtAuthenticationTokenFilter.java new file mode 100644 index 00000000..7eda6f7e --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/filter/security/JwtAuthenticationTokenFilter.java @@ -0,0 +1,100 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.filter.security; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.log.Log; +import com.cn.xiaonuo.core.context.requestno.RequestNoContext; +import com.cn.xiaonuo.core.exception.AuthException; +import com.cn.xiaonuo.core.exception.enums.ServerExceptionEnum; +import com.cn.xiaonuo.core.pojo.login.SysLoginUser; +import com.cn.xiaonuo.core.util.ResponseUtil; +import com.cn.xiaonuo.sys.modular.auth.service.AuthService; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +import javax.annotation.Resource; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * 这个过滤器,在所有请求之前,也在spring security filters之前 + *

+ * 这个过滤器的作用是:接口在进业务之前,添加登录上下文(SecurityContext) + *

+ * 因为现在没有用session了,只能token来校验当前的登录人的身份,所以在进业务之前要给当前登录人设置登录状态 + * + * @author yubaoshan,xuyuxiang + * @date 2020/4/11 13:02 + */ +@Component +public class JwtAuthenticationTokenFilter extends OncePerRequestFilter { + + private static final Log log = Log.get(); + + @Resource + private AuthService authService; + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException { + try { + doFilter(request, response, filterChain); + } catch (Exception e) { + log.error(">>> 服务器运行异常,请求号为:{},具体信息为:{}", RequestNoContext.get(), e.getMessage()); + ResponseUtil.responseExceptionError(response, ServerExceptionEnum.SERVER_ERROR.getCode(), + ServerExceptionEnum.SERVER_ERROR.getMessage(), e.getStackTrace()[0].toString()); + } + } + + private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException { + + // 1.如果当前请求带了token,判断token时效性,并获取当前登录用户信息 + SysLoginUser sysLoginUser = null; + try { + String token = authService.getTokenFromRequest(request); + if (StrUtil.isNotEmpty(token)) { + sysLoginUser = authService.getLoginUserByToken(token); + } + } catch (AuthException ae) { + //token过期或者token失效的情况,响应给前端 + ResponseUtil.responseExceptionError(response, ae.getCode(), ae.getErrorMessage(), ae.getStackTrace()[0].toString()); + return; + } + + // 2.如果当前登录用户不为空,就设置spring security上下文 + if (ObjectUtil.isNotNull(sysLoginUser)) { + authService.setSpringSecurityContextAuthentication(sysLoginUser); + } + + // 3.其他情况放开过滤 + filterChain.doFilter(request, response); + + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/filter/security/entrypoint/JwtAuthenticationEntryPoint.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/filter/security/entrypoint/JwtAuthenticationEntryPoint.java new file mode 100644 index 00000000..2aa684a9 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/filter/security/entrypoint/JwtAuthenticationEntryPoint.java @@ -0,0 +1,99 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.filter.security.entrypoint; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.log.Log; +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.core.exception.enums.AuthExceptionEnum; +import com.cn.xiaonuo.core.exception.enums.PermissionExceptionEnum; +import com.cn.xiaonuo.core.exception.enums.ServerExceptionEnum; +import com.cn.xiaonuo.core.util.ResponseUtil; +import com.cn.xiaonuo.sys.core.cache.ResourceCache; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.Serializable; +import java.util.Collection; + +/** + * 未认证用户访问须授权资源端点 + * + * @author xuyuxiang + * @date 2020/3/18 11:52 + */ +@Component +public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint, Serializable { + + private static final Log log = Log.get(); + + @Resource + private ResourceCache resourceCache; + + /** + * 访问未经授权的接口时执行此方法,未经授权的接口包含系统中存在和不存在的接口,分别处理 + * + * @author xuyuxiang + * @date 2020/3/18 19:15 + */ + @Override + public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException { + + String requestUri = request.getRequestURI(); + + //1.检查redis中RESOURCE缓存是否为空,如果为空,直接抛出系统异常,缓存url作用详见ResourceCollectListener + Collection urlCollections = resourceCache.getAllResources(); + if (ObjectUtil.isEmpty(urlCollections)) { + log.error(">>> 获取缓存的Resource Url为空,请检查缓存中是否被误删,requestUri={}", requestUri); + ResponseUtil.responseExceptionError(response, + ServerExceptionEnum.SERVER_ERROR.getCode(), + ServerExceptionEnum.SERVER_ERROR.getMessage(), + new ServiceException(ServerExceptionEnum.SERVER_ERROR).getStackTrace()[0].toString()); + return; + } + + //2.判断缓存的url中是否有当前请求的uri,没有的话响应给前端404 + if (!urlCollections.contains(requestUri)) { + log.error(">>> 当前请求的uri不存在,请检查请求地址是否正确或缓存中是否被误删,requestUri={}", requestUri); + ResponseUtil.responseExceptionError(response, + PermissionExceptionEnum.URL_NOT_EXIST.getCode(), + PermissionExceptionEnum.URL_NOT_EXIST.getMessage(), + new ServiceException(PermissionExceptionEnum.URL_NOT_EXIST).getStackTrace()[0].toString()); + return; + } + + //3.响应给前端无权限访问本接口(没有携带token) + log.error(">>> 没有权限访问该资源,requestUri={}", requestUri); + ResponseUtil.responseExceptionError(response, + AuthExceptionEnum.REQUEST_TOKEN_EMPTY.getCode(), + AuthExceptionEnum.REQUEST_TOKEN_EMPTY.getMessage(), + new ServiceException(AuthExceptionEnum.REQUEST_TOKEN_EMPTY).getStackTrace()[0].toString()); + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/filter/xss/XssFilter.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/filter/xss/XssFilter.java new file mode 100644 index 00000000..75a2cb77 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/filter/xss/XssFilter.java @@ -0,0 +1,58 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.filter.xss; + + +import com.cn.xiaonuo.core.context.constant.ConstantContextHolder; +import com.cn.xiaonuo.core.context.constant.ConstantContextHolder; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.util.List; + +/** + * xss过滤器 + * + * @author yubaoshan + * @date 2020/6/21 10:04 + */ +public class XssFilter implements Filter { + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + HttpServletRequest httpServletRequest = (HttpServletRequest) request; + String servletPath = httpServletRequest.getServletPath(); + + // 获取不进行url过滤的接口 + List unXssFilterUrl = ConstantContextHolder.getUnXssFilterUrl(); + if (unXssFilterUrl != null && unXssFilterUrl.contains(servletPath)) { + chain.doFilter(request, response); + } else { + chain.doFilter(new XssHttpServletRequestWrapper((HttpServletRequest) request), response); + } + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/filter/xss/XssHttpServletRequestWrapper.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/filter/xss/XssHttpServletRequestWrapper.java new file mode 100644 index 00000000..c519b173 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/filter/xss/XssHttpServletRequestWrapper.java @@ -0,0 +1,91 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.filter.xss; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; + +/** + * xss针对http请求的包装 + * + * @author yubaoshan + * @date 2020/6/21 10:29 + */ +public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { + + XssHttpServletRequestWrapper(HttpServletRequest servletRequest) { + super(servletRequest); + } + + @Override + public String[] getParameterValues(String parameter) { + String[] values = super.getParameterValues(parameter); + if (values == null) { + return null; + } + int count = values.length; + String[] encodedValues = new String[count]; + for (int i = 0; i < count; i++) { + encodedValues[i] = cleanXss(values[i]); + } + return encodedValues; + + } + + @Override + public String getParameter(String parameter) { + String value = super.getParameter(parameter); + if (value == null) { + return null; + } + return cleanXss(value); + } + + @Override + public String getHeader(String name) { + String value = super.getHeader(name); + if (value == null) { + return null; + } + return cleanXss(value); + } + + private String cleanXss(String value) { + + value = value.replaceAll("<", "& lt;").replaceAll(">", "& gt;"); + + value = value.replaceAll("\\(", "& #40;").replaceAll("\\)", "& #41;"); + + value = value.replaceAll("'", "& #39;"); + + value = value.replaceAll("eval\\((.*)\\)", ""); + + value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\""); + + return value; + + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/jwt/JwtPayLoad.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/jwt/JwtPayLoad.java new file mode 100644 index 00000000..2763aaa1 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/jwt/JwtPayLoad.java @@ -0,0 +1,62 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.jwt; + +import cn.hutool.core.util.IdUtil; +import lombok.Data; + +/** + * JwtPayLoad部分 + * + * @author xuyuxiang + * @date 2020/3/12 17:41 + */ +@Data +public class JwtPayLoad { + + /** + * 用户id + */ + private Long userId; + + /** + * 账号 + */ + private String account; + + /** + * 唯一表示id, 用于缓存登录用户的唯一凭证 + */ + private String uuid; + + public JwtPayLoad() { + } + + public JwtPayLoad(Long userId, String account) { + this.userId = userId; + this.account = account; + this.uuid = IdUtil.fastUUID(); + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/jwt/JwtTokenUtil.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/jwt/JwtTokenUtil.java new file mode 100644 index 00000000..736f039a --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/jwt/JwtTokenUtil.java @@ -0,0 +1,118 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.jwt; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.convert.Convert; +import cn.hutool.core.date.DateTime; +import cn.hutool.core.date.DateUtil; +import com.cn.xiaonuo.core.context.constant.ConstantContextHolder; +import com.cn.xiaonuo.core.context.constant.ConstantContextHolder; +import io.jsonwebtoken.*; + +import java.util.Date; + +/** + * JwtToken工具类 + * + * @author xuyuxiang + * @date 2020/3/12 17:39 + */ +public class JwtTokenUtil { + + /** + * 生成token + * + * @author xuyuxiang + * @date 2020/3/12 17:52 + */ + public static String generateToken(JwtPayLoad jwtPayLoad) { + + DateTime expirationDate = DateUtil.offsetMillisecond(new Date(), + Convert.toInt(ConstantContextHolder.getTokenExpireSec()) * 1000); + return Jwts.builder() + .setClaims(BeanUtil.beanToMap(jwtPayLoad)) + .setSubject(jwtPayLoad.getUserId().toString()) + .setIssuedAt(new Date()) + .setExpiration(expirationDate) + .signWith(SignatureAlgorithm.HS512, ConstantContextHolder.getJwtSecret()) + .compact(); + } + + /** + * 根据token获取Claims + * + * @author xuyuxiang + * @date 2020/3/13 10:29 + */ + private static Claims getClaimsFromToken(String token) { + return Jwts.parser() + .setSigningKey(ConstantContextHolder.getJwtSecret()) + .parseClaimsJws(token) + .getBody(); + } + + /** + * 获取JwtPayLoad部分 + * + * @author xuyuxiang + * @date 2020/3/12 17:53 + */ + public static JwtPayLoad getJwtPayLoad(String token) { + Claims claims = getClaimsFromToken(token); + return BeanUtil.mapToBean(claims, JwtPayLoad.class, false); + } + + /** + * 校验token是否正确 + * + * @author xuyuxiang + * @date 2020/3/13 10:36 + */ + public static Boolean checkToken(String token) { + try { + getClaimsFromToken(token); + return true; + } catch (JwtException jwtException) { + return false; + } + } + + /** + * 校验token是否失效 + * + * @author xuyuxiang + * @date 2020/3/13 10:30 + */ + public static Boolean isTokenExpired(String token) { + try { + Claims claims = getClaimsFromToken(token); + final Date expiration = claims.getExpiration(); + return expiration.before(new Date()); + } catch (ExpiredJwtException expiredJwtException) { + return true; + } + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/listener/ConstantsInitListener.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/listener/ConstantsInitListener.java new file mode 100644 index 00000000..4fb66a3f --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/listener/ConstantsInitListener.java @@ -0,0 +1,105 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.listener; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.db.DbUtil; +import cn.hutool.db.Entity; +import cn.hutool.db.handler.EntityListHandler; +import cn.hutool.db.sql.SqlExecutor; +import cn.hutool.log.Log; +import com.cn.xiaonuo.core.context.constant.ConstantContext; +import com.cn.xiaonuo.core.enums.CommonStatusEnum; +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.sys.modular.consts.enums.SysConfigExceptionEnum; +import com.cn.xiaonuo.core.context.constant.ConstantContext; +import com.cn.xiaonuo.core.enums.CommonStatusEnum; +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.sys.modular.consts.enums.SysConfigExceptionEnum; +import org.springframework.boot.context.event.ApplicationContextInitializedEvent; +import org.springframework.context.ApplicationListener; +import org.springframework.core.Ordered; +import org.springframework.core.env.ConfigurableEnvironment; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.List; + +/** + * 初始化常量的监听器 + *

+ * 当spring装配好配置后,就去数据库读constants + * + * @author yubaoshan + * @date 2020/6/6 23:39 + */ +public class ConstantsInitListener implements ApplicationListener, Ordered { + + private static final Log log = Log.get(); + + private static final String CONFIG_LIST_SQL = "select code,value from sys_config where status = ?"; + + @Override + public int getOrder() { + return Ordered.HIGHEST_PRECEDENCE; + } + + @Override + public void onApplicationEvent(ApplicationContextInitializedEvent applicationContextInitializedEvent) { + ConfigurableEnvironment environment = applicationContextInitializedEvent.getApplicationContext().getEnvironment(); + + // 获取数据库连接配置 + String dataSourceUrl = environment.getProperty("spring.datasource.url"); + String dataSourceUsername = environment.getProperty("spring.datasource.username"); + String dataSourcePassword = environment.getProperty("spring.datasource.password"); + + // 如果有为空的配置,终止执行 + if (ObjectUtil.hasEmpty(dataSourceUrl, dataSourceUsername, dataSourcePassword)) { + throw new ServiceException(SysConfigExceptionEnum.DATA_SOURCE_NOT_EXIST); + } + + Connection conn = null; + try { + Class.forName("com.mysql.cj.jdbc.Driver"); + assert dataSourceUrl != null; + conn = DriverManager.getConnection(dataSourceUrl, dataSourceUsername, dataSourcePassword); + + // 获取sys_config表的数据 + List entityList = SqlExecutor.query(conn, CONFIG_LIST_SQL, new EntityListHandler(), CommonStatusEnum.ENABLE.getCode()); + + // 将查询到的参数配置添加到缓存 + if (ObjectUtil.isNotEmpty(entityList)) { + entityList.forEach(sysConfig -> ConstantContext.putConstant(sysConfig.getStr("code"), sysConfig.getStr("value"))); + } + } catch (SQLException | ClassNotFoundException e) { + log.error(">>> 读取数据库constants配置信息出错:{}", e.getMessage()); + throw new ServiceException(SysConfigExceptionEnum.DATA_SOURCE_NOT_EXIST); + } finally { + DbUtil.close(conn); + } + + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/listener/RemoveRequestParamListener.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/listener/RemoveRequestParamListener.java new file mode 100644 index 00000000..8d1d70f3 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/listener/RemoveRequestParamListener.java @@ -0,0 +1,20 @@ +package com.cn.xiaonuo.sys.core.listener; + +import com.cn.xiaonuo.core.context.param.RequestParamContext; +import org.springframework.context.ApplicationListener; +import org.springframework.web.context.support.ServletRequestHandledEvent; + +/** + * 用来清除临时缓存的@RequestBody的请求参数 + * + * @author xuyuxiang + * @date 2020/8/21 21:14 + */ +public class RemoveRequestParamListener implements ApplicationListener { + + @Override + public void onApplicationEvent(ServletRequestHandledEvent event) { + RequestParamContext.clear(); + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/listener/ResourceCollectListener.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/listener/ResourceCollectListener.java new file mode 100644 index 00000000..0f8cc6e6 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/listener/ResourceCollectListener.java @@ -0,0 +1,79 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.listener; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.extra.spring.SpringUtil; +import cn.hutool.log.Log; +import com.cn.xiaonuo.sys.core.cache.ResourceCache; +import com.cn.xiaonuo.sys.core.cache.ResourceCache; +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Component; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; + +import javax.annotation.Resource; +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +/** + * 资源搜集器,将项目中所有接口(带@RequestMapping的)都搜集起来 + *

+ * 搜集到的接口会被缓存,用于请求时判断请求的接口是否存在 + * + * @author xuyuxiang + * @date 2020/3/19 17:33 + */ +@Component +public class ResourceCollectListener implements CommandLineRunner { + + private static final Log log = Log.get(); + + @Resource + private ResourceCache resourceCache; + + @Override + public void run(String... args) { + + //1.获取所有后端接口 + Set urlSet = CollectionUtil.newHashSet(); + Map mappingMap = SpringUtil.getApplicationContext().getBeansOfType(RequestMappingHandlerMapping.class); + Collection mappings = mappingMap.values(); + for (RequestMappingHandlerMapping mapping : mappings) { + Map map = mapping.getHandlerMethods(); + map.keySet().forEach(requestMappingInfo -> { + Set patterns = requestMappingInfo.getPatternsCondition().getPatterns(); + urlSet.addAll(patterns); + }); + } + + //2.汇总添加到缓存 + resourceCache.putAllResources(urlSet); + + log.info(">>> 缓存资源URL集合完成!资源数量:{}", urlSet.size()); + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/listener/TimerTaskRunListener.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/listener/TimerTaskRunListener.java new file mode 100644 index 00000000..e1a2f405 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/listener/TimerTaskRunListener.java @@ -0,0 +1,80 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.listener; + +import cn.hutool.cron.CronUtil; +import cn.hutool.extra.spring.SpringUtil; +import com.cn.xiaonuo.sys.modular.timer.entity.SysTimers; +import com.cn.xiaonuo.sys.modular.timer.enums.TimerJobStatusEnum; +import com.cn.xiaonuo.sys.modular.timer.param.SysTimersParam; +import com.cn.xiaonuo.sys.modular.timer.service.SysTimersService; +import com.cn.xiaonuo.sys.modular.timer.service.TimerExeService; +import com.cn.xiaonuo.sys.modular.timer.entity.SysTimers; +import com.cn.xiaonuo.sys.modular.timer.enums.TimerJobStatusEnum; +import com.cn.xiaonuo.sys.modular.timer.param.SysTimersParam; +import com.cn.xiaonuo.sys.modular.timer.service.SysTimersService; +import com.cn.xiaonuo.sys.modular.timer.service.TimerExeService; +import org.springframework.boot.context.event.ApplicationStartedEvent; +import org.springframework.context.ApplicationListener; +import org.springframework.core.Ordered; + +import java.util.List; + +/** + * 项目定时任务启动的listener + * + * @author yubaoshan + * @date 2020/7/1 15:30 + */ +public class TimerTaskRunListener implements ApplicationListener, Ordered { + + @Override + public void onApplicationEvent(ApplicationStartedEvent event) { + + SysTimersService sysTimersService = SpringUtil.getBean(SysTimersService.class); + TimerExeService timerExeService = SpringUtil.getBean(TimerExeService.class); + + // 获取所有开启状态的任务 + SysTimersParam sysTimersParam = new SysTimersParam(); + sysTimersParam.setJobStatus(TimerJobStatusEnum.RUNNING.getCode()); + List list = sysTimersService.list(sysTimersParam); + + // 添加定时任务到调度器 + for (SysTimers sysTimers : list) { + timerExeService.startTimer(String.valueOf(sysTimers.getId()), sysTimers.getCron(), sysTimers.getActionClass()); + } + + // 设置秒级别的启用 + CronUtil.setMatchSecond(true); + + // 启动定时器执行器 + CronUtil.start(); + } + + @Override + public int getOrder() { + return LOWEST_PRECEDENCE; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/log/LogManager.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/log/LogManager.java new file mode 100644 index 00000000..d2be4e83 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/log/LogManager.java @@ -0,0 +1,185 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.log; + +import cn.hutool.core.util.ObjectUtil; +import com.cn.xiaonuo.core.annotion.BusinessLog; +import com.cn.xiaonuo.core.context.constant.ConstantContextHolder; +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.core.exception.enums.ServerExceptionEnum; +import com.cn.xiaonuo.core.util.HttpServletUtil; +import com.cn.xiaonuo.core.util.IpAddressUtil; +import com.cn.xiaonuo.core.util.UaUtil; +import com.cn.xiaonuo.sys.core.log.factory.LogFactory; +import com.cn.xiaonuo.sys.core.log.factory.LogTaskFactory; +import com.cn.xiaonuo.sys.modular.log.entity.SysOpLog; +import com.cn.xiaonuo.sys.modular.log.entity.SysVisLog; +import com.cn.xiaonuo.core.annotion.BusinessLog; +import com.cn.xiaonuo.core.context.constant.ConstantContextHolder; +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.core.exception.enums.ServerExceptionEnum; +import com.cn.xiaonuo.core.util.HttpServletUtil; +import com.cn.xiaonuo.core.util.IpAddressUtil; +import com.cn.xiaonuo.core.util.UaUtil; +import org.aspectj.lang.JoinPoint; +import org.springframework.scheduling.concurrent.ScheduledExecutorFactoryBean; + +import javax.servlet.http.HttpServletRequest; +import java.util.TimerTask; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + + +/** + * 日志管理器 + * + * @author xuyuxiang + * @date 2020/3/12 14:13 + */ +public class LogManager { + + /** + * 异步操作记录日志的线程池 + */ + private static final ScheduledThreadPoolExecutor EXECUTOR = new ScheduledThreadPoolExecutor(10, new ScheduledExecutorFactoryBean()); + + private LogManager() { + } + + private static final LogManager LOG_MANAGER = new LogManager(); + + public static LogManager me() { + return LOG_MANAGER; + } + + /** + * 异步执行日志的方法 + * + * @author xuyuxiang + * @date 2020/4/8 19:19 + */ + private void executeLog(TimerTask task) { + + //如果演示模式开启,则不记录日志 + if (ConstantContextHolder.getDemoEnvFlag()) { + return; + } + + //日志记录操作延时 + int operateDelayTime = 10; + EXECUTOR.schedule(task, operateDelayTime, TimeUnit.MILLISECONDS); + } + + /** + * 登录日志 + * + * @author xuyuxiang + * @date 2020/3/18 20:00 + */ + public void executeLoginLog(final String account, final String success, final String failMessage) { + SysVisLog sysVisLog = this.genBaseSysVisLog(); + TimerTask timerTask = LogTaskFactory.loginLog(sysVisLog, account, + success, + failMessage); + executeLog(timerTask); + } + + /** + * 登出日志 + * + * @author xuyuxiang + * @date 2020/3/18 20:01 + */ + public void executeExitLog(final String account) { + SysVisLog sysVisLog = this.genBaseSysVisLog(); + TimerTask timerTask = LogTaskFactory.exitLog(sysVisLog, account); + executeLog(timerTask); + } + + /** + * 操作日志 + * + * @author xuyuxiang + * @date 2020/3/18 20:01 + */ + public void executeOperationLog(BusinessLog businessLog, final String account, JoinPoint joinPoint, final String result) { + SysOpLog sysOpLog = this.genBaseSysOpLog(); + TimerTask timerTask = LogTaskFactory.operationLog(sysOpLog, account, businessLog, joinPoint, result); + executeLog(timerTask); + } + + /** + * 异常日志 + * + * @author xuyuxiang + * @date 2020/3/18 20:01 + */ + public void executeExceptionLog(BusinessLog businessLog, final String account, JoinPoint joinPoint, Exception exception) { + SysOpLog sysOpLog = this.genBaseSysOpLog(); + TimerTask timerTask = LogTaskFactory.exceptionLog(sysOpLog, account, businessLog, joinPoint, exception); + executeLog(timerTask); + } + + /** + * 构建基础访问日志 + * + * @author xuyuxiang + * @date 2020/3/19 14:44 + */ + private SysVisLog genBaseSysVisLog() { + HttpServletRequest request = HttpServletUtil.getRequest(); + if (ObjectUtil.isNotNull(request)) { + String ip = IpAddressUtil.getIp(request); + String address = IpAddressUtil.getAddress(request); + String browser = UaUtil.getBrowser(request); + String os = UaUtil.getOs(request); + return LogFactory.genBaseSysVisLog(ip, address, browser, os); + } else { + throw new ServiceException(ServerExceptionEnum.REQUEST_EMPTY); + } + } + + /** + * 构建基础操作日志 + * + * @author xuyuxiang + * @date 2020/3/19 14:44 + */ + private SysOpLog genBaseSysOpLog() { + HttpServletRequest request = HttpServletUtil.getRequest(); + if (ObjectUtil.isNotNull(request)) { + String ip = IpAddressUtil.getIp(request); + String address = IpAddressUtil.getAddress(request); + String browser = UaUtil.getBrowser(request); + String os = UaUtil.getOs(request); + String url = request.getRequestURI(); + String method = request.getMethod(); + return LogFactory.genBaseSysOpLog(ip, address, browser, os, url, method); + } else { + throw new ServiceException(ServerExceptionEnum.REQUEST_EMPTY); + } + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/log/factory/LogFactory.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/log/factory/LogFactory.java new file mode 100644 index 00000000..28c7527b --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/log/factory/LogFactory.java @@ -0,0 +1,169 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.log.factory; + +import cn.hutool.core.date.DateTime; +import com.cn.xiaonuo.core.annotion.BusinessLog; +import com.cn.xiaonuo.core.consts.SymbolConstant; +import com.cn.xiaonuo.core.util.JoinPointUtil; +import com.cn.xiaonuo.sys.core.enums.LogSuccessStatusEnum; +import com.cn.xiaonuo.sys.core.enums.VisLogTypeEnum; +import com.cn.xiaonuo.sys.modular.log.entity.SysOpLog; +import com.cn.xiaonuo.sys.modular.log.entity.SysVisLog; +import com.cn.xiaonuo.core.annotion.BusinessLog; +import com.cn.xiaonuo.core.consts.SymbolConstant; +import com.cn.xiaonuo.core.util.JoinPointUtil; +import com.cn.xiaonuo.sys.core.enums.LogSuccessStatusEnum; +import com.cn.xiaonuo.sys.core.enums.VisLogTypeEnum; +import org.aspectj.lang.JoinPoint; + +import java.util.Arrays; + +/** + * 日志对象创建工厂 + * + * @author xuyuxiang + * @date 2020/3/12 14:31 + */ +public class LogFactory { + + /** + * 创建登录日志 + * + * @author xuyuxiang + * @date 2020/3/12 16:09 + */ + static void createSysLoginLog(SysVisLog sysVisLog, String account, String successCode, String failMessage) { + sysVisLog.setName(VisLogTypeEnum.LOGIN.getMessage()); + sysVisLog.setSuccess(successCode); + + sysVisLog.setVisType(VisLogTypeEnum.LOGIN.getCode()); + sysVisLog.setVisTime(DateTime.now()); + sysVisLog.setAccount(account); + + if (LogSuccessStatusEnum.SUCCESS.getCode().equals(successCode)) { + sysVisLog.setMessage(VisLogTypeEnum.LOGIN.getMessage() + LogSuccessStatusEnum.SUCCESS.getMessage()); + } + if (LogSuccessStatusEnum.FAIL.getCode().equals(successCode)) { + sysVisLog.setMessage(VisLogTypeEnum.LOGIN.getMessage() + + LogSuccessStatusEnum.FAIL.getMessage() + SymbolConstant.COLON + failMessage); + } + } + + /** + * 创建登出日志 + * + * @author xuyuxiang + * @date 2020/3/12 16:09 + */ + static void createSysExitLog(SysVisLog sysVisLog, String account) { + sysVisLog.setName(VisLogTypeEnum.EXIT.getMessage()); + sysVisLog.setSuccess(LogSuccessStatusEnum.SUCCESS.getCode()); + sysVisLog.setMessage(VisLogTypeEnum.EXIT.getMessage() + LogSuccessStatusEnum.SUCCESS.getMessage()); + sysVisLog.setVisType(VisLogTypeEnum.EXIT.getCode()); + sysVisLog.setVisTime(DateTime.now()); + sysVisLog.setAccount(account); + } + + /** + * 创建操作日志 + * + * @author xuyuxiang + * @date 2020/3/12 16:09 + */ + static void createSysOperationLog(SysOpLog sysOpLog, String account, BusinessLog businessLog, JoinPoint joinPoint, String result) { + fillCommonSysOpLog(sysOpLog, account, businessLog, joinPoint); + sysOpLog.setSuccess(LogSuccessStatusEnum.SUCCESS.getCode()); + sysOpLog.setResult(result); + sysOpLog.setMessage(LogSuccessStatusEnum.SUCCESS.getMessage()); + } + + /** + * 创建异常日志 + * + * @author xuyuxiang + * @date 2020/3/16 17:18 + */ + static void createSysExceptionLog(SysOpLog sysOpLog, String account, BusinessLog businessLog, JoinPoint joinPoint, Exception exception) { + fillCommonSysOpLog(sysOpLog, account, businessLog, joinPoint); + sysOpLog.setSuccess(LogSuccessStatusEnum.FAIL.getCode()); + sysOpLog.setMessage(Arrays.toString(exception.getStackTrace())); + } + + /** + * 生成通用操作日志字段 + * + * @author xuyuxiang + * @date 2020/3/16 17:20 + */ + private static void fillCommonSysOpLog(SysOpLog sysOpLog, String account, BusinessLog businessLog, JoinPoint joinPoint) { + String className = joinPoint.getTarget().getClass().getName(); + + String methodName = joinPoint.getSignature().getName(); + + String param = JoinPointUtil.getArgsJsonString(joinPoint); + + sysOpLog.setName(businessLog.title()); + sysOpLog.setOpType(businessLog.opType().ordinal()); + sysOpLog.setClassName(className); + sysOpLog.setMethodName(methodName); + sysOpLog.setParam(param); + sysOpLog.setOpTime(DateTime.now()); + sysOpLog.setAccount(account); + } + + /** + * 构建基础访问日志 + * + * @author xuyuxiang + * @date 2020/3/19 14:36 + */ + public static SysVisLog genBaseSysVisLog(String ip, String location, String browser, String os) { + SysVisLog sysVisLog = new SysVisLog(); + sysVisLog.setIp(ip); + sysVisLog.setLocation(location); + sysVisLog.setBrowser(browser); + sysVisLog.setOs(os); + return sysVisLog; + } + + /** + * 构建基础操作日志 + * + * @author xuyuxiang + * @date 2020/3/19 14:36 + */ + public static SysOpLog genBaseSysOpLog(String ip, String location, String browser, String os, String url, String method) { + SysOpLog sysOpLog = new SysOpLog(); + sysOpLog.setIp(ip); + sysOpLog.setLocation(location); + sysOpLog.setBrowser(browser); + sysOpLog.setOs(os); + sysOpLog.setUrl(url); + sysOpLog.setReqMethod(method); + return sysOpLog; + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/log/factory/LogTaskFactory.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/log/factory/LogTaskFactory.java new file mode 100644 index 00000000..1364921f --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/log/factory/LogTaskFactory.java @@ -0,0 +1,135 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.log.factory; + +import cn.hutool.extra.spring.SpringUtil; +import cn.hutool.log.Log; +import com.cn.xiaonuo.core.annotion.BusinessLog; +import com.cn.xiaonuo.core.context.requestno.RequestNoContext; +import com.cn.xiaonuo.sys.modular.log.entity.SysOpLog; +import com.cn.xiaonuo.sys.modular.log.entity.SysVisLog; +import com.cn.xiaonuo.sys.modular.log.service.SysOpLogService; +import com.cn.xiaonuo.sys.modular.log.service.SysVisLogService; +import com.cn.xiaonuo.core.annotion.BusinessLog; +import com.cn.xiaonuo.core.context.requestno.RequestNoContext; +import org.aspectj.lang.JoinPoint; + +import java.util.TimerTask; + + +/** + * 日志操作任务创建工厂 + * + * @author xuyuxiang + * @date 2020/3/12 14:18 + */ +public class LogTaskFactory { + + private static final Log log = Log.get(); + + private static final SysVisLogService sysVisLogService = SpringUtil.getBean(SysVisLogService.class); + + private static final SysOpLogService sysOpLogService = SpringUtil.getBean(SysOpLogService.class); + + /** + * 登录日志 + * + * @author xuyuxiang + * @date 2020/3/12 15:21 + */ + public static TimerTask loginLog(SysVisLog sysVisLog, final String account, String success, String failMessage) { + return new TimerTask() { + @Override + public void run() { + try { + LogFactory.createSysLoginLog(sysVisLog, account, success, failMessage); + sysVisLogService.save(sysVisLog); + } catch (Exception e) { + log.error(">>> 创建登录日志异常,请求号为:{},具体信息为:{}", RequestNoContext.get(), e.getMessage()); + } + } + }; + } + + /** + * 登出日志 + * + * @author xuyuxiang + * @date 2020/3/12 15:21 + */ + public static TimerTask exitLog(SysVisLog sysVisLog, String account) { + return new TimerTask() { + @Override + public void run() { + try { + LogFactory.createSysExitLog(sysVisLog, account); + sysVisLogService.save(sysVisLog); + } catch (Exception e) { + log.error(">>> 创建退出日志异常,请求号为:{},具体信息为:{}", RequestNoContext.get(), e.getMessage()); + } + } + }; + } + + /** + * 操作日志 + * + * @author xuyuxiang + * @date 2020/3/12 15:21 + */ + public static TimerTask operationLog(SysOpLog sysOpLog, String account, BusinessLog businessLog, JoinPoint joinPoint, String result) { + return new TimerTask() { + @Override + public void run() { + try { + LogFactory.createSysOperationLog(sysOpLog, account, businessLog, joinPoint, result); + sysOpLogService.save(sysOpLog); + } catch (Exception e) { + log.error(">>> 创建操作日志异常,请求号为:{},具体信息为:{}", RequestNoContext.get(), e.getMessage()); + } + } + }; + } + + /** + * 异常日志 + * + * @author xuyuxiang + * @date 2020/3/12 15:21 + */ + public static TimerTask exceptionLog(SysOpLog sysOpLog, String account, BusinessLog businessLog, JoinPoint joinPoint, Exception exception) { + return new TimerTask() { + @Override + public void run() { + try { + LogFactory.createSysExceptionLog(sysOpLog, account, businessLog, joinPoint, exception); + sysOpLogService.save(sysOpLog); + } catch (Exception e) { + log.error(">>> 创建异常日志异常,请求号为:{},具体信息为:{}", RequestNoContext.get(), e.getMessage()); + } + } + }; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/mybatis/dbid/XiaoNuoDatabaseIdProvider.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/mybatis/dbid/XiaoNuoDatabaseIdProvider.java new file mode 100644 index 00000000..ed976bd9 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/mybatis/dbid/XiaoNuoDatabaseIdProvider.java @@ -0,0 +1,61 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.mybatis.dbid; + +import com.cn.xiaonuo.core.enums.DbIdEnum; +import com.cn.xiaonuo.core.enums.DbIdEnum; +import org.apache.ibatis.mapping.DatabaseIdProvider; + +import javax.sql.DataSource; +import java.sql.SQLException; +import java.util.Properties; + +/** + * 数据库id选择器 + * + * @author yubaoshan + * @date 2019/3/30 22:26 + */ +public class XiaoNuoDatabaseIdProvider implements DatabaseIdProvider { + + @Override + public void setProperties(Properties p) { + } + + @Override + public String getDatabaseId(DataSource dataSource) throws SQLException { + String url = dataSource.getConnection().getMetaData().getURL(); + + if (url.contains(DbIdEnum.ORACLE.getName())) { + return DbIdEnum.ORACLE.getCode(); + } else if (url.contains(DbIdEnum.PG_SQL.getName())) { + return DbIdEnum.PG_SQL.getCode(); + } else if (url.contains(DbIdEnum.MS_SQL.getName())) { + return DbIdEnum.MS_SQL.getCode(); + } else { + return DbIdEnum.MYSQL.getCode(); + } + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/mybatis/fieldfill/CustomMetaObjectHandler.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/mybatis/fieldfill/CustomMetaObjectHandler.java new file mode 100644 index 00000000..e8775ada --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/mybatis/fieldfill/CustomMetaObjectHandler.java @@ -0,0 +1,90 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.mybatis.fieldfill; + +import cn.hutool.log.Log; +import com.cn.xiaonuo.core.context.login.LoginContextHolder; +import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; +import com.cn.xiaonuo.core.context.login.LoginContextHolder; +import org.apache.ibatis.reflection.MetaObject; +import org.apache.ibatis.reflection.ReflectionException; + +import java.util.Date; + +/** + * 自定义sql字段填充器,自动填充创建修改相关字段 + * + * @author xuyuxiang + * @date 2020/3/30 15:21 + */ +public class CustomMetaObjectHandler implements MetaObjectHandler { + + private static final Log log = Log.get(); + + private static final String CREATE_USER = "createUser"; + + private static final String CREATE_TIME = "createTime"; + + private static final String UPDATE_USER = "updateUser"; + + private static final String UPDATE_TIME = "updateTime"; + + @Override + public void insertFill(MetaObject metaObject) { + try { + //设置createUser(BaseEntity) + setFieldValByName(CREATE_USER, this.getUserUniqueId(), metaObject); + + //设置createTime(BaseEntity) + setFieldValByName(CREATE_TIME, new Date(), metaObject); + } catch (ReflectionException e) { + log.warn(">>> CustomMetaObjectHandler处理过程中无相关字段,不做处理"); + } + } + + @Override + public void updateFill(MetaObject metaObject) { + try { + //设置updateUser(BaseEntity) + setFieldValByName(UPDATE_USER, this.getUserUniqueId(), metaObject); + //设置updateTime(BaseEntity) + setFieldValByName(UPDATE_TIME, new Date(), metaObject); + } catch (ReflectionException e) { + log.warn(">>> CustomMetaObjectHandler处理过程中无相关字段,不做处理"); + } + } + + /** + * 获取用户唯一id + */ + private Long getUserUniqueId() { + try { + return LoginContextHolder.me().getSysLoginUserId(); + } catch (Exception e) { + //如果获取不到就返回-1 + return -1L; + } + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/mybatis/sqlfilter/DemoProfileSqlInterceptor.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/mybatis/sqlfilter/DemoProfileSqlInterceptor.java new file mode 100644 index 00000000..b0788839 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/mybatis/sqlfilter/DemoProfileSqlInterceptor.java @@ -0,0 +1,85 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.mybatis.sqlfilter; + +import com.cn.xiaonuo.core.consts.SpringSecurityConstant; +import com.cn.xiaonuo.core.context.constant.ConstantContextHolder; +import com.cn.xiaonuo.core.exception.DemoException; +import com.cn.xiaonuo.core.util.HttpServletUtil; +import com.baomidou.mybatisplus.core.toolkit.PluginUtils; +import com.cn.xiaonuo.core.consts.SpringSecurityConstant; +import com.cn.xiaonuo.core.context.constant.ConstantContextHolder; +import com.cn.xiaonuo.core.exception.DemoException; +import com.cn.xiaonuo.core.util.HttpServletUtil; +import org.apache.ibatis.executor.statement.StatementHandler; +import org.apache.ibatis.mapping.MappedStatement; +import org.apache.ibatis.mapping.SqlCommandType; +import org.apache.ibatis.plugin.Interceptor; +import org.apache.ibatis.plugin.Intercepts; +import org.apache.ibatis.plugin.Invocation; +import org.apache.ibatis.plugin.Signature; +import org.apache.ibatis.reflection.MetaObject; +import org.apache.ibatis.reflection.SystemMetaObject; +import org.springframework.util.AntPathMatcher; + +import java.sql.Connection; + +/** + * 演示环境的sql过滤器,只放开select语句,其他语句都不放过 + * + * @author yubaoshan + * @date 2020/5/5 12:21 + */ +@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})}) +public class DemoProfileSqlInterceptor implements Interceptor { + + @Override + public Object intercept(Invocation invocation) throws Throwable { + + // 演示环境没开,直接跳过此过滤器 + if (!ConstantContextHolder.getDemoEnvFlag()) { + return invocation.proceed(); + } + + StatementHandler statementHandler = PluginUtils.realTarget(invocation.getTarget()); + MetaObject metaStatementHandler = SystemMetaObject.forObject(statementHandler); + MappedStatement mappedStatement = (MappedStatement) metaStatementHandler.getValue("delegate.mappedStatement"); + + if (SqlCommandType.SELECT.equals(mappedStatement.getSqlCommandType())) { + return invocation.proceed(); + } else { + + //放开不进行安全过滤的接口 + for (String notAuthResource : SpringSecurityConstant.NONE_SECURITY_URL_PATTERNS) { + AntPathMatcher antPathMatcher = new AntPathMatcher(); + if (antPathMatcher.match(notAuthResource, HttpServletUtil.getRequest().getRequestURI())) { + return invocation.proceed(); + } + } + throw new DemoException(); + } + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/redis/FastJson2JsonRedisSerializer.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/redis/FastJson2JsonRedisSerializer.java new file mode 100644 index 00000000..874b3e88 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/redis/FastJson2JsonRedisSerializer.java @@ -0,0 +1,90 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.redis; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.data.redis.serializer.SerializationException; + +import java.nio.charset.Charset; + +/** + * redis序列化器 + * + * @author xuyuxiang + * @date 2020/3/30 18:30 + */ +public class FastJson2JsonRedisSerializer implements RedisSerializer { + + private final Class clazz; + + static { + ParserConfig.getGlobalInstance().setAutoTypeSupport(true); + } + + /** + * 构造函数 + * + * @author xuyuxiang + * @date 2020/4/8 19:12 + */ + public FastJson2JsonRedisSerializer(Class clazz) { + super(); + this.clazz = clazz; + } + + /** + * 序列化 + * + * @author xuyuxiang + * @date 2020/4/8 19:12 + */ + @Override + public byte[] serialize(T t) throws SerializationException { + if (ObjectUtil.isEmpty(t)) { + return new byte[0]; + } + return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(Charset.defaultCharset()); + } + + /** + * 反序列化 + * + * @author xuyuxiang + * @date 2020/4/8 19:12 + */ + @Override + public T deserialize(byte[] bytes) throws SerializationException { + if (ObjectUtil.isEmpty(bytes)) { + return null; + } + String str = new String(bytes, Charset.defaultCharset()); + return (T) JSON.parseObject(str, clazz); + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/scanner/ApiResourceScanner.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/scanner/ApiResourceScanner.java new file mode 100644 index 00000000..867dc034 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/scanner/ApiResourceScanner.java @@ -0,0 +1,210 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.core.scanner; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.cn.xiaonuo.core.consts.SymbolConstant; +import com.cn.xiaonuo.core.context.resources.ApiResourceContext; +import com.cn.xiaonuo.core.util.AopTargetUtil; +import com.cn.xiaonuo.core.consts.SymbolConstant; +import com.cn.xiaonuo.core.context.resources.ApiResourceContext; +import com.cn.xiaonuo.core.util.AopTargetUtil; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.lang.annotation.Annotation; +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Method; +import java.util.Set; + +/** + * 资源扫描器 + * + * @author yubaoshan + * @date 2018/1/3 14:58 + */ +public class ApiResourceScanner implements BeanPostProcessor { + + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + return bean; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + + //如果controller是代理对象,则需要获取原始类的信息 + Object aopTarget = AopTargetUtil.getTarget(bean); + + if (aopTarget == null) { + aopTarget = bean; + } + Class clazz = aopTarget.getClass(); + + //判断是不是控制器,不是控制器就略过 + boolean controllerFlag = getControllerFlag(clazz); + if (!controllerFlag) { + return bean; + } + + //扫描控制器的所有带ApiResource注解的方法 + Set apiUrls = doScan(clazz); + + //将扫描到的注解存储到缓存 + persistApiResources(apiUrls); + + return bean; + } + + + /** + * 判断一个类是否是控制器 + * + * @author yubaoshan + * @date 2020/6/21 18:23 + */ + private boolean getControllerFlag(Class clazz) { + Annotation[] annotations = clazz.getAnnotations(); + + for (Annotation annotation : annotations) { + if (RestController.class.equals(annotation.annotationType()) || Controller.class.equals(annotation.annotationType())) { + return true; + } + } + return false; + } + + /** + * 扫描整个类中包含的所有控制器 + * + * @author yubaoshan + * @date 2020/6/21 18:23 + */ + private Set doScan(Class clazz) { + + // 获取类头的@RequestMapping内容 + String primaryMappingUrl = getRequestMappingUrl(clazz); + + // 获取所有方法的RequestMapping的url + Set apiResources = CollectionUtil.newHashSet(); + Method[] declaredMethods = clazz.getDeclaredMethods(); + if (declaredMethods.length > 0) { + for (Method declaredMethod : declaredMethods) { + String requestMappingUrl = getRequestMappingUrl(declaredMethod); + apiResources.add(primaryMappingUrl + requestMappingUrl); + } + } + return apiResources; + } + + /** + * 存储扫描到的api资源 + * + * @author yubaoshan + * @date 2020/6/21 17:43 + */ + private void persistApiResources(Set apiResources) { + ApiResourceContext.addBatchUrls(apiResources); + } + + /** + * 获取@RequestMapping注解的url信息 + * + * @author yubaoshan + * @date 2020/6/21 17:43 + */ + private String getRequestMappingUrl(AnnotatedElement annotatedElement) { + + RequestMapping requestMapping = annotatedElement.getAnnotation(RequestMapping.class); + GetMapping getMapping = annotatedElement.getAnnotation(GetMapping.class); + PostMapping postMapping = annotatedElement.getAnnotation(PostMapping.class); + + // 分别判断三个注解中有没有value和path的值,优先级是 RequestMapping > GetMapping > PostMapping + if (requestMapping != null) { + String[] value = requestMapping.value(); + String[] path = requestMapping.path(); + if (value.length > 0) { + return getRequestMappingPath(value); + } else if (path.length > 0) { + return getRequestMappingPath(path); + } + } else if (getMapping != null) { + String[] value = getMapping.value(); + String[] path = getMapping.path(); + if (value.length > 0) { + return getRequestMappingPath(value); + } else if (path.length > 0) { + return getRequestMappingPath(path); + } + } else if (postMapping != null) { + String[] value = postMapping.value(); + String[] path = postMapping.path(); + if (value.length > 0) { + return getRequestMappingPath(value); + } else if (path.length > 0) { + return getRequestMappingPath(path); + } + } + + return ""; + } + + /** + * 获取数组第一个字符串 + * + * @author yubaoshan + * @date 2020/6/21 18:10 + */ + private String getRequestMappingPath(String[] strings) { + if (strings.length == 0) { + return ""; + } + String result = strings[0]; + + // 如果RequestMapping的值是“/”直接返回 + if (SymbolConstant.LEFT_DIVIDE.equals(result)) { + return result; + } + + // 添加路径首部的"/" + if (!result.startsWith(SymbolConstant.LEFT_DIVIDE)) { + result = SymbolConstant.LEFT_DIVIDE + result; + } + + // 则去掉尾部的"/" + if (result.endsWith(SymbolConstant.LEFT_DIVIDE)) { + result = StrUtil.removeSuffix(result, SymbolConstant.LEFT_DIVIDE); + } + + return result; + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/validator/XiaoNuoValidator.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/validator/XiaoNuoValidator.java new file mode 100644 index 00000000..6c8a6cfd --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/core/validator/XiaoNuoValidator.java @@ -0,0 +1,94 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ + +package com.cn.xiaonuo.sys.core.validator; + +import cn.hutool.log.Log; +import com.cn.xiaonuo.core.context.group.RequestGroupContext; +import com.cn.xiaonuo.core.context.group.RequestParamIdContext; +import com.cn.xiaonuo.core.consts.CommonConstant; +import org.springframework.validation.Errors; +import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; + +import java.beans.PropertyDescriptor; + +/** + * 用于真正校验参数之前缓存一下group的class类型 + *

+ * 因为ConstraintValidator的自定义校验中获取不到当前进行的group + * + * @author xuyuxiang + * @date 2020/8/12 20:07 + */ +public class XiaoNuoValidator extends LocalValidatorFactoryBean { + + private static final Log log = Log.get(); + + @Override + public void validate(Object target, Errors errors, Object... validationHints) { + + try { + if (validationHints.length > 0) { + + // 如果是class类型,利用ThreadLocal缓存一下class类型 + if (validationHints[0] instanceof Class) { + + // 临时保存group的class值 + RequestGroupContext.set((Class) validationHints[0]); + + // 临时保存字段为id的值 + RequestParamIdContext.set(getParamIdValue(target)); + } + } + super.validate(target, errors, validationHints); + } finally { + RequestGroupContext.clear(); + RequestParamIdContext.clear(); + } + } + + /** + * 获取参数中的id的值,如果没有id字段就返回null + * + * @author xuyuxiang + * @date 2020/8/12 21:24 + */ + private Long getParamIdValue(Object target) { + + try { + PropertyDescriptor prop = new PropertyDescriptor(CommonConstant.ID, target.getClass()); + Object paramId = prop.getReadMethod().invoke(target); + if (paramId != null) { + if (paramId instanceof Long) { + return (Long) paramId; + } + } + } catch (Exception e) { + log.error(">>> 获取参数的id值时候出错:{}", e.getMessage()); + } + + return null; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/IndexController.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/IndexController.java new file mode 100644 index 00000000..684b8291 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/IndexController.java @@ -0,0 +1,50 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular; + +import com.cn.xiaonuo.core.consts.CommonConstant; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * 首页控制器 + * + * @author xuyuxiang + * @date 2020/3/18 11:20 + */ +@RestController +public class IndexController { + + /** + * 访问首页,提示语 + * + * @author xuyuxiang + * @date 2020/4/8 19:27 + */ + @RequestMapping("/") + public String index() { + return CommonConstant.INDEX_TIPS; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/app/controller/SysAppController.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/app/controller/SysAppController.java new file mode 100644 index 00000000..1b148fc5 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/app/controller/SysAppController.java @@ -0,0 +1,148 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.app.controller; + +import com.cn.xiaonuo.core.annotion.BusinessLog; +import com.cn.xiaonuo.core.annotion.Permission; +import com.cn.xiaonuo.core.enums.LogAnnotionOpTypeEnum; +import com.cn.xiaonuo.core.pojo.response.ResponseData; +import com.cn.xiaonuo.core.pojo.response.SuccessResponseData; +import com.cn.xiaonuo.sys.modular.app.param.SysAppParam; +import com.cn.xiaonuo.sys.modular.app.service.SysAppService; +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.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + * 系统应用控制器 + * + * @author xuyuxiang + * @date 2020/3/20 21:25 + */ +@RestController +public class SysAppController { + + @Resource + private SysAppService sysAppService; + + /** + * 查询系统应用 + * + * @author xuyuxiang + * @date 2020/3/20 21:23 + */ + @Permission + @GetMapping("/sysApp/page") + @BusinessLog(title = "系统应用_查询", opType = LogAnnotionOpTypeEnum.QUERY) + public ResponseData page(SysAppParam sysAppParam) { + return new SuccessResponseData(sysAppService.page(sysAppParam)); + } + + /** + * 添加系统应用 + * + * @author xuyuxiang + * @date 2020/3/25 14:44 + */ + @Permission + @PostMapping("/sysApp/add") + @BusinessLog(title = "系统应用_增加", opType = LogAnnotionOpTypeEnum.ADD) + public ResponseData add(@RequestBody @Validated(SysAppParam.add.class) SysAppParam sysAppParam) { + sysAppService.add(sysAppParam); + return new SuccessResponseData(); + } + + /** + * 删除系统应用 + * + * @author xuyuxiang + * @date 2020/3/25 14:54 + */ + @Permission + @PostMapping("/sysApp/delete") + @BusinessLog(title = "系统应用_删除", opType = LogAnnotionOpTypeEnum.DELETE) + public ResponseData delete(@RequestBody @Validated(SysAppParam.delete.class) SysAppParam sysAppParam) { + sysAppService.delete(sysAppParam); + return new SuccessResponseData(); + } + + /** + * 编辑系统应用 + * + * @author xuyuxiang + * @date 2020/3/25 14:54 + */ + @Permission + @PostMapping("/sysApp/edit") + @BusinessLog(title = "系统应用_编辑", opType = LogAnnotionOpTypeEnum.EDIT) + public ResponseData edit(@RequestBody @Validated(SysAppParam.edit.class) SysAppParam sysAppParam) { + sysAppService.edit(sysAppParam); + return new SuccessResponseData(); + } + + /** + * 查看系统应用 + * + * @author xuyuxiang + * @date 2020/3/26 9:49 + */ + @Permission + @GetMapping("/sysApp/detail") + @BusinessLog(title = "系统应用_查看", opType = LogAnnotionOpTypeEnum.DETAIL) + public ResponseData detail(@Validated(SysAppParam.detail.class) SysAppParam sysAppParam) { + return new SuccessResponseData(sysAppService.detail(sysAppParam)); + } + + /** + * 系统应用列表 + * + * @author xuyuxiang + * @date 2020/4/19 14:55 + */ + @Permission + @GetMapping("/sysApp/list") + @BusinessLog(title = "系统应用_列表", opType = LogAnnotionOpTypeEnum.QUERY) + public ResponseData list(SysAppParam sysAppParam) { + return new SuccessResponseData(sysAppService.list(sysAppParam)); + } + + /** + * 设为默认应用 + * + * @author xuyuxiang + * @date 2020/6/29 16:49 + */ + @Permission + @PostMapping("/sysApp/setAsDefault") + @BusinessLog(title = "系统应用_设为默认应用", opType = LogAnnotionOpTypeEnum.EDIT) + public ResponseData setAsDefault(@RequestBody @Validated(SysAppParam.detail.class) SysAppParam sysAppParam) { + sysAppService.setAsDefault(sysAppParam); + return new SuccessResponseData(); + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/app/entity/SysApp.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/app/entity/SysApp.java new file mode 100644 index 00000000..9a169a78 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/app/entity/SysApp.java @@ -0,0 +1,72 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.app.entity; + +import com.cn.xiaonuo.core.pojo.base.entity.BaseEntity; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.cn.xiaonuo.core.pojo.base.entity.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 系统应用表 + * + * @author xuyuxiang + * @date 2020/3/11 12:14 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@TableName("sys_app") +public class SysApp extends BaseEntity { + + /** + * 主键 + */ + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + /** + * 名称 + */ + private String name; + + /** + * 编码 + */ + private String code; + + /** + * 是否默认激活(Y-是,N-否),只能有一个系统默认激活 + * 用户登录后默认展示此系统菜单 + */ + private String active; + + /** + * 状态(字典 0正常 1停用 2删除) + */ + private Integer status; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/app/enums/SysAppExceptionEnum.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/app/enums/SysAppExceptionEnum.java new file mode 100644 index 00000000..967c1be5 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/app/enums/SysAppExceptionEnum.java @@ -0,0 +1,85 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.app.enums; + +import com.cn.xiaonuo.core.annotion.ExpEnumType; +import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum; +import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory; +import com.cn.xiaonuo.sys.core.consts.SysExpEnumConstant; + +/** + * 系统应用相关异常枚举 + * + * @author xuyuxiang + * @date 2020/3/26 10:11 + */ +@ExpEnumType(module = SysExpEnumConstant.XIAONUO_SYS_MODULE_EXP_CODE, kind = SysExpEnumConstant.SYS_APP_EXCEPTION_ENUM) +public enum SysAppExceptionEnum implements AbstractBaseExceptionEnum { + + /** + * 应用不存在 + */ + APP_NOT_EXIST(1, "应用不存在"), + + /** + * 应用编码重复 + */ + APP_CODE_REPEAT(2, "应用编码重复,请检查code参数"), + + /** + * 应用名称重复 + */ + APP_NAME_REPEAT(3, "应用名称重复,请检查name参数"), + + /** + * 默认激活的系统只能有一个 + */ + APP_ACTIVE_REPEAT(4, "默认激活的系统只能有一个,请检查active参数"), + + /** + * 该应用下有菜单 + */ + APP_CANNOT_DELETE(5, "该应用下有菜单,无法删除"); + + private final Integer code; + + private final String message; + + SysAppExceptionEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return ExpEnumCodeFactory.getExpEnumCode(this.getClass(), code); + } + + @Override + public String getMessage() { + return message; + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/app/mapper/SysAppMapper.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/app/mapper/SysAppMapper.java new file mode 100644 index 00000000..32e824f0 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/app/mapper/SysAppMapper.java @@ -0,0 +1,38 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.app.mapper; + +import com.cn.xiaonuo.sys.modular.app.entity.SysApp; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.cn.xiaonuo.sys.modular.app.entity.SysApp; + +/** + * 系统应用mapper接口 + * + * @author xuyuxiang + * @date 2020/3/13 16:17 + */ +public interface SysAppMapper extends BaseMapper { +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/app/mapper/mapping/SysAppMapper.xml b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/app/mapper/mapping/SysAppMapper.xml new file mode 100644 index 00000000..8443604f --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/app/mapper/mapping/SysAppMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/app/param/SysAppParam.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/app/param/SysAppParam.java new file mode 100644 index 00000000..3dd76ca6 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/app/param/SysAppParam.java @@ -0,0 +1,72 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.app.param; + +import com.cn.xiaonuo.core.pojo.base.param.BaseParam; +import com.cn.xiaonuo.core.validation.flag.FlagValue; +import com.cn.xiaonuo.core.pojo.base.param.BaseParam; +import com.cn.xiaonuo.core.validation.flag.FlagValue; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 系统应用参数 + * + * @author xuyuxiang + * @date 2020/3/24 20:53 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class SysAppParam extends BaseParam { + + /** + * 主键 + */ + @NotNull(message = "id不能为空,请检查id参数", groups = {edit.class, delete.class, detail.class}) + private Long id; + + /** + * 名称 + */ + @NotBlank(message = "名称不能为空,请检查name参数", groups = {add.class, edit.class}) + private String name; + + /** + * 编码 + */ + @NotBlank(message = "编码不能为空,请检查code参数", groups = {add.class, edit.class}) + private String code; + + /** + * 是否默认激活(Y-是,N-否),只能有一个系统默认激活 + * 用户登录后默认展示此系统菜单 + */ + @NotBlank(message = "是否默认激活不能为空,请检查active参数", groups = {add.class, edit.class}) + @FlagValue(message = "是否默认激活格式错误,正确格式应该Y或者N,请检查active参数", groups = {add.class, edit.class}) + private String active; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/app/service/SysAppService.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/app/service/SysAppService.java new file mode 100644 index 00000000..fe572fb4 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/app/service/SysAppService.java @@ -0,0 +1,118 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.app.service; + +import cn.hutool.core.lang.Dict; +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.modular.app.entity.SysApp; +import com.cn.xiaonuo.sys.modular.app.param.SysAppParam; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +/** + * 系统应用service接口 + * + * @author xuyuxiang + * @date 2020/3/13 16:14 + */ +public interface SysAppService extends IService { + + /** + * 获取用户应用相关信息 + * + * @param userId 用户id + * @return 用户拥有的应用信息,格式:[{"code":"system","name":"系统应用","active":true}] + * @author xuyuxiang + * @date 2020/3/13 16:25 + */ + List getLoginApps(Long userId); + + /** + * 查询系统应用 + * + * @param sysAppParam 查询参数 + * @return 查询分页结果 + * @author xuyuxiang + * @date 2020/3/24 20:55 + */ + PageResult page(SysAppParam sysAppParam); + + /** + * 添加系统应用 + * + * @param sysAppParam 添加参数 + * @author xuyuxiang + * @date 2020/3/25 14:57 + */ + void add(SysAppParam sysAppParam); + + /** + * 删除系统应用 + * + * @param sysAppParam 删除参数 + * @author xuyuxiang + * @date 2020/3/25 14:57 + */ + void delete(SysAppParam sysAppParam); + + /** + * 编辑系统应用 + * + * @param sysAppParam 编辑参数 + * @author xuyuxiang + * @date 2020/3/25 14:58 + */ + void edit(SysAppParam sysAppParam); + + /** + * 查看系统应用 + * + * @param sysAppParam 查看参数 + * @return 系统应用 + * @author xuyuxiang + * @date 2020/3/26 9:50 + */ + SysApp detail(SysAppParam sysAppParam); + + /** + * 系统应用列表 + * + * @param sysAppParam 查询参数 + * @return 系统应用列表 + * @author xuyuxiang + * @date 2020/4/19 14:56 + */ + List list(SysAppParam sysAppParam); + + /** + * 设为默认应用 + * + * @param sysAppParam 设为默认应用参数 + * @author xuyuxiang + * @date 2020/6/29 16:49 + */ + void setAsDefault(SysAppParam sysAppParam); +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/app/service/impl/SysAppServiceImpl.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/app/service/impl/SysAppServiceImpl.java new file mode 100644 index 00000000..ae1644d2 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/app/service/impl/SysAppServiceImpl.java @@ -0,0 +1,276 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.app.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.lang.Dict; +import cn.hutool.core.util.ObjectUtil; +import com.cn.xiaonuo.core.consts.CommonConstant; +import com.cn.xiaonuo.core.enums.CommonStatusEnum; +import com.cn.xiaonuo.core.enums.YesOrNotEnum; +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.core.factory.PageFactory; +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.core.enums.AdminTypeEnum; +import com.cn.xiaonuo.sys.modular.app.entity.SysApp; +import com.cn.xiaonuo.sys.modular.app.enums.SysAppExceptionEnum; +import com.cn.xiaonuo.sys.modular.app.mapper.SysAppMapper; +import com.cn.xiaonuo.sys.modular.app.param.SysAppParam; +import com.cn.xiaonuo.sys.modular.app.service.SysAppService; +import com.cn.xiaonuo.sys.modular.menu.service.SysMenuService; +import com.cn.xiaonuo.sys.modular.user.entity.SysUser; +import com.cn.xiaonuo.sys.modular.user.service.SysUserService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.cn.xiaonuo.core.consts.CommonConstant; +import com.cn.xiaonuo.core.enums.CommonStatusEnum; +import com.cn.xiaonuo.core.enums.YesOrNotEnum; +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.core.factory.PageFactory; +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.core.enums.AdminTypeEnum; +import com.cn.xiaonuo.sys.modular.app.service.SysAppService; +import com.cn.xiaonuo.sys.modular.menu.service.SysMenuService; +import com.cn.xiaonuo.sys.modular.user.entity.SysUser; +import com.cn.xiaonuo.sys.modular.user.service.SysUserService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * 系统应用service接口实现类 + * + * @author xuyuxiang + * @date 2020/3/13 16:15 + */ +@Service +public class SysAppServiceImpl extends ServiceImpl implements SysAppService { + + @Resource + private SysUserService sysUserService; + + @Resource + private SysMenuService sysMenuService; + + @Override + public List getLoginApps(Long userId) { + List userAppDictList = CollectionUtil.newArrayList(); + + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysApp::getStatus, CommonStatusEnum.ENABLE.getCode()); + + + SysUser sysUser = sysUserService.getById(userId); + Integer adminType = sysUser.getAdminType(); + + //如果不是超级管理员则有自己的菜单对应的应用编码 + if (!AdminTypeEnum.SUPER_ADMIN.getCode().equals(adminType)) { + //获取用户菜单对应的应用编码集合 + List appCodeList = sysMenuService.getUserMenuAppCodeList(userId); + //当应用编码不为空时,则限制查询范围 + if (ObjectUtil.isNotEmpty(appCodeList)) { + queryWrapper.in(SysApp::getCode, appCodeList); + } else { + //没查到应用编码则直接返回 + return userAppDictList; + } + } + //定义是否有默认激活的应用标志 + AtomicBoolean hasDefaultActive = new AtomicBoolean(false); + //遍历 + this.list(queryWrapper).forEach(sysApp -> { + Dict dict = Dict.create(); + dict.put(CommonConstant.CODE, sysApp.getCode()); + dict.put(CommonConstant.NAME, sysApp.getName()); + //如果有默认激活的 + if (YesOrNotEnum.Y.getCode().equals(sysApp.getActive())) { + hasDefaultActive.set(true); + dict.put("active", true); + //将其放在第一个 + userAppDictList.add(0, dict); + } else { + dict.put("active", false); + userAppDictList.add(dict); + } + + }); + if (ObjectUtil.isNotEmpty(userAppDictList)) { + //如果默认激活的系统没有,则第一个为默认激活的系统 + if (!hasDefaultActive.get()) { + Dict dict = userAppDictList.get(0); + dict.put("active", true); + } + } + return userAppDictList; + } + + @Override + public PageResult page(SysAppParam sysAppParam) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + if (ObjectUtil.isNotNull(sysAppParam)) { + //根据名称模糊查询 + if (ObjectUtil.isNotEmpty(sysAppParam.getName())) { + queryWrapper.like(SysApp::getName, sysAppParam.getName()); + } + //根据编码模糊查询 + if (ObjectUtil.isNotEmpty(sysAppParam.getCode())) { + queryWrapper.like(SysApp::getCode, sysAppParam.getCode()); + } + } + queryWrapper.eq(SysApp::getStatus, CommonStatusEnum.ENABLE.getCode()); + return new PageResult<>(this.page(PageFactory.defaultPage(), queryWrapper)); + } + + @Override + public void add(SysAppParam sysAppParam) { + //校验参数,检查是否存在相同的名称和编码,以及默认激活的系统的数量是否合理 + checkParam(sysAppParam, false); + SysApp sysApp = new SysApp(); + BeanUtil.copyProperties(sysAppParam, sysApp); + sysApp.setStatus(CommonStatusEnum.ENABLE.getCode()); + this.save(sysApp); + } + + @Override + public void delete(SysAppParam sysAppParam) { + SysApp sysApp = this.querySysApp(sysAppParam); + String code = sysApp.getCode(); + //该应用下是否有状态为正常的菜单 + boolean hasMenu = sysMenuService.hasMenu(code); + //只要有,则不能删 + if (hasMenu) { + throw new ServiceException(SysAppExceptionEnum.APP_CANNOT_DELETE); + } + sysApp.setStatus(CommonStatusEnum.DELETED.getCode()); + this.updateById(sysApp); + } + + @Override + public void edit(SysAppParam sysAppParam) { + SysApp sysApp = this.querySysApp(sysAppParam); + //校验参数,检查是否存在相同的名称和编码,以及默认激活的系统的数量是否合理 + checkParam(sysAppParam, true); + BeanUtil.copyProperties(sysAppParam, sysApp); + //不能修改状态,用修改状态接口修改状态 + sysApp.setStatus(null); + this.updateById(sysApp); + } + + @Override + public SysApp detail(SysAppParam sysAppParam) { + return this.querySysApp(sysAppParam); + } + + @Override + public List list(SysAppParam sysAppParam) { + LambdaQueryWrapper appQueryWrapper = new LambdaQueryWrapper<>(); + appQueryWrapper.eq(SysApp::getStatus, CommonStatusEnum.ENABLE.getCode()); + return this.list(appQueryWrapper); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void setAsDefault(SysAppParam sysAppParam) { + SysApp currentApp = this.querySysApp(sysAppParam); + //所有已激活的改为未激活 + LambdaQueryWrapper appQueryWrapper = new LambdaQueryWrapper<>(); + appQueryWrapper.eq(SysApp::getStatus, CommonStatusEnum.ENABLE.getCode()) + .eq(SysApp::getActive, YesOrNotEnum.Y.getCode()); + this.list(appQueryWrapper).forEach(sysApp -> { + sysApp.setActive(YesOrNotEnum.N.getCode()); + this.updateById(sysApp); + }); + //当前的设置为已激活 + currentApp.setActive(YesOrNotEnum.Y.getCode()); + this.updateById(currentApp); + } + + /** + * 校验参数,检查是否存在相同的名称和编码,以及默认激活的系统的数量是否合理 + * + * @author xuyuxiang + * @date 2020/3/25 21:23 + */ + private void checkParam(SysAppParam sysAppParam, boolean isExcludeSelf) { + Long id = sysAppParam.getId(); + String name = sysAppParam.getName(); + String code = sysAppParam.getCode(); + String active = sysAppParam.getActive(); + + // 查询名称有无重复 + LambdaQueryWrapper appQueryWrapperByName = new LambdaQueryWrapper<>(); + appQueryWrapperByName.eq(SysApp::getName, name) + .ne(SysApp::getStatus, CommonStatusEnum.DELETED.getCode()); + + // 查询编码有无重复 + LambdaQueryWrapper appQueryWrapperByCode = new LambdaQueryWrapper<>(); + appQueryWrapperByCode.eq(SysApp::getCode, code) + .ne(SysApp::getStatus, CommonStatusEnum.DELETED.getCode()); + + // 查询激活状态有无已经有Y的,也就是激活的 + LambdaQueryWrapper appQueryWrapperByActive = new LambdaQueryWrapper<>(); + appQueryWrapperByActive.eq(SysApp::getActive, active) + .ne(SysApp::getStatus, CommonStatusEnum.DELETED.getCode()); + + if (isExcludeSelf) { + appQueryWrapperByName.ne(SysApp::getId, id); + appQueryWrapperByCode.ne(SysApp::getId, id); + appQueryWrapperByActive.ne(SysApp::getId, id); + } + int countByName = this.count(appQueryWrapperByName); + int countByCode = this.count(appQueryWrapperByCode); + int countByActive = this.count(appQueryWrapperByActive); + + if (countByName >= 1) { + throw new ServiceException(SysAppExceptionEnum.APP_NAME_REPEAT); + } + if (countByCode >= 1) { + throw new ServiceException(SysAppExceptionEnum.APP_CODE_REPEAT); + } + + // 只判断激活状态为Y时候数量是否大于1了 + if (countByActive >= 1 && YesOrNotEnum.Y.getCode().equals(sysAppParam.getActive())) { + throw new ServiceException(SysAppExceptionEnum.APP_ACTIVE_REPEAT); + } + } + + /** + * 获取系统应用 + * + * @author xuyuxiang + * @date 2020/3/26 9:56 + */ + private SysApp querySysApp(SysAppParam sysAppParam) { + SysApp sysApp = this.getById(sysAppParam.getId()); + if (ObjectUtil.isNull(sysApp)) { + throw new ServiceException(SysAppExceptionEnum.APP_NOT_EXIST); + } + return sysApp; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/auth/context/LoginContextSpringSecurityImpl.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/auth/context/LoginContextSpringSecurityImpl.java new file mode 100644 index 00000000..ee0c0e46 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/auth/context/LoginContextSpringSecurityImpl.java @@ -0,0 +1,291 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.auth.context; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.cn.xiaonuo.core.consts.CommonConstant; +import com.cn.xiaonuo.core.consts.SymbolConstant; +import com.cn.xiaonuo.core.context.login.LoginContext; +import com.cn.xiaonuo.core.exception.AuthException; +import com.cn.xiaonuo.core.exception.enums.AuthExceptionEnum; +import com.cn.xiaonuo.core.pojo.login.LoginEmpInfo; +import com.cn.xiaonuo.core.pojo.login.SysLoginUser; +import com.cn.xiaonuo.sys.core.enums.AdminTypeEnum; +import com.cn.xiaonuo.sys.modular.auth.service.AuthService; +import com.cn.xiaonuo.sys.modular.user.entity.SysUser; +import com.cn.xiaonuo.sys.modular.user.service.SysUserService; +import org.springframework.security.authentication.AnonymousAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 登录用户上下文实现类 + * + * @author xuyuxiang + * @date 2020/3/13 12:19 + */ +@Component +public class LoginContextSpringSecurityImpl implements LoginContext { + + @Resource + private AuthService authService; + + @Resource + private SysUserService sysUserService; + + private LoginContextSpringSecurityImpl() { + + } + + /** + * 获取当前登录用户 + * + * @author xuyuxiang + * @date 2020/3/13 14:42 + */ + @Override + public SysLoginUser getSysLoginUser() { + Authentication authentication = authService.getAuthentication(); + if (ObjectUtil.isEmpty(authentication) || authentication.getPrincipal() instanceof String) { + throw new AuthException(AuthExceptionEnum.NO_LOGIN_USER); + } else { + return (SysLoginUser) authentication.getPrincipal(); + } + } + + /** + * 获取当前登录用户,如未登录,则返回null,不抛异常 + * + * @author xuyuxiang + * @date 2020/3/13 14:42 + */ + @Override + public SysLoginUser getSysLoginUserWithoutException() { + Authentication authentication = authService.getAuthentication(); + if (ObjectUtil.isEmpty(authentication) || authentication.getPrincipal() instanceof String) { + return null; + } else { + return (SysLoginUser) authentication.getPrincipal(); + } + } + + /** + * 获取当前登录用户的id + * + * @author xuyuxiang + * @date 2020/3/18 19:26 + */ + @Override + public Long getSysLoginUserId() { + return this.getSysLoginUser().getId(); + } + + /** + * 判断用户是否登录 + * + * @author xuyuxiang + * @date 2020/3/18 19:23 + */ + @Override + public boolean hasLogin() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (ObjectUtil.isEmpty(authentication) || authentication.getPrincipal() instanceof String) { + return false; + } else { + return !(authentication instanceof AnonymousAuthenticationToken); + } + } + + /** + * 获取当前登录的用户账号 + * + * @author xuyuxiang + * @date 2020/3/23 8:49 + */ + @Override + public String getSysLoginUserAccount() { + return this.getSysLoginUser().getAccount(); + } + + /** + * 判断当前登录用户是否有某资源的访问权限 + * + * @author xuyuxiang + * @date 2020/3/23 8:49 + */ + @Override + public boolean hasPermission(String requestUri) { + String removePrefix = StrUtil.removePrefix(requestUri, SymbolConstant.LEFT_DIVIDE); + String requestPermission = removePrefix.replaceAll(SymbolConstant.LEFT_DIVIDE, SymbolConstant.COLON); + return this.getSysLoginUser().getPermissions().contains(requestPermission); + } + + /** + * 判断当前登录用户是否包含某个角色 + * + * @author xuyuxiang + * @date 2020/3/23 8:55 + */ + @Override + public boolean hasRole(String roleCode) { + List roleCodeList = this.getLoginUserRoleCodeList(); + return roleCodeList.contains(roleCode); + } + + /** + * 判断当前登录用户是否包含任意一个角色 + * + * @author xuyuxiang + * @date 2020/3/23 8:55 + */ + @Override + public boolean hasAnyRole(String roleCodes) { + boolean flag = false; + List loginUserRoleCodeList = this.getLoginUserRoleCodeList(); + String[] roleCodeArr = StrUtil.split(roleCodes, SymbolConstant.COMMA); + for (String roleCode : roleCodeArr) { + if (loginUserRoleCodeList.contains(roleCode)) { + flag = true; + break; + } + } + return flag; + } + + /** + * 管理员类型(0超级管理员 1非管理员) + * 判断当前登录用户是否是超级管理员 + * + * @author xuyuxiang + * @date 2020/3/23 17:51 + */ + @Override + public boolean isSuperAdmin() { + return this.isAdmin(AdminTypeEnum.SUPER_ADMIN.getCode()); + } + + /** + * 判断当前登录用户是否包含所有角色 + * + * @author xuyuxiang + * @date 2020/4/5 10:28 + */ + @Override + public boolean hasAllRole(String roleCodes) { + boolean flag = true; + List loginUserRoleCodeList = this.getLoginUserRoleCodeList(); + String[] roleCodeArr = StrUtil.split(roleCodes, SymbolConstant.COMMA); + for (String roleCode : roleCodeArr) { + if (!loginUserRoleCodeList.contains(roleCode)) { + flag = false; + break; + } + } + return flag; + } + + /** + * 判断当前登录用户是否是指定类型的管理员 + * + * @author xuyuxiang + * @date 2020/4/5 11:43 + */ + private boolean isAdmin(Integer adminTypeCode) { + Integer adminType = this.getSysLoginUser().getAdminType(); + boolean flag = false; + if (adminType.equals(adminTypeCode)) { + flag = true; + } + return flag; + } + + /** + * 当前登录用户的数据范围(组织机构id集合) + * + * @author xuyuxiang + * @date 2020/4/5 17:20 + */ + @Override + public List getLoginUserDataScopeIdList() { + return this.getSysLoginUser().getDataScopes(); + } + + /** + * 获取当前登录用户的组织机构id集合 + * + * @author xuyuxiang + * @date 2020/4/5 18:32 + */ + @Override + public Long getSysLoginUserOrgId() { + LoginEmpInfo loginEmpInfo = this.getSysLoginUser().getLoginEmpInfo(); + if (ObjectUtil.isNotNull(loginEmpInfo)) { + if (ObjectUtil.isNotEmpty(loginEmpInfo.getOrgId())) { + return loginEmpInfo.getOrgId(); + } + } + return null; + } + + /** + * 获取当前登录用户的角色id集合 + * + * @author xuyuxiang + * @date 2020/4/20 16:04 + */ + @Override + public List getLoginUserRoleIds() { + List resultList = CollectionUtil.newArrayList(); + this.getSysLoginUser().getRoles().forEach(dict -> resultList.add(dict.getStr(CommonConstant.ID))); + return resultList; + } + + @Override + public SysLoginUser getSysLoginUserUpToDate() { + SysLoginUser sysLoginUser = this.getSysLoginUser(); + Long loginUserId = sysLoginUser.getId(); + SysUser sysUser = sysUserService.getById(loginUserId); + //构造SysLoginUser + return authService.genSysLoginUser(sysUser); + } + + /** + * 获取当前用户的角色编码集合 + * + * @author xuyuxiang + * @date 2020/3/23 8:58 + */ + private List getLoginUserRoleCodeList() { + List roleCodeList = CollectionUtil.newArrayList(); + this.getSysLoginUser().getRoles().forEach(dict -> roleCodeList.add(dict.getStr(CommonConstant.CODE))); + return roleCodeList; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/auth/controller/SysLoginController.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/auth/controller/SysLoginController.java new file mode 100644 index 00000000..93c55de8 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/auth/controller/SysLoginController.java @@ -0,0 +1,106 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.auth.controller; + +import cn.hutool.core.lang.Dict; +import com.cn.xiaonuo.core.context.constant.ConstantContextHolder; +import com.cn.xiaonuo.core.context.login.LoginContextHolder; +import com.cn.xiaonuo.core.pojo.response.ResponseData; +import com.cn.xiaonuo.core.pojo.response.SuccessResponseData; +import com.cn.xiaonuo.sys.modular.auth.service.AuthService; +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.RestController; + +import javax.annotation.Resource; + +/** + * 登录控制器 + * + * @author xuyuxiang + * @date 2020/3/11 12:20 + */ +@RestController +public class SysLoginController { + + @Resource + private AuthService authService; + + /** + * 获取是否开启租户的标识 + * + * @author xuyuxiang + * @date 2020/9/4 + */ + @GetMapping("/getTenantOpen") + public ResponseData getTenantOpen() { + return new SuccessResponseData(ConstantContextHolder.getTenantOpenFlag()); + } + + /** + * 账号密码登录 + * + * @author xuyuxiang + * @date 2020/3/11 15:52 + */ + @PostMapping("/login") + public ResponseData login(@RequestBody Dict dict) { + String account = dict.getStr("account"); + String password = dict.getStr("password"); + String tenantCode = dict.getStr("tenantCode"); + + //如果系统开启了多租户开关,则添加租户的临时缓存 + if (ConstantContextHolder.getTenantOpenFlag()) { + authService.cacheTenantInfo(tenantCode); + } + + String token = authService.login(account, password); + return new SuccessResponseData(token); + } + + /** + * 退出登录 + * + * @author xuyuxiang + * @date 2020/3/16 15:02 + */ + @GetMapping("/logout") + public void logout() { + authService.logout(); + } + + /** + * 获取当前登录用户信息 + * + * @author xuyuxiang + * @date 2020/3/23 17:57 + */ + @GetMapping("/getLoginUser") + public ResponseData getLoginUser() { + return new SuccessResponseData(LoginContextHolder.me().getSysLoginUserUpToDate()); + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/auth/factory/LoginUserFactory.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/auth/factory/LoginUserFactory.java new file mode 100644 index 00000000..f008ae46 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/auth/factory/LoginUserFactory.java @@ -0,0 +1,136 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.auth.factory; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.date.DateTime; +import cn.hutool.core.lang.Dict; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.extra.spring.SpringUtil; +import com.cn.xiaonuo.core.consts.CommonConstant; +import com.cn.xiaonuo.core.context.constant.ConstantContextHolder; +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.core.exception.enums.ServerExceptionEnum; +import com.cn.xiaonuo.core.pojo.login.LoginEmpInfo; +import com.cn.xiaonuo.core.pojo.login.SysLoginUser; +import com.cn.xiaonuo.core.tenant.consts.TenantConstants; +import com.cn.xiaonuo.core.tenant.context.TenantCodeHolder; +import com.cn.xiaonuo.core.tenant.context.TenantDbNameHolder; +import com.cn.xiaonuo.core.util.HttpServletUtil; +import com.cn.xiaonuo.core.util.IpAddressUtil; +import com.cn.xiaonuo.core.util.UaUtil; +import com.cn.xiaonuo.sys.modular.app.service.SysAppService; +import com.cn.xiaonuo.sys.modular.emp.service.SysEmpService; +import com.cn.xiaonuo.sys.modular.menu.service.SysMenuService; +import com.cn.xiaonuo.sys.modular.role.service.SysRoleService; +import com.cn.xiaonuo.sys.modular.user.service.SysUserService; + +import javax.servlet.http.HttpServletRequest; +import java.util.List; + +/** + * 登录用户工厂类 + * + * @author xuyuxiang + * @date 2020/3/13 14:58 + */ +public class LoginUserFactory { + + private static final SysUserService sysUserService = SpringUtil.getBean(SysUserService.class); + + private static final SysEmpService sysEmpService = SpringUtil.getBean(SysEmpService.class); + + private static final SysAppService sysAppService = SpringUtil.getBean(SysAppService.class); + + private static final SysMenuService sysMenuService = SpringUtil.getBean(SysMenuService.class); + + private static final SysRoleService sysRoleService = SpringUtil.getBean(SysRoleService.class); + + /** + * 填充登录用户相关信息 + * + * @author xuyuxiang yubaoshan + * @date 2020/3/13 15:01 + */ + public static void fillLoginUserInfo(SysLoginUser sysLoginUser) { + HttpServletRequest request = HttpServletUtil.getRequest(); + if (ObjectUtil.isNotNull(request)) { + sysLoginUser.setLastLoginIp(IpAddressUtil.getIp(request)); + sysLoginUser.setLastLoginTime(DateTime.now().toString()); + sysLoginUser.setLastLoginAddress(IpAddressUtil.getAddress(request)); + sysLoginUser.setLastLoginBrowser(UaUtil.getBrowser(request)); + sysLoginUser.setLastLoginOs(UaUtil.getOs(request)); + Long userId = sysLoginUser.getId(); + + // 员工信息 + LoginEmpInfo loginEmpInfo = sysEmpService.getLoginEmpInfo(userId); + sysLoginUser.setLoginEmpInfo(loginEmpInfo); + + // 角色信息 + List roles = sysRoleService.getLoginRoles(userId); + sysLoginUser.setRoles(roles); + + // 权限信息 + List permissions = sysMenuService.getLoginPermissions(userId); + sysLoginUser.setPermissions(permissions); + + // 数据范围信息 + List dataScopes = sysUserService.getUserDataScopeIdList(userId, loginEmpInfo.getOrgId()); + sysLoginUser.setDataScopes(dataScopes); + + // 具备应用信息(多系统,默认激活一个,可根据系统切换菜单),返回的结果中第一个为激活的系统 + List apps = sysAppService.getLoginApps(userId); + sysLoginUser.setApps(apps); + + // 如果根本没有应用信息,则没有菜单信息 + if (ObjectUtil.isEmpty(apps)) { + sysLoginUser.setMenus(CollectionUtil.newArrayList()); + } else { + //AntDesign菜单信息,根据人获取,用于登录后展示菜单树,默认获取默认激活的系统的菜单 + String defaultActiveAppCode = apps.get(0).getStr(CommonConstant.CODE); + sysLoginUser.setMenus(sysMenuService.getLoginMenusAntDesign(userId, defaultActiveAppCode)); + } + + //如果开启了多租户功能,则设置当前登录用户的租户标识 + if (ConstantContextHolder.getTenantOpenFlag()) { + String tenantCode = TenantCodeHolder.get(); + String dataBaseName = TenantDbNameHolder.get(); + if (StrUtil.isNotBlank(tenantCode) && StrUtil.isNotBlank(dataBaseName)) { + Dict tenantInfo = Dict.create(); + tenantInfo.set(TenantConstants.TENANT_CODE, tenantCode); + tenantInfo.set(TenantConstants.TENANT_DB_NAME, dataBaseName); + sysLoginUser.setTenants(tenantInfo); + } + //注意,这里remove不代表所有情况,在aop remove + TenantCodeHolder.remove(); + TenantDbNameHolder.remove(); + } + + } else { + throw new ServiceException(ServerExceptionEnum.REQUEST_EMPTY); + } + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/auth/service/AuthService.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/auth/service/AuthService.java new file mode 100644 index 00000000..09708765 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/auth/service/AuthService.java @@ -0,0 +1,135 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.auth.service; + +import com.cn.xiaonuo.core.pojo.login.SysLoginUser; +import com.cn.xiaonuo.sys.modular.user.entity.SysUser; +import org.springframework.security.core.Authentication; + +import javax.servlet.http.HttpServletRequest; + +/** + * 认证相关service + * + * @author xuyuxiang + * @date 2020/3/11 14:14 + */ +public interface AuthService { + + /** + * 账号密码登录 + * + * @param account 账号 + * @param password 密码 + * @return token + * @author xuyuxiang + * @date 2020/3/11 15:57 + */ + String login(String account, String password); + + /** + * 根据已有用户信息登录 + * + * @param sysUser 用户信息 + * @return token + * @author xuyuxiang + * @date 2020/7/29 10:12 + **/ + String doLogin(SysUser sysUser); + + /** + * 从request获取token + * + * @param request request + * @return token + * @author xuyuxiang + * @date 2020/3/13 11:41 + */ + String getTokenFromRequest(HttpServletRequest request); + + /** + * 根据token获取登录用户信息 + * + * @param token token + * @return 当前登陆的用户信息 + * @author xuyuxiang + * @date 2020/3/13 11:59 + */ + SysLoginUser getLoginUserByToken(String token); + + /** + * 退出登录 + * + * @author xuyuxiang + * @date 2020/3/16 15:03 + */ + void logout(); + + /** + * 设置SpringSecurityContext上下文,方便获取用户 + * + * @param sysLoginUser 当前登录用户信息 + * @author xuyuxiang + * @date 2020/3/19 19:59 + */ + void setSpringSecurityContextAuthentication(SysLoginUser sysLoginUser); + + /** + * 获取SpringSecurityContext中认证信息 + * + * @return 认证信息 + * @author xuyuxiang + * @date 2020/3/19 20:02 + */ + Authentication getAuthentication(); + + /** + * 校验token是否正确 + * + * @param token token + * @author xuyuxiang + * @date 2020/5/28 9:57 + */ + void checkToken(String token); + + /** + * 临时缓存租户信息 + * + * @param tenantCode 多租户编码 + * @author xuyuxiang + * @date 2020/9/3 21:22 + */ + void cacheTenantInfo(String tenantCode); + + /** + * 根据系统用户构造用户登陆信息 + * + * @param sysUser 系统用户 + * @return 用户信息 + * @author xuyuxiang + * @date 2020/9/20 15:21 + **/ + SysLoginUser genSysLoginUser(SysUser sysUser); +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/auth/service/impl/AuthServiceImpl.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/auth/service/impl/AuthServiceImpl.java new file mode 100644 index 00000000..4b0e8b0f --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/auth/service/impl/AuthServiceImpl.java @@ -0,0 +1,363 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.auth.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.date.DateTime; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.extra.spring.SpringUtil; +import com.cn.xiaonuo.core.consts.CommonConstant; +import com.cn.xiaonuo.core.context.constant.ConstantContextHolder; +import com.cn.xiaonuo.core.dbs.CurrentDataSourceContext; +import com.cn.xiaonuo.core.enums.CommonStatusEnum; +import com.cn.xiaonuo.core.exception.AuthException; +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.core.exception.enums.AuthExceptionEnum; +import com.cn.xiaonuo.core.exception.enums.ServerExceptionEnum; +import com.cn.xiaonuo.core.pojo.login.SysLoginUser; +import com.cn.xiaonuo.core.tenant.context.TenantCodeHolder; +import com.cn.xiaonuo.core.tenant.context.TenantDbNameHolder; +import com.cn.xiaonuo.core.tenant.entity.TenantInfo; +import com.cn.xiaonuo.core.tenant.exception.TenantException; +import com.cn.xiaonuo.core.tenant.exception.enums.TenantExceptionEnum; +import com.cn.xiaonuo.core.tenant.service.TenantInfoService; +import com.cn.xiaonuo.core.util.HttpServletUtil; +import com.cn.xiaonuo.core.util.IpAddressUtil; +import com.cn.xiaonuo.sys.core.cache.UserCache; +import com.cn.xiaonuo.sys.core.enums.LogSuccessStatusEnum; +import com.cn.xiaonuo.sys.core.jwt.JwtPayLoad; +import com.cn.xiaonuo.sys.core.jwt.JwtTokenUtil; +import com.cn.xiaonuo.sys.core.log.LogManager; +import com.cn.xiaonuo.sys.modular.auth.factory.LoginUserFactory; +import com.cn.xiaonuo.sys.modular.auth.service.AuthService; +import com.cn.xiaonuo.sys.modular.user.entity.SysUser; +import com.cn.xiaonuo.sys.modular.user.service.SysUserService; +import com.cn.xiaonuo.sys.modular.auth.factory.LoginUserFactory; +import com.cn.xiaonuo.sys.modular.auth.service.AuthService; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.crypto.bcrypt.BCrypt; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.util.Map; + +/** + * 认证相关service实现类 + * + * @author xuyuxiang + * @date 2020/3/11 16:58 + */ +@Service +public class AuthServiceImpl implements AuthService, UserDetailsService { + + @Resource + private SysUserService sysUserService; + + @Resource + private UserCache userCache; + + @Override + public String login(String account, String password) { + + if (ObjectUtil.hasEmpty(account, password)) { + LogManager.me().executeLoginLog(account, LogSuccessStatusEnum.FAIL.getCode(), AuthExceptionEnum.ACCOUNT_PWD_EMPTY.getMessage()); + throw new AuthException(AuthExceptionEnum.ACCOUNT_PWD_EMPTY); + } + + SysUser sysUser = sysUserService.getUserByCount(account); + + //用户不存在,账号或密码错误 + if (ObjectUtil.isEmpty(sysUser)) { + LogManager.me().executeLoginLog(account, LogSuccessStatusEnum.FAIL.getCode(), AuthExceptionEnum.ACCOUNT_PWD_ERROR.getMessage()); + throw new AuthException(AuthExceptionEnum.ACCOUNT_PWD_ERROR); + } + + String passwordBcrypt = sysUser.getPassword(); + + //验证账号密码是否正确 + if (ObjectUtil.isEmpty(passwordBcrypt) || !BCrypt.checkpw(password, passwordBcrypt)) { + LogManager.me().executeLoginLog(sysUser.getAccount(), LogSuccessStatusEnum.FAIL.getCode(), AuthExceptionEnum.ACCOUNT_PWD_ERROR.getMessage()); + throw new AuthException(AuthExceptionEnum.ACCOUNT_PWD_ERROR); + } + + return doLogin(sysUser); + } + + @Override + public String doLogin(SysUser sysUser) { + + Integer sysUserStatus = sysUser.getStatus(); + + //验证账号是否被冻结 + if (CommonStatusEnum.DISABLE.getCode().equals(sysUserStatus)) { + LogManager.me().executeLoginLog(sysUser.getAccount(), LogSuccessStatusEnum.FAIL.getCode(), AuthExceptionEnum.ACCOUNT_FREEZE_ERROR.getMessage()); + throw new AuthException(AuthExceptionEnum.ACCOUNT_FREEZE_ERROR); + } + + //构造SysLoginUser + SysLoginUser sysLoginUser = this.genSysLoginUser(sysUser); + + //构造jwtPayLoad + JwtPayLoad jwtPayLoad = new JwtPayLoad(sysUser.getId(), sysUser.getAccount()); + + //生成token + String token = JwtTokenUtil.generateToken(jwtPayLoad); + + //缓存token与登录用户信息对应, 默认2个小时 + this.cacheLoginUser(jwtPayLoad, sysLoginUser); + + //设置最后登录ip和时间 + sysUser.setLastLoginIp(IpAddressUtil.getIp(HttpServletUtil.getRequest())); + sysUser.setLastLoginTime(DateTime.now()); + + //更新用户登录信息 + sysUserService.updateById(sysUser); + + //登录成功,记录登录日志 + LogManager.me().executeLoginLog(sysUser.getAccount(), LogSuccessStatusEnum.SUCCESS.getCode(), null); + + //登录成功,设置SpringSecurityContext上下文,方便获取用户 + this.setSpringSecurityContextAuthentication(sysLoginUser); + + //如果开启限制单用户登陆,则踢掉原来的用户 + Boolean enableSingleLogin = ConstantContextHolder.getEnableSingleLogin(); + if (enableSingleLogin) { + + //获取所有的登陆用户 + Map allLoginUsers = userCache.getAllKeyValues(); + for (Map.Entry loginedUserEntry : allLoginUsers.entrySet()) { + + String loginedUserKey = loginedUserEntry.getKey(); + SysLoginUser loginedUser = loginedUserEntry.getValue(); + + //如果账号名称相同,并且redis缓存key和刚刚生成的用户的uuid不一样,则清除以前登录的 + if (loginedUser.getName().equals(sysUser.getName()) + && !loginedUserKey.equals(jwtPayLoad.getUuid())) { + this.clearUser(loginedUserKey, loginedUser.getAccount()); + } + } + } + + //返回token + return token; + } + + @Override + public String getTokenFromRequest(HttpServletRequest request) { + String authToken = request.getHeader(CommonConstant.AUTHORIZATION); + if (ObjectUtil.isEmpty(authToken)) { + return null; + } else { + //token不是以Bearer打头,则响应回格式不正确 + if (!authToken.startsWith(CommonConstant.TOKEN_TYPE_BEARER)) { + throw new AuthException(AuthExceptionEnum.NOT_VALID_TOKEN_TYPE); + } + try { + authToken = authToken.substring(CommonConstant.TOKEN_TYPE_BEARER.length() + 1); + } catch (StringIndexOutOfBoundsException e) { + throw new AuthException(AuthExceptionEnum.NOT_VALID_TOKEN_TYPE); + } + } + + return authToken; + } + + @Override + public SysLoginUser getLoginUserByToken(String token) { + + //校验token,错误则抛异常 + this.checkToken(token); + + //根据token获取JwtPayLoad部分 + JwtPayLoad jwtPayLoad = JwtTokenUtil.getJwtPayLoad(token); + + //从redis缓存中获取登录用户 + Object cacheObject = userCache.get(jwtPayLoad.getUuid()); + + //用户不存在则表示登录已过期 + if (ObjectUtil.isEmpty(cacheObject)) { + throw new AuthException(AuthExceptionEnum.LOGIN_EXPIRED); + } + + //转换成登录用户 + SysLoginUser sysLoginUser = (SysLoginUser) cacheObject; + + //用户存在, 无痛刷新缓存,在登录过期前活动的用户自动刷新缓存时间 + this.cacheLoginUser(jwtPayLoad, sysLoginUser); + + //返回用户 + return sysLoginUser; + } + + @Override + public void logout() { + + HttpServletRequest request = HttpServletUtil.getRequest(); + + if (ObjectUtil.isNotNull(request)) { + + //获取token + String token = this.getTokenFromRequest(request); + + //如果token为空直接返回 + if (ObjectUtil.isEmpty(token)) { + return; + } + + //校验token,错误则抛异常,待确定 + this.checkToken(token); + + //根据token获取JwtPayLoad部分 + JwtPayLoad jwtPayLoad = JwtTokenUtil.getJwtPayLoad(token); + + //获取缓存的key + String loginUserCacheKey = jwtPayLoad.getUuid(); + this.clearUser(loginUserCacheKey, jwtPayLoad.getAccount()); + + } else { + throw new ServiceException(ServerExceptionEnum.REQUEST_EMPTY); + } + } + + @Override + public void setSpringSecurityContextAuthentication(SysLoginUser sysLoginUser) { + UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = + new UsernamePasswordAuthenticationToken( + sysLoginUser, + null, + sysLoginUser.getAuthorities()); + SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken); + } + + @Override + public Authentication getAuthentication() { + return SecurityContextHolder.getContext().getAuthentication(); + } + + @Override + public void checkToken(String token) { + //校验token是否正确 + Boolean tokenCorrect = JwtTokenUtil.checkToken(token); + if (!tokenCorrect) { + throw new AuthException(AuthExceptionEnum.REQUEST_TOKEN_ERROR); + } + + //校验token是否失效 + Boolean tokenExpired = JwtTokenUtil.isTokenExpired(token); + if (tokenExpired) { + throw new AuthException(AuthExceptionEnum.LOGIN_EXPIRED); + } + } + + @Override + public void cacheTenantInfo(String tenantCode) { + if (StrUtil.isBlank(tenantCode)) { + return; + } + + // 从spring容器中获取service,如果没开多租户功能,没引入相关包,这里会报错 + TenantInfoService tenantInfoService = null; + try { + tenantInfoService = SpringUtil.getBean(TenantInfoService.class); + } catch (Exception e) { + throw new TenantException(TenantExceptionEnum.TENANT_MODULE_NOT_ENABLE_ERROR); + } + + // 获取租户信息 + TenantInfo tenantInfo = tenantInfoService.getByCode(tenantCode); + if (tenantInfo != null) { + String dbName = tenantInfo.getDbName(); + + // 租户编码的临时存放 + TenantCodeHolder.put(tenantCode); + + // 租户的数据库名称临时缓存 + TenantDbNameHolder.put(dbName); + + // 数据源信息临时缓存 + CurrentDataSourceContext.setDataSourceType(dbName); + } else { + throw new TenantException(TenantExceptionEnum.CNAT_FIND_TENANT_ERROR); + } + } + + @Override + public SysLoginUser loadUserByUsername(String account) throws UsernameNotFoundException { + SysLoginUser sysLoginUser = new SysLoginUser(); + SysUser user = sysUserService.getUserByCount(account); + BeanUtil.copyProperties(user, sysLoginUser); + return sysLoginUser; + } + + /** + * 根据key清空登陆信息 + * + * @author xuyuxiang + * @date 2020/6/19 12:28 + */ + private void clearUser(String loginUserKey, String account) { + //获取缓存的用户 + Object cacheObject = userCache.get(loginUserKey); + + //如果缓存的用户存在,清除会话,否则表示该会话信息已失效,不执行任何操作 + if (ObjectUtil.isNotEmpty(cacheObject)) { + //清除登录会话 + userCache.remove(loginUserKey); + //创建退出登录日志 + LogManager.me().executeExitLog(account); + } + } + + /** + * 构造登录用户信息 + * + * @author xuyuxiang + * @date 2020/3/12 17:32 + */ + @Override + public SysLoginUser genSysLoginUser(SysUser sysUser) { + SysLoginUser sysLoginUser = new SysLoginUser(); + BeanUtil.copyProperties(sysUser, sysLoginUser); + LoginUserFactory.fillLoginUserInfo(sysLoginUser); + return sysLoginUser; + } + + /** + * 缓存token与登录用户信息对应, 默认2个小时 + * + * @author xuyuxiang + * @date 2020/3/13 14:51 + */ + private void cacheLoginUser(JwtPayLoad jwtPayLoad, SysLoginUser sysLoginUser) { + String redisLoginUserKey = jwtPayLoad.getUuid(); + userCache.put(redisLoginUserKey, sysLoginUser); + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/consts/controller/SysConfigController.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/consts/controller/SysConfigController.java new file mode 100644 index 00000000..945a9375 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/consts/controller/SysConfigController.java @@ -0,0 +1,138 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.consts.controller; + +import com.cn.xiaonuo.core.annotion.BusinessLog; +import com.cn.xiaonuo.core.annotion.Permission; +import com.cn.xiaonuo.core.enums.LogAnnotionOpTypeEnum; +import com.cn.xiaonuo.core.pojo.response.ResponseData; +import com.cn.xiaonuo.core.pojo.response.SuccessResponseData; +import com.cn.xiaonuo.sys.modular.consts.param.SysConfigParam; +import com.cn.xiaonuo.sys.modular.consts.service.SysConfigService; +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.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + + +/** + * 参数配置控制器 + * + * @author yubaoshan + * @date 2020/4/13 22:46 + */ +@RestController +public class SysConfigController { + + @Resource + private SysConfigService sysConfigService; + + /** + * 分页查询配置列表 + * + * @author xuyuxiang + * @date 2020/4/14 11:10 + */ + @Permission + @GetMapping("/sysConfig/page") + @BusinessLog(title = "系统参数配置_查询", opType = LogAnnotionOpTypeEnum.QUERY) + public ResponseData page(SysConfigParam sysConfigParam) { + return new SuccessResponseData(sysConfigService.page(sysConfigParam)); + } + + /** + * 系统参数配置列表 + * + * @author xuyuxiang + * @date 2020/4/14 11:10 + */ + @Permission + @GetMapping("/sysConfig/list") + @BusinessLog(title = "系统参数配置_列表", opType = LogAnnotionOpTypeEnum.QUERY) + public ResponseData list(SysConfigParam sysConfigParam) { + return new SuccessResponseData(sysConfigService.list(sysConfigParam)); + } + + /** + * 查看系统参数配置 + * + * @author xuyuxiang + * @date 2020/4/14 11:12 + */ + @Permission + @GetMapping("/sysConfig/detail") + @BusinessLog(title = "系统参数配置_详情", opType = LogAnnotionOpTypeEnum.DETAIL) + public ResponseData detail(@Validated(SysConfigParam.detail.class) SysConfigParam sysConfigParam) { + return new SuccessResponseData(sysConfigService.detail(sysConfigParam)); + } + + /** + * 添加系统参数配置 + * + * @author xuyuxiang + * @date 2020/4/14 11:11 + */ + @Permission + @PostMapping("/sysConfig/add") + @BusinessLog(title = "系统参数配置_增加", opType = LogAnnotionOpTypeEnum.ADD) + public ResponseData add(@RequestBody @Validated(SysConfigParam.add.class) SysConfigParam sysConfigParam) { + sysConfigService.add(sysConfigParam); + return new SuccessResponseData(); + } + + /** + * 删除系统参数配置 + * + * @author xuyuxiang + * @date 2020/4/14 11:11 + */ + @Permission + @PostMapping("/sysConfig/delete") + @BusinessLog(title = "系统参数配置_删除", opType = LogAnnotionOpTypeEnum.DELETE) + public ResponseData delete(@RequestBody @Validated(SysConfigParam.delete.class) SysConfigParam sysConfigParam) { + sysConfigService.delete(sysConfigParam); + return new SuccessResponseData(); + } + + /** + * 编辑系统参数配置 + * + * @author xuyuxiang + * @date 2020/4/14 11:11 + */ + @Permission + @PostMapping("/sysConfig/edit") + @BusinessLog(title = "系统参数配置_编辑", opType = LogAnnotionOpTypeEnum.EDIT) + public ResponseData edit(@RequestBody @Validated(SysConfigParam.edit.class) SysConfigParam sysConfigParam) { + sysConfigService.edit(sysConfigParam); + return new SuccessResponseData(); + } + +} + + diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/consts/entity/SysConfig.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/consts/entity/SysConfig.java new file mode 100644 index 00000000..af43e5d2 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/consts/entity/SysConfig.java @@ -0,0 +1,87 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.consts.entity; + +import com.cn.xiaonuo.core.pojo.base.entity.BaseEntity; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * 参数配置 + *

+ * + * @author yubaoshan + * @date 2019/6/20 13:44 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@TableName("sys_config") +public class SysConfig extends BaseEntity { + + /** + * 主键 + */ + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + /** + * 名称 + */ + private String name; + + /** + * 编码 + */ + private String code; + + /** + * 属性值 + */ + private String value; + + /** + * 是否是系统参数(Y-是,N-否) + */ + private String sysFlag; + + /** + * 备注 + */ + @TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED) + private String remark; + + /** + * 状态(字典 0正常 1停用 2删除) + */ + private Integer status; + + /** + * 常量所属分类的编码,来自于“常量的分类”字典 + */ + private String groupCode; + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/consts/enums/SysConfigExceptionEnum.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/consts/enums/SysConfigExceptionEnum.java new file mode 100644 index 00000000..6c3a0706 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/consts/enums/SysConfigExceptionEnum.java @@ -0,0 +1,90 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.consts.enums; + +import com.cn.xiaonuo.core.annotion.ExpEnumType; +import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum; +import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory; +import com.cn.xiaonuo.sys.core.consts.SysExpEnumConstant; + +/** + * 系统参数配置相关异常枚举 + * + * @author xuyuxiang + * @date 2020/4/14 11:24 + */ +@ExpEnumType(module = SysExpEnumConstant.XIAONUO_SYS_MODULE_EXP_CODE, kind = SysExpEnumConstant.SYS_CONFIG_EXCEPTION_ENUM) +public enum SysConfigExceptionEnum implements AbstractBaseExceptionEnum { + + /** + * 数据库连接配置不存在 + */ + DATA_SOURCE_NOT_EXIST(1, "数据库连接配置不存在,请检查spring.datasource配置"), + + /** + * 系统参数配置不存在 + */ + CONFIG_NOT_EXIST(2, "系统参数配置不存在"), + + /** + * 系统参数配置编码重复 + */ + CONFIG_CODE_REPEAT(3, "系统参数配置编码重复,请检查code参数"), + + /** + * 系统参数配置名称重复 + */ + CONFIG_NAME_REPEAT(4, "系统参数配置名称重复,请检查name参数"), + + /** + * 不能删除系统参数 + */ + CONFIG_SYS_CAN_NOT_DELETE(5, "系统参数配置不能删除"), + + /** + * 常量分类在字典中未找到 + */ + NOT_EXIST_DICT_TYPE(6, "字典类型中未找到常量分类,请检查字典类型表"); + + private final Integer code; + + private final String message; + + SysConfigExceptionEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return ExpEnumCodeFactory.getExpEnumCode(this.getClass(), code); + } + + @Override + public String getMessage() { + return message; + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/consts/mapper/SysConfigMapper.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/consts/mapper/SysConfigMapper.java new file mode 100644 index 00000000..35b2791f --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/consts/mapper/SysConfigMapper.java @@ -0,0 +1,40 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.consts.mapper; + +import com.cn.xiaonuo.sys.modular.consts.entity.SysConfig; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.cn.xiaonuo.sys.modular.consts.entity.SysConfig; + +/** + * 系统参数配置 Mapper 接口 + * + * @author yubaoshan + * @date 2019/6/20 13:44 + */ +public interface SysConfigMapper extends BaseMapper { + + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/consts/mapper/mapping/SysConfigMapper.xml b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/consts/mapper/mapping/SysConfigMapper.xml new file mode 100644 index 00000000..39027996 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/consts/mapper/mapping/SysConfigMapper.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/consts/param/SysConfigParam.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/consts/param/SysConfigParam.java new file mode 100644 index 00000000..b3c398f9 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/consts/param/SysConfigParam.java @@ -0,0 +1,86 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.consts.param; + +import com.cn.xiaonuo.core.pojo.base.param.BaseParam; +import com.cn.xiaonuo.core.validation.flag.FlagValue; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 系统参数配置参数 + * + * @author xuyuxiang + * @date 2020/4/14 10:18 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class SysConfigParam extends BaseParam { + + /** + * 主键 + */ + @NotNull(message = "id不能为空,请检查id参数", groups = {edit.class, delete.class, detail.class}) + private Long id; + + /** + * 名称 + */ + @NotBlank(message = "名称不能为空,请检查name参数", groups = {add.class, edit.class}) + private String name; + + /** + * 编码 + */ + @NotBlank(message = "编码不能为空,请检查code参数", groups = {add.class, edit.class}) + private String code; + + /** + * 值 + */ + @NotBlank(message = "值不能为空,请检查value参数", groups = {add.class, edit.class}) + private String value; + + /** + * 是否是系统参数(Y-是,N-否) + */ + @NotBlank(message = "是否是系统参数不能为空,请检查sysFlag参数", groups = {add.class, edit.class}) + @FlagValue(message = "是否是系统参数格式错误,正确格式应该Y或者N,请检查sysFlag参数", groups = {add.class, edit.class}) + private String sysFlag; + + /** + * 备注 + */ + private String remark; + + /** + * 常量所属分类的编码,来自于“常量的分类”字典 + */ + @NotBlank(message = "值不能为空,请检查value参数", groups = {add.class, edit.class}) + private String groupCode; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/consts/service/SysConfigService.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/consts/service/SysConfigService.java new file mode 100644 index 00000000..10443348 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/consts/service/SysConfigService.java @@ -0,0 +1,99 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.consts.service; + +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.modular.consts.entity.SysConfig; +import com.cn.xiaonuo.sys.modular.consts.param.SysConfigParam; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +/** + * 系统参数配置service接口 + * + * @author xuyuxiang + * @date 2020/4/14 11:14 + */ +public interface SysConfigService extends IService { + + /** + * 查询系统参数配置 + * + * @param sysConfigParam 查询参数 + * @return 查询分页结果 + * @author xuyuxiang + * @date 2020/4/14 11:14 + */ + PageResult page(SysConfigParam sysConfigParam); + + /** + * 查询系统参数配置 + * + * @param sysConfigParam 查询参数 + * @return 系统参数配置列表 + * @author xuyuxiang + * @date 2020/4/14 11:14 + */ + List list(SysConfigParam sysConfigParam); + + /** + * 查看系统参数配置 + * + * @param sysConfigParam 查看参数 + * @return 系统参数配置 + * @author xuyuxiang + * @date 2020/4/14 11:15 + */ + SysConfig detail(SysConfigParam sysConfigParam); + + /** + * 添加系统参数配置 + * + * @param sysConfigParam 添加参数 + * @author xuyuxiang + * @date 2020/4/14 11:14 + */ + void add(SysConfigParam sysConfigParam); + + /** + * 删除系统参数配置 + * + * @param sysConfigParam 删除参数 + * @author xuyuxiang + * @date 2020/4/14 11:15 + */ + void delete(SysConfigParam sysConfigParam); + + /** + * 编辑系统参数配置 + * + * @param sysConfigParam 编辑参数 + * @author xuyuxiang + * @date 2020/4/14 11:15 + */ + void edit(SysConfigParam sysConfigParam); + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/consts/service/impl/SysConfigServiceImpl.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/consts/service/impl/SysConfigServiceImpl.java new file mode 100644 index 00000000..a4fe211c --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/consts/service/impl/SysConfigServiceImpl.java @@ -0,0 +1,210 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.consts.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.ObjectUtil; +import com.cn.xiaonuo.core.context.constant.ConstantContext; +import com.cn.xiaonuo.core.enums.CommonStatusEnum; +import com.cn.xiaonuo.core.enums.YesOrNotEnum; +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.core.factory.PageFactory; +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.modular.consts.entity.SysConfig; +import com.cn.xiaonuo.sys.modular.consts.enums.SysConfigExceptionEnum; +import com.cn.xiaonuo.sys.modular.consts.mapper.SysConfigMapper; +import com.cn.xiaonuo.sys.modular.consts.param.SysConfigParam; +import com.cn.xiaonuo.sys.modular.consts.service.SysConfigService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +import java.util.List; + + +/** + * 系统参数配置service接口实现类 + * + * @author xuyuxiang + * @date 2020/4/14 11:16 + */ +@Service +public class SysConfigServiceImpl extends ServiceImpl implements SysConfigService { + + @Override + public PageResult page(SysConfigParam sysConfigParam) { + + //构造查询条件 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + + if (ObjectUtil.isNotNull(sysConfigParam)) { + //如果名称不为空,则带上名称搜素搜条件 + if (ObjectUtil.isNotEmpty(sysConfigParam.getName())) { + queryWrapper.like(SysConfig::getName, sysConfigParam.getName()); + } + //如果常量编码不为空,则带上常量编码搜素搜条件 + if (ObjectUtil.isNotEmpty(sysConfigParam.getCode())) { + queryWrapper.like(SysConfig::getCode, sysConfigParam.getCode()); + } + //如果分类编码不为空,则带上分类编码 + if (ObjectUtil.isNotEmpty(sysConfigParam.getGroupCode())) { + queryWrapper.eq(SysConfig::getGroupCode, sysConfigParam.getGroupCode()); + } + } + + //查询未删除的 + queryWrapper.ne(SysConfig::getStatus, CommonStatusEnum.DELETED.getCode()); + + //按类型升序排列,同类型的排在一起 + queryWrapper.orderByDesc(SysConfig::getGroupCode); + + //查询分页结果 + return new PageResult<>(this.page(PageFactory.defaultPage(), queryWrapper)); + } + + @Override + public List list(SysConfigParam sysConfigParam) { + + //构造条件 + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + + //查询未删除的 + wrapper.ne(SysConfig::getStatus, CommonStatusEnum.DELETED.getCode()); + + return this.list(wrapper); + } + + @Override + public SysConfig detail(SysConfigParam sysConfigParam) { + return this.querySysConfig(sysConfigParam); + } + + @Override + public void add(SysConfigParam sysConfigParam) { + + //1.校验参数,是否有重复的名称和编码,不排除当前记录 + checkRepeatParam(sysConfigParam, false); + + //2.构造实体 + SysConfig sysConfig = new SysConfig(); + BeanUtil.copyProperties(sysConfigParam, sysConfig); + sysConfig.setStatus(CommonStatusEnum.ENABLE.getCode()); + + //3.保存到库中 + this.save(sysConfig); + + //4.添加对应context + ConstantContext.putConstant(sysConfigParam.getCode(), sysConfigParam.getValue()); + } + + @Override + public void delete(SysConfigParam sysConfigParam) { + + //1.根据id获取常量 + SysConfig sysConfig = this.querySysConfig(sysConfigParam); + + //2.不能删除系统参数 + if (YesOrNotEnum.Y.getCode().equals(sysConfig.getSysFlag())) { + throw new ServiceException(SysConfigExceptionEnum.CONFIG_SYS_CAN_NOT_DELETE); + } + + //3.设置状态为已删除 + sysConfig.setStatus(CommonStatusEnum.DELETED.getCode()); + this.updateById(sysConfig); + + //4.删除对应context + ConstantContext.deleteConstant(sysConfigParam.getCode()); + } + + @Override + public void edit(SysConfigParam sysConfigParam) { + + //1.根据id获取常量信息 + SysConfig sysConfig = this.querySysConfig(sysConfigParam); + + //2.校验参数,是否有重复的名称和编码,排除本条记录 + checkRepeatParam(sysConfigParam, true); + + //请求参数转化为实体 + BeanUtil.copyProperties(sysConfigParam, sysConfig); + //不能修改状态,用修改状态接口修改状态 + sysConfig.setStatus(null); + + //3.更新记录 + this.updateById(sysConfig); + + //4.更新对应常量context + ConstantContext.putConstant(sysConfigParam.getCode(), sysConfigParam.getValue()); + } + + /** + * 校验参数,是否有重复的名称和编码 + * + * @author xuyuxiang + * @date 2020/4/14 11:18 + */ + private void checkRepeatParam(SysConfigParam sysConfigParam, boolean isExcludeSelf) { + Long id = sysConfigParam.getId(); + String name = sysConfigParam.getName(); + String code = sysConfigParam.getCode(); + + //构建带name和code的查询条件 + LambdaQueryWrapper queryWrapperByName = new LambdaQueryWrapper<>(); + queryWrapperByName.eq(SysConfig::getName, name); + + LambdaQueryWrapper queryWrapperByCode = new LambdaQueryWrapper<>(); + queryWrapperByCode.eq(SysConfig::getCode, code); + + //如果排除自己,则增加查询条件主键id不等于本条id + if (isExcludeSelf) { + queryWrapperByName.ne(SysConfig::getId, id); + queryWrapperByCode.ne(SysConfig::getId, id); + } + int countByName = this.count(queryWrapperByName); + int countByCode = this.count(queryWrapperByCode); + + //如果存在重复的记录,抛出异常,直接返回前端 + if (countByName >= 1) { + throw new ServiceException(SysConfigExceptionEnum.CONFIG_NAME_REPEAT); + } + if (countByCode >= 1) { + throw new ServiceException(SysConfigExceptionEnum.CONFIG_CODE_REPEAT); + } + } + + /** + * 获取系统参数配置 + * + * @author xuyuxiang + * @date 2020/4/14 11:19 + */ + private SysConfig querySysConfig(SysConfigParam sysConfigParam) { + SysConfig sysConfig = this.getById(sysConfigParam.getId()); + if (ObjectUtil.isEmpty(sysConfig)) { + throw new ServiceException(SysConfigExceptionEnum.CONFIG_NOT_EXIST); + } + return sysConfig; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/controller/SysDictDataController.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/controller/SysDictDataController.java new file mode 100644 index 00000000..f18a6977 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/controller/SysDictDataController.java @@ -0,0 +1,149 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.dict.controller; + +import com.cn.xiaonuo.core.annotion.BusinessLog; +import com.cn.xiaonuo.core.annotion.Permission; +import com.cn.xiaonuo.core.enums.LogAnnotionOpTypeEnum; +import com.cn.xiaonuo.core.pojo.response.ResponseData; +import com.cn.xiaonuo.core.pojo.response.SuccessResponseData; +import com.cn.xiaonuo.sys.modular.dict.param.SysDictDataParam; +import com.cn.xiaonuo.sys.modular.dict.service.SysDictDataService; +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.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + * 系统字典值控制器 + * + * @author xuyuxiang + * @date 2020/3/31 20:49 + */ +@RestController +public class SysDictDataController { + + @Resource + private SysDictDataService sysDictDataService; + + /** + * 查询系统字典值 + * + * @author xuyuxiang + * @date 2020/3/31 20:50 + */ + @Permission + @GetMapping("/sysDictData/page") + @BusinessLog(title = "系统字典值_查询", opType = LogAnnotionOpTypeEnum.QUERY) + public ResponseData page(SysDictDataParam sysDictDataParam) { + return new SuccessResponseData(sysDictDataService.page(sysDictDataParam)); + } + + /** + * 某个字典类型下所有的字典 + * + * @author xuyuxiang + * @date 2020/3/31 21:03 + */ + @Permission + @GetMapping("/sysDictData/list") + @BusinessLog(title = "系统字典值_列表", opType = LogAnnotionOpTypeEnum.QUERY) + public ResponseData list(@Validated(SysDictDataParam.list.class) SysDictDataParam sysDictDataParam) { + return new SuccessResponseData(sysDictDataService.list(sysDictDataParam)); + } + + /** + * 查看系统字典值 + * + * @author xuyuxiang + * @date 2020/3/31 20:51 + */ + @Permission + @GetMapping("/sysDictData/detail") + @BusinessLog(title = "系统字典值_查看", opType = LogAnnotionOpTypeEnum.DETAIL) + public ResponseData detail(@Validated(SysDictDataParam.detail.class) SysDictDataParam sysDictDataParam) { + return new SuccessResponseData(sysDictDataService.detail(sysDictDataParam)); + } + + /** + * 添加系统字典值 + * + * @author xuyuxiang + * @date 2020/3/31 20:50 + */ + @Permission + @PostMapping("/sysDictData/add") + @BusinessLog(title = "系统字典值_增加", opType = LogAnnotionOpTypeEnum.ADD) + public ResponseData add(@RequestBody @Validated(SysDictDataParam.add.class) SysDictDataParam sysDictDataParam) { + sysDictDataService.add(sysDictDataParam); + return new SuccessResponseData(); + } + + /** + * 删除系统字典值 + * + * @author xuyuxiang + * @date 2020/3/31 20:50 + */ + @Permission + @PostMapping("/sysDictData/delete") + @BusinessLog(title = "系统字典值_删除", opType = LogAnnotionOpTypeEnum.DELETE) + public ResponseData delete(@RequestBody @Validated(SysDictDataParam.delete.class) SysDictDataParam sysDictDataParam) { + sysDictDataService.delete(sysDictDataParam); + return new SuccessResponseData(); + } + + /** + * 编辑系统字典值 + * + * @author xuyuxiang + * @date 2020/3/31 20:51 + */ + @Permission + @PostMapping("/sysDictData/edit") + @BusinessLog(title = "系统字典值_编辑", opType = LogAnnotionOpTypeEnum.EDIT) + public ResponseData edit(@RequestBody @Validated(SysDictDataParam.edit.class) SysDictDataParam sysDictDataParam) { + sysDictDataService.edit(sysDictDataParam); + return new SuccessResponseData(); + } + + /** + * 修改状态 + * + * @author yubaoshan + * @date 2020/5/1 9:43 + */ + @Permission + @PostMapping("/sysDictData/changeStatus") + @BusinessLog(title = "系统字典值_修改状态", opType = LogAnnotionOpTypeEnum.CHANGE_STATUS) + public ResponseData changeStatus(@RequestBody @Validated(SysDictDataParam.changeStatus.class) SysDictDataParam sysDictDataParam) { + sysDictDataService.changeStatus(sysDictDataParam); + return new SuccessResponseData(); + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/controller/SysDictTypeController.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/controller/SysDictTypeController.java new file mode 100644 index 00000000..ab3d6681 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/controller/SysDictTypeController.java @@ -0,0 +1,172 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.dict.controller; + +import com.cn.xiaonuo.core.annotion.BusinessLog; +import com.cn.xiaonuo.core.annotion.Permission; +import com.cn.xiaonuo.core.enums.LogAnnotionOpTypeEnum; +import com.cn.xiaonuo.core.pojo.response.ResponseData; +import com.cn.xiaonuo.core.pojo.response.SuccessResponseData; +import com.cn.xiaonuo.sys.modular.dict.param.SysDictTypeParam; +import com.cn.xiaonuo.sys.modular.dict.service.SysDictTypeService; +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.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + * 系统字典类型控制器 + * + * @author xuyuxiang,xuyuxiang + * @date 2020/3/31 20:49 + */ +@RestController +public class SysDictTypeController { + + @Resource + private SysDictTypeService sysDictTypeService; + + /** + * 分页查询系统字典类型 + * + * @author xuyuxiang,xuyuxiang + * @date 2020/3/31 20:30 + */ + @Permission + @GetMapping("/sysDictType/page") + @BusinessLog(title = "系统字典类型_分页查询", opType = LogAnnotionOpTypeEnum.QUERY) + public ResponseData page(SysDictTypeParam sysDictTypeParam) { + return new SuccessResponseData(sysDictTypeService.page(sysDictTypeParam)); + } + + /** + * 获取字典类型列表 + * + * @author xuyuxiang,xuyuxiang + * @date 2020/3/31 21:03 + */ + @Permission + @GetMapping("/sysDictType/list") + @BusinessLog(title = "系统字典类型_列表", opType = LogAnnotionOpTypeEnum.QUERY) + public ResponseData list(SysDictTypeParam sysDictTypeParam) { + return new SuccessResponseData(sysDictTypeService.list(sysDictTypeParam)); + } + + /** + * 获取字典类型下所有字典,举例,返回格式为:[{code:"M",value:"男"},{code:"F",value:"女"}] + * + * @author xuyuxiang,xuyuxiang yubaoshan + * @date 2020/3/31 21:18 + */ + @GetMapping("/sysDictType/dropDown") + @BusinessLog(title = "系统字典类型_下拉", opType = LogAnnotionOpTypeEnum.QUERY) + public ResponseData dropDown(@Validated(SysDictTypeParam.dropDown.class) SysDictTypeParam sysDictTypeParam) { + return new SuccessResponseData(sysDictTypeService.dropDown(sysDictTypeParam)); + } + + /** + * 查看系统字典类型 + * + * @author xuyuxiang,xuyuxiang + * @date 2020/3/31 20:31 + */ + @Permission + @GetMapping("/sysDictType/detail") + @BusinessLog(title = "系统字典类型_查看", opType = LogAnnotionOpTypeEnum.DETAIL) + public ResponseData detail(@Validated(SysDictTypeParam.detail.class) SysDictTypeParam sysDictTypeParam) { + return new SuccessResponseData(sysDictTypeService.detail(sysDictTypeParam)); + } + + /** + * 添加系统字典类型 + * + * @author xuyuxiang,xuyuxiang + * @date 2020/3/31 20:30 + */ + @Permission + @PostMapping("/sysDictType/add") + @BusinessLog(title = "系统字典类型_增加", opType = LogAnnotionOpTypeEnum.ADD) + public ResponseData add(@RequestBody @Validated(SysDictTypeParam.add.class) SysDictTypeParam sysDictTypeParam) { + sysDictTypeService.add(sysDictTypeParam); + return new SuccessResponseData(); + } + + /** + * 删除系统字典类型 + * + * @author xuyuxiang,xuyuxiang + * @date 2020/3/31 20:30 + */ + @Permission + @PostMapping("/sysDictType/delete") + @BusinessLog(title = "系统字典类型_删除", opType = LogAnnotionOpTypeEnum.DELETE) + public ResponseData delete(@RequestBody @Validated(SysDictTypeParam.delete.class) SysDictTypeParam sysDictTypeParam) { + sysDictTypeService.delete(sysDictTypeParam); + return new SuccessResponseData(); + } + + /** + * 编辑系统字典类型 + * + * @author xuyuxiang,xuyuxiang + * @date 2020/3/31 20:31 + */ + @Permission + @PostMapping("/sysDictType/edit") + @BusinessLog(title = "系统字典类型_编辑", opType = LogAnnotionOpTypeEnum.EDIT) + public ResponseData edit(@RequestBody @Validated(SysDictTypeParam.edit.class) SysDictTypeParam sysDictTypeParam) { + sysDictTypeService.edit(sysDictTypeParam); + return new SuccessResponseData(); + } + + /** + * 修改状态 + * + * @author yubaoshan + * @date 2020/4/30 22:20 + */ + @Permission + @PostMapping("/sysDictType/changeStatus") + @BusinessLog(title = "系统字典类型_修改状态", opType = LogAnnotionOpTypeEnum.CHANGE_STATUS) + public ResponseData changeStatus(@RequestBody @Validated(SysDictTypeParam.changeStatus.class) SysDictTypeParam sysDictTypeParam) { + sysDictTypeService.changeStatus(sysDictTypeParam); + return new SuccessResponseData(); + } + + /** + * 系统字典类型与字典值构造的树 + * + * @author yubaoshan + * @date 2020/4/30 22:20 + */ + @GetMapping("/sysDictType/tree") + @BusinessLog(title = "系统字典类型_树", opType = LogAnnotionOpTypeEnum.QUERY) + public ResponseData tree() { + return new SuccessResponseData(sysDictTypeService.tree()); + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/entity/SysDictData.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/entity/SysDictData.java new file mode 100644 index 00000000..12658cf6 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/entity/SysDictData.java @@ -0,0 +1,79 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.dict.entity; + +import com.cn.xiaonuo.core.pojo.base.entity.BaseEntity; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 系统字典值表 + * + * @author xuyuxiang + * @date 2020/3/11 12:08 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@TableName("sys_dict_data") +public class SysDictData extends BaseEntity { + + /** + * 主键 + */ + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + /** + * 字典类型id + */ + private Long typeId; + + /** + * 值 + */ + private String value; + + /** + * 编码 + */ + private String code; + + /** + * 排序 + */ + private Integer sort; + + /** + * 备注 + */ + @TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED) + private String remark; + + /** + * 状态(字典 0正常 1停用 2删除) + */ + private Integer status; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/entity/SysDictType.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/entity/SysDictType.java new file mode 100644 index 00000000..08504be8 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/entity/SysDictType.java @@ -0,0 +1,75 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.dict.entity; + +import com.cn.xiaonuo.core.pojo.base.entity.BaseEntity; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 系统字典类型表 + * + * @author xuyuxiang + * @date 2020/3/11 12:08 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@TableName("sys_dict_type") +public class SysDictType extends BaseEntity { + + /** + * 主键 + */ + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + /** + * 名称 + */ + private String name; + + /** + * 编码 + */ + private String code; + + /** + * 排序 + */ + private Integer sort; + + /** + * 备注 + */ + @TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED) + private String remark; + + /** + * 状态(字典 0正常 1停用 2删除) + */ + private Integer status; + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/enums/SysDictDataExceptionEnum.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/enums/SysDictDataExceptionEnum.java new file mode 100644 index 00000000..92a11b8a --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/enums/SysDictDataExceptionEnum.java @@ -0,0 +1,70 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.dict.enums; + +import com.cn.xiaonuo.core.annotion.ExpEnumType; +import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum; +import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory; +import com.cn.xiaonuo.sys.core.consts.SysExpEnumConstant; + +/** + * 系统字典值相关异常枚举 + * + * @author xuyuxiang + * @date 2020/3/31 20:47 + */ +@ExpEnumType(module = SysExpEnumConstant.XIAONUO_SYS_MODULE_EXP_CODE, kind = SysExpEnumConstant.SYS_DICT_DATA_EXCEPTION_ENUM) +public enum SysDictDataExceptionEnum implements AbstractBaseExceptionEnum { + + /** + * 字典值不存在 + */ + DICT_DATA_NOT_EXIST(1, "字典值不存在"), + + /** + * 字典值编码重复 + */ + DICT_DATA_CODE_REPEAT(2, "字典值编码重复,请检查code参数"); + + private final Integer code; + + private final String message; + + SysDictDataExceptionEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return ExpEnumCodeFactory.getExpEnumCode(this.getClass(), code); + } + + @Override + public String getMessage() { + return message; + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/enums/SysDictTypeExceptionEnum.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/enums/SysDictTypeExceptionEnum.java new file mode 100644 index 00000000..0993d56a --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/enums/SysDictTypeExceptionEnum.java @@ -0,0 +1,75 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.dict.enums; + +import com.cn.xiaonuo.core.annotion.ExpEnumType; +import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum; +import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory; +import com.cn.xiaonuo.sys.core.consts.SysExpEnumConstant; + +/** + * 系统字典类型相关异常枚举 + * + * @author xuyuxiang + * @date 2020/3/31 20:44 + */ +@ExpEnumType(module = SysExpEnumConstant.XIAONUO_SYS_MODULE_EXP_CODE, kind = SysExpEnumConstant.SYS_DICT_TYPE_EXCEPTION_ENUM) +public enum SysDictTypeExceptionEnum implements AbstractBaseExceptionEnum { + + /** + * 字典类型不存在 + */ + DICT_TYPE_NOT_EXIST(1, "字典类型不存在"), + + /** + * 字典类型编码重复 + */ + DICT_TYPE_CODE_REPEAT(2, "字典类型编码重复,请检查code参数"), + + /** + * 字典类型名称重复 + */ + DICT_TYPE_NAME_REPEAT(3, "字典类型名称重复,请检查name参数"); + + private final Integer code; + + private final String message; + + SysDictTypeExceptionEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return ExpEnumCodeFactory.getExpEnumCode(this.getClass(), code); + } + + @Override + public String getMessage() { + return message; + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/mapper/SysDictDataMapper.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/mapper/SysDictDataMapper.java new file mode 100644 index 00000000..856648bf --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/mapper/SysDictDataMapper.java @@ -0,0 +1,50 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.dict.mapper; + +import com.cn.xiaonuo.sys.modular.dict.entity.SysDictData; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +import java.util.List; + +/** + * 系统字典值mapper接口 + * + * @author xuyuxiang + * @date 2020/3/13 16:12 + */ +public interface SysDictDataMapper extends BaseMapper { + + /** + * 通过字典类型code获取字典编码值列表 + * + * @param dictTypeCodes 字典类型编码集合 + * @return 字典编码值列表 + * @author xuyuxiang + * @date 2020/8/9 14:27 + */ + List getDictCodesByDictTypeCode(String[] dictTypeCodes); + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/mapper/SysDictTypeMapper.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/mapper/SysDictTypeMapper.java new file mode 100644 index 00000000..2d2fcd9e --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/mapper/SysDictTypeMapper.java @@ -0,0 +1,38 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.dict.mapper; + +import com.cn.xiaonuo.sys.modular.dict.entity.SysDictType; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.cn.xiaonuo.sys.modular.dict.entity.SysDictType; + +/** + * 系统字典类型mapper接口 + * + * @author xuyuxiang + * @date 2020/3/13 16:11 + */ +public interface SysDictTypeMapper extends BaseMapper { +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/mapper/mapping/SysDictDataMapper.xml b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/mapper/mapping/SysDictDataMapper.xml new file mode 100644 index 00000000..d0fe03b6 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/mapper/mapping/SysDictDataMapper.xml @@ -0,0 +1,17 @@ + + + + + + + diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/mapper/mapping/SysDictTypeMapper.xml b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/mapper/mapping/SysDictTypeMapper.xml new file mode 100644 index 00000000..f10fc723 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/mapper/mapping/SysDictTypeMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/param/SysDictDataParam.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/param/SysDictDataParam.java new file mode 100644 index 00000000..d21790f8 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/param/SysDictDataParam.java @@ -0,0 +1,84 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.dict.param; + +import com.cn.xiaonuo.core.pojo.base.param.BaseParam; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 系统字典值参数 + * + * @author xuyuxiang + * @date 2020/3/31 20:32 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class SysDictDataParam extends BaseParam { + + /** + * 主键 + */ + @NotNull(message = "id不能为空,请检查id参数", groups = {edit.class, delete.class, detail.class, changeStatus.class}) + private Long id; + + /** + * 字典类型id + */ + @NotNull(message = "字典类型typeId不能为空,请检查typeId参数", groups = {list.class, add.class, edit.class}) + private Long typeId; + + /** + * 值 + */ + @NotBlank(message = "值不能为空,请检查value参数", groups = {add.class, edit.class}) + private String value; + + /** + * 编码 + */ + @NotBlank(message = "编码不能为空,请检查code参数", groups = {dropDown.class, add.class, edit.class}) + private String code; + + /** + * 排序 + */ + @NotNull(message = "排序不能为空,请检查sort参数", groups = {add.class, edit.class}) + private Integer sort; + + /** + * 备注 + */ + private String remark; + + /** + * 状态(字典 0正常 1停用 2删除) + */ + @NotNull(message = "状态不能为空,请检查status参数", groups = changeStatus.class) + private Integer status; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/param/SysDictTypeParam.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/param/SysDictTypeParam.java new file mode 100644 index 00000000..ca5c185b --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/param/SysDictTypeParam.java @@ -0,0 +1,78 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.dict.param; + +import com.cn.xiaonuo.core.pojo.base.param.BaseParam; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 系统字典类型参数 + * + * @author xuyuxiang + * @date 2020/3/31 20:32 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class SysDictTypeParam extends BaseParam { + + /** + * 主键 + */ + @NotNull(message = "id不能为空,请检查id参数", groups = {edit.class, delete.class, detail.class, changeStatus.class}) + private Long id; + + /** + * 名称 + */ + @NotBlank(message = "名称不能为空,请检查name参数", groups = {add.class, edit.class}) + private String name; + + /** + * 编码 + */ + @NotBlank(message = "编码不能为空,请检查code参数", groups = {add.class, edit.class, dropDown.class,}) + private String code; + + /** + * 排序 + */ + @NotNull(message = "排序不能为空,请检查sort参数", groups = {add.class, edit.class}) + private Integer sort; + + /** + * 备注 + */ + private String remark; + + /** + * 状态 + */ + @NotNull(message = "状态不能为空,请检查status参数", groups = {changeStatus.class}) + private Integer status; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/result/SysDictTreeNode.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/result/SysDictTreeNode.java new file mode 100644 index 00000000..7287dfe7 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/result/SysDictTreeNode.java @@ -0,0 +1,56 @@ +package com.cn.xiaonuo.sys.modular.dict.result; + +import com.cn.xiaonuo.core.pojo.base.node.BaseTreeNode; +import lombok.Data; + +import java.util.List; + +/** + * 系统字典树 + * + * @author xuyuxiang + * @date 2020/3/11 12:08 + */ +@Data +public class SysDictTreeNode implements BaseTreeNode { + + /** + * id + */ + private Long id; + + /** + * 父id + */ + private Long pid; + + /** + * 编码-对应字典值的编码 + */ + private String code; + + /** + * 名称-对应字典值的value + */ + private String name; + + /** + * 子节点集合 + */ + private List children; + + @Override + public Long getId() { + return this.id; + } + + @Override + public Long getPid() { + return this.pid; + } + + @Override + public void setChildren(List children) { + this.children = children; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/service/SysDictDataService.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/service/SysDictDataService.java new file mode 100644 index 00000000..6f710e07 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/service/SysDictDataService.java @@ -0,0 +1,137 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.dict.service; + +import cn.hutool.core.lang.Dict; +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.modular.dict.entity.SysDictData; +import com.cn.xiaonuo.sys.modular.dict.param.SysDictDataParam; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +/** + * 系统字典值service接口 + * + * @author xuyuxiang + * @date 2020/3/13 16:10 + */ +public interface SysDictDataService extends IService { + + /** + * 查询系统字典值 + * + * @param sysDictDataParam 查询参数 + * @return 查询分页结果 + * @author xuyuxiang + * @date 2020/3/31 20:53 + */ + PageResult page(SysDictDataParam sysDictDataParam); + + /** + * 系统字典值列表 + * + * @param sysDictDataParam 查询参数 + * @return 系统字典值列表 + * @author xuyuxiang + * @date 2020/3/31 21:07 + */ + List list(SysDictDataParam sysDictDataParam); + + /** + * 添加系统字典值 + * + * @param sysDictDataParam 添加参数 + * @author xuyuxiang + * @date 2020/3/31 20:53 + */ + void add(SysDictDataParam sysDictDataParam); + + /** + * 删除系统字典值 + * + * @param sysDictDataParam 删除参数 + * @author xuyuxiang + * @date 2020/3/31 20:54 + */ + void delete(SysDictDataParam sysDictDataParam); + + /** + * 编辑系统字典值 + * + * @param sysDictDataParam 编辑参数 + * @author xuyuxiang + * @date 2020/3/31 20:54 + */ + void edit(SysDictDataParam sysDictDataParam); + + /** + * 查看系统字典值 + * + * @param sysDictDataParam 查看参数 + * @return 系统字典值 + * @author xuyuxiang + * @date 2020/3/31 20:54 + */ + SysDictData detail(SysDictDataParam sysDictDataParam); + + /** + * 根据typeId下拉 + * + * @param dictTypeId 字典类型id + * @return 增强版hashMap,格式:[{"code:":"1", "value":"正常"}] + * @author xuyuxiang yubaoshan + * @date 2020/3/31 21:27 + */ + List getDictDataListByDictTypeId(Long dictTypeId); + + /** + * 根据typeId删除 + * + * @param dictTypeId 字典类型id + * @author xuyuxiang + * @date 2020/4/1 10:27 + */ + void deleteByTypeId(Long dictTypeId); + + /** + * 修改状态 + * + * @param sysDictDataParam 修改参数 + * @author yubaoshan + * @date 2020/5/1 9:44 + */ + void changeStatus(SysDictDataParam sysDictDataParam); + + /** + * 根据字典类型获取字典的code值 + * + * @param dictTypeCodes 字典类型编码集合 + * @return 字典编码值列表 + * @author xuyuxiang + * @date 2020/8/9 14:18 + */ + List getDictCodesByDictTypeCode(String... dictTypeCodes); +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/service/SysDictTypeService.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/service/SysDictTypeService.java new file mode 100644 index 00000000..6c260ff6 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/service/SysDictTypeService.java @@ -0,0 +1,129 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.dict.service; + +import cn.hutool.core.lang.Dict; +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.modular.dict.entity.SysDictType; +import com.cn.xiaonuo.sys.modular.dict.param.SysDictTypeParam; +import com.cn.xiaonuo.sys.modular.dict.result.SysDictTreeNode; +import com.baomidou.mybatisplus.extension.service.IService; +import com.cn.xiaonuo.sys.modular.dict.result.SysDictTreeNode; + +import java.util.List; + +/** + * 系统字典类型service接口 + * + * @author xuyuxiang,xuyuxiang + * @date 2020/3/13 16:10 + */ +public interface SysDictTypeService extends IService { + + /** + * 查询系统字典类型 + * + * @param sysDictTypeParam 查询参数 + * @return 查询分页结果 + * @author xuyuxiang,xuyuxiang + * @date 2020/3/31 20:34 + */ + PageResult page(SysDictTypeParam sysDictTypeParam); + + /** + * 获取字典类型列表 + * + * @param sysDictTypeParam 查询参数 + * @return 系统字典类型列表 + * @author xuyuxiang,xuyuxiang + * @date 2020/3/31 21:07 + */ + List list(SysDictTypeParam sysDictTypeParam); + + /** + * 系统字典类型下拉 + * + * @param sysDictTypeParam 下拉参数 + * @return 增强版hashMap,格式:[{"code:":"1", "value":"正常"}] + * @author xuyuxiang,xuyuxiang + * @date 2020/3/31 21:23 + */ + List dropDown(SysDictTypeParam sysDictTypeParam); + + /** + * 添加系统字典类型 + * + * @param sysDictTypeParam 添加参数 + * @author xuyuxiang,xuyuxiang + * @date 2020/3/31 20:35 + */ + void add(SysDictTypeParam sysDictTypeParam); + + /** + * 删除系统字典类型 + * + * @param sysDictTypeParam 删除参数 + * @author xuyuxiang,xuyuxiang + * @date 2020/3/31 20:35 + */ + void delete(SysDictTypeParam sysDictTypeParam); + + /** + * 编辑系统字典类型 + * + * @param sysDictTypeParam 编辑参数 + * @author xuyuxiang,xuyuxiang + * @date 2020/3/31 20:35 + */ + void edit(SysDictTypeParam sysDictTypeParam); + + /** + * 查看系统字典类型 + * + * @param sysDictTypeParam 查看参数 + * @return 系统字典类型 + * @author xuyuxiang,xuyuxiang + * @date 2020/3/31 20:35 + */ + SysDictType detail(SysDictTypeParam sysDictTypeParam); + + /** + * 修改状态(字典 0正常 1停用 2删除) + * + * @param sysDictTypeParam 修改参数 + * @author yubaoshan + * @date 2020/4/30 22:30 + */ + void changeStatus(SysDictTypeParam sysDictTypeParam); + + /** + * 系统字典类型与字典值构造的树 + * + * @return 树 + * @author xuyuxiang + * @date 2020/4/30 22:30 + */ + List tree(); +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/service/impl/SysDictDataServiceImpl.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/service/impl/SysDictDataServiceImpl.java new file mode 100644 index 00000000..22f8a56f --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/service/impl/SysDictDataServiceImpl.java @@ -0,0 +1,258 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.dict.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.lang.Dict; +import cn.hutool.core.util.ObjectUtil; +import com.cn.xiaonuo.core.consts.CommonConstant; +import com.cn.xiaonuo.core.enums.CommonStatusEnum; +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.core.exception.enums.StatusExceptionEnum; +import com.cn.xiaonuo.core.factory.PageFactory; +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.modular.dict.entity.SysDictData; +import com.cn.xiaonuo.sys.modular.dict.enums.SysDictDataExceptionEnum; +import com.cn.xiaonuo.sys.modular.dict.mapper.SysDictDataMapper; +import com.cn.xiaonuo.sys.modular.dict.param.SysDictDataParam; +import com.cn.xiaonuo.sys.modular.dict.service.SysDictDataService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.cn.xiaonuo.sys.modular.dict.mapper.SysDictDataMapper; +import com.cn.xiaonuo.sys.modular.dict.service.SysDictDataService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 系统字典值service接口实现类 + * + * @author xuyuxiang + * @date 2020/3/13 16:11 + */ +@Service +public class SysDictDataServiceImpl extends ServiceImpl implements SysDictDataService { + + @Override + public PageResult page(SysDictDataParam sysDictDataParam) { + + //构造条件 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + if (ObjectUtil.isNotNull(sysDictDataParam)) { + //根据字典类型查询 + if (ObjectUtil.isNotEmpty(sysDictDataParam.getTypeId())) { + queryWrapper.eq(SysDictData::getTypeId, sysDictDataParam.getTypeId()); + } + //根据字典值的编码模糊查询 + if (ObjectUtil.isNotEmpty(sysDictDataParam.getCode())) { + queryWrapper.like(SysDictData::getCode, sysDictDataParam.getCode()); + } + //根据字典值的内容模糊查询 + if (ObjectUtil.isNotEmpty(sysDictDataParam.getValue())) { + queryWrapper.like(SysDictData::getValue, sysDictDataParam.getValue()); + } + } + //查询未删除的 + queryWrapper.ne(SysDictData::getStatus, CommonStatusEnum.DELETED.getCode()); + //根据排序升序排列,序号越小越在前 + queryWrapper.orderByAsc(SysDictData::getSort); + //返回分页查询结果 + return new PageResult<>(this.page(PageFactory.defaultPage(), queryWrapper)); + } + + @Override + public List list(SysDictDataParam sysDictDataParam) { + //构造条件,查询某个字典类型下的 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + if (ObjectUtil.isNotNull(sysDictDataParam)) { + if (ObjectUtil.isNotEmpty(sysDictDataParam.getTypeId())) { + queryWrapper.eq(SysDictData::getTypeId, sysDictDataParam.getTypeId()); + } + } + //查询未删除的 + queryWrapper.ne(SysDictData::getStatus, CommonStatusEnum.DELETED.getCode()); + //根据排序升序排列,序号越小越在前 + queryWrapper.orderByAsc(SysDictData::getSort); + return this.list(queryWrapper); + } + + @Override + public void add(SysDictDataParam sysDictDataParam) { + + //校验参数,检查是否存在重复的编码,不排除当前添加的这条记录 + checkParam(sysDictDataParam, false); + + //将dto转为实体 + SysDictData sysDictData = new SysDictData(); + BeanUtil.copyProperties(sysDictDataParam, sysDictData); + + //设置状态为启用 + sysDictData.setStatus(CommonStatusEnum.ENABLE.getCode()); + + this.save(sysDictData); + } + + @Override + public void delete(SysDictDataParam sysDictDataParam) { + + //根据id查询实体 + SysDictData sysDictData = this.querySysDictData(sysDictDataParam); + + //逻辑删除,修改状态 + sysDictData.setStatus(CommonStatusEnum.DELETED.getCode()); + + //更新实体 + this.updateById(sysDictData); + } + + @Override + public void edit(SysDictDataParam sysDictDataParam) { + + //根据id查询实体 + SysDictData sysDictData = this.querySysDictData(sysDictDataParam); + + //校验参数,检查是否存在重复的编码或者名称,排除当前编辑的这条记录 + checkParam(sysDictDataParam, true); + + //请求参数转化为实体 + BeanUtil.copyProperties(sysDictDataParam, sysDictData); + + //不能修改状态,用修改状态接口修改状态 + sysDictData.setStatus(null); + + this.updateById(sysDictData); + } + + @Override + public SysDictData detail(SysDictDataParam sysDictDataParam) { + return this.querySysDictData(sysDictDataParam); + } + + @Override + public List getDictDataListByDictTypeId(Long dictTypeId) { + + //构造查询条件 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper(); + queryWrapper.eq(SysDictData::getTypeId, dictTypeId).ne(SysDictData::getStatus, CommonStatusEnum.DELETED.getCode()); + //根据排序升序排列,序号越小越在前 + queryWrapper.orderByAsc(SysDictData::getSort); + //查询dictTypeId下所有的字典项 + List results = this.list(queryWrapper); + + //抽取code和value封装到map返回 + List dictList = CollectionUtil.newArrayList(); + results.forEach(sysDictData -> { + Dict dict = Dict.create(); + dict.put(CommonConstant.CODE, sysDictData.getCode()); + dict.put(CommonConstant.VALUE, sysDictData.getValue()); + dictList.add(dict); + }); + + return dictList; + } + + @Override + public void deleteByTypeId(Long typeId) { + //将所有typeId为某值的记录全部置为delete状态 + LambdaUpdateWrapper queryWrapper = new LambdaUpdateWrapper<>(); + queryWrapper.eq(SysDictData::getTypeId, typeId) + .set(SysDictData::getStatus, CommonStatusEnum.DELETED.getCode()); + this.update(queryWrapper); + } + + @Override + public void changeStatus(SysDictDataParam sysDictDataParam) { + //根据id查询实体 + SysDictData sysDictData = this.querySysDictData(sysDictDataParam); + Long id = sysDictData.getId(); + + Integer status = sysDictDataParam.getStatus(); + + //校验状态在不在枚举值里 + CommonStatusEnum.validateStatus(status); + + //更新枚举,更新只能更新未删除状态的 + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.eq(SysDictData::getId, id) + .and(i -> i.ne(SysDictData::getStatus, CommonStatusEnum.DELETED.getCode())) + .set(SysDictData::getStatus, status); + boolean update = this.update(updateWrapper); + if (!update) { + throw new ServiceException(StatusExceptionEnum.UPDATE_STATUS_ERROR); + } + } + + @Override + public List getDictCodesByDictTypeCode(String... dictTypeCodes) { + return this.baseMapper.getDictCodesByDictTypeCode(dictTypeCodes); + } + + /** + * 校验参数,校验是否存在相同的编码 + * + * @author xuyuxiang + * @date 2020/3/31 20:56 + */ + private void checkParam(SysDictDataParam sysDictDataParam, boolean isExcludeSelf) { + Long id = sysDictDataParam.getId(); + Long typeId = sysDictDataParam.getTypeId(); + String code = sysDictDataParam.getCode(); + + //构建带code的查询条件 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysDictData::getTypeId, typeId) + .eq(SysDictData::getCode, code) + .ne(SysDictData::getStatus, CommonStatusEnum.DELETED.getCode()); + + //如果排除自己,则增加查询条件主键id不等于本条id + if (isExcludeSelf) { + queryWrapper.ne(SysDictData::getId, id); + } + + //查询重复记录的数量 + int countByCode = this.count(queryWrapper); + + //如果存在重复的记录,抛出异常,直接返回前端 + if (countByCode >= 1) { + throw new ServiceException(SysDictDataExceptionEnum.DICT_DATA_CODE_REPEAT); + } + } + + /** + * 获取系统字典值 + * + * @author xuyuxiang + * @date 2020/3/31 20:56 + */ + private SysDictData querySysDictData(SysDictDataParam sysDictDataParam) { + SysDictData sysDictData = this.getById(sysDictDataParam.getId()); + if (ObjectUtil.isNull(sysDictData)) { + throw new ServiceException(SysDictDataExceptionEnum.DICT_DATA_NOT_EXIST); + } + return sysDictData; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/service/impl/SysDictTypeServiceImpl.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/service/impl/SysDictTypeServiceImpl.java new file mode 100644 index 00000000..1556da7e --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/dict/service/impl/SysDictTypeServiceImpl.java @@ -0,0 +1,274 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.dict.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.lang.Dict; +import cn.hutool.core.util.ObjectUtil; +import com.cn.xiaonuo.core.enums.CommonStatusEnum; +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.core.exception.enums.StatusExceptionEnum; +import com.cn.xiaonuo.core.factory.PageFactory; +import com.cn.xiaonuo.core.factory.TreeBuildFactory; +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.modular.dict.entity.SysDictData; +import com.cn.xiaonuo.sys.modular.dict.entity.SysDictType; +import com.cn.xiaonuo.sys.modular.dict.enums.SysDictTypeExceptionEnum; +import com.cn.xiaonuo.sys.modular.dict.mapper.SysDictTypeMapper; +import com.cn.xiaonuo.sys.modular.dict.param.SysDictTypeParam; +import com.cn.xiaonuo.sys.modular.dict.result.SysDictTreeNode; +import com.cn.xiaonuo.sys.modular.dict.service.SysDictDataService; +import com.cn.xiaonuo.sys.modular.dict.service.SysDictTypeService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.cn.xiaonuo.sys.modular.dict.entity.SysDictData; +import com.cn.xiaonuo.sys.modular.dict.entity.SysDictType; +import com.cn.xiaonuo.sys.modular.dict.enums.SysDictTypeExceptionEnum; +import com.cn.xiaonuo.sys.modular.dict.mapper.SysDictTypeMapper; +import com.cn.xiaonuo.sys.modular.dict.param.SysDictTypeParam; +import com.cn.xiaonuo.sys.modular.dict.result.SysDictTreeNode; +import com.cn.xiaonuo.sys.modular.dict.service.SysDictDataService; +import com.cn.xiaonuo.sys.modular.dict.service.SysDictTypeService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 系统字典类型service接口实现类 + * + * @author xuyuxiang,xuyuxiang + * @date 2020/3/13 16:11 + */ +@Service +public class SysDictTypeServiceImpl extends ServiceImpl implements SysDictTypeService { + + @Resource + private SysDictDataService sysDictDataService; + + @Override + public PageResult page(SysDictTypeParam sysDictTypeParam) { + + //构造条件 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + + if (ObjectUtil.isNotNull(sysDictTypeParam)) { + //根据字典类型名称模糊查询 + if (ObjectUtil.isNotEmpty(sysDictTypeParam.getName())) { + queryWrapper.like(SysDictType::getName, sysDictTypeParam.getName()); + } + + //根据字典类型编码模糊查询 + if (ObjectUtil.isNotEmpty(sysDictTypeParam.getCode())) { + queryWrapper.like(SysDictType::getCode, sysDictTypeParam.getCode()); + } + } + + //查询未删除的 + queryWrapper.ne(SysDictType::getStatus, CommonStatusEnum.DELETED.getCode()); + //根据排序升序排列,序号越小越在前 + queryWrapper.orderByAsc(SysDictType::getSort); + //查询分页结果 + return new PageResult<>(this.page(PageFactory.defaultPage(), queryWrapper)); + } + + @Override + public List list(SysDictTypeParam sysDictTypeParam) { + + //构造条件 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + + //查询未删除的 + queryWrapper.ne(SysDictType::getStatus, CommonStatusEnum.DELETED.getCode()); + + return this.list(queryWrapper); + } + + @Override + public List dropDown(SysDictTypeParam sysDictTypeParam) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() + .eq(SysDictType::getCode, sysDictTypeParam.getCode()); + + SysDictType sysDictType = this.getOne(queryWrapper); + if (ObjectUtil.isNull(sysDictType)) { + throw new ServiceException(SysDictTypeExceptionEnum.DICT_TYPE_NOT_EXIST); + } + return sysDictDataService.getDictDataListByDictTypeId(sysDictType.getId()); + } + + @Override + public void add(SysDictTypeParam sysDictTypeParam) { + + //校验参数,检查是否存在重复的编码或者名称,不排除当前添加的这条记录 + checkParam(sysDictTypeParam, false); + + //将dto转为实体 + SysDictType sysDictType = new SysDictType(); + BeanUtil.copyProperties(sysDictTypeParam, sysDictType); + + //设置状态为启用 + sysDictType.setStatus(CommonStatusEnum.ENABLE.getCode()); + + this.save(sysDictType); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void delete(SysDictTypeParam sysDictTypeParam) { + + //根据id查询实体 + SysDictType sysDictType = this.querySysDictType(sysDictTypeParam); + + //逻辑删除,修改状态 + sysDictType.setStatus(CommonStatusEnum.DELETED.getCode()); + + //更新实体 + this.updateById(sysDictType); + + //级联删除字典值 + sysDictDataService.deleteByTypeId(sysDictType.getId()); + } + + @Override + public void edit(SysDictTypeParam sysDictTypeParam) { + + //根据id查询实体 + SysDictType sysDictType = this.querySysDictType(sysDictTypeParam); + + //校验参数,检查是否存在重复的编码或者名称,排除当前编辑的这条记录 + checkParam(sysDictTypeParam, true); + + //请求参数转化为实体 + BeanUtil.copyProperties(sysDictTypeParam, sysDictType); + + //不能修改状态,用修改状态接口修改状态 + sysDictType.setStatus(null); + + this.updateById(sysDictType); + } + + @Override + public SysDictType detail(SysDictTypeParam sysDictTypeParam) { + return this.querySysDictType(sysDictTypeParam); + } + + @Override + public void changeStatus(SysDictTypeParam sysDictTypeParam) { + Long id = sysDictTypeParam.getId(); + Integer status = sysDictTypeParam.getStatus(); + + //校验状态在不在枚举值里 + CommonStatusEnum.validateStatus(status); + + //更新枚举,更新只能更新未删除状态的 + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.eq(SysDictType::getId, id) + .and(i -> i.ne(SysDictType::getStatus, CommonStatusEnum.DELETED.getCode())) + .set(SysDictType::getStatus, status); + boolean update = this.update(updateWrapper); + if (!update) { + throw new ServiceException(StatusExceptionEnum.UPDATE_STATUS_ERROR); + } + } + + @Override + public List tree() { + List resultList = CollectionUtil.newArrayList(); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.ne(SysDictType::getStatus, CommonStatusEnum.DELETED.getCode()); + this.list(queryWrapper).forEach(sysDictType -> { + SysDictTreeNode sysDictTreeNode = new SysDictTreeNode(); + BeanUtil.copyProperties(sysDictType, sysDictTreeNode); + sysDictTreeNode.setPid(0L); + resultList.add(sysDictTreeNode); + }); + sysDictDataService.list(new LambdaQueryWrapper().ne(SysDictData::getStatus, CommonStatusEnum.DELETED.getCode())) + .forEach(sysDictData -> { + SysDictTreeNode sysDictTreeNode = new SysDictTreeNode(); + sysDictTreeNode.setId(sysDictData.getId()); + sysDictTreeNode.setPid(sysDictData.getTypeId()); + sysDictTreeNode.setCode(sysDictData.getCode()); + sysDictTreeNode.setName(sysDictData.getValue()); + resultList.add(sysDictTreeNode); + }); + return new TreeBuildFactory().doTreeBuild(resultList); + } + + /** + * 校验参数,检查是否存在重复的编码或者名称 + * + * @author xuyuxiang,xuyuxiang + * @date 2020/3/25 21:23 + */ + private void checkParam(SysDictTypeParam sysDictTypeParam, boolean isExcludeSelf) { + Long id = sysDictTypeParam.getId(); + String name = sysDictTypeParam.getName(); + String code = sysDictTypeParam.getCode(); + + //构建带name和code的查询条件 + LambdaQueryWrapper queryWrapperByName = new LambdaQueryWrapper<>(); + queryWrapperByName.eq(SysDictType::getName, name) + .ne(SysDictType::getStatus, CommonStatusEnum.DELETED.getCode()); + + LambdaQueryWrapper queryWrapperByCode = new LambdaQueryWrapper<>(); + queryWrapperByCode.eq(SysDictType::getCode, code) + .ne(SysDictType::getStatus, CommonStatusEnum.DELETED.getCode()); + + //如果排除自己,则增加查询条件主键id不等于本条id + if (isExcludeSelf) { + queryWrapperByName.ne(SysDictType::getId, id); + queryWrapperByCode.ne(SysDictType::getId, id); + } + + //查询重复记录的数量 + int countByName = this.count(queryWrapperByName); + int countByCode = this.count(queryWrapperByCode); + + //如果存在重复的记录,抛出异常,直接返回前端 + if (countByName >= 1) { + throw new ServiceException(SysDictTypeExceptionEnum.DICT_TYPE_NAME_REPEAT); + } + if (countByCode >= 1) { + throw new ServiceException(SysDictTypeExceptionEnum.DICT_TYPE_CODE_REPEAT); + } + } + + /** + * 获取系统字典类型 + * + * @author xuyuxiang,xuyuxiang + * @date 2020/3/31 20:38 + */ + private SysDictType querySysDictType(SysDictTypeParam sysDictTypeParam) { + SysDictType sysDictType = this.getById(sysDictTypeParam.getId()); + if (ObjectUtil.isNull(sysDictType)) { + throw new ServiceException(SysDictTypeExceptionEnum.DICT_TYPE_NOT_EXIST); + } + return sysDictType; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/email/controler/EmailController.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/email/controler/EmailController.java new file mode 100644 index 00000000..f169ec3a --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/email/controler/EmailController.java @@ -0,0 +1,122 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.email.controler; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.extra.mail.MailException; +import cn.hutool.log.Log; +import com.cn.xiaonuo.core.annotion.BusinessLog; +import com.cn.xiaonuo.core.context.requestno.RequestNoContext; +import com.cn.xiaonuo.core.email.MailSender; +import com.cn.xiaonuo.core.email.modular.model.SendMailParam; +import com.cn.xiaonuo.core.enums.LogAnnotionOpTypeEnum; +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.core.pojo.response.ResponseData; +import com.cn.xiaonuo.core.pojo.response.SuccessResponseData; +import com.cn.xiaonuo.sys.modular.email.enums.SysEmailExceptionEnum; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + * 邮件发送控制器 + * + * @author yubaoshan + * @date 2020/6/9 23:02 + */ +@RestController +public class EmailController { + + private static final Log log = Log.get(); + + @Resource + private MailSender mailSender; + + /** + * 发送邮件 + * + * @author yubaoshan, xuyuxiang + * @date 2020/6/9 23:02 + */ + @PostMapping("/email/sendEmail") + @BusinessLog(title = "发送邮件", opType = LogAnnotionOpTypeEnum.OTHER) + public ResponseData sendEmail(@RequestBody SendMailParam sendMailParam) { + String to = sendMailParam.getTo(); + if (ObjectUtil.isEmpty(to)) { + throw new ServiceException(SysEmailExceptionEnum.EMAIL_TO_EMPTY); + } + + String title = sendMailParam.getTitle(); + if (ObjectUtil.isEmpty(title)) { + throw new ServiceException(SysEmailExceptionEnum.EMAIL_TITLE_EMPTY); + } + + String content = sendMailParam.getContent(); + if (ObjectUtil.isEmpty(content)) { + throw new ServiceException(SysEmailExceptionEnum.EMAIL_CONTENT_EMPTY); + } + try { + mailSender.sendMail(sendMailParam); + } catch (MailException e) { + log.error(">>> 邮件发送异常,请求号为:{},具体信息为:{}", RequestNoContext.get(), e.getMessage()); + throw new ServiceException(SysEmailExceptionEnum.EMAIL_SEND_ERROR); + } + return new SuccessResponseData(); + } + + /** + * 发送邮件(html) + * + * @author yubaoshan, xuyuxiang + * @date 2020/6/9 23:02 + */ + @PostMapping("/email/sendEmailHtml") + @BusinessLog(title = "发送邮件", opType = LogAnnotionOpTypeEnum.OTHER) + public ResponseData sendEmailHtml(@RequestBody SendMailParam sendMailParam) { + String to = sendMailParam.getTo(); + if (ObjectUtil.isEmpty(to)) { + throw new ServiceException(SysEmailExceptionEnum.EMAIL_TO_EMPTY); + } + + String title = sendMailParam.getTitle(); + if (ObjectUtil.isEmpty(title)) { + throw new ServiceException(SysEmailExceptionEnum.EMAIL_TITLE_EMPTY); + } + + String content = sendMailParam.getContent(); + if (ObjectUtil.isEmpty(content)) { + throw new ServiceException(SysEmailExceptionEnum.EMAIL_CONTENT_EMPTY); + } + try { + mailSender.sendMailHtml(sendMailParam); + } catch (MailException e) { + log.error(">>> 邮件发送异常,请求号为:{},具体信息为:{}", RequestNoContext.get(), e.getMessage()); + throw new ServiceException(SysEmailExceptionEnum.EMAIL_SEND_ERROR); + } + return new SuccessResponseData(); + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/email/enums/SysEmailExceptionEnum.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/email/enums/SysEmailExceptionEnum.java new file mode 100644 index 00000000..5141630f --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/email/enums/SysEmailExceptionEnum.java @@ -0,0 +1,80 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.email.enums; + +import com.cn.xiaonuo.core.annotion.ExpEnumType; +import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum; +import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory; +import com.cn.xiaonuo.sys.core.consts.SysExpEnumConstant; + +/** + * 系统应用相关异常枚举 + * + * @author xuyuxiang + * @date 2020/3/26 10:11 + */ +@ExpEnumType(module = SysExpEnumConstant.XIAONUO_SYS_MODULE_EXP_CODE, kind = SysExpEnumConstant.EMAIL_EXCEPTION_ENUM) +public enum SysEmailExceptionEnum implements AbstractBaseExceptionEnum { + + /** + * 收件人为空 + */ + EMAIL_TO_EMPTY(1, "收件人为空,请检查to参数"), + + /** + * 标题为空 + */ + EMAIL_TITLE_EMPTY(2, "标题为空,请检查title参数"), + + /** + * 内容为空 + */ + EMAIL_CONTENT_EMPTY(3, "内容为空,请检查content参数"), + + /** + * 邮件发送失败 + */ + EMAIL_SEND_ERROR(4, "邮件发送失败,请检查发送参数"); + + private final Integer code; + + private final String message; + + SysEmailExceptionEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return ExpEnumCodeFactory.getExpEnumCode(this.getClass(), code); + } + + @Override + public String getMessage() { + return message; + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/entity/SysEmp.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/entity/SysEmp.java new file mode 100644 index 00000000..bdda2022 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/entity/SysEmp.java @@ -0,0 +1,62 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.emp.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * 员工表 + * + * @author xuyuxiang + * @date 2020/3/11 11:20 + */ +@Data +@TableName("sys_emp") +public class SysEmp { + + /** + * 主键 + */ + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + /** + * 工号 + */ + private String jobNum; + + /** + * 所属机构id + */ + private Long orgId; + + /** + * 所属机构名称 + */ + private String orgName; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/entity/SysEmpExtOrgPos.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/entity/SysEmpExtOrgPos.java new file mode 100644 index 00000000..125dc7ef --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/entity/SysEmpExtOrgPos.java @@ -0,0 +1,62 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.emp.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * 员工附属机构职位表 + * + * @author xuyuxiang + * @date 2020/3/11 11:47 + */ +@Data +@TableName("sys_emp_ext_org_pos") +public class SysEmpExtOrgPos { + + /** + * 主键 + */ + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + /** + * 员工id + */ + private Long empId; + + /** + * 机构id + */ + private Long orgId; + + /** + * 职位id + */ + private Long posId; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/entity/SysEmpPos.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/entity/SysEmpPos.java new file mode 100644 index 00000000..3fe216bb --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/entity/SysEmpPos.java @@ -0,0 +1,57 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.emp.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * 员工职位关联表 + * + * @author xuyuxiang + * @date 2020/3/11 11:47 + */ +@Data +@TableName("sys_emp_pos") +public class SysEmpPos { + + /** + * 主键 + */ + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + /** + * 员工id + */ + private Long empId; + + /** + * 职位id + */ + private Long posId; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/mapper/SysEmpExtOrgPosMapper.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/mapper/SysEmpExtOrgPosMapper.java new file mode 100644 index 00000000..2acad935 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/mapper/SysEmpExtOrgPosMapper.java @@ -0,0 +1,37 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.emp.mapper; + +import com.cn.xiaonuo.sys.modular.emp.entity.SysEmpExtOrgPos; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 员工附属机构mapper接口 + * + * @author xuyuxiang + * @date 2020/3/13 15:13 + */ +public interface SysEmpExtOrgPosMapper extends BaseMapper { +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/mapper/SysEmpMapper.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/mapper/SysEmpMapper.java new file mode 100644 index 00000000..ec09356f --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/mapper/SysEmpMapper.java @@ -0,0 +1,37 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.emp.mapper; + +import com.cn.xiaonuo.sys.modular.emp.entity.SysEmp; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 员工mapper接口 + * + * @author xuyuxiang + * @date 2020/3/13 15:13 + */ +public interface SysEmpMapper extends BaseMapper { +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/mapper/SysEmpPosMapper.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/mapper/SysEmpPosMapper.java new file mode 100644 index 00000000..96078706 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/mapper/SysEmpPosMapper.java @@ -0,0 +1,37 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.emp.mapper; + +import com.cn.xiaonuo.sys.modular.emp.entity.SysEmpPos; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 员工职位mapper接口 + * + * @author xuyuxiang + * @date 2020/3/13 15:12 + */ +public interface SysEmpPosMapper extends BaseMapper { +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/mapper/mapping/SysEmpExtOrgPosMapper.xml b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/mapper/mapping/SysEmpExtOrgPosMapper.xml new file mode 100644 index 00000000..8c84de1f --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/mapper/mapping/SysEmpExtOrgPosMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/mapper/mapping/SysEmpMapper.xml b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/mapper/mapping/SysEmpMapper.xml new file mode 100644 index 00000000..a2bd8f42 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/mapper/mapping/SysEmpMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/mapper/mapping/SysEmpPosMapper.xml b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/mapper/mapping/SysEmpPosMapper.xml new file mode 100644 index 00000000..37826507 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/mapper/mapping/SysEmpPosMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/param/SysEmpParam.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/param/SysEmpParam.java new file mode 100644 index 00000000..bec9c45a --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/param/SysEmpParam.java @@ -0,0 +1,79 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.emp.param; + +import cn.hutool.core.lang.Dict; +import com.cn.xiaonuo.core.pojo.base.param.BaseParam; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 员工参数 + * + * @author xuyuxiang + * @date 2020/4/1 19:28 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class SysEmpParam extends BaseParam { + + /** + * 主键 + */ + private Long id; + + /** + * 工号 + */ + private String jobNum; + + /** + * 所属机构id + */ + @NotNull(message = "所属机构id不能为空,请检查sysEmpParam.orgId参数", groups = {add.class, edit.class}) + private Long orgId; + + /** + * 所属机构名称 + */ + @NotBlank(message = "所属机构名称不能为空,请检查sysEmpParam.orgName参数", groups = {add.class, edit.class}) + private String orgName; + + /** + * 附属机构id和附属职位id集合 + */ + @NotNull(message = "附属信息不能为空,请检查sysEmpParam.extIds参数", groups = {add.class, edit.class}) + private List extIds; + + /** + * 职位id集合 + */ + @NotNull(message = "所属职位不能为空,请检查sysEmpParam.posIdList参数", groups = {add.class, edit.class}) + private List posIdList; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/result/SysEmpInfo.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/result/SysEmpInfo.java new file mode 100644 index 00000000..937f1515 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/result/SysEmpInfo.java @@ -0,0 +1,69 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.emp.result; + +import cn.hutool.core.lang.Dict; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 用户员工信息 + * + * @author xuyuxiang + * @date 2020/4/2 20:22 + */ +@Data +public class SysEmpInfo implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 工号 + */ + private String jobNum; + + /** + * 所属机构id + */ + private Long orgId; + + /** + * 所属机构名称 + */ + private String orgName; + + /** + * 附属机构与职位信息 + */ + private List extOrgPos; + + /** + * 职位信息 + */ + private List positions; + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/service/SysEmpExtOrgPosService.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/service/SysEmpExtOrgPosService.java new file mode 100644 index 00000000..164c8e95 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/service/SysEmpExtOrgPosService.java @@ -0,0 +1,90 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.emp.service; + +import cn.hutool.core.lang.Dict; +import com.cn.xiaonuo.sys.modular.emp.entity.SysEmpExtOrgPos; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +/** + * 员工附属机构service接口 + * + * @author xuyuxiang + * @date 2020/3/13 15:10 + */ +public interface SysEmpExtOrgPosService extends IService { + + /** + * 保存或编辑附属机构相关信息 + * + * @param empId 员工id(用户id) + * @param extIdList 附属机构职位信息集合,格式:[{"orgId":1234, "posId":5678}] + * @author xuyuxiang + * @date 2020/4/2 8:59 + */ + void addOrEdit(Long empId, List extIdList); + + /** + * 获取附属机构和职位信息 + * + * @param empId 员工id(用户id) + * @param isFillId 是否需要返回id信息 + * @return 增强版hashMap,格式:[{"orgId":123, "orgCode":"yfb", "orgName":"研发部", "posId":456, "posCode":"zjl", "posName":"总经理"}] + * @author xuyuxiang + * @date 2020/4/2 20:07 + */ + List getEmpExtOrgPosDictList(Long empId, boolean isFillId); + + /** + * 根据机构id判断该附属机构下是否有员工 + * + * @param orgId 机构id + * @return 该附属机构下是否有员工,true是,false否 + * @author xuyuxiang + * @date 2020/6/23 10:30 + */ + boolean hasExtOrgEmp(Long orgId); + + /** + * 根据职位id判断该附属职位下是否有员工 + * + * @param posId 职位id + * @return 该附属职位下是否有员工,true是,false否 + * @author xuyuxiang + * @date 2020/6/23 10:38 + */ + boolean hasExtPosEmp(Long posId); + + /** + * 根据员工id删除对应的员工-附属信息 + * + * @param empId 员工id(用户id) + * @author xuyuxiang + * @date 2020/6/28 14:57 + */ + void deleteEmpExtInfoByUserId(Long empId); +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/service/SysEmpPosService.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/service/SysEmpPosService.java new file mode 100644 index 00000000..63aec3cb --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/service/SysEmpPosService.java @@ -0,0 +1,80 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.emp.service; + +import cn.hutool.core.lang.Dict; +import com.cn.xiaonuo.sys.modular.emp.entity.SysEmpPos; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +/** + * 员工职位service接口 + * + * @author xuyuxiang + * @date 2020/3/13 15:10 + */ +public interface SysEmpPosService extends IService { + + /** + * 保存职位相关信息 + * + * @param empId 员工id(用户id) + * @param posIdList 职位id集合 + * @author xuyuxiang + * @date 2020/4/2 9:00 + */ + void addOrEdit(Long empId, List posIdList); + + /** + * 获取所属职位信息 + * + * @param empId 员工id(用户id) + * @param isFillId 是否需要返回id信息 + * @return 增强版hashMap,格式:[{"posId":456, "posCode":"zjl", "posName":"总经理"}] + * @author xuyuxiang + * @date 2020/4/2 20:07 + */ + List getEmpPosDictList(Long empId, boolean isFillId); + + /** + * 根据职位id判断该职位下是否有员工 + * + * @param posId 职位id + * @return 该职位下是否有员工,true是,false否 + * @author xuyuxiang + * @date 2020/6/23 10:40 + */ + boolean hasPosEmp(Long posId); + + /** + * 根据员工id删除对用的员工-职位信息 + * + * @param empId 员工id(用户id) + * @author xuyuxiang + * @date 2020/6/28 14:58 + */ + void deleteEmpPosInfoByUserId(Long empId); +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/service/SysEmpService.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/service/SysEmpService.java new file mode 100644 index 00000000..25570767 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/service/SysEmpService.java @@ -0,0 +1,100 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.emp.service; + +import com.cn.xiaonuo.core.pojo.login.LoginEmpInfo; +import com.cn.xiaonuo.sys.modular.emp.entity.SysEmp; +import com.cn.xiaonuo.sys.modular.emp.param.SysEmpParam; +import com.cn.xiaonuo.sys.modular.emp.result.SysEmpInfo; +import com.baomidou.mybatisplus.extension.service.IService; +import com.cn.xiaonuo.core.pojo.login.LoginEmpInfo; +import com.cn.xiaonuo.sys.modular.emp.result.SysEmpInfo; + +/** + * 员工service接口 + * + * @author xuyuxiang + * @date 2020/3/13 15:08 + */ +public interface SysEmpService extends IService { + + /** + * 获取登录用户员工相关信息 + * + * @param empId 员工id(用户id) + * @return 登录用户员工相关信息 + * @author xuyuxiang + * @date 2020/3/13 15:23 + */ + LoginEmpInfo getLoginEmpInfo(Long empId); + + /** + * 获取用户员工相关信息 + * + * @param empId 员工id(用户id) + * @return 用户员工相关信息 + * @author xuyuxiang + * @date 2020/4/2 20:33 + */ + SysEmpInfo getSysEmpInfo(Long empId); + + /** + * 增加或编辑员工相关信息 + * + * @param sysEmpParam 增加或编辑参数 + * @author xuyuxiang + * @date 2020/4/2 8:44 + */ + void addOrUpdate(SysEmpParam sysEmpParam); + + /** + * 修改员工相关机构信息 + * + * @param orgId 机构id + * @param orgName 机构名称 + * @author xuyuxiang + * @date 2020/6/23 9:57 + */ + void updateEmpOrgInfo(Long orgId, String orgName); + + /** + * 根据机构id判断该机构下是否有员工 + * + * @param orgId 机构id + * @return 该机构下是否有员工,true是,false否 + * @author xuyuxiang + * @date 2020/6/23 10:30 + */ + boolean hasOrgEmp(Long orgId); + + /** + * 根据员工id删除对应的员工表信息 + * + * @param empId 员工id(用户id) + * @author xuyuxiang + * @date 2020/6/28 14:51 + */ + void deleteEmpInfoByUserId(Long empId); +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/service/impl/SysEmpExtOrgPosPosServiceImpl.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/service/impl/SysEmpExtOrgPosPosServiceImpl.java new file mode 100644 index 00000000..d97acc7d --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/service/impl/SysEmpExtOrgPosPosServiceImpl.java @@ -0,0 +1,157 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.emp.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.lang.Dict; +import com.cn.xiaonuo.sys.modular.emp.entity.SysEmpExtOrgPos; +import com.cn.xiaonuo.sys.modular.emp.mapper.SysEmpExtOrgPosMapper; +import com.cn.xiaonuo.sys.modular.emp.service.SysEmpExtOrgPosService; +import com.cn.xiaonuo.sys.modular.org.entity.SysOrg; +import com.cn.xiaonuo.sys.modular.org.service.SysOrgService; +import com.cn.xiaonuo.sys.modular.pos.entity.SysPos; +import com.cn.xiaonuo.sys.modular.pos.service.SysPosService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 员工附属机构service接口实现类 + * + * @author xuyuxiang + * @date 2020/3/13 15:11 + */ +@Service +public class SysEmpExtOrgPosPosServiceImpl extends ServiceImpl implements SysEmpExtOrgPosService { + + @Resource + private SysOrgService sysOrgService; + + @Resource + private SysPosService sysPosService; + + /** + * 附属机构id参数键 + */ + private static final String EXT_ORG_ID_DICT_KEY = "orgId"; + + /** + * 附属机构编码参数键 + */ + private static final String EXT_ORG_CODE_DICT_KEY = "orgCode"; + + /** + * 附属机构名称参数键 + */ + private static final String EXT_ORG_NAME_DICT_KEY = "orgName"; + + /** + * 附属职位id参数键 + */ + private static final String EXT_POS_ID_DICT_KEY = "posId"; + + /** + * 附属职位编码参数键 + */ + private static final String EXT_POS_CODE_DICT_KEY = "posCode"; + + /** + * 附属职位名称参数键 + */ + private static final String EXT_POS_NAME_DICT_KEY = "posName"; + + @Override + public void addOrEdit(Long empId, List extIdList) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysEmpExtOrgPos::getEmpId, empId); + //删除附属信息 + this.remove(queryWrapper); + //保存附属信息 + extIdList.forEach(dict -> { + Long orgId = dict.getLong(EXT_ORG_ID_DICT_KEY); + Long posId = dict.getLong(EXT_POS_ID_DICT_KEY); + SysEmpExtOrgPos sysEmpExtOrgPos = new SysEmpExtOrgPos(); + sysEmpExtOrgPos.setEmpId(empId); + sysEmpExtOrgPos.setOrgId(orgId); + sysEmpExtOrgPos.setPosId(posId); + this.save(sysEmpExtOrgPos); + }); + } + + @Override + public List getEmpExtOrgPosDictList(Long empId, boolean isFillId) { + List dictList = CollectionUtil.newArrayList(); + + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysEmpExtOrgPos::getEmpId, empId); + + this.list(queryWrapper).forEach(sysEmpExtOrgPos -> { + Dict dict = Dict.create(); + Long orgId = sysEmpExtOrgPos.getOrgId(); + SysOrg sysOrg = sysOrgService.getById(orgId); + dict.put(EXT_ORG_CODE_DICT_KEY, sysOrg.getCode()); + dict.put(EXT_ORG_NAME_DICT_KEY, sysOrg.getName()); + + Long posId = sysEmpExtOrgPos.getPosId(); + SysPos sysPos = sysPosService.getById(posId); + dict.put(EXT_POS_CODE_DICT_KEY, sysPos.getCode()); + dict.put(EXT_POS_NAME_DICT_KEY, sysPos.getName()); + + if (isFillId) { + dict.put(EXT_ORG_ID_DICT_KEY, orgId); + dict.put(EXT_POS_ID_DICT_KEY, posId); + } + dictList.add(dict); + }); + + return dictList; + } + + @Override + public boolean hasExtOrgEmp(Long orgId) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysEmpExtOrgPos::getOrgId, orgId); + List list = this.list(queryWrapper); + return list.size() != 0; + } + + @Override + public boolean hasExtPosEmp(Long posId) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysEmpExtOrgPos::getPosId, posId); + List list = this.list(queryWrapper); + return list.size() != 0; + } + + @Override + public void deleteEmpExtInfoByUserId(Long empId) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysEmpExtOrgPos::getEmpId, empId); + this.remove(queryWrapper); + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/service/impl/SysEmpPosServiceImpl.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/service/impl/SysEmpPosServiceImpl.java new file mode 100644 index 00000000..96d849bc --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/service/impl/SysEmpPosServiceImpl.java @@ -0,0 +1,124 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.emp.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.convert.Convert; +import cn.hutool.core.lang.Dict; +import com.cn.xiaonuo.sys.modular.emp.entity.SysEmpPos; +import com.cn.xiaonuo.sys.modular.emp.mapper.SysEmpPosMapper; +import com.cn.xiaonuo.sys.modular.emp.service.SysEmpPosService; +import com.cn.xiaonuo.sys.modular.pos.entity.SysPos; +import com.cn.xiaonuo.sys.modular.pos.service.SysPosService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.cn.xiaonuo.sys.modular.emp.entity.SysEmpPos; +import com.cn.xiaonuo.sys.modular.emp.mapper.SysEmpPosMapper; +import com.cn.xiaonuo.sys.modular.emp.service.SysEmpPosService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 员工职位service接口实现类 + * + * @author xuyuxiang + * @date 2020/3/13 15:11 + */ +@Service +public class SysEmpPosServiceImpl extends ServiceImpl implements SysEmpPosService { + + @Resource + private SysPosService sysPosService; + + /** + * 职位id参数键 + */ + private static final String POS_ID_DICT_KEY = "posId"; + + /** + * 职位编码参数键 + */ + private static final String POS_CODE_DICT_KEY = "posCode"; + + /** + * 职位名称参数键 + */ + private static final String POS_NAME_DICT_KEY = "posName"; + + @Override + public void addOrEdit(Long empId, List posIdList) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysEmpPos::getEmpId, empId); + + //删除职位信息 + this.remove(queryWrapper); + + //保存职位信息 + posIdList.forEach(posId -> { + SysEmpPos sysEmpPos = new SysEmpPos(); + sysEmpPos.setEmpId(empId); + sysEmpPos.setPosId(Convert.toLong(posId)); + this.save(sysEmpPos); + }); + } + + @Override + public List getEmpPosDictList(Long empId, boolean isFillId) { + List dictList = CollectionUtil.newArrayList(); + + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysEmpPos::getEmpId, empId); + + this.list(queryWrapper).forEach(sysEmpPos -> { + Dict dict = Dict.create(); + Long posId = sysEmpPos.getPosId(); + SysPos sysPos = sysPosService.getById(posId); + if (isFillId) { + dict.put(POS_ID_DICT_KEY, posId); + } + dict.put(POS_CODE_DICT_KEY, sysPos.getCode()); + dict.put(POS_NAME_DICT_KEY, sysPos.getName()); + dictList.add(dict); + }); + return dictList; + } + + @Override + public boolean hasPosEmp(Long posId) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysEmpPos::getPosId, posId); + List list = this.list(queryWrapper); + return list.size() != 0; + } + + @Override + public void deleteEmpPosInfoByUserId(Long empId) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysEmpPos::getEmpId, empId); + this.remove(queryWrapper); + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/service/impl/SysEmpServiceImpl.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/service/impl/SysEmpServiceImpl.java new file mode 100644 index 00000000..6064f0e9 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/emp/service/impl/SysEmpServiceImpl.java @@ -0,0 +1,153 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.emp.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.lang.Dict; +import cn.hutool.core.util.ObjectUtil; +import com.cn.xiaonuo.core.pojo.login.LoginEmpInfo; +import com.cn.xiaonuo.sys.modular.emp.entity.SysEmp; +import com.cn.xiaonuo.sys.modular.emp.mapper.SysEmpMapper; +import com.cn.xiaonuo.sys.modular.emp.param.SysEmpParam; +import com.cn.xiaonuo.sys.modular.emp.result.SysEmpInfo; +import com.cn.xiaonuo.sys.modular.emp.service.SysEmpExtOrgPosService; +import com.cn.xiaonuo.sys.modular.emp.service.SysEmpPosService; +import com.cn.xiaonuo.sys.modular.emp.service.SysEmpService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 员工service接口实现类 + * + * @author xuyuxiang + * @date 2020/3/13 15:10 + */ +@Service +public class SysEmpServiceImpl extends ServiceImpl implements SysEmpService { + + @Resource + private SysEmpExtOrgPosService sysEmpExtOrgPosService; + + @Resource + private SysEmpPosService sysEmpPosService; + + @Override + public LoginEmpInfo getLoginEmpInfo(Long empId) { + + LoginEmpInfo loginEmpInfo = new LoginEmpInfo(); + //获取员工信息 + SysEmp sysEmp = this.getById(empId); + if (ObjectUtil.isNotNull(sysEmp)) { + BeanUtil.copyProperties(sysEmp, loginEmpInfo); + //获取附属机构和职位信息 + List empExtOrgPosDictList = sysEmpExtOrgPosService.getEmpExtOrgPosDictList(sysEmp.getId(), false); + loginEmpInfo.setExtOrgPos(empExtOrgPosDictList); + + //获取所属职位信息 + List empEmpPosDictList = sysEmpPosService.getEmpPosDictList(sysEmp.getId(), false); + loginEmpInfo.setPositions(empEmpPosDictList); + } else { + loginEmpInfo.setExtOrgPos(CollectionUtil.newArrayList()); + loginEmpInfo.setPositions(CollectionUtil.newArrayList()); + } + return loginEmpInfo; + } + + @Override + public SysEmpInfo getSysEmpInfo(Long empId) { + SysEmpInfo sysEmpInfo = new SysEmpInfo(); + //获取员工信息 + SysEmp sysEmp = this.getById(empId); + if (ObjectUtil.isNotNull(sysEmp)) { + BeanUtil.copyProperties(sysEmp, sysEmpInfo); + //获取附属机构和职位信息 + List empExtOrgPosDictList = sysEmpExtOrgPosService.getEmpExtOrgPosDictList(sysEmp.getId(), true); + sysEmpInfo.setExtOrgPos(empExtOrgPosDictList); + + //获取所属职位信息 + List empEmpPosDictList = sysEmpPosService.getEmpPosDictList(sysEmp.getId(), true); + sysEmpInfo.setPositions(empEmpPosDictList); + } else { + sysEmpInfo.setExtOrgPos(CollectionUtil.newArrayList()); + sysEmpInfo.setPositions(CollectionUtil.newArrayList()); + } + return sysEmpInfo; + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void addOrUpdate(SysEmpParam sysEmpParam) { + Long empId = sysEmpParam.getId(); + SysEmp sysEmp = this.getById(empId); + if (ObjectUtil.isNull(sysEmp)) { + sysEmp = new SysEmp(); + } + BeanUtil.copyProperties(sysEmpParam, sysEmp); + this.saveOrUpdate(sysEmp); + //编辑附属机构职位相关信息 + List extIdList = sysEmpParam.getExtIds(); + sysEmpExtOrgPosService.addOrEdit(empId, extIdList); + //编辑职位相关信息 + List posIdList = sysEmpParam.getPosIdList(); + sysEmpPosService.addOrEdit(empId, posIdList); + } + + @Override + public void updateEmpOrgInfo(Long orgId, String orgName) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysEmp::getOrgId, orgId); + this.list(queryWrapper).forEach(sysEmp -> { + sysEmp.setOrgName(orgName); + this.updateById(sysEmp); + }); + } + + @Override + public boolean hasOrgEmp(Long orgId) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysEmp::getOrgId, orgId); + List list = this.list(queryWrapper); + return list.size() != 0; + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void deleteEmpInfoByUserId(Long empId) { + //删除员工信息 + this.removeById(empId); + + //级联删除对应的员工-附属信息 + sysEmpExtOrgPosService.deleteEmpExtInfoByUserId(empId); + + //级联删除对用的员工-职位信息 + sysEmpPosService.deleteEmpPosInfoByUserId(empId); + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/file/controller/SysFileInfoController.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/file/controller/SysFileInfoController.java new file mode 100644 index 00000000..f3f646cd --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/file/controller/SysFileInfoController.java @@ -0,0 +1,142 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.file.controller; + +import com.cn.xiaonuo.core.annotion.BusinessLog; +import com.cn.xiaonuo.core.annotion.Permission; +import com.cn.xiaonuo.core.enums.LogAnnotionOpTypeEnum; +import com.cn.xiaonuo.core.pojo.response.ResponseData; +import com.cn.xiaonuo.core.pojo.response.SuccessResponseData; +import com.cn.xiaonuo.sys.modular.file.param.SysFileInfoParam; +import com.cn.xiaonuo.sys.modular.file.service.SysFileInfoService; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; + +/** + * 文件信息表 控制器 + * + * @author yubaoshan + * @date 2020/6/7 22:15 + */ +@RestController +public class SysFileInfoController { + + @Resource + private SysFileInfoService sysFileInfoService; + + /** + * 上传文件 + * + * @author yubaoshan + * @date 2020/6/7 22:15 + */ + @PostMapping("/sysFileInfo/upload") + @BusinessLog(title = "文件信息表_上传文件", opType = LogAnnotionOpTypeEnum.OTHER) + public ResponseData upload(@RequestPart("file") MultipartFile file) { + Long fileId = sysFileInfoService.uploadFile(file); + return new SuccessResponseData(fileId); + } + + /** + * 下载文件 + * + * @author yubaoshan, xuyuxiang + * @date 2020/6/9 21:53 + */ + @GetMapping("/sysFileInfo/download") + @BusinessLog(title = "文件信息表_下载文件", opType = LogAnnotionOpTypeEnum.OTHER) + public void download(@Validated(SysFileInfoParam.detail.class) SysFileInfoParam sysFileInfoParam, HttpServletResponse response) { + sysFileInfoService.download(sysFileInfoParam, response); + } + + /** + * 文件预览 + * + * @author yubaoshan, xuyuxiang + * @date 2020/6/9 22:07 + */ + @GetMapping("/sysFileInfo/preview") + public void preview(@Validated(SysFileInfoParam.detail.class) SysFileInfoParam sysFileInfoParam, HttpServletResponse response) { + sysFileInfoService.preview(sysFileInfoParam, response); + } + + /** + * 分页查询文件信息表 + * + * @author yubaoshan + * @date 2020/6/7 22:15 + */ + @Permission + @GetMapping("/sysFileInfo/page") + @BusinessLog(title = "文件信息表_分页查询", opType = LogAnnotionOpTypeEnum.QUERY) + public ResponseData page(SysFileInfoParam sysFileInfoParam) { + return new SuccessResponseData(sysFileInfoService.page(sysFileInfoParam)); + } + + /** + * 获取全部文件信息表 + * + * @author yubaoshan + * @date 2020/6/7 22:15 + */ + @Permission + @GetMapping("/sysFileInfo/list") + @BusinessLog(title = "文件信息表_查询所有", opType = LogAnnotionOpTypeEnum.QUERY) + public ResponseData list(SysFileInfoParam sysFileInfoParam) { + return new SuccessResponseData(sysFileInfoService.list(sysFileInfoParam)); + } + + /** + * 查看详情文件信息表 + * + * @author yubaoshan + * @date 2020/6/7 22:15 + */ + @Permission + @GetMapping("/sysFileInfo/detail") + @BusinessLog(title = "文件信息表_查看详情", opType = LogAnnotionOpTypeEnum.DETAIL) + public ResponseData detail(@Validated(SysFileInfoParam.detail.class) SysFileInfoParam sysFileInfoParam) { + return new SuccessResponseData(sysFileInfoService.detail(sysFileInfoParam)); + } + + /** + * 删除文件信息表 + * + * @author yubaoshan + * @date 2020/6/7 22:15 + */ + @Permission + @PostMapping("/sysFileInfo/delete") + @BusinessLog(title = "文件信息表_删除", opType = LogAnnotionOpTypeEnum.DELETE) + public ResponseData delete(@RequestBody @Validated(SysFileInfoParam.delete.class) SysFileInfoParam sysFileInfoParam) { + sysFileInfoService.delete(sysFileInfoParam); + return new SuccessResponseData(); + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/file/entity/SysFileInfo.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/file/entity/SysFileInfo.java new file mode 100644 index 00000000..2b41e180 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/file/entity/SysFileInfo.java @@ -0,0 +1,93 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.file.entity; + +import com.cn.xiaonuo.core.pojo.base.entity.BaseEntity; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * 文件信息表 + *

+ * + * @author yubaoshan + * @date 2020/6/7 22:15 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@TableName("sys_file_info") +public class SysFileInfo extends BaseEntity { + + /** + * 主键id + */ + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + /** + * 文件存储位置(1:阿里云,2:腾讯云,3:minio,4:本地) + */ + private Integer fileLocation; + + /** + * 文件仓库 + */ + private String fileBucket; + + /** + * 文件名称(上传时候的文件名) + */ + private String fileOriginName; + + /** + * 文件后缀 + */ + private String fileSuffix; + + /** + * 文件大小kb + */ + private Long fileSizeKb; + + /** + * 文件大小信息,计算后的 + */ + private String fileSizeInfo; + + /** + * 存储到bucket的名称(文件唯一标识id) + */ + private String fileObjectName; + + /** + * 存储路径 + */ + private String filePath; + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/file/enums/FileLocationEnum.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/file/enums/FileLocationEnum.java new file mode 100644 index 00000000..8a273b14 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/file/enums/FileLocationEnum.java @@ -0,0 +1,64 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.file.enums; + +import lombok.Getter; + +/** + * 文件存储位置 + * + * @author yubaoshan + * @date 2020/6/7 22:24 + */ +@Getter +public enum FileLocationEnum { + + /** + * 阿里云 + */ + ALIYUN(1), + + /** + * 腾讯云 + */ + TENCENT(2), + + /** + * minio服务器 + */ + MINIO(3), + + /** + * 本地 + */ + LOCAL(4); + + private final Integer code; + + FileLocationEnum(int code) { + this.code = code; + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/file/enums/SysFileInfoExceptionEnum.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/file/enums/SysFileInfoExceptionEnum.java new file mode 100644 index 00000000..6562dd7d --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/file/enums/SysFileInfoExceptionEnum.java @@ -0,0 +1,95 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.file.enums; + +import com.cn.xiaonuo.core.annotion.ExpEnumType; +import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum; +import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory; +import com.cn.xiaonuo.sys.core.consts.SysExpEnumConstant; + +/** + * 文件信息表相关枚举 + * + * @author yubaoshan + * @date 2020/6/7 22:15 + */ +@ExpEnumType(module = SysExpEnumConstant.XIAONUO_SYS_MODULE_EXP_CODE, kind = SysExpEnumConstant.SYS_FILE_INFO_EXCEPTION_ENUM) +public enum SysFileInfoExceptionEnum implements AbstractBaseExceptionEnum { + + /** + * 该条记录不存在 + */ + NOT_EXISTED(1, "您查询的该条记录不存在"), + + /** + * 获取文件流错误 + */ + FILE_STREAM_ERROR(2, "获取文件流错误"), + + /** + * 文件不存在 + */ + NOT_EXISTED_FILE(3, "文件不存在"), + + /** + * 获取上传文件异常 + */ + ERROR_FILE(4, "获取上传文件异常"), + + /** + * 下载文件错误 + */ + DOWNLOAD_FILE_ERROR(5, "下载文件错误"), + + /** + * 预览文件异常 + */ + PREVIEW_ERROR_NOT_SUPPORT(6, "预览文件异常,您预览的文件类型不支持或文件出现错误"), + + /** + * 预览文件异常 + */ + PREVIEW_ERROR_LIBREOFFICE(7, "预览文件异常,请检查LibreOffice是否启动"); + + private final Integer code; + + private final String message; + + SysFileInfoExceptionEnum(int code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return ExpEnumCodeFactory.getExpEnumCode(this.getClass(), code); + } + + @Override + public String getMessage() { + return message; + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/file/mapper/SysFileInfoMapper.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/file/mapper/SysFileInfoMapper.java new file mode 100644 index 00000000..e067ee1e --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/file/mapper/SysFileInfoMapper.java @@ -0,0 +1,41 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.file.mapper; + +import com.cn.xiaonuo.sys.modular.file.entity.SysFileInfo; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.cn.xiaonuo.sys.modular.file.entity.SysFileInfo; + +/** + *

+ * 文件信息表 Mapper 接口 + *

+ * + * @author yubaoshan + * @date 2020/6/7 22:15 + */ +public interface SysFileInfoMapper extends BaseMapper { + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/file/mapper/mapping/SysFileInfoMapper.xml b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/file/mapper/mapping/SysFileInfoMapper.xml new file mode 100644 index 00000000..ae77ec7e --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/file/mapper/mapping/SysFileInfoMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/file/param/SysFileInfoParam.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/file/param/SysFileInfoParam.java new file mode 100644 index 00000000..a969a197 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/file/param/SysFileInfoParam.java @@ -0,0 +1,86 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.file.param; + +import com.cn.xiaonuo.core.pojo.base.param.BaseParam; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.NotNull; + +/** + *

+ * 文件信息表 + *

+ * + * @author yubaoshan + * @date 2020/6/7 22:15 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class SysFileInfoParam extends BaseParam { + + /** + * 主键id + */ + @NotNull(message = "id不能为空,请检查id参数", groups = {delete.class, detail.class}) + private Long id; + + /** + * 文件存储位置(1:阿里云,2:腾讯云,3:minio,4:本地) + */ + private Integer fileLocation; + + /** + * 文件仓库 + */ + private String fileBucket; + + /** + * 文件名称(上传时候的文件名) + */ + private String fileOriginName; + + /** + * 文件后缀 + */ + private String fileSuffix; + + /** + * 文件大小kb + */ + private Long fileSizeKb; + + /** + * 存储到bucket的名称(文件唯一标识id) + */ + private String fileObjectName; + + /** + * 存储路径 + */ + private String filePath; + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/file/result/SysFileInfoResult.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/file/result/SysFileInfoResult.java new file mode 100644 index 00000000..65c1a6c5 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/file/result/SysFileInfoResult.java @@ -0,0 +1,83 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.file.result; + +import lombok.Data; + +/** + * 文件信息结果集 + * + * @author yubaoshan + * @date 2020/6/7 22:15 + */ +@Data +public class SysFileInfoResult { + + /** + * 主键id + */ + private Long id; + + /** + * 文件存储位置(1:阿里云,2:腾讯云,3:minio,4:本地) + */ + private Integer fileLocation; + + /** + * 文件仓库 + */ + private String fileBucket; + + /** + * 文件名称(上传时候的文件名) + */ + private String fileOriginName; + + /** + * 文件后缀 + */ + private String fileSuffix; + + /** + * 文件大小kb + */ + private Long fileSizeKb; + + /** + * 存储到bucket的名称(文件唯一标识id) + */ + private String fileObjectName; + + /** + * 存储路径 + */ + private String filePath; + + /** + * 文件的字节 + */ + private byte[] fileBytes; + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/file/service/SysFileInfoService.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/file/service/SysFileInfoService.java new file mode 100644 index 00000000..2e0241d0 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/file/service/SysFileInfoService.java @@ -0,0 +1,150 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.file.service; + +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.modular.file.entity.SysFileInfo; +import com.cn.xiaonuo.sys.modular.file.param.SysFileInfoParam; +import com.cn.xiaonuo.sys.modular.file.result.SysFileInfoResult; +import com.baomidou.mybatisplus.extension.service.IService; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 文件信息表 服务类 + * + * @author yubaoshan + * @date 2020/6/7 22:15 + */ +public interface SysFileInfoService extends IService { + + /** + * 分页查询文件信息表 + * + * @param sysFileInfoParam 查询参数 + * @return 查询分页结果 + * @author yubaoshan + * @date 2020/6/7 22:15 + */ + PageResult page(SysFileInfoParam sysFileInfoParam); + + /** + * 查询所有文件信息表 + * + * @param sysFileInfoParam 查询参数 + * @return 文件信息列表 + * @author yubaoshan + * @date 2020/6/7 22:15 + */ + List list(SysFileInfoParam sysFileInfoParam); + + /** + * 添加文件信息表 + * + * @param sysFileInfoParam 添加参数 + * @author yubaoshan + * @date 2020/6/7 22:15 + */ + void add(SysFileInfoParam sysFileInfoParam); + + /** + * 删除文件信息表 + * + * @param sysFileInfoParam 删除参数 + * @author yubaoshan + * @date 2020/6/7 22:15 + */ + void delete(SysFileInfoParam sysFileInfoParam); + + /** + * 编辑文件信息表 + * + * @param sysFileInfoParam 编辑参数 + * @author yubaoshan + * @date 2020/6/7 22:15 + */ + void edit(SysFileInfoParam sysFileInfoParam); + + /** + * 查看详情文件信息表 + * + * @param sysFileInfoParam 查看参数 + * @return 文件信息 + * @author yubaoshan + * @date 2020/6/7 22:15 + */ + SysFileInfo detail(SysFileInfoParam sysFileInfoParam); + + /** + * 上传文件,返回文件的唯一标识 + * + * @param file 要上传的文件 + * @return 文件id + * @author yubaoshan + * @date 2020/6/9 21:21 + */ + Long uploadFile(MultipartFile file); + + /** + * 获取文件信息结果集 + * + * @param fileId 文件id + * @return 文件信息结果集 + * @author yubaoshan + * @date 2020/6/9 21:56 + */ + SysFileInfoResult getFileInfoResult(Long fileId); + + /** + * 判断文件是否存在 + * + * @param field 文件id + * @author xuyuxiang + * @date 2020/6/28 15:55 + */ + void assertFile(Long field); + + /** + * 文件预览 + * + * @param sysFileInfoParam 文件预览参数 + * @param response 响应结果 + * @author xuyuxiang + * @date 2020/7/7 11:23 + */ + void preview(SysFileInfoParam sysFileInfoParam, HttpServletResponse response); + + /** + * 文件下载 + * + * @param sysFileInfoParam 文件下载参数 + * @param response 响应结果 + * @author xuyuxiang + * @date 2020/7/7 12:09 + */ + void download(SysFileInfoParam sysFileInfoParam, HttpServletResponse response); +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/file/service/impl/SysFileInfoServiceImpl.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/file/service/impl/SysFileInfoServiceImpl.java new file mode 100644 index 00000000..e1dd3d03 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/file/service/impl/SysFileInfoServiceImpl.java @@ -0,0 +1,321 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.file.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.convert.Convert; +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.io.IoUtil; +import cn.hutool.core.util.NumberUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.log.Log; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.IdWorker; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.cn.xiaonuo.core.consts.SymbolConstant; +import com.cn.xiaonuo.core.context.requestno.RequestNoContext; +import com.cn.xiaonuo.core.exception.LibreOfficeException; +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.core.factory.PageFactory; +import com.cn.xiaonuo.core.file.FileOperator; +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.core.util.LibreOfficeUtil; +import com.cn.xiaonuo.sys.modular.file.entity.SysFileInfo; +import com.cn.xiaonuo.sys.modular.file.enums.FileLocationEnum; +import com.cn.xiaonuo.sys.modular.file.enums.SysFileInfoExceptionEnum; +import com.cn.xiaonuo.sys.modular.file.mapper.SysFileInfoMapper; +import com.cn.xiaonuo.sys.modular.file.param.SysFileInfoParam; +import com.cn.xiaonuo.sys.modular.file.result.SysFileInfoResult; +import com.cn.xiaonuo.sys.modular.file.service.SysFileInfoService; +import com.cn.xiaonuo.sys.modular.file.util.DownloadUtil; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.InputStream; +import java.math.BigDecimal; +import java.util.List; + +import static com.cn.xiaonuo.sys.config.FileConfig.DEFAULT_BUCKET; + +/** + * 文件信息表 服务实现类 + * + * @author yubaoshan + * @date 2020/6/7 22:15 + */ +@Service +public class SysFileInfoServiceImpl extends ServiceImpl implements SysFileInfoService { + + private static final Log log = Log.get(); + + @Resource + private FileOperator fileOperator; + + @Override + public PageResult page(SysFileInfoParam sysFileInfoParam) { + + // 构造条件 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + + // 拼接查询条件-文件存储位置(1:阿里云,2:腾讯云,3:minio,4:本地) + if (ObjectUtil.isNotNull(sysFileInfoParam)) { + if (ObjectUtil.isNotEmpty(sysFileInfoParam.getFileLocation())) { + queryWrapper.like(SysFileInfo::getFileLocation, sysFileInfoParam.getFileLocation()); + } + + // 拼接查询条件-文件仓库 + if (ObjectUtil.isNotEmpty(sysFileInfoParam.getFileBucket())) { + queryWrapper.like(SysFileInfo::getFileBucket, sysFileInfoParam.getFileBucket()); + } + + // 拼接查询条件-文件名称(上传时候的文件名) + if (ObjectUtil.isNotEmpty(sysFileInfoParam.getFileOriginName())) { + queryWrapper.like(SysFileInfo::getFileOriginName, sysFileInfoParam.getFileOriginName()); + } + } + + // 查询分页结果 + return new PageResult<>(this.page(PageFactory.defaultPage(), queryWrapper)); + } + + @Override + public List list(SysFileInfoParam sysFileInfoParam) { + + // 构造条件 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + + return this.list(queryWrapper); + } + + @Override + public void add(SysFileInfoParam sysFileInfoParam) { + + // 将dto转为实体 + SysFileInfo sysFileInfo = new SysFileInfo(); + BeanUtil.copyProperties(sysFileInfoParam, sysFileInfo); + + this.save(sysFileInfo); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void delete(SysFileInfoParam sysFileInfoParam) { + + // 查询文件的信息 + SysFileInfo sysFileInfo = this.getById(sysFileInfoParam.getId()); + + // 删除文件记录 + this.removeById(sysFileInfoParam.getId()); + + // 删除具体文件 + this.fileOperator.deleteFile(sysFileInfo.getFileBucket(), sysFileInfo.getFileObjectName()); + } + + @Override + public void edit(SysFileInfoParam sysFileInfoParam) { + + // 根据id查询实体 + SysFileInfo sysFileInfo = this.querySysFileInfo(sysFileInfoParam); + + // 请求参数转化为实体 + BeanUtil.copyProperties(sysFileInfoParam, sysFileInfo); + + this.updateById(sysFileInfo); + } + + @Override + public SysFileInfo detail(SysFileInfoParam sysFileInfoParam) { + return this.querySysFileInfo(sysFileInfoParam); + } + + @Override + public Long uploadFile(MultipartFile file) { + + // 生成文件的唯一id + Long fileId = IdWorker.getId(); + + // 获取文件原始名称 + String originalFilename = file.getOriginalFilename(); + + // 获取文件后缀 + String fileSuffix = null; + + if (ObjectUtil.isNotEmpty(originalFilename)) { + fileSuffix = StrUtil.subAfter(originalFilename, SymbolConstant.PERIOD, true); + } + // 生成文件的最终名称 + String finalName = fileId + SymbolConstant.PERIOD + fileSuffix; + + // 存储文件 + byte[] bytes; + try { + bytes = file.getBytes(); + fileOperator.storageFile(DEFAULT_BUCKET, finalName, bytes); + } catch (IOException e) { + throw new ServiceException(SysFileInfoExceptionEnum.ERROR_FILE); + } + + // 计算文件大小kb + long fileSizeKb = Convert.toLong(NumberUtil.div(new BigDecimal(file.getSize()), BigDecimal.valueOf(1024)) + .setScale(0, BigDecimal.ROUND_HALF_UP)); + + //计算文件大小信息 + String fileSizeInfo = FileUtil.readableFileSize(file.getSize()); + + // 存储文件信息 + SysFileInfo sysFileInfo = new SysFileInfo(); + sysFileInfo.setId(fileId); + sysFileInfo.setFileLocation(FileLocationEnum.LOCAL.getCode()); + sysFileInfo.setFileBucket(DEFAULT_BUCKET); + sysFileInfo.setFileObjectName(finalName); + sysFileInfo.setFileOriginName(originalFilename); + sysFileInfo.setFileSuffix(fileSuffix); + sysFileInfo.setFileSizeKb(fileSizeKb); + sysFileInfo.setFileSizeInfo(fileSizeInfo); + this.save(sysFileInfo); + + // 返回文件id + return fileId; + } + + @Override + public SysFileInfoResult getFileInfoResult(Long fileId) { + byte[] fileBytes; + // 获取文件名 + SysFileInfo sysFileInfo = this.getById(fileId); + if (sysFileInfo == null) { + throw new ServiceException(SysFileInfoExceptionEnum.NOT_EXISTED_FILE); + } + try { + // 返回文件字节码 + fileBytes = fileOperator.getFileBytes(DEFAULT_BUCKET, sysFileInfo.getFileObjectName()); + } catch (Exception e) { + log.error(">>> 获取文件流异常,请求号为:{},具体信息为:{}", RequestNoContext.get(), e.getMessage()); + throw new ServiceException(SysFileInfoExceptionEnum.FILE_STREAM_ERROR); + } + + SysFileInfoResult sysFileInfoResult = new SysFileInfoResult(); + BeanUtil.copyProperties(sysFileInfo, sysFileInfoResult); + sysFileInfoResult.setFileBytes(fileBytes); + + return sysFileInfoResult; + } + + @Override + public void assertFile(Long field) { + SysFileInfo sysFileInfo = this.getById(field); + if (ObjectUtil.isEmpty(sysFileInfo)) { + throw new ServiceException(SysFileInfoExceptionEnum.NOT_EXISTED); + } + } + + @Override + public void preview(SysFileInfoParam sysFileInfoParam, HttpServletResponse response) { + + byte[] fileBytes; + //根据文件id获取文件信息结果集 + SysFileInfoResult sysFileInfoResult = this.getFileInfoResult(sysFileInfoParam.getId()); + //获取文件后缀 + String fileSuffix = sysFileInfoResult.getFileSuffix().toLowerCase(); + //获取文件字节码 + fileBytes = sysFileInfoResult.getFileBytes(); + //如果是图片类型,则直接输出 + if (LibreOfficeUtil.isPic(fileSuffix)) { + try { + //设置contentType + response.setContentType(MediaType.IMAGE_JPEG_VALUE); + //获取outputStream + ServletOutputStream outputStream = response.getOutputStream(); + //输出 + IoUtil.write(outputStream, true, fileBytes); + } catch (IOException e) { + throw new ServiceException(SysFileInfoExceptionEnum.PREVIEW_ERROR_NOT_SUPPORT); + } + + } else if (LibreOfficeUtil.isDoc(fileSuffix)) { + try { + //如果是文档类型,则使用libreoffice转换为pdf或html + InputStream inputStream = IoUtil.toStream(fileBytes); + + //获取目标contentType(word和ppt和text转成pdf,excel转成html) + String targetContentType = LibreOfficeUtil.getTargetContentTypeBySuffix(fileSuffix); + + //设置contentType + response.setContentType(targetContentType); + + //获取outputStream + ServletOutputStream outputStream = response.getOutputStream(); + + //转换 + LibreOfficeUtil.convertToPdf(inputStream, outputStream, fileSuffix); + + //输出 + IoUtil.write(outputStream, true, fileBytes); + } catch (IOException e) { + log.error(">>> 预览文件异常", e.getMessage()); + throw new ServiceException(SysFileInfoExceptionEnum.PREVIEW_ERROR_NOT_SUPPORT); + + } catch (LibreOfficeException e) { + log.error(">>> 初始化LibreOffice失败", e.getMessage()); + throw new ServiceException(SysFileInfoExceptionEnum.PREVIEW_ERROR_LIBREOFFICE); + } + + } else { + //否则不支持预览(暂时) + throw new ServiceException(SysFileInfoExceptionEnum.PREVIEW_ERROR_NOT_SUPPORT); + } + } + + @Override + public void download(SysFileInfoParam sysFileInfoParam, HttpServletResponse response) { + // 获取文件信息结果集 + SysFileInfoResult sysFileInfoResult = this.getFileInfoResult(sysFileInfoParam.getId()); + String fileName = sysFileInfoResult.getFileOriginName(); + byte[] fileBytes = sysFileInfoResult.getFileBytes(); + DownloadUtil.download(fileName, fileBytes, response); + } + + /** + * 获取文件信息表 + * + * @author yubaoshan + * @date 2020/6/7 22:15 + */ + private SysFileInfo querySysFileInfo(SysFileInfoParam sysFileInfoParam) { + SysFileInfo sysFileInfo = this.getById(sysFileInfoParam.getId()); + if (ObjectUtil.isEmpty(sysFileInfo)) { + throw new ServiceException(SysFileInfoExceptionEnum.NOT_EXISTED); + } + return sysFileInfo; + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/file/util/DownloadUtil.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/file/util/DownloadUtil.java new file mode 100644 index 00000000..4faf0fd7 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/file/util/DownloadUtil.java @@ -0,0 +1,65 @@ +package com.cn.xiaonuo.sys.modular.file.util; + +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.io.IoUtil; +import cn.hutool.core.util.CharsetUtil; +import cn.hutool.core.util.URLUtil; +import cn.hutool.log.Log; +import com.cn.xiaonuo.core.context.requestno.RequestNoContext; +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.sys.modular.file.enums.SysFileInfoExceptionEnum; + +import javax.servlet.http.HttpServletResponse; +import java.io.File; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; + +/** + * 文件下载工具类 + * + * @author xuyuxiang + * @date 2020/8/5 21:45 + */ +public class DownloadUtil { + + private static final Log log = Log.get(); + + public static void download(String fileName, byte[] fileBytes, HttpServletResponse response) { + try { + response.reset(); + response.setHeader("Content-Disposition", "attachment; filename=\"" + URLUtil.encode(fileName) + "\""); + response.addHeader("Content-Length", "" + fileBytes.length); + response.setHeader("Access-Control-Allow-Origin", "*"); + response.setHeader("Access-Control-Expose-Headers", "Content-Disposition"); + response.setContentType("application/octet-stream;charset=UTF-8"); + IoUtil.write(response.getOutputStream(), true, fileBytes); + } catch (IOException e) { + log.error(">>> 下载文件异常,请求号为:{},具体信息为:{}", RequestNoContext.get(), e.getMessage()); + throw new ServiceException(SysFileInfoExceptionEnum.DOWNLOAD_FILE_ERROR); + } + } + + /** + * 下载文件 + * + * @param file 要下载的文件 + * @param response 响应 + * @author xuyuxiang + * @date 2020/8/5 21:46 + */ + public static void download(File file, HttpServletResponse response) { + // 获取文件字节 + byte[] fileBytes = FileUtil.readBytes(file); + //获取文件名称 + String fileName; + try { + fileName = URLEncoder.encode(file.getName(), CharsetUtil.UTF_8); + } catch (UnsupportedEncodingException e) { + log.error(">>> 下载文件异常,请求号为:{},具体信息为:{}", RequestNoContext.get(), e.getMessage()); + throw new ServiceException(SysFileInfoExceptionEnum.DOWNLOAD_FILE_ERROR); + } + //下载文件 + download(fileName, fileBytes, response); + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/controller/SysLogController.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/controller/SysLogController.java new file mode 100644 index 00000000..1b0a40b2 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/controller/SysLogController.java @@ -0,0 +1,108 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.log.controller; + +import com.cn.xiaonuo.core.annotion.BusinessLog; +import com.cn.xiaonuo.core.annotion.Permission; +import com.cn.xiaonuo.core.enums.LogAnnotionOpTypeEnum; +import com.cn.xiaonuo.core.pojo.response.ResponseData; +import com.cn.xiaonuo.core.pojo.response.SuccessResponseData; +import com.cn.xiaonuo.sys.modular.log.param.SysOpLogParam; +import com.cn.xiaonuo.sys.modular.log.param.SysVisLogParam; +import com.cn.xiaonuo.sys.modular.log.service.SysOpLogService; +import com.cn.xiaonuo.sys.modular.log.service.SysVisLogService; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + * 系统日志控制器 + * + * @author xuyuxiang + * @date 2020/3/19 21:14 + */ +@RestController +public class SysLogController { + + @Resource + private SysVisLogService sysVisLogService; + + @Resource + private SysOpLogService sysOpLogService; + + /** + * 查询访问日志 + * + * @author xuyuxiang + * @date 2020/3/20 18:52 + */ + @Permission + @GetMapping("/sysVisLog/page") + public ResponseData visLogPage(SysVisLogParam visLogParam) { + return new SuccessResponseData(sysVisLogService.page(visLogParam)); + } + + /** + * 查询操作日志 + * + * @author xuyuxiang + * @date 2020/3/20 18:52 + */ + @Permission + @GetMapping("/sysOpLog/page") + public ResponseData opLogPage(SysOpLogParam sysOpLogParam) { + return new SuccessResponseData(sysOpLogService.page(sysOpLogParam)); + } + + /** + * 清空访问日志 + * + * @author xuyuxiang + * @date 2020/3/23 16:28 + */ + @Permission + @PostMapping("/sysVisLog/delete") + @BusinessLog(title = "访问日志_清空", opType = LogAnnotionOpTypeEnum.CLEAN) + public ResponseData visLogDelete() { + sysVisLogService.delete(); + return new SuccessResponseData(); + } + + /** + * 清空操作日志 + * + * @author xuyuxiang + * @date 2020/3/23 16:28 + */ + @Permission + @PostMapping("/sysOpLog/delete") + @BusinessLog(title = "操作日志_清空", opType = LogAnnotionOpTypeEnum.CLEAN) + public ResponseData opLogDelete() { + sysOpLogService.delete(); + return new SuccessResponseData(); + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/entity/SysOpLog.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/entity/SysOpLog.java new file mode 100644 index 00000000..20ad3b6c --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/entity/SysOpLog.java @@ -0,0 +1,131 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.log.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.util.Date; + +/** + * 系统操作日志表 + * + * @author xuyuxiang + * @date 2020/3/11 11:56 + */ +@Data +@TableName("sys_op_log") +public class SysOpLog { + + /** + * 主键 + */ + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + /** + * 名称 + */ + private String name; + + /** + * 操作类型(见LogAnnotionOpTypeEnum) + */ + private Integer opType; + + /** + * 是否执行成功(Y-是,N-否) + */ + private String success; + + /** + * 具体消息 + */ + private String message; + + /** + * ip + */ + private String ip; + + /** + * 地址 + */ + private String location; + + /** + * 浏览器 + */ + private String browser; + + /** + * 操作系统 + */ + private String os; + + /** + * 请求地址 + */ + private String url; + + /** + * 类名称 + */ + private String className; + + /** + * 方法名称 + */ + private String methodName; + + /** + * 请求方式(GET POST PUT DELETE) + */ + private String reqMethod; + + /** + * 请求参数 + */ + private String param; + + /** + * 返回结果 + */ + private String result; + + /** + * 操作时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date opTime; + + /** + * 操作人 + */ + private String account; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/entity/SysVisLog.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/entity/SysVisLog.java new file mode 100644 index 00000000..427ebca5 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/entity/SysVisLog.java @@ -0,0 +1,101 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.log.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.util.Date; + +/** + * 系统访问日志表 + * + * @author xuyuxiang + * @date 2020/3/11 11:56 + */ +@Data +@TableName("sys_vis_log") +public class SysVisLog { + + /** + * 主键 + */ + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + /** + * 名称 + */ + private String name; + + /** + * 是否执行成功(Y-是,N-否) + */ + private String success; + + /** + * 具体消息 + */ + private String message; + + /** + * ip + */ + private String ip; + + /** + * 地址 + */ + private String location; + + /** + * 浏览器 + */ + private String browser; + + /** + * 操作系统 + */ + private String os; + + /** + * 访问类型(字典 1登入 2登出) + */ + private Integer visType; + + /** + * 访问时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date visTime; + + /** + * 访问人 + */ + private String account; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/mapper/SysOpLogMapper.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/mapper/SysOpLogMapper.java new file mode 100644 index 00000000..6562032a --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/mapper/SysOpLogMapper.java @@ -0,0 +1,37 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.log.mapper; + +import com.cn.xiaonuo.sys.modular.log.entity.SysOpLog; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 系统访问日志mapper + * + * @author xuyuxiang + * @date 2020/3/12 14:24 + */ +public interface SysOpLogMapper extends BaseMapper { +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/mapper/SysVisLogMapper.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/mapper/SysVisLogMapper.java new file mode 100644 index 00000000..96fe7859 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/mapper/SysVisLogMapper.java @@ -0,0 +1,38 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.log.mapper; + +import com.cn.xiaonuo.sys.modular.log.entity.SysVisLog; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.cn.xiaonuo.sys.modular.log.entity.SysVisLog; + +/** + * 系统访问日志mapper + * + * @author xuyuxiang + * @date 2020/3/12 14:25 + */ +public interface SysVisLogMapper extends BaseMapper { +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/mapper/mapping/SysOpLogMapper.xml b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/mapper/mapping/SysOpLogMapper.xml new file mode 100644 index 00000000..b1f84af9 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/mapper/mapping/SysOpLogMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/mapper/mapping/SysVisLogMapper.xml b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/mapper/mapping/SysVisLogMapper.xml new file mode 100644 index 00000000..a6fc1039 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/mapper/mapping/SysVisLogMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/param/SysOpLogParam.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/param/SysOpLogParam.java new file mode 100644 index 00000000..909c308e --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/param/SysOpLogParam.java @@ -0,0 +1,128 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.log.param; + +import com.cn.xiaonuo.core.pojo.base.param.BaseParam; +import com.cn.xiaonuo.core.pojo.base.param.BaseParam; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + * 操作日志参数 + * + * @author xuyuxiang + * @date 2020/3/26 9:16 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class SysOpLogParam extends BaseParam { + + /** + * 主键 + */ + private Long id; + + /** + * 名称 + */ + private String name; + + /** + * 操作类型(0其他 1增加 2删除 3编辑 ...见BasePram的参数校验类型) + */ + private Integer opType; + + /** + * 是否执行成功(Y-是,N-否) + */ + private String success; + + /** + * 具体消息 + */ + private String message; + + /** + * ip + */ + private String ip; + + /** + * 地址 + */ + private String location; + + /** + * 浏览器 + */ + private String browser; + + /** + * 操作系统 + */ + private String os; + + /** + * 请求地址 + */ + private String url; + + /** + * 类名称 + */ + private String className; + + /** + * 方法名称 + */ + private String methodName; + + /** + * 请求方式(GET POST PUT DELETE) + */ + private String reqMethod; + + /** + * 请求参数 + */ + private String param; + + /** + * 返回结果 + */ + private String result; + + /** + * 操作时间 + */ + private Date opTime; + + /** + * 操作人 + */ + private String account; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/param/SysVisLogParam.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/param/SysVisLogParam.java new file mode 100644 index 00000000..8a2b1f70 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/param/SysVisLogParam.java @@ -0,0 +1,97 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.log.param; + +import com.cn.xiaonuo.core.pojo.base.param.BaseParam; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + * 访问日志参数 + * + * @author xuyuxiang + * @date 2020/3/26 9:15 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class SysVisLogParam extends BaseParam { + + /** + * 主键 + */ + private Long id; + + /** + * 名称 + */ + private String name; + + /** + * 是否执行成功(Y-是,N-否) + */ + private String success; + + /** + * 具体消息 + */ + private String message; + + /** + * ip + */ + private String ip; + + /** + * 地址 + */ + private String location; + + /** + * 浏览器 + */ + private String browser; + + /** + * 操作系统 + */ + private String os; + + /** + * 访问类型(字典 1登入 2登出) + */ + private Integer visType; + + /** + * 访问时间 + */ + private Date visTime; + + /** + * 访问人 + */ + private String account; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/service/SysOpLogService.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/service/SysOpLogService.java new file mode 100644 index 00000000..54d36b38 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/service/SysOpLogService.java @@ -0,0 +1,60 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.log.service; + +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.modular.log.entity.SysOpLog; +import com.cn.xiaonuo.sys.modular.log.param.SysOpLogParam; +import com.baomidou.mybatisplus.extension.service.IService; +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.modular.log.entity.SysOpLog; +import com.cn.xiaonuo.sys.modular.log.param.SysOpLogParam; + +/** + * 系统操作日志service接口 + * + * @author xuyuxiang + * @date 2020/3/12 14:21 + */ +public interface SysOpLogService extends IService { + + /** + * 查询系统操作日志 + * + * @param sysOpLogParam 查询参数 + * @return 查询分页结果 + * @author xuyuxiang + * @date 2020/3/30 10:32 + */ + PageResult page(SysOpLogParam sysOpLogParam); + + /** + * 清空系统操作日志 + * + * @author xuyuxiang + * @date 2020/6/1 11:05 + */ + void delete(); +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/service/SysVisLogService.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/service/SysVisLogService.java new file mode 100644 index 00000000..7b70106c --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/service/SysVisLogService.java @@ -0,0 +1,60 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.log.service; + +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.modular.log.entity.SysVisLog; +import com.cn.xiaonuo.sys.modular.log.param.SysVisLogParam; +import com.baomidou.mybatisplus.extension.service.IService; +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.modular.log.entity.SysVisLog; +import com.cn.xiaonuo.sys.modular.log.param.SysVisLogParam; + +/** + * 系统访问日志service接口 + * + * @author xuyuxiang + * @date 2020/3/12 14:20 + */ +public interface SysVisLogService extends IService { + + /** + * 查询系统访问日志 + * + * @param sysVisLogParam 查询参数 + * @return 查询结果集合 + * @author xuyuxiang + * @date 2020/3/24 20:55 + */ + PageResult page(SysVisLogParam sysVisLogParam); + + /** + * 清空系统访问日志 + * + * @author xuyuxiang + * @date 2020/6/1 11:04 + */ + void delete(); +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/service/impl/SysOpLogServiceImpl.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/service/impl/SysOpLogServiceImpl.java new file mode 100644 index 00000000..eb6af694 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/service/impl/SysOpLogServiceImpl.java @@ -0,0 +1,80 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.log.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.cn.xiaonuo.core.factory.PageFactory; +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.modular.log.entity.SysOpLog; +import com.cn.xiaonuo.sys.modular.log.mapper.SysOpLogMapper; +import com.cn.xiaonuo.sys.modular.log.param.SysOpLogParam; +import com.cn.xiaonuo.sys.modular.log.service.SysOpLogService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.cn.xiaonuo.core.factory.PageFactory; +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.modular.log.entity.SysOpLog; +import com.cn.xiaonuo.sys.modular.log.mapper.SysOpLogMapper; +import com.cn.xiaonuo.sys.modular.log.param.SysOpLogParam; +import com.cn.xiaonuo.sys.modular.log.service.SysOpLogService; +import org.springframework.stereotype.Service; + +/** + * 系统操作日志service接口实现类 + * + * @author xuyuxiang + * @date 2020/3/12 14:22 + */ +@Service +public class SysOpLogServiceImpl extends ServiceImpl implements SysOpLogService { + + @Override + public PageResult page(SysOpLogParam sysOpLogParam) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + if (ObjectUtil.isNotNull(sysOpLogParam)) { + //根据名称模糊查询 + if (ObjectUtil.isNotEmpty(sysOpLogParam.getName())) { + queryWrapper.like(SysOpLog::getName, sysOpLogParam.getName()); + } + //根据操作类型查询 + if (ObjectUtil.isNotEmpty(sysOpLogParam.getOpType())) { + queryWrapper.eq(SysOpLog::getOpType, sysOpLogParam.getOpType()); + } + //根据是否成功查询 + if (ObjectUtil.isNotEmpty(sysOpLogParam.getSuccess())) { + queryWrapper.eq(SysOpLog::getSuccess, sysOpLogParam.getSuccess()); + } + } + Page page = this.page(PageFactory.defaultPage(), queryWrapper); + return new PageResult<>(page); + } + + @Override + public void delete() { + this.remove(new QueryWrapper<>()); + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/service/impl/SysVisLogServiceImpl.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/service/impl/SysVisLogServiceImpl.java new file mode 100644 index 00000000..a5ce8b18 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/log/service/impl/SysVisLogServiceImpl.java @@ -0,0 +1,72 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.log.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.cn.xiaonuo.core.factory.PageFactory; +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.modular.log.entity.SysVisLog; +import com.cn.xiaonuo.sys.modular.log.mapper.SysVisLogMapper; +import com.cn.xiaonuo.sys.modular.log.param.SysVisLogParam; +import com.cn.xiaonuo.sys.modular.log.service.SysVisLogService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + * 系统访问日志service接口实现类 + * + * @author xuyuxiang + * @date 2020/3/12 14:23 + */ +@Service +public class SysVisLogServiceImpl extends ServiceImpl implements SysVisLogService { + + @Override + public PageResult page(SysVisLogParam sysVisLogParam) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + if (ObjectUtil.isNotNull(sysVisLogParam)) { + //根据名称模糊查询 + if (ObjectUtil.isNotEmpty(sysVisLogParam.getName())) { + queryWrapper.like(SysVisLog::getName, sysVisLogParam.getName()); + } + //跟据访问类型(字典 1登入 2登出)查询 + if (ObjectUtil.isNotEmpty(sysVisLogParam.getVisType())) { + queryWrapper.eq(SysVisLog::getVisType, sysVisLogParam.getVisType()); + } + //根据是否成功查询 + if (ObjectUtil.isNotEmpty(sysVisLogParam.getSuccess())) { + queryWrapper.eq(SysVisLog::getSuccess, sysVisLogParam.getSuccess()); + } + } + return new PageResult<>(this.page(PageFactory.defaultPage(), queryWrapper)); + } + + @Override + public void delete() { + this.remove(new QueryWrapper<>()); + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/menu/controller/SysMenuController.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/menu/controller/SysMenuController.java new file mode 100644 index 00000000..5555e03e --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/menu/controller/SysMenuController.java @@ -0,0 +1,161 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.menu.controller; + +import com.cn.xiaonuo.core.annotion.BusinessLog; +import com.cn.xiaonuo.core.annotion.Permission; +import com.cn.xiaonuo.core.context.login.LoginContextHolder; +import com.cn.xiaonuo.core.enums.LogAnnotionOpTypeEnum; +import com.cn.xiaonuo.core.pojo.response.ResponseData; +import com.cn.xiaonuo.core.pojo.response.SuccessResponseData; +import com.cn.xiaonuo.sys.modular.menu.param.SysMenuParam; +import com.cn.xiaonuo.sys.modular.menu.service.SysMenuService; +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.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + * 系统菜单控制器 + * + * @author xuyuxiang + * @date 2020/3/20 18:54 + */ +@RestController +public class SysMenuController { + + @Resource + private SysMenuService sysMenuService; + + /** + * 系统菜单列表(树) + * + * @author xuyuxiang + * @date 2020/3/20 21:23 + */ + @Permission + @GetMapping("/sysMenu/list") + @BusinessLog(title = "系统菜单_列表", opType = LogAnnotionOpTypeEnum.QUERY) + public ResponseData list(SysMenuParam sysMenuParam) { + return new SuccessResponseData(sysMenuService.list(sysMenuParam)); + } + + /** + * 添加系统菜单 + * + * @author xuyuxiang + * @date 2020/3/27 8:57 + */ + @Permission + @PostMapping("/sysMenu/add") + @BusinessLog(title = "系统菜单_增加", opType = LogAnnotionOpTypeEnum.ADD) + public ResponseData add(@RequestBody @Validated(SysMenuParam.add.class) SysMenuParam sysMenuParam) { + sysMenuService.add(sysMenuParam); + return new SuccessResponseData(); + } + + /** + * 删除系统菜单 + * + * @author xuyuxiang + * @date 2020/3/27 8:58 + */ + @Permission + @PostMapping("/sysMenu/delete") + @BusinessLog(title = "系统菜单_删除", opType = LogAnnotionOpTypeEnum.DELETE) + public ResponseData delete(@RequestBody @Validated(SysMenuParam.delete.class) SysMenuParam sysMenuParam) { + sysMenuService.delete(sysMenuParam); + return new SuccessResponseData(); + } + + /** + * 编辑系统菜单 + * + * @author xuyuxiang + * @date 2020/3/27 8:59 + */ + @Permission + @PostMapping("/sysMenu/edit") + @BusinessLog(title = "系统菜单_编辑", opType = LogAnnotionOpTypeEnum.EDIT) + public ResponseData edit(@RequestBody @Validated(SysMenuParam.edit.class) SysMenuParam sysMenuParam) { + sysMenuService.edit(sysMenuParam); + return new SuccessResponseData(); + } + + /** + * 查看系统菜单 + * + * @author xuyuxiang + * @date 2020/3/27 9:01 + */ + @Permission + @PostMapping("/sysMenu/detail") + @BusinessLog(title = "系统菜单_查看", opType = LogAnnotionOpTypeEnum.DETAIL) + public ResponseData detail(@Validated(SysMenuParam.detail.class) SysMenuParam sysMenuParam) { + return new SuccessResponseData(sysMenuService.detail(sysMenuParam)); + } + + /** + * 获取系统菜单树,用于新增,编辑时选择上级节点 + * + * @author xuyuxiang + * @date 2020/3/27 15:55 + */ + @Permission + @GetMapping("/sysMenu/tree") + @BusinessLog(title = "系统菜单_树", opType = LogAnnotionOpTypeEnum.TREE) + public ResponseData tree(SysMenuParam sysMenuParam) { + return new SuccessResponseData(sysMenuService.tree(sysMenuParam)); + } + + /** + * 获取系统菜单树,用于给角色授权时选择 + * + * @author xuyuxiang + * @date 2020/4/5 15:00 + */ + @Permission + @GetMapping("/sysMenu/treeForGrant") + @BusinessLog(title = "系统菜单_授权树", opType = LogAnnotionOpTypeEnum.TREE) + public ResponseData treeForGrant(SysMenuParam sysMenuParam) { + return new SuccessResponseData(sysMenuService.treeForGrant(sysMenuParam)); + } + + /** + * 根据系统切换菜单 + * + * @author xuyuxiang + * @date 2020/4/19 15:50 + */ + @PostMapping("/sysMenu/change") + @BusinessLog(title = "系统菜单_切换", opType = LogAnnotionOpTypeEnum.TREE) + public ResponseData change(@RequestBody @Validated(SysMenuParam.change.class) SysMenuParam sysMenuParam) { + Long sysLoginUserId = LoginContextHolder.me().getSysLoginUserId(); + return new SuccessResponseData(sysMenuService.getLoginMenusAntDesign(sysLoginUserId, sysMenuParam.getApplication())); + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/menu/entity/SysMenu.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/menu/entity/SysMenu.java new file mode 100644 index 00000000..5b4ba0f2 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/menu/entity/SysMenu.java @@ -0,0 +1,153 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.menu.entity; + +import com.cn.xiaonuo.core.pojo.base.entity.BaseEntity; +import com.cn.xiaonuo.core.pojo.base.node.BaseTreeNode; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.List; + +/** + * 系统菜单表 + * + * @author xuyuxiang + * @date 2020/3/11 11:20 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@TableName("sys_menu") +public class SysMenu extends BaseEntity implements BaseTreeNode { + + /** + * 主键 + */ + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + /** + * 父id + */ + private Long pid; + + /** + * 父ids + */ + private String pids; + + /** + * 名称 + */ + private String name; + + /** + * 编码 + */ + private String code; + + /** + * 菜单类型(字典 0目录 1菜单 2按钮) + */ + private Integer type; + + /** + * 图标 + */ + private String icon; + + /** + * 路由地址 + */ + private String router; + + /** + * 组件地址 + */ + private String component; + + /** + * 权限标识 + */ + private String permission; + + /** + * 应用分类(应用编码) + */ + private String application; + + /** + * 打开方式(字典 0无 1组件 2内链 3外链) + */ + private Integer openType; + + /** + * 是否可见(Y-是,N-否) + */ + private String visible; + + /** + * 内链地址 + */ + private String link; + + /** + * 重定向地址 + */ + private String redirect; + + /** + * 权重(字典 1系统权重 2业务权重) + */ + private Integer weight; + + /** + * 排序 + */ + private Integer sort; + + /** + * 备注 + */ + @TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED) + private String remark; + + /** + * 状态(字典 0正常 1停用 2删除) + */ + private Integer status; + + /** + * 子节点(表中不存在,用于构造树) + */ + @TableField(exist = false) + private List children; + + @Override + public void setChildren(List children) { + this.children = children; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/menu/enums/SysMenuExceptionEnum.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/menu/enums/SysMenuExceptionEnum.java new file mode 100644 index 00000000..e5747251 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/menu/enums/SysMenuExceptionEnum.java @@ -0,0 +1,115 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.menu.enums; + +import com.cn.xiaonuo.core.annotion.ExpEnumType; +import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum; +import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory; +import com.cn.xiaonuo.sys.core.consts.SysExpEnumConstant; + +/** + * 系统菜单相关异常枚举 + * + * @author xuyuxiang + * @date 2020/3/26 10:12 + */ +@ExpEnumType(module = SysExpEnumConstant.XIAONUO_SYS_MODULE_EXP_CODE, kind = SysExpEnumConstant.SYS_MENU_EXCEPTION_ENUM) +public enum SysMenuExceptionEnum implements AbstractBaseExceptionEnum { + + /** + * 菜单不存在 + */ + MENU_NOT_EXIST(1, "菜单不存在"), + + /** + * 菜单编码重复 + */ + MENU_CODE_REPEAT(2, "菜单编码重复,请检查code参数"), + + /** + * 菜单名称重复 + */ + MENU_NAME_REPEAT(3, "菜单名称重复,请检查name参数"), + + /** + * 路由地址为空 + */ + MENU_ROUTER_EMPTY(4, "路由地址为空,请检查router参数"), + + /** + * 组件地址为空 + */ + MENU_COMPONENT_EMPTY(5, "组件地址为空,请检查component参数"), + + /** + * 打开方式为空 + */ + MENU_OPEN_TYPE_EMPTY(6, "打开方式为空,请检查openType参数"), + + /** + * 权限标识格式为空 + */ + MENU_PERMISSION_EMPTY(7, "权限标识为空,请检查permission参数"), + + /** + * 权限标识格式错误 + */ + MENU_PERMISSION_ERROR(8, "权限标识格式错误,请检查permission参数"), + + /** + * 权限不存在 + */ + MENU_PERMISSION_NOT_EXIST(9, "权限不存在,请检查permission参数"), + + /** + * 不能移动根节点 + */ + CANT_MOVE_APP(10, "父节点不是根节点不能移动应用"), + + /** + * 父级菜单不能为当前节点,请从新选择父级菜单 + */ + PID_CANT_EQ_ID(11, "父级菜单不能为当前节点,请从新选择父级菜单"); + + private final Integer code; + + private final String message; + + SysMenuExceptionEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return ExpEnumCodeFactory.getExpEnumCode(this.getClass(), code); + } + + @Override + public String getMessage() { + return message; + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/menu/mapper/SysMenuMapper.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/menu/mapper/SysMenuMapper.java new file mode 100644 index 00000000..9e249a45 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/menu/mapper/SysMenuMapper.java @@ -0,0 +1,38 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.menu.mapper; + +import com.cn.xiaonuo.sys.modular.menu.entity.SysMenu; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.cn.xiaonuo.sys.modular.menu.entity.SysMenu; + +/** + * 系统菜单mapper接口 + * + * @author xuyuxiang + * @date 2020/3/13 16:05 + */ +public interface SysMenuMapper extends BaseMapper { +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/menu/mapper/mapping/SysMenuMapper.xml b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/menu/mapper/mapping/SysMenuMapper.xml new file mode 100644 index 00000000..e0ce18cf --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/menu/mapper/mapping/SysMenuMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/menu/node/MenuBaseTreeNode.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/menu/node/MenuBaseTreeNode.java new file mode 100644 index 00000000..82018fd6 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/menu/node/MenuBaseTreeNode.java @@ -0,0 +1,86 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.menu.node; + +import com.cn.xiaonuo.core.pojo.base.node.BaseTreeNode; +import lombok.Data; + +import java.util.List; + +/** + * 菜单树节点 + * + * @author xuyuxiang + * @date 2020/4/5 12:03 + */ +@Data +public class MenuBaseTreeNode implements BaseTreeNode { + + /** + * 主键 + */ + private Long id; + + /** + * 父id + */ + private Long parentId; + + /** + * 名称 + */ + private String title; + + /** + * 值 + */ + private String value; + + /** + * 排序,越小优先级越高 + */ + private Integer weight; + + /** + * 子节点 + */ + private List children; + + /** + * 父id别名 + */ + @Override + public Long getPid() { + return this.parentId; + } + + /** + * 子节点 + */ + @Override + public void setChildren(List children) { + this.children = children; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/menu/param/SysMenuParam.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/menu/param/SysMenuParam.java new file mode 100644 index 00000000..148e88ee --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/menu/param/SysMenuParam.java @@ -0,0 +1,148 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.menu.param; + +import com.cn.xiaonuo.core.pojo.base.param.BaseParam; +import com.cn.xiaonuo.core.validation.flag.FlagValue; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 系统菜单参数 + * + * @author xuyuxiang + * @date 2020/3/26 20:42 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class SysMenuParam extends BaseParam { + + /** + * 主键 + */ + @NotNull(message = "id不能为空,请检查id参数", groups = {edit.class, delete.class, detail.class}) + private Long id; + + /** + * 父id + */ + @NotNull(message = "pid不能为空,请检查pid参数", groups = {add.class, edit.class}) + private Long pid; + + /** + * 名称 + */ + @NotBlank(message = "名称不能为空,请检查name参数", groups = {add.class, edit.class}) + private String name; + + /** + * 编码 + */ + @NotBlank(message = "编码不能为空,请检查code参数", groups = {add.class, edit.class}) + private String code; + + /** + * 菜单类型(字典 0目录 1菜单 2按钮) + */ + @NotNull(message = "菜单类型不能为空,请检查type参数", groups = {add.class, edit.class}) + @Min(value = 0, message = "菜单类型格式错误,请检查type参数", groups = {add.class, edit.class}) + @Max(value = 2, message = "菜单类型格式错误,请检查type参数", groups = {add.class, edit.class}) + private Integer type; + + /** + * 图标 + */ + private String icon; + + /** + * 路由地址 + */ + private String router; + + /** + * 组件地址 + */ + private String component; + + /** + * 权限标识 + */ + private String permission; + + /** + * 应用分类(应用编码) + */ + @NotBlank(message = "应用分类不能为空,请检查application参数", groups = {add.class, edit.class, change.class}) + private String application; + + /** + * 打开方式(字典 0无 1组件 2内链 3外链) + */ + @NotNull(message = "打开方式不能为空,请检查openType参数", groups = {add.class, edit.class}) + @Min(value = 0, message = "打开方式格式错误,请检查openType参数", groups = {add.class, edit.class}) + @Max(value = 3, message = "打开方式格式错误,请检查openType参数", groups = {add.class, edit.class}) + private Integer openType; + + /** + * 是否可见(Y-是,N-否) + */ + @NotBlank(message = "是否可见不能为空,请检查visible参数", groups = {add.class, edit.class}) + @FlagValue(message = "是否可见格式错误,正确格式应该Y或者N,请检查visible参数", groups = {add.class, edit.class}) + private String visible; + + /** + * 内链地址 + */ + private String link; + + /** + * 重定向地址 + */ + private String redirect; + + /** + * 权重(字典 1系统权重 2业务权重) + */ + @NotNull(message = "权重不能为空,请检查weight参数", groups = {add.class, edit.class}) + @Min(value = 0, message = "权重格式错误,请检查weight参数", groups = {add.class, edit.class}) + @Max(value = 2, message = "权重格式错误,请检查weight参数", groups = {add.class, edit.class}) + private Integer weight; + + /** + * 排序 + */ + @NotNull(message = "排序不能为空,请检查sort参数", groups = {add.class, edit.class}) + private Integer sort; + + /** + * 备注 + */ + private String remark; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/menu/service/SysMenuService.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/menu/service/SysMenuService.java new file mode 100644 index 00000000..29c2cfb8 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/menu/service/SysMenuService.java @@ -0,0 +1,153 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.menu.service; + +import com.cn.xiaonuo.core.pojo.node.LoginMenuTreeNode; +import com.cn.xiaonuo.sys.modular.menu.entity.SysMenu; +import com.cn.xiaonuo.sys.modular.menu.node.MenuBaseTreeNode; +import com.cn.xiaonuo.sys.modular.menu.param.SysMenuParam; +import com.baomidou.mybatisplus.extension.service.IService; +import com.cn.xiaonuo.sys.modular.menu.entity.SysMenu; +import com.cn.xiaonuo.sys.modular.menu.node.MenuBaseTreeNode; +import com.cn.xiaonuo.sys.modular.menu.param.SysMenuParam; + +import java.util.List; + +/** + * 系统菜单service接口 + * + * @author xuyuxiang + * @date 2020/3/13 16:05 + */ +public interface SysMenuService extends IService { + + /** + * 获取用户权限相关信息 + * + * @param userId 用户id + * @return 权限集合 + * @author xuyuxiang + * @date 2020/3/13 16:26 + */ + List getLoginPermissions(Long userId); + + /** + * 获取用户AntDesign菜单相关信息,前端使用 + * + * @param userId 用户id + * @param appCode 应用编码 + * @return AntDesign菜单信息结果集 + * @author yubaoshan + * @date 2020/4/17 17:48 + */ + List getLoginMenusAntDesign(Long userId, String appCode); + + /** + * 获取用户菜单所属的应用编码集合 + * + * @param userId 用户id + * @return 用户菜单所属的应用编码集合 + * @author xuyuxiang + * @date 2020/3/21 11:01 + */ + List getUserMenuAppCodeList(Long userId); + + /** + * 系统菜单列表(树表) + * + * @param sysMenuParam 查询参数 + * @return 菜单树表列表 + * @author xuyuxiang + * @date 2020/3/26 10:19 + */ + List list(SysMenuParam sysMenuParam); + + /** + * 添加系统菜单 + * + * @param sysMenuParam 添加参数 + * @author xuyuxiang + * @date 2020/3/27 9:03 + */ + void add(SysMenuParam sysMenuParam); + + /** + * 删除系统菜单 + * + * @param sysMenuParam 删除参数 + * @author xuyuxiang + * @date 2020/3/27 9:03 + */ + void delete(SysMenuParam sysMenuParam); + + /** + * 编辑系统菜单 + * + * @param sysMenuParam 编辑参数 + * @author xuyuxiang + * @date 2020/3/27 9:03 + */ + void edit(SysMenuParam sysMenuParam); + + /** + * 查看系统菜单 + * + * @param sysMenuParam 查看参数 + * @return 系统菜单 + * @author xuyuxiang + * @date 2020/3/27 9:03 + */ + SysMenu detail(SysMenuParam sysMenuParam); + + /** + * 获取系统菜单树,用于新增,编辑时选择上级节点 + * + * @param sysMenuParam 查询参数 + * @return 菜单树列表 + * @author xuyuxiang + * @date 2020/3/27 15:56 + */ + List tree(SysMenuParam sysMenuParam); + + /** + * 获取系统菜单树,用于给角色授权时选择 + * + * @param sysMenuParam 查询参数 + * @return 菜单树列表 + * @author xuyuxiang + * @date 2020/4/5 15:01 + */ + List treeForGrant(SysMenuParam sysMenuParam); + + /** + * 根据应用编码判断该机构下是否有状态为正常的菜单 + * + * @param appCode 应用编码 + * @return 该应用下是否有正常菜单,true是,false否 + * @author xuyuxiang + * @date 2020/6/28 12:14 + */ + boolean hasMenu(String appCode); +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/menu/service/impl/SysMenuServiceImpl.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/menu/service/impl/SysMenuServiceImpl.java new file mode 100644 index 00000000..b362e267 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/menu/service/impl/SysMenuServiceImpl.java @@ -0,0 +1,555 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.menu.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.cn.xiaonuo.core.consts.SymbolConstant; +import com.cn.xiaonuo.core.context.login.LoginContextHolder; +import com.cn.xiaonuo.core.enums.CommonStatusEnum; +import com.cn.xiaonuo.core.enums.YesOrNotEnum; +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.core.factory.TreeBuildFactory; +import com.cn.xiaonuo.core.pojo.node.LoginMenuTreeNode; +import com.cn.xiaonuo.sys.core.cache.ResourceCache; +import com.cn.xiaonuo.sys.core.enums.AdminTypeEnum; +import com.cn.xiaonuo.sys.core.enums.MenuOpenTypeEnum; +import com.cn.xiaonuo.sys.core.enums.MenuTypeEnum; +import com.cn.xiaonuo.sys.core.enums.MenuWeightEnum; +import com.cn.xiaonuo.sys.modular.menu.entity.SysMenu; +import com.cn.xiaonuo.sys.modular.menu.enums.SysMenuExceptionEnum; +import com.cn.xiaonuo.sys.modular.menu.mapper.SysMenuMapper; +import com.cn.xiaonuo.sys.modular.menu.node.MenuBaseTreeNode; +import com.cn.xiaonuo.sys.modular.menu.param.SysMenuParam; +import com.cn.xiaonuo.sys.modular.menu.service.SysMenuService; +import com.cn.xiaonuo.sys.modular.role.service.SysRoleMenuService; +import com.cn.xiaonuo.sys.modular.user.entity.SysUser; +import com.cn.xiaonuo.sys.modular.user.service.SysUserRoleService; +import com.cn.xiaonuo.sys.modular.user.service.SysUserService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Set; + +/** + * 系统菜单service接口实现类 + * + * @author xuyuxiang + * @date 2020/3/13 16:05 + */ +@Service +@SuppressWarnings("unchecked") +public class SysMenuServiceImpl extends ServiceImpl implements SysMenuService { + + @Resource + private SysUserService sysUserService; + + @Resource + private SysUserRoleService sysUserRoleService; + + @Resource + private SysRoleMenuService sysRoleMenuService; + + @Resource + private ResourceCache resourceCache; + + @Override + public List getLoginPermissions(Long userId) { + Set permissions = CollectionUtil.newHashSet(); + List roleIdList = sysUserRoleService.getUserRoleIdList(userId); + if (ObjectUtil.isNotEmpty(roleIdList)) { + List menuIdList = sysRoleMenuService.getRoleMenuIdList(roleIdList); + if (ObjectUtil.isNotEmpty(menuIdList)) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + + queryWrapper.in(SysMenu::getId, menuIdList).eq(SysMenu::getType, MenuTypeEnum.BTN.getCode()) + .eq(SysMenu::getStatus, CommonStatusEnum.ENABLE.getCode()); + + this.list(queryWrapper).forEach(sysMenu -> permissions.add(sysMenu.getPermission())); + } + } + return CollectionUtil.newArrayList(permissions); + } + + @Override + public List getLoginMenusAntDesign(Long userId, String appCode) { + List sysMenuList; + //如果是超级管理员则展示所有系统权重菜单,不能展示业务权重菜单 + SysUser sysUser = sysUserService.getById(userId); + Integer adminType = sysUser.getAdminType(); + + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + + if (AdminTypeEnum.SUPER_ADMIN.getCode().equals(adminType)) { + + //查询权重不为业务权重的且类型不是按钮的 + queryWrapper.eq(SysMenu::getStatus, CommonStatusEnum.ENABLE.getCode()) + .eq(SysMenu::getApplication, appCode) + .notIn(SysMenu::getType, MenuTypeEnum.BTN.getCode()) + .notIn(SysMenu::getWeight, MenuWeightEnum.DEFAULT_WEIGHT.getCode()) + .orderByAsc(SysMenu::getSort); + } else { + + //非超级管理员则获取自己角色所拥有的菜单集合 + List roleIdList = sysUserRoleService.getUserRoleIdList(userId); + if (ObjectUtil.isNotEmpty(roleIdList)) { + List menuIdList = sysRoleMenuService.getRoleMenuIdList(roleIdList); + if (ObjectUtil.isNotEmpty(menuIdList)) { + queryWrapper.in(SysMenu::getId, menuIdList) + .eq(SysMenu::getStatus, CommonStatusEnum.ENABLE.getCode()) + .eq(SysMenu::getApplication, appCode) + .notIn(SysMenu::getType, MenuTypeEnum.BTN.getCode()) + .orderByAsc(SysMenu::getSort); + + } else { + //如果角色的菜单为空,则查不到菜单 + return CollectionUtil.newArrayList(); + } + } else { + //如果角色为空,则根本没菜单 + return CollectionUtil.newArrayList(); + } + } + //查询列表 + sysMenuList = this.list(queryWrapper); + //转换成登录菜单 + return this.convertSysMenuToLoginMenu(sysMenuList); + } + + /** + * 将SysMenu格式菜单转换为LoginMenuTreeNode菜单 + * + * @author xuyuxiang + * @date 2020/4/17 17:53 + */ + private List convertSysMenuToLoginMenu(List sysMenuList) { + List antDesignMenuTreeNodeList = CollectionUtil.newArrayList(); + sysMenuList.forEach(sysMenu -> { + LoginMenuTreeNode loginMenuTreeNode = new LoginMenuTreeNode(); + loginMenuTreeNode.setComponent(sysMenu.getComponent()); + loginMenuTreeNode.setId(sysMenu.getId()); + loginMenuTreeNode.setName(sysMenu.getCode()); + loginMenuTreeNode.setPath(sysMenu.getRouter()); + loginMenuTreeNode.setPid(sysMenu.getPid()); + LoginMenuTreeNode.Meta mateItem = new LoginMenuTreeNode().new Meta(); + mateItem.setIcon(sysMenu.getIcon()); + mateItem.setTitle(sysMenu.getName()); + mateItem.setLink(sysMenu.getLink()); + //是否可见 + mateItem.setShow(!YesOrNotEnum.N.getCode().equals(sysMenu.getVisible())); + //设置的首页,默认打开此链接 + loginMenuTreeNode.setRedirect(sysMenu.getRedirect()); + //是否是外链 + if (MenuOpenTypeEnum.OUTER.getCode().equals(sysMenu.getOpenType())) { + //打开外链 + mateItem.setTarget("_blank"); + loginMenuTreeNode.setPath(sysMenu.getLink()); + loginMenuTreeNode.setRedirect(sysMenu.getLink()); + } + loginMenuTreeNode.setMeta(mateItem); + antDesignMenuTreeNodeList.add(loginMenuTreeNode); + }); + return antDesignMenuTreeNodeList; + } + + @Override + public List getUserMenuAppCodeList(Long userId) { + Set appCodeSet = CollectionUtil.newHashSet(); + List roleIdList = sysUserRoleService.getUserRoleIdList(userId); + + if (ObjectUtil.isNotEmpty(roleIdList)) { + List menuIdList = sysRoleMenuService.getRoleMenuIdList(roleIdList); + + if (ObjectUtil.isNotEmpty(menuIdList)) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.in(SysMenu::getId, menuIdList) + .eq(SysMenu::getStatus, CommonStatusEnum.ENABLE.getCode()); + + this.list(queryWrapper).forEach(sysMenu -> appCodeSet.add(sysMenu.getApplication())); + } + } + + return CollectionUtil.newArrayList(appCodeSet); + } + + @Override + public List list(SysMenuParam sysMenuParam) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + if (ObjectUtil.isNotNull(sysMenuParam)) { + //根据所属应用查询 + if (ObjectUtil.isNotEmpty(sysMenuParam.getApplication())) { + queryWrapper.eq(SysMenu::getApplication, sysMenuParam.getApplication()); + } + //根据菜单名称模糊查询 + if (ObjectUtil.isNotEmpty(sysMenuParam.getName())) { + queryWrapper.like(SysMenu::getName, sysMenuParam.getName()); + } + } + queryWrapper.eq(SysMenu::getStatus, CommonStatusEnum.ENABLE.getCode()); + //根据排序升序排列,序号越小越在前 + queryWrapper.orderByAsc(SysMenu::getSort); + List sysMenuList = this.list(queryWrapper); + //将结果集处理成树 + return new TreeBuildFactory().doTreeBuild(sysMenuList); + } + + @Override + public void add(SysMenuParam sysMenuParam) { + // 校验参数 + checkParam(sysMenuParam, false); + + SysMenu sysMenu = new SysMenu(); + BeanUtil.copyProperties(sysMenuParam, sysMenu); + + // 设置新的pid + String newPids = createNewPids(sysMenuParam.getPid()); + sysMenu.setPids(newPids); + + // 设置启用状态 + sysMenu.setStatus(CommonStatusEnum.ENABLE.getCode()); + + this.save(sysMenu); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void delete(SysMenuParam sysMenuParam) { + Long id = sysMenuParam.getId(); + //级联删除子节点 + List childIdList = this.getChildIdListById(id); + childIdList.add(id); + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.in(SysMenu::getId, childIdList) + .set(SysMenu::getStatus, CommonStatusEnum.DELETED.getCode()); + this.update(updateWrapper); + //级联删除该菜单及子菜单对应的角色-菜单表信息 + sysRoleMenuService.deleteRoleMenuListByMenuIdList(childIdList); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void edit(SysMenuParam sysMenuParam) { + + // 校验参数 + checkParam(sysMenuParam, true); + + // 获取修改的菜单的旧数据(库中的) + SysMenu oldMenu = this.querySysMenu(sysMenuParam); + + // 本菜单旧的pids + Long oldPid = oldMenu.getPid(); + String oldPids = oldMenu.getPids(); + + // 生成新的pid和pids + Long newPid = sysMenuParam.getPid(); + String newPids = this.createNewPids(sysMenuParam.getPid()); + + // 是否更新子应用的标识 + boolean updateSubAppsFlag = false; + + // 是否更新子节点的pids的标识 + boolean updateSubPidsFlag = false; + + // 如果应用有变化 + if (!sysMenuParam.getApplication().equals(oldMenu.getApplication())) { + // 父节点不是根节点不能移动应用 + if (!oldPid.equals(0L)) { + throw new ServiceException(SysMenuExceptionEnum.CANT_MOVE_APP); + } + updateSubAppsFlag = true; + } + + // 父节点有变化 + if (!newPid.equals(oldPid)) { + updateSubPidsFlag = true; + } + + // 开始更新所有子节点的配置 + if (updateSubAppsFlag || updateSubPidsFlag) { + + // 查找所有叶子节点,包含子节点的子节点 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.like(SysMenu::getPids, oldMenu.getId()); + List list = this.list(queryWrapper); + + // 更新所有子节点的应用为当前菜单的应用 + if (ObjectUtil.isNotEmpty(list)) { + + // 更新所有子节点的application + if (updateSubAppsFlag) { + list.forEach(child -> child.setApplication(sysMenuParam.getApplication())); + } + // 更新所有子节点的pids + if (updateSubPidsFlag) { + list.forEach(child -> { + // 子节点pids组成 = 当前菜单新pids + 当前菜单id + 子节点自己的pids后缀 + String oldParentCodesPrefix = oldPids + SymbolConstant.LEFT_SQUARE_BRACKETS + oldMenu.getId() + + SymbolConstant.RIGHT_SQUARE_BRACKETS + SymbolConstant.COMMA; + String oldParentCodesSuffix = child.getPids().substring(oldParentCodesPrefix.length()); + String menuParentCodes = newPids + SymbolConstant.LEFT_SQUARE_BRACKETS + oldMenu.getId() + + SymbolConstant.RIGHT_SQUARE_BRACKETS + SymbolConstant.COMMA + oldParentCodesSuffix; + child.setPids(menuParentCodes); + }); + } + + this.updateBatchById(list); + } + } + + // 拷贝参数到实体中 + BeanUtil.copyProperties(sysMenuParam, oldMenu); + + // 设置新的pids + oldMenu.setPids(newPids); + //不能修改状态,用修改状态接口修改状态 + oldMenu.setStatus(null); + this.updateById(oldMenu); + } + + @Override + public SysMenu detail(SysMenuParam sysMenuParam) { + return this.querySysMenu(sysMenuParam); + } + + @Override + public List tree(SysMenuParam sysMenuParam) { + List menuTreeNodeList = CollectionUtil.newArrayList(); + + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + + if (ObjectUtil.isNotNull(sysMenuParam)) { + if (ObjectUtil.isNotEmpty(sysMenuParam.getApplication())) { + queryWrapper.eq(SysMenu::getApplication, sysMenuParam.getApplication()); + } + } + queryWrapper.eq(SysMenu::getStatus, CommonStatusEnum.ENABLE.getCode()) + .in(SysMenu::getType, CollectionUtil.newArrayList(MenuTypeEnum.DIR.getCode(), MenuTypeEnum.MENU.getCode())); + //根据排序升序排列,序号越小越在前 + queryWrapper.orderByAsc(SysMenu::getSort); + this.list(queryWrapper).forEach(sysMenu -> { + MenuBaseTreeNode menuTreeNode = new MenuBaseTreeNode(); + menuTreeNode.setId(sysMenu.getId()); + menuTreeNode.setParentId(sysMenu.getPid()); + menuTreeNode.setValue(String.valueOf(sysMenu.getId())); + menuTreeNode.setTitle(sysMenu.getName()); + menuTreeNode.setWeight(sysMenu.getSort()); + menuTreeNodeList.add(menuTreeNode); + }); + return new TreeBuildFactory().doTreeBuild(menuTreeNodeList); + } + + @Override + public List treeForGrant(SysMenuParam sysMenuParam) { + List menuTreeNodeList = CollectionUtil.newArrayList(); + + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + //根据应用查询 + if (ObjectUtil.isNotNull(sysMenuParam)) { + if (ObjectUtil.isNotEmpty(sysMenuParam.getApplication())) { + queryWrapper.eq(SysMenu::getApplication, sysMenuParam.getApplication()); + } + } + //如果是超级管理员给角色授权菜单时可选择所有菜单 + if (LoginContextHolder.me().isSuperAdmin()) { + queryWrapper.eq(SysMenu::getStatus, CommonStatusEnum.ENABLE.getCode()); + } else { + //非超级管理员则获取自己拥有的菜单,分配给人员,防止越级授权 + Long userId = LoginContextHolder.me().getSysLoginUserId(); + List roleIdList = sysUserRoleService.getUserRoleIdList(userId); + if (ObjectUtil.isNotEmpty(roleIdList)) { + List menuIdList = sysRoleMenuService.getRoleMenuIdList(roleIdList); + if (ObjectUtil.isNotEmpty(menuIdList)) { + queryWrapper.in(SysMenu::getId, menuIdList) + .eq(SysMenu::getStatus, CommonStatusEnum.ENABLE.getCode()); + } else { + //如果角色的菜单为空,则查不到菜单 + return CollectionUtil.newArrayList(); + } + } else { + //如果角色为空,则根本没菜单 + return CollectionUtil.newArrayList(); + } + } + //根据排序升序排列,序号越小越在前 + queryWrapper.orderByAsc(SysMenu::getSort); + this.list(queryWrapper).forEach(sysMenu -> { + MenuBaseTreeNode menuTreeNode = new MenuBaseTreeNode(); + menuTreeNode.setId(sysMenu.getId()); + menuTreeNode.setParentId(sysMenu.getPid()); + menuTreeNode.setValue(String.valueOf(sysMenu.getId())); + menuTreeNode.setTitle(sysMenu.getName()); + menuTreeNode.setWeight(sysMenu.getSort()); + menuTreeNodeList.add(menuTreeNode); + }); + return new TreeBuildFactory().doTreeBuild(menuTreeNodeList); + } + + @Override + public boolean hasMenu(String appCode) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysMenu::getApplication, appCode) + .ne(SysMenu::getStatus, CommonStatusEnum.DELETED.getCode()); + return this.list(queryWrapper).size() != 0; + } + + /** + * 校验参数 + * + * @author xuyuxiang + * @date 2020/3/27 9:15 + */ + private void checkParam(SysMenuParam sysMenuParam, boolean isExcludeSelf) { + //菜单类型(字典 0目录 1菜单 2按钮) + Integer type = sysMenuParam.getType(); + + String router = sysMenuParam.getRouter(); + + String permission = sysMenuParam.getPermission(); + + Integer openType = sysMenuParam.getOpenType(); + + if (MenuTypeEnum.DIR.getCode().equals(type)) { + if (ObjectUtil.isEmpty(router)) { + throw new ServiceException(SysMenuExceptionEnum.MENU_ROUTER_EMPTY); + } + } + + if (MenuTypeEnum.MENU.getCode().equals(type)) { + if (ObjectUtil.isEmpty(router)) { + throw new ServiceException(SysMenuExceptionEnum.MENU_ROUTER_EMPTY); + } + if (ObjectUtil.isEmpty(openType)) { + throw new ServiceException(SysMenuExceptionEnum.MENU_OPEN_TYPE_EMPTY); + } + } + + if (MenuTypeEnum.BTN.getCode().equals(type)) { + if (ObjectUtil.isEmpty(permission)) { + throw new ServiceException(SysMenuExceptionEnum.MENU_PERMISSION_EMPTY); + } else { + Set urlSet = resourceCache.getAllResources(); + + if (!permission.contains(SymbolConstant.COLON)) { + throw new ServiceException(SysMenuExceptionEnum.MENU_PERMISSION_ERROR); + } + permission = SymbolConstant.COLON + permission; + if (!urlSet.contains(permission.replaceAll(SymbolConstant.COLON, SymbolConstant.LEFT_DIVIDE))) { + throw new ServiceException(SysMenuExceptionEnum.MENU_PERMISSION_NOT_EXIST); + } + } + } + + // 如果是编辑菜单时候,pid和id不能一致,一致会导致无限递归 + if (isExcludeSelf) { + if (sysMenuParam.getId().equals(sysMenuParam.getPid())) { + throw new ServiceException(SysMenuExceptionEnum.PID_CANT_EQ_ID); + } + } + + Long id = sysMenuParam.getId(); + String name = sysMenuParam.getName(); + String code = sysMenuParam.getCode(); + + LambdaQueryWrapper queryWrapperByName = new LambdaQueryWrapper<>(); + queryWrapperByName.eq(SysMenu::getName, name) + .ne(SysMenu::getStatus, CommonStatusEnum.DELETED.getCode()); + + LambdaQueryWrapper queryWrapperByCode = new LambdaQueryWrapper<>(); + queryWrapperByCode.eq(SysMenu::getCode, code) + .ne(SysMenu::getStatus, CommonStatusEnum.DELETED.getCode()); + + if (isExcludeSelf) { + queryWrapperByName.ne(SysMenu::getId, id); + queryWrapperByCode.ne(SysMenu::getId, id); + } + int countByName = this.count(queryWrapperByName); + int countByCode = this.count(queryWrapperByCode); + + if (countByName >= 1) { + throw new ServiceException(SysMenuExceptionEnum.MENU_NAME_REPEAT); + } + if (countByCode >= 1) { + throw new ServiceException(SysMenuExceptionEnum.MENU_CODE_REPEAT); + } + } + + /** + * 获取系统菜单 + * + * @author xuyuxiang + * @date 2020/3/27 9:13 + */ + private SysMenu querySysMenu(SysMenuParam sysMenuParam) { + SysMenu sysMenu = this.getById(sysMenuParam.getId()); + if (ObjectUtil.isNull(sysMenu)) { + throw new ServiceException(SysMenuExceptionEnum.MENU_NOT_EXIST); + } + return sysMenu; + } + + /** + * 创建pids的值 + *

+ * 如果pid是0顶级节点,pids就是 [0], + *

+ * 如果pid不是顶级节点,pids就是 pid菜单的pids + [pid] + , + * + * @author xuyuxiang + * @date 2020/3/26 11:28 + */ + private String createNewPids(Long pid) { + if (pid.equals(0L)) { + return SymbolConstant.LEFT_SQUARE_BRACKETS + 0 + SymbolConstant.RIGHT_SQUARE_BRACKETS + + SymbolConstant.COMMA; + } else { + //获取父菜单 + SysMenu parentMenu = this.getById(pid); + return parentMenu.getPids() + + SymbolConstant.LEFT_SQUARE_BRACKETS + pid + SymbolConstant.RIGHT_SQUARE_BRACKETS + + SymbolConstant.COMMA; + } + } + + /** + * 根据节点id获取所有子节点id集合 + * + * @author xuyuxiang + * @date 2020/3/26 11:31 + */ + private List getChildIdListById(Long id) { + List childIdList = CollectionUtil.newArrayList(); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.like(SysMenu::getPids, SymbolConstant.LEFT_SQUARE_BRACKETS + id + + SymbolConstant.RIGHT_SQUARE_BRACKETS); + this.list(queryWrapper).forEach(sysMenu -> childIdList.add(sysMenu.getId())); + return childIdList; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/monitor/controller/SysMachineController.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/monitor/controller/SysMachineController.java new file mode 100644 index 00000000..8b364324 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/monitor/controller/SysMachineController.java @@ -0,0 +1,60 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.monitor.controller; + +import com.cn.xiaonuo.core.annotion.BusinessLog; +import com.cn.xiaonuo.core.enums.LogAnnotionOpTypeEnum; +import com.cn.xiaonuo.core.pojo.response.ResponseData; +import com.cn.xiaonuo.core.pojo.response.SuccessResponseData; +import com.cn.xiaonuo.sys.modular.monitor.service.SysMachineService; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + * 系统属性监控控制器 + * + * @author xuyuxiang + * @date 2020/6/5 14:36 + */ +@RestController +public class SysMachineController { + + @Resource + private SysMachineService sysMachineService; + + /** + * 系统属性监控 + * + * @author xuyuxiang + * @date 2020/6/5 14:38 + */ + @GetMapping("/sysMachine/query") + @BusinessLog(title = "系统属性监控_查询", opType = LogAnnotionOpTypeEnum.QUERY) + public ResponseData query() { + return new SuccessResponseData(sysMachineService.query()); + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/monitor/controller/SysOnlineUserController.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/monitor/controller/SysOnlineUserController.java new file mode 100644 index 00000000..a3954d22 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/monitor/controller/SysOnlineUserController.java @@ -0,0 +1,81 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.monitor.controller; + +import com.cn.xiaonuo.core.annotion.BusinessLog; +import com.cn.xiaonuo.core.annotion.Permission; +import com.cn.xiaonuo.core.enums.LogAnnotionOpTypeEnum; +import com.cn.xiaonuo.core.pojo.response.ResponseData; +import com.cn.xiaonuo.core.pojo.response.SuccessResponseData; +import com.cn.xiaonuo.sys.modular.monitor.param.SysOnlineUserParam; +import com.cn.xiaonuo.sys.modular.monitor.service.SysOnlineUserService; +import com.cn.xiaonuo.sys.modular.monitor.service.SysOnlineUserService; +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.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + * 在线用户控制器 + * + * @author xuyuxiang + * @date 2020/4/7 16:57 + */ +@RestController +public class SysOnlineUserController { + + @Resource + private SysOnlineUserService sysOnlineUserService; + + /** + * 在线用户列表 + * + * @author xuyuxiang + * @date 2020/4/7 16:58 + */ + @Permission + @GetMapping("/sysOnlineUser/list") + @BusinessLog(title = "系统在线用户_列表", opType = LogAnnotionOpTypeEnum.QUERY) + public ResponseData list(SysOnlineUserParam sysOnlineUserParam) { + return new SuccessResponseData(sysOnlineUserService.list(sysOnlineUserParam)); + } + + /** + * 在线用户强退 + * + * @author xuyuxiang + * @date 2020/4/7 17:36 + */ + @Permission + @PostMapping("/sysOnlineUser/forceExist") + @BusinessLog(title = "系统在线用户_强退", opType = LogAnnotionOpTypeEnum.FORCE) + public ResponseData forceExist(@RequestBody @Validated(SysOnlineUserParam.force.class) SysOnlineUserParam sysOnlineUserParam) { + sysOnlineUserService.forceExist(sysOnlineUserParam); + return new SuccessResponseData(); + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/monitor/param/SysOnlineUserParam.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/monitor/param/SysOnlineUserParam.java new file mode 100644 index 00000000..4a607557 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/monitor/param/SysOnlineUserParam.java @@ -0,0 +1,83 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.monitor.param; + +import com.cn.xiaonuo.core.pojo.base.param.BaseParam; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.NotEmpty; + +/** + * 系统在线用户参数 + * + * @author xuyuxiang + * @date 2020/4/7 17:38 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class SysOnlineUserParam extends BaseParam { + + /** + * 会话id + */ + @NotEmpty(message = "sessionId不能为空,请检查sessionId参数", groups = {force.class}) + private String sessionId; + + /** + * 账号 + */ + private String account; + + /** + * 昵称 + */ + private String nickName; + + /** + * 最后登陆IP + */ + private String lastLoginIp; + + /** + * 最后登陆时间 + */ + private String lastLoginTime; + + /** + * 最后登陆地址 + */ + private String lastLoginAddress; + + /** + * 最后登陆所用浏览器 + */ + private String lastLoginBrowser; + + /** + * 最后登陆所用系统 + */ + private String lastLoginOs; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/monitor/result/SysMachineResult.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/monitor/result/SysMachineResult.java new file mode 100644 index 00000000..97e22ecf --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/monitor/result/SysMachineResult.java @@ -0,0 +1,172 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.monitor.result; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 系统属性结果集 + * + * @author xuyuxiang + * @date 2020/6/5 15:02 + */ +@Data +public class SysMachineResult implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 系统信息 + */ + private SysOsInfo sysOsInfo; + + /** + * Java信息 + */ + private SysJavaInfo sysJavaInfo; + + /** + * JVM内存信息 + */ + private SysJvmMemInfo sysJvmMemInfo; + + /** + * 系统信息内部类 + * + * @author xuyuxiang + * @date 2020/6/5 15:19 + */ + @NoArgsConstructor + @Data + public static class SysOsInfo { + + /** + * 系统名称 + */ + private String osName; + + /** + * 系统架构 + */ + private String osArch; + + /** + * 系统版本 + */ + private String osVersion; + + /** + * 主机名称 + */ + private String osHostName; + + /** + * 主机ip地址 + */ + private String osHostAddress; + + } + + /** + * JVM信息内部类 + * + * @author xuyuxiang + * @date 2020/6/5 15:19 + */ + @NoArgsConstructor + @Data + public static class SysJavaInfo { + + /** + * 虚拟机名称 + */ + private String jvmName; + + /** + * 虚拟机版本 + */ + private String jvmVersion; + + /** + * 虚拟机供应商 + */ + private String jvmVendor; + + /** + * java名称 + */ + private String javaName; + + /** + * java版本 + */ + private String javaVersion; + + } + + /** + * JVM内存信息 + * + * @author xuyuxiang + * @date 2020/6/5 15:19 + */ + @NoArgsConstructor + @Data + public static class SysJvmMemInfo { + + /** + * 最大内存 + */ + private String jvmMaxMemory; + + /** + * 可用内存 + */ + private String jvmUsableMemory; + + /** + * 总内存 + */ + private String jvmTotalMemory; + + /** + * 已使用内存 + */ + private String jvmUsedMemory; + + /** + * 空余内存 + */ + private String jvmFreeMemory; + + /** + * 使用率 + */ + private String jvmMemoryUsedRate; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/monitor/result/SysOnlineUserResult.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/monitor/result/SysOnlineUserResult.java new file mode 100644 index 00000000..64ff5b95 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/monitor/result/SysOnlineUserResult.java @@ -0,0 +1,81 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.monitor.result; + +import lombok.Data; + +import java.io.Serializable; + +/** + * 系统在线用户结果集 + * + * @author xuyuxiang + * @date 2020/4/7 17:07 + */ +@Data +public class SysOnlineUserResult implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 会话id + */ + private String sessionId; + + /** + * 账号 + */ + private String account; + + /** + * 昵称 + */ + private String nickName; + + /** + * 最后登陆IP + */ + private String lastLoginIp; + + /** + * 最后登陆时间 + */ + private String lastLoginTime; + + /** + * 最后登陆地址 + */ + private String lastLoginAddress; + + /** + * 最后登陆所用浏览器 + */ + private String lastLoginBrowser; + + /** + * 最后登陆所用系统 + */ + private String lastLoginOs; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/monitor/service/SysMachineService.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/monitor/service/SysMachineService.java new file mode 100644 index 00000000..797f8ef7 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/monitor/service/SysMachineService.java @@ -0,0 +1,46 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.monitor.service; + +import com.cn.xiaonuo.sys.modular.monitor.result.SysMachineResult; +import com.cn.xiaonuo.sys.modular.monitor.result.SysMachineResult; + +/** + * 系统属性监控service接口 + * + * @author xuyuxiang + * @date 2020/6/5 14:39 + */ +public interface SysMachineService { + + /** + * 系统属性监控 + * + * @return 系统属性结果集 + * @author xuyuxiang + * @date 2020/6/5 14:45 + */ + SysMachineResult query(); +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/monitor/service/SysOnlineUserService.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/monitor/service/SysOnlineUserService.java new file mode 100644 index 00000000..79b6aa4b --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/monitor/service/SysOnlineUserService.java @@ -0,0 +1,58 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.monitor.service; + +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.modular.monitor.param.SysOnlineUserParam; +import com.cn.xiaonuo.sys.modular.monitor.result.SysOnlineUserResult; +import com.cn.xiaonuo.sys.modular.monitor.result.SysOnlineUserResult; + +/** + * 系统在线用户service接口 + * + * @author xuyuxiang + * @date 2020/4/7 17:06 + */ +public interface SysOnlineUserService { + + /** + * 系统在线用户列表 + * + * @param sysOnlineUserParam 查询参数 + * @return 在线用户列表 + * @author xuyuxiang + * @date 2020/4/7 17:09 + */ + PageResult list(SysOnlineUserParam sysOnlineUserParam); + + /** + * 系统在线用户强退 + * + * @param sysOnlineUserParam 操作参数 + * @author xuyuxiang + * @date 2020/4/7 20:20 + */ + void forceExist(SysOnlineUserParam sysOnlineUserParam); +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/monitor/service/impl/SysMachineServiceImpl.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/monitor/service/impl/SysMachineServiceImpl.java new file mode 100644 index 00000000..4117c740 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/monitor/service/impl/SysMachineServiceImpl.java @@ -0,0 +1,91 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.monitor.service.impl; + +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.util.NumberUtil; +import cn.hutool.system.*; +import com.cn.xiaonuo.core.consts.SymbolConstant; +import com.cn.xiaonuo.sys.modular.monitor.result.SysMachineResult; +import com.cn.xiaonuo.sys.modular.monitor.service.SysMachineService; +import com.cn.xiaonuo.sys.modular.monitor.result.SysMachineResult; +import com.cn.xiaonuo.sys.modular.monitor.service.SysMachineService; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.text.DecimalFormat; + +/** + * 系统属性监控service接口实现类 + * + * @author xuyuxiang + * @date 2020/6/5 14:40 + */ +@Service +public class SysMachineServiceImpl implements SysMachineService { + + @Override + public SysMachineResult query() { + JvmInfo jvmInfo = SystemUtil.getJvmInfo(); + JavaRuntimeInfo javaRuntimeInfo = SystemUtil.getJavaRuntimeInfo(); + OsInfo osInfo = SystemUtil.getOsInfo(); + HostInfo hostInfo = SystemUtil.getHostInfo(); + RuntimeInfo runtimeInfo = SystemUtil.getRuntimeInfo(); + //系统属性结果集 + SysMachineResult sysMachineResult = new SysMachineResult(); + + //系统信息 + SysMachineResult.SysOsInfo sysOsInfo = new SysMachineResult.SysOsInfo(); + sysOsInfo.setOsName(osInfo.getName()); + sysOsInfo.setOsArch(osInfo.getArch()); + sysOsInfo.setOsVersion(osInfo.getVersion()); + sysOsInfo.setOsHostName(hostInfo.getName()); + sysOsInfo.setOsHostAddress(hostInfo.getAddress()); + sysMachineResult.setSysOsInfo(sysOsInfo); + + //Java信息 + SysMachineResult.SysJavaInfo sysJavaInfo = new SysMachineResult.SysJavaInfo(); + sysJavaInfo.setJvmName(jvmInfo.getName()); + sysJavaInfo.setJvmVersion(jvmInfo.getVersion()); + sysJavaInfo.setJvmVendor(jvmInfo.getVendor()); + sysJavaInfo.setJavaName(javaRuntimeInfo.getName()); + sysJavaInfo.setJavaVersion(javaRuntimeInfo.getVersion()); + sysMachineResult.setSysJavaInfo(sysJavaInfo); + + //jvm内存信息 + SysMachineResult.SysJvmMemInfo sysJvmMemInfo = new SysMachineResult.SysJvmMemInfo(); + sysJvmMemInfo.setJvmMaxMemory(FileUtil.readableFileSize(runtimeInfo.getMaxMemory())); + sysJvmMemInfo.setJvmUsableMemory(FileUtil.readableFileSize(runtimeInfo.getUsableMemory())); + sysJvmMemInfo.setJvmTotalMemory(FileUtil.readableFileSize(runtimeInfo.getTotalMemory())); + sysJvmMemInfo.setJvmFreeMemory(FileUtil.readableFileSize(runtimeInfo.getFreeMemory())); + BigDecimal usedMemory = NumberUtil.sub(new BigDecimal(runtimeInfo.getTotalMemory()), new BigDecimal(runtimeInfo.getFreeMemory())); + sysJvmMemInfo.setJvmUsedMemory(FileUtil.readableFileSize(usedMemory.longValue())); + BigDecimal rate = NumberUtil.div(usedMemory, runtimeInfo.getTotalMemory()); + String usedRate = new DecimalFormat("#.00").format(NumberUtil.mul(rate, 100)) + SymbolConstant.PERCENT; + sysJvmMemInfo.setJvmMemoryUsedRate(usedRate); + sysMachineResult.setSysJvmMemInfo(sysJvmMemInfo); + return sysMachineResult; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/monitor/service/impl/SysOnlineUserServiceImpl.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/monitor/service/impl/SysOnlineUserServiceImpl.java new file mode 100644 index 00000000..e5c4e7e7 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/monitor/service/impl/SysOnlineUserServiceImpl.java @@ -0,0 +1,109 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.monitor.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import com.cn.xiaonuo.core.context.constant.ConstantContextHolder; +import com.cn.xiaonuo.core.context.login.LoginContextHolder; +import com.cn.xiaonuo.core.exception.DemoException; +import com.cn.xiaonuo.core.factory.PageFactory; +import com.cn.xiaonuo.core.pojo.login.SysLoginUser; +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.core.util.PageUtil; +import com.cn.xiaonuo.sys.core.cache.UserCache; +import com.cn.xiaonuo.sys.core.log.LogManager; +import com.cn.xiaonuo.sys.modular.monitor.param.SysOnlineUserParam; +import com.cn.xiaonuo.sys.modular.monitor.result.SysOnlineUserResult; +import com.cn.xiaonuo.sys.modular.monitor.service.SysOnlineUserService; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 系统组织机构service接口实现类 + * + * @author xuyuxiang + * @date 2020/4/7 17:06 + */ +@Service +public class SysOnlineUserServiceImpl implements SysOnlineUserService { + + @Resource + private UserCache userCache; + + @Override + public PageResult list(SysOnlineUserParam sysOnlineUserParam) { + List tempList = CollectionUtil.newArrayList(); + // 获取缓存中的所有用户 + Map allKeyValues = userCache.getAllKeyValues(); + for (Map.Entry sysLoginUserEntry : allKeyValues.entrySet()) { + SysOnlineUserResult sysOnlineUserResult = new SysOnlineUserResult(); + sysOnlineUserResult.setSessionId(sysLoginUserEntry.getKey()); + BeanUtil.copyProperties(sysLoginUserEntry.getValue(), sysOnlineUserResult); + tempList.add(sysOnlineUserResult); + } + List listAll = tempList.stream() + .sorted(Comparator.comparing(SysOnlineUserResult::getLastLoginTime, Comparator.reverseOrder())) + .collect(Collectors.toList()); + Page page = PageFactory.defaultPage(); + page.setTotal(tempList.size()); + List resultList = PageUtil.page(page, listAll); + return new PageResult<>(page, resultList); + } + + @Override + public void forceExist(SysOnlineUserParam sysOnlineUserParam) { + Boolean demoEnvFlag = ConstantContextHolder.getDemoEnvFlag(); + if (demoEnvFlag) { + throw new DemoException(); + } + + //获取缓存的key + String redisLoginUserKey = sysOnlineUserParam.getSessionId(); + + //获取缓存的用户 + SysLoginUser sysLoginUser = userCache.get(redisLoginUserKey); + + //如果缓存的用户存在,清除会话,否则表示该会话信息已失效,不执行任何操作 + if (ObjectUtil.isNotNull(sysLoginUser)) { + + //清除登录会话 + userCache.remove(redisLoginUserKey); + + //获取登录用户的账户信息 + String account = LoginContextHolder.me().getSysLoginUserAccount(); + + //创建退出登录日志 + LogManager.me().executeExitLog(account); + } + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/controller/SysNoticeController.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/controller/SysNoticeController.java new file mode 100644 index 00000000..548a14eb --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/controller/SysNoticeController.java @@ -0,0 +1,150 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.notice.controller; + +import com.cn.xiaonuo.core.annotion.BusinessLog; +import com.cn.xiaonuo.core.annotion.Permission; +import com.cn.xiaonuo.core.enums.LogAnnotionOpTypeEnum; +import com.cn.xiaonuo.core.pojo.response.ResponseData; +import com.cn.xiaonuo.core.pojo.response.SuccessResponseData; +import com.cn.xiaonuo.sys.modular.notice.param.SysNoticeParam; +import com.cn.xiaonuo.sys.modular.notice.service.SysNoticeService; +import com.cn.xiaonuo.sys.modular.notice.param.SysNoticeParam; +import com.cn.xiaonuo.sys.modular.notice.service.SysNoticeService; +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.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + * 系统通知公告控制器 + * + * @author xuyuxiang + * @date 2020/6/28 17:18 + */ +@RestController +public class SysNoticeController { + + @Resource + private SysNoticeService sysNoticeService; + + /** + * 查询系统通知公告 + * + * @author xuyuxiang + * @date 2020/6/28 17:24 + */ + @Permission + @GetMapping("/sysNotice/page") + @BusinessLog(title = "系统通知公告_查询", opType = LogAnnotionOpTypeEnum.QUERY) + public ResponseData page(SysNoticeParam sysNoticeParam) { + return new SuccessResponseData(sysNoticeService.page(sysNoticeParam)); + } + + /** + * 查询我收到的系统通知公告 + * + * @author xuyuxiang + * @date 2020/6/29 11:59 + */ + @Permission + @GetMapping("/sysNotice/received") + @BusinessLog(title = "系统通知公告_已收", opType = LogAnnotionOpTypeEnum.QUERY) + public ResponseData received(SysNoticeParam sysNoticeParam) { + return new SuccessResponseData(sysNoticeService.received(sysNoticeParam)); + } + + /** + * 添加系统通知公告 + * + * @author xuyuxiang + * @date 2020/6/28 17:24 + */ + @Permission + @PostMapping("/sysNotice/add") + @BusinessLog(title = "系统通知公告_增加", opType = LogAnnotionOpTypeEnum.ADD) + public ResponseData add(@RequestBody @Validated(SysNoticeParam.add.class) SysNoticeParam sysNoticeParam) { + sysNoticeService.add(sysNoticeParam); + return new SuccessResponseData(); + } + + /** + * 删除系统通知公告 + * + * @author xuyuxiang + * @date 2020/6/28 17:25 + */ + @Permission + @PostMapping("/sysNotice/delete") + @BusinessLog(title = "系统通知公告_删除", opType = LogAnnotionOpTypeEnum.DELETE) + public ResponseData delete(@RequestBody @Validated(SysNoticeParam.delete.class) SysNoticeParam sysNoticeParam) { + sysNoticeService.delete(sysNoticeParam); + return new SuccessResponseData(); + } + + /** + * 编辑系统通知公告 + * + * @author xuyuxiang + * @date 2020/6/28 17:25 + */ + @Permission + @PostMapping("/sysNotice/edit") + @BusinessLog(title = "系统通知公告_编辑", opType = LogAnnotionOpTypeEnum.EDIT) + public ResponseData edit(@RequestBody @Validated(SysNoticeParam.edit.class) SysNoticeParam sysNoticeParam) { + sysNoticeService.edit(sysNoticeParam); + return new SuccessResponseData(); + } + + /** + * 查看系统通知公告 + * + * @author xuyuxiang + * @date 2020/6/28 17:25 + */ + @Permission + @GetMapping("/sysNotice/detail") + @BusinessLog(title = "系统通知公告_查看", opType = LogAnnotionOpTypeEnum.DETAIL) + public ResponseData detail(@Validated(SysNoticeParam.detail.class) SysNoticeParam sysNoticeParam) { + return new SuccessResponseData(sysNoticeService.detail(sysNoticeParam)); + } + + /** + * 修改状态 + * + * @author xuyuxiang + * @date 2020/6/29 9:44 + */ + @Permission + @PostMapping("/sysNotice/changeStatus") + @BusinessLog(title = "系统通知公告_修改状态", opType = LogAnnotionOpTypeEnum.CHANGE_STATUS) + public ResponseData changeStatus(@RequestBody @Validated(SysNoticeParam.changeStatus.class) SysNoticeParam sysNoticeParam) { + sysNoticeService.changeStatus(sysNoticeParam); + return new SuccessResponseData(); + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/entity/SysNotice.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/entity/SysNotice.java new file mode 100644 index 00000000..de2aea02 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/entity/SysNotice.java @@ -0,0 +1,102 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.notice.entity; + +import com.cn.xiaonuo.core.pojo.base.entity.BaseEntity; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + * 系统通知公告表 + * + * @author xuyuxiang + * @date 2020/6/28 17:12 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@TableName("sys_notice") +public class SysNotice extends BaseEntity { + + /** + * 主键 + */ + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + /** + * 标题 + */ + private String title; + + /** + * 内容 + */ + private String content; + + /** + * 类型(字典 1通知 2公告) + */ + private Integer type; + + /** + * 发布人id + */ + private Long publicUserId; + + /** + * 发布人姓名 + */ + private String publicUserName; + + /** + * 发布机构id + */ + private Long publicOrgId; + + /** + * 发布机构名称 + */ + private String publicOrgName; + + /** + * 发布时间 + */ + private Date publicTime; + + /** + * 撤回时间 + */ + private Date cancelTime; + + /** + * 状态(字典 0草稿 1发布 2撤回 3删除) + */ + private Integer status; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/entity/SysNoticeUser.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/entity/SysNoticeUser.java new file mode 100644 index 00000000..e038c06e --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/entity/SysNoticeUser.java @@ -0,0 +1,69 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.notice.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.util.Date; + +/** + * 系统通知公告用户表 + * + * @author xuyuxiang + * @date 2020/6/29 10:45 + */ +@Data +@TableName("sys_notice_user") +public class SysNoticeUser { + + /** + * 主键 + */ + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + /** + * 通知公告id + */ + private Long noticeId; + + /** + * 用户id + */ + private Long userId; + + /** + * 状态(字典 0未读 1已读) + */ + private Integer status; + + /** + * 阅读时间 + */ + private Date readTime; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/enums/SysNoticeExceptionEnum.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/enums/SysNoticeExceptionEnum.java new file mode 100644 index 00000000..221a9ede --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/enums/SysNoticeExceptionEnum.java @@ -0,0 +1,80 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.notice.enums; + +import com.cn.xiaonuo.core.annotion.ExpEnumType; +import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum; +import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory; +import com.cn.xiaonuo.sys.core.consts.SysExpEnumConstant; + +/** + * 系统应用相关异常枚举 + * + * @author xuyuxiang + * @date 2020/3/26 10:11 + */ +@ExpEnumType(module = SysExpEnumConstant.XIAONUO_SYS_MODULE_EXP_CODE, kind = SysExpEnumConstant.SYS_NOTICE_EXCEPTION_ENUM) +public enum SysNoticeExceptionEnum implements AbstractBaseExceptionEnum { + + /** + * 通知公告不存在 + */ + NOTICE_NOT_EXIST(1, "通知公告不存在"), + + /** + * 编辑失败 + */ + NOTICE_CANNOT_EDIT(2, "编辑失败,通知公告非草稿状态时无法编辑"), + + /** + * 状态格式错误 + */ + NOTICE_STATUS_ERROR(3, "状态格式错误,请检查status参数"), + + /** + * 删除失败 + */ + NOTICE_CANNOT_DELETE(4, "删除失败,通知公告已发布或已删除"); + + private final Integer code; + + private final String message; + + SysNoticeExceptionEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return ExpEnumCodeFactory.getExpEnumCode(this.getClass(), code); + } + + @Override + public String getMessage() { + return message; + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/mapper/SysNoticeMapper.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/mapper/SysNoticeMapper.java new file mode 100644 index 00000000..79887ae3 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/mapper/SysNoticeMapper.java @@ -0,0 +1,54 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.notice.mapper; + +import com.cn.xiaonuo.sys.modular.notice.entity.SysNotice; +import com.cn.xiaonuo.sys.modular.notice.result.SysNoticeReceiveResult; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.cn.xiaonuo.sys.modular.notice.entity.SysNotice; +import com.cn.xiaonuo.sys.modular.notice.result.SysNoticeReceiveResult; +import org.apache.ibatis.annotations.Param; + +/** + * 系统通知公告mapper接口 + * + * @author xuyuxiang + * @date 2020/6/28 17:18 + */ +public interface SysNoticeMapper extends BaseMapper { + + /** + * 查询当前登陆用户已收公告 + * + * @param page 分页参数 + * @param queryWrapper 查询参数 + * @return 查询分页结果 + * @author xuyuxiang + * @date 2020/6/29 14:32 + */ + Page page(@Param("page") Page page, @Param("ew") QueryWrapper queryWrapper); +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/mapper/SysNoticeUserMapper.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/mapper/SysNoticeUserMapper.java new file mode 100644 index 00000000..717b4080 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/mapper/SysNoticeUserMapper.java @@ -0,0 +1,37 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.notice.mapper; + +import com.cn.xiaonuo.sys.modular.notice.entity.SysNoticeUser; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 系统通知公告用户mapper接口 + * + * @author xuyuxiang + * @date 2020/6/29 10:52 + */ +public interface SysNoticeUserMapper extends BaseMapper { +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/mapper/mapping/SysNoticeMapper.xml b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/mapper/mapping/SysNoticeMapper.xml new file mode 100644 index 00000000..b5350783 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/mapper/mapping/SysNoticeMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/mapper/mapping/SysNoticeUserMapper.xml b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/mapper/mapping/SysNoticeUserMapper.xml new file mode 100644 index 00000000..55eeb7d2 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/mapper/mapping/SysNoticeUserMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/param/SysNoticeParam.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/param/SysNoticeParam.java new file mode 100644 index 00000000..8533d27c --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/param/SysNoticeParam.java @@ -0,0 +1,84 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.notice.param; + +import com.cn.xiaonuo.core.pojo.base.param.BaseParam; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 系统通知公告参数 + * + * @author xuyuxiang + * @date 2020/6/28 17:19 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class SysNoticeParam extends BaseParam { + + /** + * 主键 + */ + @NotNull(message = "id不能为空,请检查id参数", groups = {edit.class, delete.class, detail.class, changeStatus.class}) + private Long id; + + /** + * 标题 + */ + @NotBlank(message = "标题不能为空,请检查title参数", groups = {add.class, edit.class}) + private String title; + + /** + * 内容 + */ + @NotBlank(message = "内容不能为空,请检查content参数", groups = {add.class, edit.class}) + private String content; + + /** + * 类型(字典 1通知 2公告) + */ + @NotNull(message = "类型不能为空,请检查type参数", groups = {add.class, edit.class}) + @Min(value = 1, message = "类型格式错误,请检查type参数", groups = {add.class, edit.class}) + @Max(value = 2, message = "类型格式错误,请检查type参数", groups = {add.class, edit.class}) + private Integer type; + + /** + * 状态(字典 0草稿 1发布 2撤回 3删除) + */ + @NotNull(message = "状态不能为空,请检查status参数", groups = {add.class, edit.class, changeStatus.class}) + private Integer status; + + /** + * 通知到的人 + */ + @NotNull(message = "通知到的人不能为空,请检查noticeUserIdList参数", groups = {add.class, edit.class}) + private List noticeUserIdList; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/result/SysNoticeDetailResult.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/result/SysNoticeDetailResult.java new file mode 100644 index 00000000..4593e930 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/result/SysNoticeDetailResult.java @@ -0,0 +1,109 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.notice.result; + +import cn.hutool.core.lang.Dict; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.util.Date; +import java.util.List; + +/** + * 系统通知公告详情结果集 + * + * @author xuyuxiang + * @date 2020/6/29 11:46 + */ +@Data +public class SysNoticeDetailResult { + + /** + * 主键 + */ + private Long id; + + /** + * 标题 + */ + private String title; + + /** + * 内容 + */ + private String content; + + /** + * 类型(字典 1通知 2公告) + */ + private Integer type; + + /** + * 发布人id + */ + private Long publicUserId; + + /** + * 发布人姓名 + */ + private String publicUserName; + + /** + * 发布机构id + */ + private Long publicOrgId; + + /** + * 发布机构名称 + */ + private String publicOrgName; + + /** + * 发布时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date publicTime; + + /** + * 撤回时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date cancelTime; + + /** + * 状态(字典 0草稿 1发布 2撤回 3删除) + */ + private Integer status; + + /** + * 通知到的用户id集合 + */ + private List noticeUserIdList; + + /** + * 通知到的用户阅读信息集合 + */ + private List noticeUserReadInfoList; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/result/SysNoticeReceiveResult.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/result/SysNoticeReceiveResult.java new file mode 100644 index 00000000..bc424b2d --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/result/SysNoticeReceiveResult.java @@ -0,0 +1,104 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.notice.result; + +import lombok.Data; + +import java.util.Date; + +/** + * 已收系统通知公告结果集 + * + * @author xuyuxiang + * @date 2020/6/29 12:20 + */ +@Data +public class SysNoticeReceiveResult { + + /** + * 主键 + */ + private Long id; + + /** + * 标题 + */ + private String title; + + /** + * 内容 + */ + private String content; + + /** + * 类型(字典 1通知 2公告) + */ + private Integer type; + + /** + * 发布人id + */ + private Long publicUserId; + + /** + * 发布人姓名 + */ + private String publicUserName; + + /** + * 发布机构id + */ + private Long publicOrgId; + + /** + * 发布机构名称 + */ + private String publicOrgName; + + /** + * 发布时间 + */ + private Date publicTime; + + /** + * 撤回时间 + */ + private Date cancelTime; + + /** + * 状态(字典 0草稿 1发布 2撤回 3删除) + */ + private Integer status; + + /** + * 阅读状态(字典 0未读 1已读) + */ + private Integer readStatus; + + /** + * 阅读时间 + */ + private Date readTime; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/service/SysNoticeService.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/service/SysNoticeService.java new file mode 100644 index 00000000..c6c31258 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/service/SysNoticeService.java @@ -0,0 +1,109 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.notice.service; + +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.modular.notice.entity.SysNotice; +import com.cn.xiaonuo.sys.modular.notice.param.SysNoticeParam; +import com.cn.xiaonuo.sys.modular.notice.result.SysNoticeDetailResult; +import com.cn.xiaonuo.sys.modular.notice.result.SysNoticeReceiveResult; +import com.baomidou.mybatisplus.extension.service.IService; +import com.cn.xiaonuo.sys.modular.notice.result.SysNoticeDetailResult; +import com.cn.xiaonuo.sys.modular.notice.result.SysNoticeReceiveResult; + +/** + * 系统通知公告service接口 + * + * @author xuyuxiang + * @date 2020/6/28 17:16 + */ +public interface SysNoticeService extends IService { + + /** + * 查询系统通知公告 + * + * @param sysNoticeParam 查询参数 + * @return 查询分页结果 + * @author xuyuxiang + * @date 2020/6/28 17:16 + */ + PageResult page(SysNoticeParam sysNoticeParam); + + /** + * 添加系统通知公告 + * + * @param sysNoticeParam 添加参数 + * @author xuyuxiang + * @date 2020/6/28 17:21 + */ + void add(SysNoticeParam sysNoticeParam); + + /** + * 删除系统通知公告 + * + * @param sysNoticeParam 删除参数 + * @author xuyuxiang + * @date 2020/6/28 17:22 + */ + void delete(SysNoticeParam sysNoticeParam); + + /** + * 编辑系统通知公告 + * + * @param sysNoticeParam 编辑参数 + * @author xuyuxiang + * @date 2020/6/28 17:22 + */ + void edit(SysNoticeParam sysNoticeParam); + + /** + * 查看系统通知公告 + * + * @param sysNoticeParam 查看参数 + * @return 通知公告详情结果 + * @author xuyuxiang + * @date 2020/6/28 17:22 + */ + SysNoticeDetailResult detail(SysNoticeParam sysNoticeParam); + + /** + * 修改状态 + * + * @param sysNoticeParam 修改参数 + * @author xuyuxiang + * @date 2020/6/29 9:45 + */ + void changeStatus(SysNoticeParam sysNoticeParam); + + /** + * 查询当前登陆用户已收通知公告 + * + * @param sysNoticeParam 查询参数 + * @return 查询分页结果 + * @author xuyuxiang + * @date 2020/6/29 12:01 + */ + PageResult received(SysNoticeParam sysNoticeParam); +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/service/SysNoticeUserService.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/service/SysNoticeUserService.java new file mode 100644 index 00000000..91f97072 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/service/SysNoticeUserService.java @@ -0,0 +1,82 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.notice.service; + +import com.cn.xiaonuo.sys.modular.notice.entity.SysNoticeUser; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +/** + * 系统通知公告用户service接口 + * + * @author xuyuxiang + * @date 2020/6/29 10:51 + */ +public interface SysNoticeUserService extends IService { + + /** + * 添加 + * + * @param noticeId 通知公告id + * @param noticeUserIdList 通知到的用户id集合 + * @param noticeUserStatus 阅读状态 + * @author xuyuxiang + * @date 2020/6/29 11:06 + */ + void add(Long noticeId, List noticeUserIdList, Integer noticeUserStatus); + + /** + * 编辑 + * + * @param noticeId 通知公告id + * @param noticeUserIdList 通知到的用户id集合 + * @param noticeUserStatus 阅读状态 + * @author xuyuxiang + * @date 2020/6/29 11:40 + */ + void edit(Long noticeId, List noticeUserIdList, Integer noticeUserStatus); + + /** + * 根据通知公告id查询通知人员信息集合 + * + * @param noticeId 通知公告id + * @return 通知用户列表 + * @author xuyuxiang + * @date 2020/6/29 11:50 + */ + List getSysNoticeUserListByNoticeId(Long noticeId); + + /** + * 设为已读 + * + * @param noticeId 通知公告id + * @param userId 用户id + * @param status 阅读状态 + * @author xuyuxiang + * @date 2020/6/29 12:05 + */ + void read(Long noticeId, Long userId, Integer status); +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/service/impl/SysNoticeServiceImpl.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/service/impl/SysNoticeServiceImpl.java new file mode 100644 index 00000000..b9e19b71 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/service/impl/SysNoticeServiceImpl.java @@ -0,0 +1,267 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.notice.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.lang.Dict; +import cn.hutool.core.util.ObjectUtil; +import com.cn.xiaonuo.core.context.login.LoginContextHolder; +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.core.factory.PageFactory; +import com.cn.xiaonuo.core.pojo.login.SysLoginUser; +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.core.enums.NoticeStatusEnum; +import com.cn.xiaonuo.sys.core.enums.NoticeUserStatusEnum; +import com.cn.xiaonuo.sys.modular.notice.entity.SysNotice; +import com.cn.xiaonuo.sys.modular.notice.entity.SysNoticeUser; +import com.cn.xiaonuo.sys.modular.notice.enums.SysNoticeExceptionEnum; +import com.cn.xiaonuo.sys.modular.notice.mapper.SysNoticeMapper; +import com.cn.xiaonuo.sys.modular.notice.param.SysNoticeParam; +import com.cn.xiaonuo.sys.modular.notice.result.SysNoticeDetailResult; +import com.cn.xiaonuo.sys.modular.notice.result.SysNoticeReceiveResult; +import com.cn.xiaonuo.sys.modular.notice.service.SysNoticeService; +import com.cn.xiaonuo.sys.modular.notice.service.SysNoticeUserService; +import com.cn.xiaonuo.sys.modular.user.service.SysUserService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.cn.xiaonuo.sys.modular.notice.entity.SysNotice; +import com.cn.xiaonuo.sys.modular.notice.entity.SysNoticeUser; +import com.cn.xiaonuo.sys.modular.notice.enums.SysNoticeExceptionEnum; +import com.cn.xiaonuo.sys.modular.notice.mapper.SysNoticeMapper; +import com.cn.xiaonuo.sys.modular.notice.param.SysNoticeParam; +import com.cn.xiaonuo.sys.modular.notice.result.SysNoticeDetailResult; +import com.cn.xiaonuo.sys.modular.notice.result.SysNoticeReceiveResult; +import com.cn.xiaonuo.sys.modular.notice.service.SysNoticeService; +import com.cn.xiaonuo.sys.modular.notice.service.SysNoticeUserService; +import com.cn.xiaonuo.sys.modular.user.service.SysUserService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.Date; +import java.util.List; + +/** + * 系统通知公告service接口实现类 + * + * @author xuyuxiang + * @date 2020/6/28 17:20 + */ +@Service +public class SysNoticeServiceImpl extends ServiceImpl implements SysNoticeService { + + @Resource + private SysNoticeUserService sysNoticeUserService; + + @Resource + private SysUserService sysUserService; + + @Override + public PageResult page(SysNoticeParam sysNoticeParam) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + if (ObjectUtil.isNotNull(sysNoticeParam)) { + //根据标题或内容模糊查询 + if (ObjectUtil.isNotEmpty(sysNoticeParam.getSearchValue())) { + queryWrapper.and(q -> q.like(SysNotice::getTitle, sysNoticeParam.getSearchValue()) + .or().like(SysNotice::getContent, sysNoticeParam.getSearchValue())); + } + //根据类型查询 + if (ObjectUtil.isNotEmpty(sysNoticeParam.getType())) { + queryWrapper.eq(SysNotice::getType, sysNoticeParam.getType()); + } + } + //查询未删除的 + queryWrapper.ne(SysNotice::getStatus, NoticeStatusEnum.DELETED.getCode()); + return new PageResult<>(this.page(PageFactory.defaultPage(), queryWrapper)); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void add(SysNoticeParam sysNoticeParam) { + //校验参数,检查状态是否正确 + checkParam(sysNoticeParam, true); + SysNotice sysNotice = new SysNotice(); + BeanUtil.copyProperties(sysNoticeParam, sysNotice); + SysLoginUser sysLoginUser = LoginContextHolder.me().getSysLoginUser(); + sysNotice.setPublicUserId(sysLoginUser.getId()); + sysNotice.setPublicUserName(sysLoginUser.getName()); + sysNotice.setPublicOrgId(sysLoginUser.getLoginEmpInfo().getOrgId()); + sysNotice.setPublicOrgName(sysLoginUser.getLoginEmpInfo().getOrgName()); + //如果是发布,则设置发布时间 + if (NoticeStatusEnum.PUBLIC.getCode().equals(sysNotice.getStatus())) { + sysNotice.setPublicTime(new Date()); + } + this.save(sysNotice); + //通知到的人 + List noticeUserIdList = sysNoticeParam.getNoticeUserIdList(); + Integer noticeUserStatus = NoticeUserStatusEnum.UNREAD.getCode(); + sysNoticeUserService.add(sysNotice.getId(), noticeUserIdList, noticeUserStatus); + } + + @Override + public void delete(SysNoticeParam sysNoticeParam) { + SysNotice sysNotice = this.querySysNotice(sysNoticeParam); + Integer status = sysNotice.getStatus(); + if (!NoticeStatusEnum.DRAFT.getCode().equals(status) && !NoticeStatusEnum.CANCEL.getCode().equals(status)) { + throw new ServiceException(SysNoticeExceptionEnum.NOTICE_CANNOT_DELETE); + } + sysNotice.setStatus(NoticeStatusEnum.DELETED.getCode()); + this.updateById(sysNotice); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void edit(SysNoticeParam sysNoticeParam) { + SysNotice sysNotice = this.querySysNotice(sysNoticeParam); + //校验参数,检查状态是否正确 + checkParam(sysNoticeParam, true); + //非草稿状态 + Integer status = sysNotice.getStatus(); + if (!NoticeStatusEnum.DRAFT.getCode().equals(status)) { + throw new ServiceException(SysNoticeExceptionEnum.NOTICE_CANNOT_EDIT); + } + BeanUtil.copyProperties(sysNoticeParam, sysNotice); + //如果是发布,则设置发布时间 + if (NoticeStatusEnum.PUBLIC.getCode().equals(sysNotice.getStatus())) { + sysNotice.setPublicTime(new Date()); + } + this.updateById(sysNotice); + //通知到的人 + List noticeUserIdList = sysNoticeParam.getNoticeUserIdList(); + Integer noticeUserStatus = NoticeUserStatusEnum.UNREAD.getCode(); + sysNoticeUserService.edit(sysNotice.getId(), noticeUserIdList, noticeUserStatus); + } + + @Override + public SysNoticeDetailResult detail(SysNoticeParam sysNoticeParam) { + SysNotice sysNotice = this.querySysNotice(sysNoticeParam); + Long id = sysNotice.getId(); + //获取通知到的用户 + List sysNoticeUserList = sysNoticeUserService.getSysNoticeUserListByNoticeId(id); + List noticeUserIdList = CollectionUtil.newArrayList(); + List noticeUserReadInfoList = CollectionUtil.newArrayList(); + SysNoticeDetailResult sysNoticeResult = new SysNoticeDetailResult(); + BeanUtil.copyProperties(sysNotice, sysNoticeResult); + if (ObjectUtil.isNotEmpty(sysNoticeUserList)) { + sysNoticeUserList.forEach(sysNoticeUser -> { + //遍历通知到的用户,并构造 + noticeUserIdList.add(sysNoticeUser.getUserId()); + Dict dict = Dict.create(); + dict.put("userId", sysNoticeUser.getUserId()); + dict.put("userName", sysUserService.getNameByUserId(sysNoticeUser.getUserId())); + dict.put("readStatus", sysNoticeUser.getStatus()); + dict.put("readTime", sysNoticeUser.getReadTime()); + noticeUserReadInfoList.add(dict); + }); + } + sysNoticeResult.setNoticeUserIdList(noticeUserIdList); + sysNoticeResult.setNoticeUserReadInfoList(noticeUserReadInfoList); + //如果该条通知公告为已发布,则将当前用户的该条通知公告设置为已读 + if (sysNotice.getStatus().equals(NoticeStatusEnum.PUBLIC.getCode())) { + sysNoticeUserService.read(sysNotice.getId(), + LoginContextHolder.me().getSysLoginUserId(), NoticeUserStatusEnum.READ.getCode()); + } + return sysNoticeResult; + } + + @Override + public void changeStatus(SysNoticeParam sysNoticeParam) { + SysNotice sysNotice = this.querySysNotice(sysNoticeParam); + //校验参数,检查状态是否正确 + checkParam(sysNoticeParam, false); + sysNotice.setStatus(sysNoticeParam.getStatus()); + //如果是撤回,则设置撤回时间 + if (NoticeStatusEnum.CANCEL.getCode().equals(sysNotice.getStatus())) { + sysNotice.setCancelTime(new Date()); + } else if (NoticeStatusEnum.PUBLIC.getCode().equals(sysNotice.getStatus())) { + //如果是发布,则设置发布时间 + sysNotice.setPublicTime(new Date()); + } + this.updateById(sysNotice); + } + + @Override + public PageResult received(SysNoticeParam sysNoticeParam) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + //查询当前用户的 + queryWrapper.eq("sys_notice_user.user_id", LoginContextHolder.me().getSysLoginUserId()); + if (ObjectUtil.isNotNull(sysNoticeParam)) { + //根据标题或内容模糊查询 + if (ObjectUtil.isNotEmpty(sysNoticeParam.getSearchValue())) { + queryWrapper.and(q -> q.like("sys_notice.title", sysNoticeParam.getSearchValue()) + .or().like("sys_notice.content", sysNoticeParam.getSearchValue())); + } + //根据类型查询 + if (ObjectUtil.isNotEmpty(sysNoticeParam.getType())) { + queryWrapper.eq("sys_notice.type", sysNoticeParam.getType()); + } + } + //查询未删除的 + queryWrapper.ne("sys_notice.status", NoticeStatusEnum.DELETED.getCode()); + return new PageResult<>(this.baseMapper.page(PageFactory.defaultPage(), queryWrapper)); + } + + /** + * 校验参数,判断状态是否正确 + * + * @author xuyuxiang + * @date 2020/6/29 10:06 + */ + private void checkParam(SysNoticeParam sysNoticeParam, boolean isAddOrEdit) { + //保存或编辑时,传递的状态参数应为草稿,或发布 + Integer status = sysNoticeParam.getStatus(); + if (isAddOrEdit) { + if (!NoticeStatusEnum.DRAFT.getCode().equals(status) && + !NoticeStatusEnum.PUBLIC.getCode().equals(status)) { + throw new ServiceException(SysNoticeExceptionEnum.NOTICE_STATUS_ERROR); + } + } else { + //修改状态时,传递的状态参数应为撤回或删除或发布 + if (!NoticeStatusEnum.CANCEL.getCode().equals(status) && + !NoticeStatusEnum.DELETED.getCode().equals(status) && + !NoticeStatusEnum.PUBLIC.getCode().equals(status)) { + throw new ServiceException(SysNoticeExceptionEnum.NOTICE_STATUS_ERROR); + } + } + + } + + /** + * 获取系统通知公告 + * + * @author xuyuxiang + * @date 2020/6/29 9:58 + */ + private SysNotice querySysNotice(SysNoticeParam sysNoticeParam) { + SysNotice sysNotice = this.getById(sysNoticeParam.getId()); + if (ObjectUtil.isNull(sysNotice)) { + throw new ServiceException(SysNoticeExceptionEnum.NOTICE_NOT_EXIST); + } + return sysNotice; + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/service/impl/SysNoticeUserServiceImpl.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/service/impl/SysNoticeUserServiceImpl.java new file mode 100644 index 00000000..597f60c2 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/notice/service/impl/SysNoticeUserServiceImpl.java @@ -0,0 +1,92 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.notice.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.cn.xiaonuo.sys.modular.notice.entity.SysNoticeUser; +import com.cn.xiaonuo.sys.modular.notice.mapper.SysNoticeUserMapper; +import com.cn.xiaonuo.sys.modular.notice.service.SysNoticeUserService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.cn.xiaonuo.sys.modular.notice.entity.SysNoticeUser; +import com.cn.xiaonuo.sys.modular.notice.mapper.SysNoticeUserMapper; +import com.cn.xiaonuo.sys.modular.notice.service.SysNoticeUserService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Date; +import java.util.List; + +/** + * 系统通知公告用户service接口实现类 + * + * @author xuyuxiang + * @date 2020/6/29 10:53 + */ +@Service +public class SysNoticeUserServiceImpl extends ServiceImpl implements SysNoticeUserService { + + @Override + public void add(Long noticeId, List noticeUserIdList, Integer noticeUserStatus) { + noticeUserIdList.forEach(userId -> { + SysNoticeUser sysNoticeUser = new SysNoticeUser(); + sysNoticeUser.setNoticeId(noticeId); + sysNoticeUser.setUserId(userId); + sysNoticeUser.setStatus(noticeUserStatus); + this.save(sysNoticeUser); + }); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void edit(Long noticeId, List noticeUserIdList, Integer noticeUserStatus) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysNoticeUser::getNoticeId, noticeId); + //先删除 + this.remove(queryWrapper); + //再增加 + this.add(noticeId, noticeUserIdList, noticeUserStatus); + } + + @Override + public List getSysNoticeUserListByNoticeId(Long noticeId) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysNoticeUser::getNoticeId, noticeId); + return this.list(queryWrapper); + } + + @Override + public void read(Long noticeId, Long userId, Integer status) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysNoticeUser::getNoticeId, noticeId) + .eq(SysNoticeUser::getUserId, userId); + SysNoticeUser sysNoticeUser = this.getOne(queryWrapper); + if (ObjectUtil.isNotNull(sysNoticeUser)) { + sysNoticeUser.setStatus(status); + sysNoticeUser.setReadTime(new Date()); + this.updateById(sysNoticeUser); + } + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/oauth/controller/SysOauthController.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/oauth/controller/SysOauthController.java new file mode 100644 index 00000000..b99334ce --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/oauth/controller/SysOauthController.java @@ -0,0 +1,77 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.oauth.controller; + +import com.cn.xiaonuo.core.consts.CommonConstant; +import com.cn.xiaonuo.core.consts.SymbolConstant; +import com.cn.xiaonuo.core.context.constant.ConstantContextHolder; +import com.cn.xiaonuo.sys.modular.oauth.service.SysOauthService; +import me.zhyd.oauth.model.AuthCallback; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * Oauth登录控制器 + * + * @author xuyuxiang + * @date 2020/7/28 16:38 + **/ +@RestController +public class SysOauthController { + + @Resource + private SysOauthService sysOauthService; + + /** + * oauth登录 + * + * @author xuyuxiang + * @date 2020/7/29 12:18 + **/ + @GetMapping("/oauth/render/{source}") + public void renderAuth(@PathVariable("source") String source, HttpServletResponse response) throws IOException { + String authorizeUrl = sysOauthService.getAuthorizeUrl(source); + response.sendRedirect(authorizeUrl); + } + + /** + * oauth平台中配置的授权回调地址 + * + * @author xuyuxiang + * @date 2020/7/29 12:19 + **/ + @GetMapping("/oauth/callback/{source}") + public void callback(@PathVariable("source") String source, AuthCallback callback, HttpServletRequest request, HttpServletResponse response) throws IOException { + String token = sysOauthService.callback(source, callback, request); + String webUrl = ConstantContextHolder.getWebUrl(); + response.sendRedirect(webUrl + SymbolConstant.QUESTION_MARK + CommonConstant.TOKEN_NAME + SymbolConstant.EQUAL + token); + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/oauth/entity/SysOauthUser.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/oauth/entity/SysOauthUser.java new file mode 100644 index 00000000..a46ce458 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/oauth/entity/SysOauthUser.java @@ -0,0 +1,105 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.oauth.entity; + +import com.cn.xiaonuo.core.pojo.base.entity.BaseEntity; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * Oauth登录用户表 + * + * @author xuyuxiang + * @date 2020/7/28 17:04 + **/ +@EqualsAndHashCode(callSuper = true) +@Data +@TableName("sys_oauth_user") +public class SysOauthUser extends BaseEntity { + + /** + * 主键 + */ + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + /** + * 第三方平台的用户唯一id + */ + private String uuid; + + /** + * 用户授权的token + */ + private String accessToken; + + /** + * 昵称 + */ + private String nickName; + + /** + * 头像 + */ + private String avatar; + + /** + * 用户网址 + */ + private String blog; + + /** + * 所在公司 + */ + private String company; + + /** + * 位置 + */ + private String location; + + /** + * 邮箱 + */ + private String email; + + /** + * 性别 + */ + private String gender; + + /** + * 用户来源 + */ + private String source; + + /** + * 用户备注(各平台中的用户个人介绍) + */ + private String remark; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/oauth/enums/SysOauthExceptionEnum.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/oauth/enums/SysOauthExceptionEnum.java new file mode 100644 index 00000000..dce792b2 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/oauth/enums/SysOauthExceptionEnum.java @@ -0,0 +1,70 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.oauth.enums; + +import com.cn.xiaonuo.core.annotion.ExpEnumType; +import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum; +import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory; +import com.cn.xiaonuo.sys.core.consts.SysExpEnumConstant; + +/** + * 系统角色相关异常枚举 + * + * @author xuyuxiang + * @date 2020/3/28 14:47 + */ +@ExpEnumType(module = SysExpEnumConstant.XIAONUO_SYS_MODULE_EXP_CODE, kind = SysExpEnumConstant.OAUTH_EXCEPTION_ENUM) +public enum SysOauthExceptionEnum implements AbstractBaseExceptionEnum { + + /** + * Oauth登录开关未开启 + */ + OAUTH_DISABLED(1, "Oauth登录开关未开启,无法使用Oauth登录"), + + /** + * 不支持该平台Oauth登录 + */ + OAUTH_NOT_SUPPORT(2, "不支持该平台Oauth登录"); + + private final Integer code; + + private final String message; + + SysOauthExceptionEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return ExpEnumCodeFactory.getExpEnumCode(this.getClass(), code); + } + + @Override + public String getMessage() { + return message; + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/oauth/mapper/SysOauthMapper.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/oauth/mapper/SysOauthMapper.java new file mode 100644 index 00000000..2c9df710 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/oauth/mapper/SysOauthMapper.java @@ -0,0 +1,37 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.oauth.mapper; + +import com.cn.xiaonuo.sys.modular.oauth.entity.SysOauthUser; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * Oauth登录相关mapper接口 + * + * @author xuyuxiang + * @date 2020/7/28 17:11 + **/ +public interface SysOauthMapper extends BaseMapper { +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/oauth/mapper/mapping/SysOauthMapper.xml b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/oauth/mapper/mapping/SysOauthMapper.xml new file mode 100644 index 00000000..12f986fb --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/oauth/mapper/mapping/SysOauthMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/oauth/service/SysOauthService.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/oauth/service/SysOauthService.java new file mode 100644 index 00000000..799806f3 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/oauth/service/SysOauthService.java @@ -0,0 +1,63 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.oauth.service; + +import com.cn.xiaonuo.sys.modular.oauth.entity.SysOauthUser; +import com.baomidou.mybatisplus.extension.service.IService; +import com.cn.xiaonuo.sys.modular.oauth.entity.SysOauthUser; +import me.zhyd.oauth.model.AuthCallback; + +import javax.servlet.http.HttpServletRequest; + +/** + * Oauth登录相关service接口 + * + * @author xuyuxiang + * @date 2020/7/28 17:06 + **/ +public interface SysOauthService extends IService { + + /** + * 根据授权平台来源获取授权地址 + * + * @param source 授权平台来源 + * @return 授权地址 + * @author xuyuxiang + * @date 2020/7/28 17:26 + **/ + String getAuthorizeUrl(String source); + + /** + * 授权后回调方法 + * + * @param source 授权来源平台 + * @param callback 授权平台返回的用户信息 + * @param request request请求 + * @return 登录成功的token + * @author xuyuxiang + * @date 2020/7/29 9:48 + **/ + String callback(String source, AuthCallback callback, HttpServletRequest request); +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/oauth/service/impl/SysOauthServiceImpl.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/oauth/service/impl/SysOauthServiceImpl.java new file mode 100644 index 00000000..d28a71ef --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/oauth/service/impl/SysOauthServiceImpl.java @@ -0,0 +1,213 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.oauth.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.cn.xiaonuo.core.context.constant.ConstantContextHolder; +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.core.pojo.oauth.OauthConfigs; +import com.cn.xiaonuo.sys.core.cache.OauthCache; +import com.cn.xiaonuo.sys.core.enums.OauthPlatformEnum; +import com.cn.xiaonuo.sys.modular.auth.service.AuthService; +import com.cn.xiaonuo.sys.modular.oauth.entity.SysOauthUser; +import com.cn.xiaonuo.sys.modular.oauth.enums.SysOauthExceptionEnum; +import com.cn.xiaonuo.sys.modular.oauth.mapper.SysOauthMapper; +import com.cn.xiaonuo.sys.modular.oauth.service.SysOauthService; +import com.cn.xiaonuo.sys.modular.user.entity.SysUser; +import com.cn.xiaonuo.sys.modular.user.service.SysUserService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.IdWorker; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.cn.xiaonuo.sys.modular.auth.service.AuthService; +import com.cn.xiaonuo.sys.modular.oauth.entity.SysOauthUser; +import com.cn.xiaonuo.sys.modular.oauth.enums.SysOauthExceptionEnum; +import com.cn.xiaonuo.sys.modular.oauth.mapper.SysOauthMapper; +import com.cn.xiaonuo.sys.modular.oauth.service.SysOauthService; +import com.cn.xiaonuo.sys.modular.user.entity.SysUser; +import com.cn.xiaonuo.sys.modular.user.service.SysUserService; +import me.zhyd.oauth.config.AuthConfig; +import me.zhyd.oauth.model.AuthCallback; +import me.zhyd.oauth.model.AuthResponse; +import me.zhyd.oauth.model.AuthUser; +import me.zhyd.oauth.request.AuthGiteeRequest; +import me.zhyd.oauth.request.AuthGithubRequest; +import me.zhyd.oauth.request.AuthRequest; +import me.zhyd.oauth.utils.AuthStateUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; + + +/** + * Oauth登录相关service接口实现类 + * + * @author xuyuxiang + * @date 2020/7/28 17:07 + **/ +@Service +public class SysOauthServiceImpl extends ServiceImpl implements SysOauthService { + + @Resource + private OauthCache oauthCache; + + @Resource + private AuthService authService; + + @Resource + private SysUserService sysUserService; + + + @Override + public String getAuthorizeUrl(String source) { + Boolean enableOauthLogin = ConstantContextHolder.getEnableOauthLogin(); + if (!enableOauthLogin) { + throw new ServiceException(SysOauthExceptionEnum.OAUTH_DISABLED); + } + AuthRequest authRequest = this.getAuthRequest(source); + return authRequest.authorize(AuthStateUtils.createState()); + } + + @SuppressWarnings("all") + @Override + public String callback(String source, AuthCallback callback, HttpServletRequest request) { + AuthRequest authRequest = this.getAuthRequest(source); + AuthResponse response = authRequest.login(callback); + if (response.ok()) { + AuthUser authUser = response.getData(); + return doLogin(authUser); + } else { + throw new ServiceException(response.getCode(), response.getMsg()); + } + } + + /** + * 根据用户授权信息进行登录 + * + * @param authUser 用户授权信息 + * @return token + * @author xuyuxiang + * @date 2020/7/29 9:54 + **/ + @Transactional(rollbackFor = Exception.class) + public String doLogin(AuthUser authUser) { + //获取uuid + String uuid = authUser.getUuid(); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysOauthUser::getUuid, uuid); + SysOauthUser oauthUser = this.getOne(queryWrapper); + //从没授权登录过 + if (ObjectUtil.isNull(oauthUser)) { + //将授权的用户信息保存到sys_oauth_user表和sys_user表 + this.saveByAuthUser(authUser); + //再获取oauthUser用户 + oauthUser = this.getOne(queryWrapper); + } + //获取用户账户信息进行登录 + Long userId = oauthUser.getId(); + SysUser sysUser = sysUserService.getUserById(userId); + return authService.doLogin(sysUser); + } + + /** + * 将授权的用户信息保存到sys_oauth_user表和sys_user表 + * + * @param authUser 用户授权信息 + * @return void + * @author xuyuxiang + * @date 2020/7/29 10:16 + **/ + @Transactional(rollbackFor = Exception.class) + public void saveByAuthUser(AuthUser authUser) { + //生成用户id + long userId = IdWorker.getId(); + //创建oauthUser对象 + SysOauthUser oauthUser = new SysOauthUser(); + oauthUser.setId(userId); + this.fillOauthUserInfo(oauthUser, authUser); + //创建sysUser对象 + SysUser sysUser = new SysUser(); + sysUser.setId(userId); + //将授权的用户信息保存到user表 + sysUserService.saveAuthUserToUser(authUser, sysUser); + this.save(oauthUser); + } + + /** + * 根据具体的授权来源,获取授权请求 + * + * @param source 授权平台来源 + * @return 授权请求 + * @author xuyuxiang + * @date 2020/7/28 17:28 + **/ + private AuthRequest getAuthRequest(String source) { + AuthRequest authRequest; + if (source.toLowerCase().equals(OauthPlatformEnum.GITEE.getCode())) { + OauthConfigs giteeOauthConfigs = ConstantContextHolder.getGiteeOauthConfigs(); + authRequest = new AuthGiteeRequest(AuthConfig.builder() + .clientId(giteeOauthConfigs.getClientId()) + .clientSecret(giteeOauthConfigs.getClientSecret()) + .redirectUri(giteeOauthConfigs.getRedirectUri()) + .build(), oauthCache); + } else if (source.toLowerCase().equals(OauthPlatformEnum.GITHUB.getCode())) { + OauthConfigs githubOauthConfigs = ConstantContextHolder.getGithubOauthConfigs(); + authRequest = new AuthGithubRequest(AuthConfig.builder() + .clientId(githubOauthConfigs.getClientId()) + .clientSecret(githubOauthConfigs.getClientSecret()) + .redirectUri(githubOauthConfigs.getRedirectUri()) + .build(), oauthCache); + } else { + throw new ServiceException(SysOauthExceptionEnum.OAUTH_NOT_SUPPORT); + } + return authRequest; + } + + /** + * 将授权用户信息填充到oauthUser + * + * @param oauthUser 系统授权用户信息 + * @param authUser 平台授权用户信息 + * @return void + * @author xuyuxiang + * @date 2020/7/29 10:42 + **/ + private void fillOauthUserInfo(SysOauthUser oauthUser, AuthUser authUser) { + oauthUser.setUuid(authUser.getUuid()); + oauthUser.setAccessToken(authUser.getToken().getAccessToken()); + oauthUser.setNickName(authUser.getNickname()); + oauthUser.setAvatar(authUser.getAvatar()); + oauthUser.setBlog(authUser.getBlog()); + oauthUser.setCompany(authUser.getCompany()); + oauthUser.setLocation(authUser.getLocation()); + oauthUser.setEmail(authUser.getEmail()); + oauthUser.setSource(authUser.getSource()); + oauthUser.setRemark(authUser.getRemark()); + if (ObjectUtil.isNotNull(authUser.getGender())) { + oauthUser.setGender(authUser.getGender().getDesc()); + } + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/org/controller/SysOrgController.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/org/controller/SysOrgController.java new file mode 100644 index 00000000..d558a550 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/org/controller/SysOrgController.java @@ -0,0 +1,163 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.org.controller; + +import com.cn.xiaonuo.core.annotion.BusinessLog; +import com.cn.xiaonuo.core.annotion.DataScope; +import com.cn.xiaonuo.core.annotion.Permission; +import com.cn.xiaonuo.core.enums.LogAnnotionOpTypeEnum; +import com.cn.xiaonuo.core.pojo.response.ResponseData; +import com.cn.xiaonuo.core.pojo.response.SuccessResponseData; +import com.cn.xiaonuo.sys.modular.org.param.SysOrgParam; +import com.cn.xiaonuo.sys.modular.org.service.SysOrgService; +import com.cn.xiaonuo.core.annotion.BusinessLog; +import com.cn.xiaonuo.core.annotion.DataScope; +import com.cn.xiaonuo.core.annotion.Permission; +import com.cn.xiaonuo.core.enums.LogAnnotionOpTypeEnum; +import com.cn.xiaonuo.core.pojo.base.param.BaseParam; +import com.cn.xiaonuo.core.pojo.response.ResponseData; +import com.cn.xiaonuo.core.pojo.response.SuccessResponseData; +import com.cn.xiaonuo.sys.modular.org.param.SysOrgParam; +import com.cn.xiaonuo.sys.modular.org.service.SysOrgService; +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.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + * 系统组织机构控制器 + * + * @author xuyuxiang + * @date 2020/3/20 19:47 + */ +@RestController +public class SysOrgController { + + @Resource + private SysOrgService sysOrgService; + + /** + * 查询系统机构 + * + * @author xuyuxiang + * @date 2020/5/11 15:49 + */ + @Permission + @DataScope + @GetMapping("/sysOrg/page") + @BusinessLog(title = "系统机构_查询", opType = LogAnnotionOpTypeEnum.QUERY) + public ResponseData page(SysOrgParam sysOrgParam) { + return new SuccessResponseData(sysOrgService.page(sysOrgParam)); + } + + /** + * 系统组织机构列表 + * + * @author xuyuxiang + * @date 2020/3/26 10:20 + */ + @Permission + @DataScope + @GetMapping("/sysOrg/list") + @BusinessLog(title = "系统组织机构_列表", opType = LogAnnotionOpTypeEnum.QUERY) + public ResponseData list(SysOrgParam sysOrgParam) { + return new SuccessResponseData(sysOrgService.list(sysOrgParam)); + } + + /** + * 添加系统组织机构 + * + * @author xuyuxiang + * @date 2020/3/25 14:44 + */ + @Permission + @DataScope + @PostMapping("/sysOrg/add") + @BusinessLog(title = "系统组织机构_增加", opType = LogAnnotionOpTypeEnum.ADD) + public ResponseData add(@RequestBody @Validated(BaseParam.add.class) SysOrgParam sysOrgParam) { + sysOrgService.add(sysOrgParam); + return new SuccessResponseData(); + } + + /** + * 删除系统组织机构 + * + * @author xuyuxiang + * @date 2020/3/25 14:54 + */ + @Permission + @DataScope + @PostMapping("/sysOrg/delete") + @BusinessLog(title = "系统组织机构_删除", opType = LogAnnotionOpTypeEnum.DELETE) + public ResponseData delete(@RequestBody @Validated(BaseParam.delete.class) SysOrgParam sysOrgParam) { + sysOrgService.delete(sysOrgParam); + return new SuccessResponseData(); + } + + /** + * 编辑系统组织机构 + * + * @author xuyuxiang + * @date 2020/3/25 14:54 + */ + @Permission + @DataScope + @PostMapping("/sysOrg/edit") + @BusinessLog(title = "系统组织机构_编辑", opType = LogAnnotionOpTypeEnum.EDIT) + public ResponseData edit(@RequestBody @Validated(BaseParam.edit.class) SysOrgParam sysOrgParam) { + sysOrgService.edit(sysOrgParam); + return new SuccessResponseData(); + } + + /** + * 查看系统组织机构 + * + * @author xuyuxiang + * @date 2020/3/26 9:49 + */ + @Permission + @GetMapping("/sysOrg/detail") + @BusinessLog(title = "系统组织机构_查看", opType = LogAnnotionOpTypeEnum.DETAIL) + public ResponseData detail(@Validated(BaseParam.detail.class) SysOrgParam sysOrgParam) { + return new SuccessResponseData(sysOrgService.detail(sysOrgParam)); + } + + /** + * 获取组织机构树 + * + * @author xuyuxiang + * @date 2020/3/26 11:55 + */ + @Permission + @DataScope + @GetMapping("/sysOrg/tree") + @BusinessLog(title = "系统组织机构_树", opType = LogAnnotionOpTypeEnum.TREE) + public ResponseData tree(SysOrgParam sysOrgParam) { + return new SuccessResponseData(sysOrgService.tree(sysOrgParam)); + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/org/entity/SysOrg.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/org/entity/SysOrg.java new file mode 100644 index 00000000..133dca43 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/org/entity/SysOrg.java @@ -0,0 +1,85 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.org.entity; + +import com.cn.xiaonuo.core.pojo.base.entity.BaseEntity; +import com.baomidou.mybatisplus.annotation.*; +import com.cn.xiaonuo.core.pojo.base.entity.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 系统组织机构表 + * + * @author xuyuxiang + * @date 2020/3/11 11:20 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@TableName("sys_org") +public class SysOrg extends BaseEntity { + + /** + * 主键 + */ + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + /** + * 父id + */ + private Long pid; + + /** + * 父ids + */ + private String pids; + + /** + * 名称 + */ + private String name; + + /** + * 编码 + */ + private String code; + + /** + * 排序 + */ + private Integer sort; + + /** + * 备注 + */ + @TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED) + private String remark; + + /** + * 状态(字典 0正常 1停用 2删除) + */ + private Integer status; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/org/enums/SysOrgExceptionEnum.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/org/enums/SysOrgExceptionEnum.java new file mode 100644 index 00000000..5db7b3cb --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/org/enums/SysOrgExceptionEnum.java @@ -0,0 +1,89 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.org.enums; + +import com.cn.xiaonuo.core.annotion.ExpEnumType; +import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum; +import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory; +import com.cn.xiaonuo.sys.core.consts.SysExpEnumConstant; +import com.cn.xiaonuo.core.annotion.ExpEnumType; +import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum; +import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory; +import com.cn.xiaonuo.sys.core.consts.SysExpEnumConstant; + +/** + * 系统组织机构相关异常枚举 + * + * @author xuyuxiang + * @date 2020/3/26 10:12 + */ +@ExpEnumType(module = SysExpEnumConstant.XIAONUO_SYS_MODULE_EXP_CODE, kind = SysExpEnumConstant.SYS_ORG_EXCEPTION_ENUM) +public enum SysOrgExceptionEnum implements AbstractBaseExceptionEnum { + + /** + * 组织机构不存在 + */ + ORG_NOT_EXIST(1, "组织机构不存在"), + + /** + * 组织机构编码重复 + */ + ORG_CODE_REPEAT(2, "组织机构编码重复,请检查code参数"), + + /** + * 组织机构名称重复 + */ + ORG_NAME_REPEAT(3, "组织机构名称重复,请检查name参数"), + + /** + * 该机构下有员工 + */ + ORG_CANNOT_DELETE(4, "该机构下有员工,无法删除"), + + /** + * 父节点不能和本节点一致,请从新选择父节点 + */ + ID_CANT_EQ_PID(5, "父节点不能和本节点一致,请从新选择父节点"); + + private final Integer code; + + private final String message; + + SysOrgExceptionEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return ExpEnumCodeFactory.getExpEnumCode(this.getClass(), code); + } + + @Override + public String getMessage() { + return message; + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/org/mapper/SysOrgMapper.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/org/mapper/SysOrgMapper.java new file mode 100644 index 00000000..00bda490 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/org/mapper/SysOrgMapper.java @@ -0,0 +1,38 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.org.mapper; + +import com.cn.xiaonuo.sys.modular.org.entity.SysOrg; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.cn.xiaonuo.sys.modular.org.entity.SysOrg; + +/** + * 系统组织机构mapper接口 + * + * @author xuyuxiang + * @date 2020/3/13 16:03 + */ +public interface SysOrgMapper extends BaseMapper { +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/org/mapper/mapping/SysOrgMapper.xml b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/org/mapper/mapping/SysOrgMapper.xml new file mode 100644 index 00000000..0469b001 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/org/mapper/mapping/SysOrgMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/org/param/SysOrgParam.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/org/param/SysOrgParam.java new file mode 100644 index 00000000..03a46711 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/org/param/SysOrgParam.java @@ -0,0 +1,79 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.org.param; + +import com.cn.xiaonuo.core.pojo.base.param.BaseParam; +import com.cn.xiaonuo.core.pojo.base.param.BaseParam; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 系统组织机构参数 + * + * @author xuyuxiang + * @date 2020/3/26 10:10 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class SysOrgParam extends BaseParam { + + /** + * 主键 + */ + @NotNull(message = "id不能为空,请检查id参数", groups = {edit.class, delete.class, detail.class}) + private Long id; + + /** + * 父id + */ + @NotNull(message = "pid不能为空,请检查pid参数", groups = {add.class, edit.class}) + private Long pid; + + /** + * 名称 + */ + @NotBlank(message = "名称不能为空,请检查name参数", groups = {add.class, edit.class}) + private String name; + + /** + * 编码 + */ + @NotBlank(message = "编码不能为空,请检查code参数", groups = {add.class, edit.class}) + private String code; + + /** + * 排序 + */ + @NotNull(message = "排序不能为空,请检查sort参数", groups = {add.class, edit.class}) + private Integer sort; + + /** + * 备注 + */ + private String remark; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/org/service/SysOrgService.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/org/service/SysOrgService.java new file mode 100644 index 00000000..3d71fa9d --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/org/service/SysOrgService.java @@ -0,0 +1,124 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.org.service; + +import com.cn.xiaonuo.core.pojo.node.AntdBaseTreeNode; +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.modular.org.entity.SysOrg; +import com.cn.xiaonuo.sys.modular.org.param.SysOrgParam; +import com.baomidou.mybatisplus.extension.service.IService; +import com.cn.xiaonuo.core.pojo.node.AntdBaseTreeNode; +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.modular.org.entity.SysOrg; +import com.cn.xiaonuo.sys.modular.org.param.SysOrgParam; + +import java.util.List; + +/** + * 系统组织机构service接口 + * + * @author xuyuxiang + * @date 2020/3/13 16:02 + */ +public interface SysOrgService extends IService { + + /** + * 查询系统机构 + * + * @param sysOrgParam 查询参数 + * @return 查询分页结果 + * @author yubaoshan + * @date 2020/5/11 15:49 + */ + PageResult page(SysOrgParam sysOrgParam); + + /** + * 系统组织机构列表 + * + * @param sysOrgParam 查询参数 + * @return 组织机构列表 + * @author xuyuxiang + * @date 2020/3/26 10:19 + */ + List list(SysOrgParam sysOrgParam); + + /** + * 添加系统组织机构 + * + * @param sysOrgParam 添加参数 + * @author xuyuxiang + * @date 2020/3/25 14:57 + */ + void add(SysOrgParam sysOrgParam); + + /** + * 删除系统组织机构 + * + * @param sysOrgParam 删除参数 + * @author xuyuxiang + * @date 2020/3/25 14:57 + */ + void delete(SysOrgParam sysOrgParam); + + /** + * 编辑系统组织机构 + * + * @param sysOrgParam 编辑参数 + * @author xuyuxiang + * @date 2020/3/25 14:58 + */ + void edit(SysOrgParam sysOrgParam); + + /** + * 查看系统组织机构 + * + * @param sysOrgParam 查看参数 + * @return 组织机构 + * @author xuyuxiang + * @date 2020/3/26 9:50 + */ + SysOrg detail(SysOrgParam sysOrgParam); + + /** + * 获取系统组织机构树 + * + * @param sysOrgParam 查询参数 + * @return 系统组织机构树 + * @author xuyuxiang yubaoshan + * @date 2020/3/26 11:56 + */ + List tree(SysOrgParam sysOrgParam); + + /** + * 根据数据范围类型获取当前登录用户的数据范围id集合 + * + * @param dataScopeType 数据范围类型(1全部数据 2本部门及以下数据 3本部门数据 4仅本人数据) + * @param orgId 组织机构id + * @return 数据范围id集合 + * @author xuyuxiang + * @date 2020/4/5 18:29 + */ + List getDataScopeListByDataScopeType(Integer dataScopeType, Long orgId); +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/org/service/impl/SysOrgServiceImpl.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/org/service/impl/SysOrgServiceImpl.java new file mode 100644 index 00000000..4f627281 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/org/service/impl/SysOrgServiceImpl.java @@ -0,0 +1,533 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.org.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.cn.xiaonuo.core.consts.SymbolConstant; +import com.cn.xiaonuo.core.context.login.LoginContextHolder; +import com.cn.xiaonuo.core.enums.CommonStatusEnum; +import com.cn.xiaonuo.core.exception.PermissionException; +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.core.exception.enums.PermissionExceptionEnum; +import com.cn.xiaonuo.core.factory.PageFactory; +import com.cn.xiaonuo.core.factory.TreeBuildFactory; +import com.cn.xiaonuo.core.pojo.node.AntdBaseTreeNode; +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.core.enums.DataScopeTypeEnum; +import com.cn.xiaonuo.sys.modular.emp.service.SysEmpExtOrgPosService; +import com.cn.xiaonuo.sys.modular.emp.service.SysEmpService; +import com.cn.xiaonuo.sys.modular.org.entity.SysOrg; +import com.cn.xiaonuo.sys.modular.org.enums.SysOrgExceptionEnum; +import com.cn.xiaonuo.sys.modular.org.mapper.SysOrgMapper; +import com.cn.xiaonuo.sys.modular.org.param.SysOrgParam; +import com.cn.xiaonuo.sys.modular.org.service.SysOrgService; +import com.cn.xiaonuo.sys.modular.role.service.SysRoleDataScopeService; +import com.cn.xiaonuo.sys.modular.user.service.SysUserDataScopeService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.cn.xiaonuo.core.consts.SymbolConstant; +import com.cn.xiaonuo.core.context.login.LoginContextHolder; +import com.cn.xiaonuo.core.enums.CommonStatusEnum; +import com.cn.xiaonuo.core.exception.PermissionException; +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.core.exception.enums.PermissionExceptionEnum; +import com.cn.xiaonuo.core.factory.PageFactory; +import com.cn.xiaonuo.core.factory.TreeBuildFactory; +import com.cn.xiaonuo.core.pojo.node.AntdBaseTreeNode; +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.core.enums.DataScopeTypeEnum; +import com.cn.xiaonuo.sys.modular.emp.service.SysEmpExtOrgPosService; +import com.cn.xiaonuo.sys.modular.emp.service.SysEmpService; +import com.cn.xiaonuo.sys.modular.org.entity.SysOrg; +import com.cn.xiaonuo.sys.modular.org.enums.SysOrgExceptionEnum; +import com.cn.xiaonuo.sys.modular.org.mapper.SysOrgMapper; +import com.cn.xiaonuo.sys.modular.org.param.SysOrgParam; +import com.cn.xiaonuo.sys.modular.org.service.SysOrgService; +import com.cn.xiaonuo.sys.modular.role.service.SysRoleDataScopeService; +import com.cn.xiaonuo.sys.modular.user.service.SysUserDataScopeService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Set; + +/** + * 系统组织机构service接口实现类 + * + * @author xuyuxiang + * @date 2020/3/13 16:02 + */ +@Service +public class SysOrgServiceImpl extends ServiceImpl implements SysOrgService { + + @Resource + private SysEmpService sysEmpService; + + @Resource + private SysEmpExtOrgPosService sysEmpExtOrgPosService; + + @Resource + private SysRoleDataScopeService sysRoleDataScopeService; + + @Resource + private SysUserDataScopeService sysUserDataScopeService; + + @Override + public PageResult page(SysOrgParam sysOrgParam) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + if (ObjectUtil.isNotNull(sysOrgParam)) { + + // 根据机构名称模糊查询 + if (ObjectUtil.isNotEmpty(sysOrgParam.getName())) { + queryWrapper.like(SysOrg::getName, sysOrgParam.getName()); + } + + // 根据机构id查询 + if (ObjectUtil.isNotEmpty(sysOrgParam.getId())) { + queryWrapper.eq(SysOrg::getId, sysOrgParam.getId()); + } + + // 根据父机构id查询 + if (ObjectUtil.isNotEmpty(sysOrgParam.getPid())) { + queryWrapper + .eq(SysOrg::getId, sysOrgParam.getPid()) + .or() + .like(SysOrg::getPids, sysOrgParam.getPid()); + } + } + + boolean superAdmin = LoginContextHolder.me().isSuperAdmin(); + + // 如果是超级管理员则获取所有组织机构,否则只获取其数据范围的机构数据 + if (!superAdmin) { + List dataScope = sysOrgParam.getDataScope(); + if (ObjectUtil.isEmpty(dataScope)) { + return new PageResult<>(new Page<>()); + } else { + Set dataScopeSet = CollectionUtil.newHashSet(dataScope); + dataScope.forEach(orgId -> { + //此处获取所有的上级节点,放入set,用于构造完整树 + List parentAndChildIdListWithSelf = this.getParentIdListById(orgId); + dataScopeSet.addAll(parentAndChildIdListWithSelf); + }); + queryWrapper.in(SysOrg::getId, dataScopeSet); + } + } + + // 查询启用状态的 + queryWrapper.eq(SysOrg::getStatus, CommonStatusEnum.ENABLE.getCode()); + //根据排序升序排列,序号越小越在前 + queryWrapper.orderByAsc(SysOrg::getSort); + return new PageResult<>(this.page(PageFactory.defaultPage(), queryWrapper)); + } + + @Override + public List list(SysOrgParam sysOrgParam) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + if (ObjectUtil.isNotNull(sysOrgParam)) { + //根据父机构id查询 + if (ObjectUtil.isNotEmpty(sysOrgParam.getPid())) { + queryWrapper.eq(SysOrg::getPid, sysOrgParam.getPid()); + } + } + //如果是超级管理员则获取所有组织机构,否则只获取其数据范围的机构数据 + boolean superAdmin = LoginContextHolder.me().isSuperAdmin(); + if (!superAdmin) { + List dataScope = sysOrgParam.getDataScope(); + if (ObjectUtil.isEmpty(dataScope)) { + return CollectionUtil.newArrayList(); + } else { + Set dataScopeSet = CollectionUtil.newHashSet(dataScope); + dataScope.forEach(orgId -> { + //此处获取所有的上级节点,放入set,用于构造完整树 + List parentAndChildIdListWithSelf = this.getParentIdListById(orgId); + dataScopeSet.addAll(parentAndChildIdListWithSelf); + }); + queryWrapper.in(SysOrg::getId, dataScopeSet); + } + } + queryWrapper.eq(SysOrg::getStatus, CommonStatusEnum.ENABLE.getCode()); + //根据排序升序排列,序号越小越在前 + queryWrapper.orderByAsc(SysOrg::getSort); + return this.list(queryWrapper); + } + + @Override + public void add(SysOrgParam sysOrgParam) { + //校验参数,检查是否存在相同的名称和编码 + checkParam(sysOrgParam, false); + //获取父id + Long pid = sysOrgParam.getPid(); + boolean superAdmin = LoginContextHolder.me().isSuperAdmin(); + //如果登录用户不是超级管理员 + if (!superAdmin) { + //如果新增的机构父id不是0,则进行数据权限校验 + if (!pid.equals(0L)) { + List dataScope = sysOrgParam.getDataScope(); + //数据范围为空 + if (ObjectUtil.isEmpty(dataScope)) { + throw new PermissionException(PermissionExceptionEnum.NO_PERMISSION_OPERATE); + } else if (!dataScope.contains(pid)) { + //所添加的组织机构的父机构不在自己的数据范围内 + throw new PermissionException(PermissionExceptionEnum.NO_PERMISSION_OPERATE); + } + } else { + //如果新增的机构父id是0,则根本没权限,只有超级管理员能添加父id为0的节点 + throw new PermissionException(PermissionExceptionEnum.NO_PERMISSION_OPERATE); + } + } + + SysOrg sysOrg = new SysOrg(); + BeanUtil.copyProperties(sysOrgParam, sysOrg); + this.fillPids(sysOrg); + sysOrg.setStatus(CommonStatusEnum.ENABLE.getCode()); + this.save(sysOrg); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void delete(SysOrgParam sysOrgParam) { + SysOrg sysOrg = this.querySysOrg(sysOrgParam); + Long id = sysOrg.getId(); + boolean superAdmin = LoginContextHolder.me().isSuperAdmin(); + if (!superAdmin) { + List dataScope = sysOrgParam.getDataScope(); + //数据范围为空 + if (ObjectUtil.isEmpty(dataScope)) { + throw new PermissionException(PermissionExceptionEnum.NO_PERMISSION_OPERATE); + } else if (!dataScope.contains(id)) { + //所操作的数据不在自己的数据范围内 + throw new PermissionException(PermissionExceptionEnum.NO_PERMISSION_OPERATE); + } + } + // 该机构下有员工,则不能删 + boolean hasOrgEmp = sysEmpService.hasOrgEmp(id); + if (hasOrgEmp) { + throw new ServiceException(SysOrgExceptionEnum.ORG_CANNOT_DELETE); + } + + // 该附属机构下若有员工,则不能删除 + boolean hasExtOrgEmp = sysEmpExtOrgPosService.hasExtOrgEmp(id); + if (hasExtOrgEmp) { + throw new ServiceException(SysOrgExceptionEnum.ORG_CANNOT_DELETE); + } + + // 级联删除子节点 + List childIdList = this.getChildIdListById(id); + childIdList.add(id); + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.in(SysOrg::getId, childIdList) + .set(SysOrg::getStatus, CommonStatusEnum.DELETED.getCode()); + this.update(updateWrapper); + + // 级联删除该机构及子机构对应的角色-数据范围关联信息 + sysRoleDataScopeService.deleteRoleDataScopeListByOrgIdList(childIdList); + + // 级联删除该机构子机构对应的用户-数据范围关联信息 + sysUserDataScopeService.deleteUserDataScopeListByOrgIdList(childIdList); + + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void edit(SysOrgParam sysOrgParam) { + + SysOrg sysOrg = this.querySysOrg(sysOrgParam); + Long id = sysOrg.getId(); + + // 检测此人数据范围能不能操作这个公司 + boolean superAdmin = LoginContextHolder.me().isSuperAdmin(); + if (!superAdmin) { + List dataScope = sysOrgParam.getDataScope(); + //数据范围为空 + if (ObjectUtil.isEmpty(dataScope)) { + throw new PermissionException(PermissionExceptionEnum.NO_PERMISSION_OPERATE); + } + //数据范围中不包含本公司 + else if (!dataScope.contains(id)) { + throw new PermissionException(PermissionExceptionEnum.NO_PERMISSION_OPERATE); + } + } + + //校验参数,检查是否存在相同的名称和编码 + checkParam(sysOrgParam, true); + + //如果名称有变化,则修改对应员工的机构相关信息 + if (!sysOrg.getName().equals(sysOrgParam.getName())) { + sysEmpService.updateEmpOrgInfo(sysOrg.getId(), sysOrg.getName()); + } + + BeanUtil.copyProperties(sysOrgParam, sysOrg); + this.fillPids(sysOrg); + + //不能修改状态,用修改状态接口修改状态 + sysOrg.setStatus(null); + this.updateById(sysOrg); + } + + @Override + public SysOrg detail(SysOrgParam sysOrgParam) { + return this.querySysOrg(sysOrgParam); + } + + @Override + public List tree(SysOrgParam sysOrgParam) { + List treeNodeList = CollectionUtil.newArrayList(); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + + // 如果是超级管理员则获取所有组织机构,否则只获取其数据范围的机构数据 + boolean superAdmin = LoginContextHolder.me().isSuperAdmin(); + if (!superAdmin) { + List dataScope = sysOrgParam.getDataScope(); + if (ObjectUtil.isEmpty(dataScope)) { + return treeNodeList; + } else { + Set dataScopeSet = CollectionUtil.newHashSet(dataScope); + dataScope.forEach(orgId -> { + //此处获取所有的上级节点,放入set,用于构造完整树 + List parentAndChildIdListWithSelf = this.getParentIdListById(orgId); + dataScopeSet.addAll(parentAndChildIdListWithSelf); + }); + queryWrapper.in(SysOrg::getId, dataScopeSet); + } + } + + // 只查询未删除的 + queryWrapper.eq(SysOrg::getStatus, CommonStatusEnum.ENABLE.getCode()); + //根据排序升序排列,序号越小越在前 + queryWrapper.orderByAsc(SysOrg::getSort); + this.list(queryWrapper).forEach(sysOrg -> { + AntdBaseTreeNode orgTreeNode = new AntdBaseTreeNode(); + orgTreeNode.setId(sysOrg.getId()); + orgTreeNode.setParentId(sysOrg.getPid()); + orgTreeNode.setTitle(sysOrg.getName()); + orgTreeNode.setValue(String.valueOf(sysOrg.getId())); + orgTreeNode.setWeight(sysOrg.getSort()); + treeNodeList.add(orgTreeNode); + }); + + return new TreeBuildFactory().doTreeBuild(treeNodeList); + } + + @Override + public List getDataScopeListByDataScopeType(Integer dataScopeType, Long orgId) { + List resultList = CollectionUtil.newArrayList(); + + if (ObjectUtil.isEmpty(orgId)) { + return CollectionUtil.newArrayList(); + } + + // 如果是范围类型是全部数据,则获取当前系统所有的组织架构id + if (DataScopeTypeEnum.ALL.getCode().equals(dataScopeType)) { + resultList = this.getOrgIdAll(); + } + // 如果范围类型是本部门及以下部门,则查询本节点和子节点集合,包含本节点 + else if (DataScopeTypeEnum.DEPT_WITH_CHILD.getCode().equals(dataScopeType)) { + resultList = this.getChildIdListWithSelfById(orgId); + } + // 如果数据范围是本部门,不含子节点,则直接返回本部门 + else if (DataScopeTypeEnum.DEPT.getCode().equals(dataScopeType)) { + resultList.add(orgId); + } + + return resultList; + } + + /** + * 根据条件获取组织机构id集合 + * + * @author xuyuxiang + * @date 2020/4/5 18:35 + */ + private List getOrgIdAll() { + List resultList = CollectionUtil.newArrayList(); + + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + + queryWrapper.eq(SysOrg::getStatus, CommonStatusEnum.ENABLE.getCode()); + + this.list(queryWrapper).forEach(sysOrg -> resultList.add(sysOrg.getId())); + return resultList; + } + + /** + * 校验参数,检查是否存在相同的名称和编码 + * + * @author xuyuxiang + * @date 2020/3/25 21:23 + */ + private void checkParam(SysOrgParam sysOrgParam, boolean isExcludeSelf) { + Long id = sysOrgParam.getId(); + String name = sysOrgParam.getName(); + String code = sysOrgParam.getCode(); + Long pid = sysOrgParam.getPid(); + + //如果父id不是根节点 + if (!pid.equals(0L)) { + SysOrg pOrg = this.getById(pid); + if (ObjectUtil.isNull(pOrg)) { + //父机构不存在 + throw new ServiceException(SysOrgExceptionEnum.ORG_NOT_EXIST); + } + } + + // 如果是编辑,父id和自己的id不能一致 + if (isExcludeSelf) { + if (sysOrgParam.getId().equals(sysOrgParam.getPid())) { + throw new ServiceException(SysOrgExceptionEnum.ID_CANT_EQ_PID); + } + } + + LambdaQueryWrapper queryWrapperByName = new LambdaQueryWrapper<>(); + queryWrapperByName.eq(SysOrg::getName, name) + .ne(SysOrg::getStatus, CommonStatusEnum.DELETED.getCode()); + + LambdaQueryWrapper queryWrapperByCode = new LambdaQueryWrapper<>(); + queryWrapperByCode.eq(SysOrg::getCode, code) + .ne(SysOrg::getStatus, CommonStatusEnum.DELETED.getCode()); + + if (isExcludeSelf) { + queryWrapperByName.ne(SysOrg::getId, id); + queryWrapperByCode.ne(SysOrg::getId, id); + } + int countByName = this.count(queryWrapperByName); + int countByCode = this.count(queryWrapperByCode); + + if (countByName >= 1) { + throw new ServiceException(SysOrgExceptionEnum.ORG_NAME_REPEAT); + } + if (countByCode >= 1) { + throw new ServiceException(SysOrgExceptionEnum.ORG_CODE_REPEAT); + } + } + + /** + * 获取系统组织机构 + * + * @author xuyuxiang + * @date 2020/3/26 9:56 + */ + private SysOrg querySysOrg(SysOrgParam sysOrgParam) { + SysOrg sysOrg = this.getById(sysOrgParam.getId()); + if (ObjectUtil.isNull(sysOrg)) { + throw new ServiceException(SysOrgExceptionEnum.ORG_NOT_EXIST); + } + return sysOrg; + } + + /** + * 填充父ids + * + * @author xuyuxiang + * @date 2020/3/26 11:28 + */ + private void fillPids(SysOrg sysOrg) { + if (sysOrg.getPid().equals(0L)) { + sysOrg.setPids(SymbolConstant.LEFT_SQUARE_BRACKETS + + 0 + + SymbolConstant.RIGHT_SQUARE_BRACKETS + + SymbolConstant.COMMA); + } else { + //获取父组织机构 + SysOrg pSysOrg = this.getById(sysOrg.getPid()); + sysOrg.setPids(pSysOrg.getPids() + + SymbolConstant.LEFT_SQUARE_BRACKETS + pSysOrg.getId() + + SymbolConstant.RIGHT_SQUARE_BRACKETS + + SymbolConstant.COMMA); + } + } + + /** + * 根据节点id获取所有子节点id集合 + * + * @author xuyuxiang + * @date 2020/3/26 11:31 + */ + private List getChildIdListById(Long id) { + List childIdList = CollectionUtil.newArrayList(); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + + queryWrapper.like(SysOrg::getPids, SymbolConstant.LEFT_SQUARE_BRACKETS + id + + SymbolConstant.RIGHT_SQUARE_BRACKETS); + + this.list(queryWrapper).forEach(sysOrg -> childIdList.add(sysOrg.getId())); + + return childIdList; + } + + /** + * 根据节点id获取所有父节点id集合,不包含自己 + * + * @author xuyuxiang + * @date 2020/4/6 14:53 + */ + private List getParentIdListById(Long id) { + List resultList = CollectionUtil.newArrayList(); + SysOrg sysOrg = this.getById(id); + String pids = sysOrg.getPids(); + String pidsWithRightSymbol = StrUtil.removeAll(pids, SymbolConstant.LEFT_SQUARE_BRACKETS); + String pidsNormal = StrUtil.removeAll(pidsWithRightSymbol, SymbolConstant.RIGHT_SQUARE_BRACKETS); + String[] pidsNormalArr = pidsNormal.split(SymbolConstant.COMMA); + for (String pid : pidsNormalArr) { + resultList.add(Convert.toLong(pid)); + } + return resultList; + } + + /** + * 根据节点id获取所有子节点id集合,包含自己 + * + * @author xuyuxiang + * @date 2020/4/6 14:54 + */ + private List getChildIdListWithSelfById(Long id) { + List childIdListById = this.getChildIdListById(id); + List resultList = CollectionUtil.newArrayList(childIdListById); + resultList.add(id); + return resultList; + } + + /** + * 根据节点id获取父节点和子节点id集合,包含自己 + * + * @author xuyuxiang + * @date 2020/4/7 16:50 + */ + private List getParentAndChildIdListWithSelfById(Long id) { + Set resultSet = CollectionUtil.newHashSet(); + List parentIdListById = this.getParentIdListById(id); + List childIdListById = this.getChildIdListById(id); + resultSet.addAll(parentIdListById); + resultSet.addAll(childIdListById); + return CollectionUtil.newArrayList(resultSet); + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/pos/controller/SysPosController.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/pos/controller/SysPosController.java new file mode 100644 index 00000000..8724b05f --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/pos/controller/SysPosController.java @@ -0,0 +1,141 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.pos.controller; + +import com.cn.xiaonuo.core.annotion.BusinessLog; +import com.cn.xiaonuo.core.annotion.Permission; +import com.cn.xiaonuo.core.enums.LogAnnotionOpTypeEnum; +import com.cn.xiaonuo.core.pojo.response.ResponseData; +import com.cn.xiaonuo.core.pojo.response.SuccessResponseData; +import com.cn.xiaonuo.sys.modular.pos.param.SysPosParam; +import com.cn.xiaonuo.sys.modular.pos.service.SysPosService; +import com.cn.xiaonuo.core.annotion.BusinessLog; +import com.cn.xiaonuo.core.annotion.Permission; +import com.cn.xiaonuo.core.enums.LogAnnotionOpTypeEnum; +import com.cn.xiaonuo.core.pojo.response.ResponseData; +import com.cn.xiaonuo.core.pojo.response.SuccessResponseData; +import com.cn.xiaonuo.sys.modular.pos.param.SysPosParam; +import com.cn.xiaonuo.sys.modular.pos.service.SysPosService; +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.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + * 系统职位控制器 + * + * @author xuyuxiang + * @date 2020/3/20 19:44 + */ +@RestController +public class SysPosController { + + @Resource + private SysPosService sysPosService; + + /** + * 查询系统职位 + * + * @author xuyuxiang + * @date 2020/3/26 10:20 + */ + @Permission + @GetMapping("/sysPos/page") + @BusinessLog(title = "系统职位_查询", opType = LogAnnotionOpTypeEnum.QUERY) + public ResponseData page(SysPosParam sysPosParam) { + return new SuccessResponseData(sysPosService.page(sysPosParam)); + } + + /** + * 系统职位列表 + * + * @author yubaoshan + * @date 2020/6/21 23:38 + */ + @Permission + @GetMapping("/sysPos/list") + @BusinessLog(title = "系统职位_列表", opType = LogAnnotionOpTypeEnum.QUERY) + public ResponseData list(SysPosParam sysPosParam) { + return new SuccessResponseData(sysPosService.list(sysPosParam)); + } + + /** + * 添加系统职位 + * + * @author xuyuxiang + * @date 2020/3/26 19:03 + */ + @Permission + @PostMapping("/sysPos/add") + @BusinessLog(title = "系统职位_增加", opType = LogAnnotionOpTypeEnum.ADD) + public ResponseData add(@RequestBody @Validated(SysPosParam.add.class) SysPosParam sysPosParam) { + sysPosService.add(sysPosParam); + return new SuccessResponseData(); + } + + /** + * 删除系统职位 + * + * @author xuyuxiang + * @date 2020/3/25 14:54 + */ + @Permission + @PostMapping("/sysPos/delete") + @BusinessLog(title = "系统职位_删除", opType = LogAnnotionOpTypeEnum.DELETE) + public ResponseData delete(@RequestBody @Validated(SysPosParam.delete.class) SysPosParam sysPosParam) { + sysPosService.delete(sysPosParam); + return new SuccessResponseData(); + } + + /** + * 编辑系统职位 + * + * @author xuyuxiang + * @date 2020/3/25 14:54 + */ + @Permission + @PostMapping("/sysPos/edit") + @BusinessLog(title = "系统职位_编辑", opType = LogAnnotionOpTypeEnum.EDIT) + public ResponseData edit(@RequestBody @Validated(SysPosParam.edit.class) SysPosParam sysPosParam) { + sysPosService.edit(sysPosParam); + return new SuccessResponseData(); + } + + /** + * 查看系统职位 + * + * @author xuyuxiang + * @date 2020/3/26 9:49 + */ + @Permission + @GetMapping("/sysPos/detail") + @BusinessLog(title = "系统职位_查看", opType = LogAnnotionOpTypeEnum.DETAIL) + public ResponseData detail(@Validated(SysPosParam.detail.class) SysPosParam sysPosParam) { + return new SuccessResponseData(sysPosService.detail(sysPosParam)); + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/pos/entity/SysPos.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/pos/entity/SysPos.java new file mode 100644 index 00000000..231d2251 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/pos/entity/SysPos.java @@ -0,0 +1,75 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.pos.entity; + +import com.cn.xiaonuo.core.pojo.base.entity.BaseEntity; +import com.baomidou.mybatisplus.annotation.*; +import com.cn.xiaonuo.core.pojo.base.entity.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 系统职位表 + * + * @author xuyuxiang + * @date 2020/3/11 11:20 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@TableName("sys_pos") +public class SysPos extends BaseEntity { + + /** + * 主键 + */ + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + /** + * 名称 + */ + private String name; + + /** + * 编码 + */ + private String code; + + /** + * 排序 + */ + private Integer sort; + + /** + * 备注 + */ + @TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED) + private String remark; + + /** + * 状态(字典 0正常 1停用 2删除) + */ + private Integer status; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/pos/enums/SysPosExceptionEnum.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/pos/enums/SysPosExceptionEnum.java new file mode 100644 index 00000000..a743f09a --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/pos/enums/SysPosExceptionEnum.java @@ -0,0 +1,80 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.pos.enums; + +import com.cn.xiaonuo.core.annotion.ExpEnumType; +import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum; +import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory; +import com.cn.xiaonuo.sys.core.consts.SysExpEnumConstant; + +/** + * 系统职位相关异常枚举 + * + * @author xuyuxiang + * @date 2020/3/26 10:12 + */ +@ExpEnumType(module = SysExpEnumConstant.XIAONUO_SYS_MODULE_EXP_CODE, kind = SysExpEnumConstant.SYS_POS_EXCEPTION_ENUM) +public enum SysPosExceptionEnum implements AbstractBaseExceptionEnum { + + /** + * 职位不存在 + */ + POS_NOT_EXIST(1, "职位不存在"), + + /** + * 职位编码重复 + */ + POS_CODE_REPEAT(2, "职位编码重复,请检查code参数"), + + /** + * 职位名称重复 + */ + POS_NAME_REPEAT(3, "职位名称重复,请检查name参数"), + + /** + * 该职位下有员工 + */ + POS_CANNOT_DELETE(4, "该职位下有员工,无法删除"); + + private final Integer code; + + private final String message; + + SysPosExceptionEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return ExpEnumCodeFactory.getExpEnumCode(this.getClass(), code); + } + + @Override + public String getMessage() { + return message; + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/pos/mapper/SysPosMapper.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/pos/mapper/SysPosMapper.java new file mode 100644 index 00000000..872358e2 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/pos/mapper/SysPosMapper.java @@ -0,0 +1,37 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.pos.mapper; + +import com.cn.xiaonuo.sys.modular.pos.entity.SysPos; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 系统职位mapper接口 + * + * @author xuyuxiang + * @date 2020/3/13 16:00 + */ +public interface SysPosMapper extends BaseMapper { +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/pos/mapper/mapping/SysPosMapper.xml b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/pos/mapper/mapping/SysPosMapper.xml new file mode 100644 index 00000000..dbdc73a2 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/pos/mapper/mapping/SysPosMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/pos/param/SysPosParam.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/pos/param/SysPosParam.java new file mode 100644 index 00000000..a2f5c1c9 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/pos/param/SysPosParam.java @@ -0,0 +1,72 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.pos.param; + +import com.cn.xiaonuo.core.pojo.base.param.BaseParam; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 系统职位参数 + * + * @author xuyuxiang + * @date 2020/3/26 19:02 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class SysPosParam extends BaseParam { + + /** + * 主键 + */ + @NotNull(message = "id不能为空,请检查id参数", groups = {edit.class, delete.class, detail.class}) + private Long id; + + /** + * 名称 + */ + @NotBlank(message = "名称不能为空,请检查name参数", groups = {add.class, edit.class}) + private String name; + + /** + * 编码 + */ + @NotBlank(message = "编码不能为空,请检查code参数", groups = {add.class, edit.class}) + private String code; + + /** + * 排序 + */ + @NotNull(message = "排序不能为空,请检查sort参数", groups = {add.class, edit.class}) + private Integer sort; + + /** + * 备注 + */ + private String remark; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/pos/service/SysPosService.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/pos/service/SysPosService.java new file mode 100644 index 00000000..6d2a1efd --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/pos/service/SysPosService.java @@ -0,0 +1,101 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.pos.service; + +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.modular.pos.entity.SysPos; +import com.cn.xiaonuo.sys.modular.pos.param.SysPosParam; +import com.baomidou.mybatisplus.extension.service.IService; +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.modular.pos.entity.SysPos; +import com.cn.xiaonuo.sys.modular.pos.param.SysPosParam; + +import java.util.List; + +/** + * 系统职位service接口 + * + * @author xuyuxiang + * @date 2020/3/13 16:00 + */ +public interface SysPosService extends IService { + + /** + * 查询系统职位 + * + * @param sysPosParam 查询参数 + * @return 查询分页结果 + * @author xuyuxiang + * @date 2020/3/26 10:19 + */ + PageResult page(SysPosParam sysPosParam); + + /** + * 系统职位列表 + * + * @param sysPosParam 查询参数 + * @return 职位列表 + * @author yubaoshan + * @date 2020/6/21 23:44 + */ + List list(SysPosParam sysPosParam); + + /** + * 添加系统职位 + * + * @param sysPosParam 添加参数 + * @author xuyuxiang + * @date 2020/3/25 14:57 + */ + void add(SysPosParam sysPosParam); + + /** + * 删除系统职位 + * + * @param sysPosParam 删除参数 + * @author xuyuxiang + * @date 2020/3/25 14:57 + */ + void delete(SysPosParam sysPosParam); + + /** + * 编辑系统职位 + * + * @param sysPosParam 编辑参数 + * @author xuyuxiang + * @date 2020/3/25 14:58 + */ + void edit(SysPosParam sysPosParam); + + /** + * 查看系统职位 + * + * @param sysPosParam 查看参数 + * @return 系统职位 + * @author xuyuxiang + * @date 2020/3/26 9:50 + */ + SysPos detail(SysPosParam sysPosParam); +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/pos/service/impl/SysPosServiceImpl.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/pos/service/impl/SysPosServiceImpl.java new file mode 100644 index 00000000..7f629d68 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/pos/service/impl/SysPosServiceImpl.java @@ -0,0 +1,204 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.pos.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.ObjectUtil; +import com.cn.xiaonuo.core.enums.CommonStatusEnum; +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.core.factory.PageFactory; +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.modular.emp.service.SysEmpExtOrgPosService; +import com.cn.xiaonuo.sys.modular.emp.service.SysEmpPosService; +import com.cn.xiaonuo.sys.modular.pos.entity.SysPos; +import com.cn.xiaonuo.sys.modular.pos.enums.SysPosExceptionEnum; +import com.cn.xiaonuo.sys.modular.pos.mapper.SysPosMapper; +import com.cn.xiaonuo.sys.modular.pos.param.SysPosParam; +import com.cn.xiaonuo.sys.modular.pos.service.SysPosService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.cn.xiaonuo.core.enums.CommonStatusEnum; +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.core.factory.PageFactory; +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.modular.emp.service.SysEmpExtOrgPosService; +import com.cn.xiaonuo.sys.modular.emp.service.SysEmpPosService; +import com.cn.xiaonuo.sys.modular.pos.entity.SysPos; +import com.cn.xiaonuo.sys.modular.pos.enums.SysPosExceptionEnum; +import com.cn.xiaonuo.sys.modular.pos.mapper.SysPosMapper; +import com.cn.xiaonuo.sys.modular.pos.param.SysPosParam; +import com.cn.xiaonuo.sys.modular.pos.service.SysPosService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 系统职位service接口实现类 + * + * @author xuyuxiang + * @date 2020/3/13 16:01 + */ +@Service +public class SysPosServiceImpl extends ServiceImpl implements SysPosService { + + @Resource + private SysEmpPosService sysEmpPosService; + + @Resource + private SysEmpExtOrgPosService sysEmpExtOrgPosService; + + @Override + public PageResult page(SysPosParam sysPosParam) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + if (ObjectUtil.isNotNull(sysPosParam)) { + //根据职位名称模糊查询 + if (ObjectUtil.isNotEmpty(sysPosParam.getName())) { + queryWrapper.like(SysPos::getName, sysPosParam.getName()); + } + //根据职位编码模糊查询 + if (ObjectUtil.isNotEmpty(sysPosParam.getCode())) { + queryWrapper.like(SysPos::getCode, sysPosParam.getCode()); + } + } + queryWrapper.eq(SysPos::getStatus, CommonStatusEnum.ENABLE.getCode()); + //根据排序升序排列,序号越小越在前 + queryWrapper.orderByAsc(SysPos::getSort); + return new PageResult<>(this.page(PageFactory.defaultPage(), queryWrapper)); + } + + @Override + public List list(SysPosParam sysPosParam) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + if (ObjectUtil.isNotNull(sysPosParam)) { + //根据职位编码模糊查询 + if (ObjectUtil.isNotEmpty(sysPosParam.getCode())) { + queryWrapper.eq(SysPos::getCode, sysPosParam.getCode()); + } + } + queryWrapper.eq(SysPos::getStatus, CommonStatusEnum.ENABLE.getCode()); + //根据排序升序排列,序号越小越在前 + queryWrapper.orderByAsc(SysPos::getSort); + return this.list(queryWrapper); + } + + @Override + public void add(SysPosParam sysPosParam) { + //校验参数,检查是否存在相同的名称和编码 + checkParam(sysPosParam, false); + SysPos sysPos = new SysPos(); + BeanUtil.copyProperties(sysPosParam, sysPos); + sysPos.setStatus(CommonStatusEnum.ENABLE.getCode()); + this.save(sysPos); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void delete(SysPosParam sysPosParam) { + SysPos sysPos = this.querySysPos(sysPosParam); + Long id = sysPos.getId(); + //该职位下是否有员工 + boolean hasPosEmp = sysEmpPosService.hasPosEmp(id); + //只要还有,则不能删 + if (hasPosEmp) { + throw new ServiceException(SysPosExceptionEnum.POS_CANNOT_DELETE); + } + //该附属职位下是否有员工 + boolean hasExtPosEmp = sysEmpExtOrgPosService.hasExtPosEmp(id); + //只要还有,则不能删 + if (hasExtPosEmp) { + throw new ServiceException(SysPosExceptionEnum.POS_CANNOT_DELETE); + } + sysPos.setStatus(CommonStatusEnum.DELETED.getCode()); + this.updateById(sysPos); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void edit(SysPosParam sysPosParam) { + SysPos sysPos = this.querySysPos(sysPosParam); + //校验参数,检查是否存在相同的名称和编码 + checkParam(sysPosParam, true); + BeanUtil.copyProperties(sysPosParam, sysPos); + //不能修改状态,用修改状态接口修改状态 + sysPos.setStatus(null); + this.updateById(sysPos); + } + + @Override + public SysPos detail(SysPosParam sysPosParam) { + return this.querySysPos(sysPosParam); + } + + /** + * 校验参数,检查是否存在相同的名称和编码 + * + * @author xuyuxiang + * @date 2020/3/25 21:23 + */ + private void checkParam(SysPosParam sysPosParam, boolean isExcludeSelf) { + Long id = sysPosParam.getId(); + String name = sysPosParam.getName(); + String code = sysPosParam.getCode(); + + LambdaQueryWrapper queryWrapperByName = new LambdaQueryWrapper<>(); + queryWrapperByName.eq(SysPos::getName, name) + .ne(SysPos::getStatus, CommonStatusEnum.DELETED.getCode()); + + LambdaQueryWrapper queryWrapperByCode = new LambdaQueryWrapper<>(); + queryWrapperByCode.eq(SysPos::getCode, code) + .ne(SysPos::getStatus, CommonStatusEnum.DELETED.getCode()); + + if (isExcludeSelf) { + queryWrapperByName.ne(SysPos::getId, id); + queryWrapperByCode.ne(SysPos::getId, id); + } + + int countByName = this.count(queryWrapperByName); + int countByCode = this.count(queryWrapperByCode); + + if (countByName >= 1) { + throw new ServiceException(SysPosExceptionEnum.POS_NAME_REPEAT); + } + if (countByCode >= 1) { + throw new ServiceException(SysPosExceptionEnum.POS_CODE_REPEAT); + } + } + + /** + * 获取系统职位 + * + * @author xuyuxiang + * @date 2020/3/26 9:56 + */ + private SysPos querySysPos(SysPosParam sysPosParam) { + SysPos sysPos = this.getById(sysPosParam.getId()); + if (ObjectUtil.isNull(sysPos)) { + throw new ServiceException(SysPosExceptionEnum.POS_NOT_EXIST); + } + return sysPos; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/controller/SysRoleController.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/controller/SysRoleController.java new file mode 100644 index 00000000..25c1434e --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/controller/SysRoleController.java @@ -0,0 +1,191 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.role.controller; + +import com.cn.xiaonuo.core.annotion.BusinessLog; +import com.cn.xiaonuo.core.annotion.DataScope; +import com.cn.xiaonuo.core.annotion.Permission; +import com.cn.xiaonuo.core.enums.LogAnnotionOpTypeEnum; +import com.cn.xiaonuo.core.pojo.response.ResponseData; +import com.cn.xiaonuo.core.pojo.response.SuccessResponseData; +import com.cn.xiaonuo.sys.modular.role.param.SysRoleParam; +import com.cn.xiaonuo.sys.modular.role.service.SysRoleService; +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.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + * 系统角色控制器 + * + * @author xuyuxiang + * @date 2020/3/20 19:42 + */ +@RestController +public class SysRoleController { + + @Resource + private SysRoleService sysRoleService; + + /** + * 查询系统角色 + * + * @author xuyuxiang + * @date 2020/3/28 14:45 + */ + @Permission + @GetMapping("/sysRole/page") + @BusinessLog(title = "系统角色_查询", opType = LogAnnotionOpTypeEnum.QUERY) + public ResponseData page(SysRoleParam sysRoleParam) { + return new SuccessResponseData(sysRoleService.page(sysRoleParam)); + } + + /** + * 系统角色下拉(用于授权角色时选择) + * + * @author xuyuxiang + * @date 2020/4/5 16:45 + */ + @Permission + @GetMapping("/sysRole/dropDown") + @BusinessLog(title = "系统角色_下拉", opType = LogAnnotionOpTypeEnum.QUERY) + public ResponseData dropDown() { + return new SuccessResponseData(sysRoleService.dropDown()); + } + + /** + * 添加系统角色 + * + * @author xuyuxiang + * @date 2020/3/28 14:45 + */ + @Permission + @PostMapping("/sysRole/add") + @BusinessLog(title = "系统角色_增加", opType = LogAnnotionOpTypeEnum.ADD) + public ResponseData add(@RequestBody @Validated(SysRoleParam.add.class) SysRoleParam sysRoleParam) { + sysRoleService.add(sysRoleParam); + return new SuccessResponseData(); + } + + /** + * 删除系统角色 + * + * @author xuyuxiang + * @date 2020/3/28 14:45 + */ + @Permission + @PostMapping("/sysRole/delete") + @BusinessLog(title = "系统角色_删除", opType = LogAnnotionOpTypeEnum.DELETE) + public ResponseData delete(@RequestBody @Validated(SysRoleParam.delete.class) SysRoleParam sysRoleParam) { + sysRoleService.delete(sysRoleParam); + return new SuccessResponseData(); + } + + /** + * 编辑系统角色 + * + * @author xuyuxiang + * @date 2020/3/28 14:46 + */ + @Permission + @PostMapping("/sysRole/edit") + @BusinessLog(title = "系统角色_编辑", opType = LogAnnotionOpTypeEnum.EDIT) + public ResponseData edit(@RequestBody @Validated(SysRoleParam.edit.class) SysRoleParam sysRoleParam) { + sysRoleService.edit(sysRoleParam); + return new SuccessResponseData(); + } + + /** + * 查看系统角色 + * + * @author xuyuxiang + * @date 2020/3/28 14:46 + */ + @Permission + @GetMapping("/sysRole/detail") + @BusinessLog(title = "系统角色_查看", opType = LogAnnotionOpTypeEnum.DETAIL) + public ResponseData detail(@Validated(SysRoleParam.detail.class) SysRoleParam sysRoleParam) { + return new SuccessResponseData(sysRoleService.detail(sysRoleParam)); + } + + /** + * 授权菜单 + * + * @author xuyuxiang + * @date 2020/3/28 16:05 + */ + @Permission + @PostMapping("/sysRole/grantMenu") + @BusinessLog(title = "系统角色_授权菜单", opType = LogAnnotionOpTypeEnum.GRANT) + public ResponseData grantMenu(@RequestBody @Validated(SysRoleParam.grantMenu.class) SysRoleParam sysRoleParam) { + sysRoleService.grantMenu(sysRoleParam); + return new SuccessResponseData(); + } + + /** + * 授权数据 + * + * @author xuyuxiang + * @date 2020/3/28 16:05 + */ + @Permission + @DataScope + @PostMapping("/sysRole/grantData") + @BusinessLog(title = "系统角色_授权数据", opType = LogAnnotionOpTypeEnum.GRANT) + public ResponseData grantData(@RequestBody @Validated(SysRoleParam.grantData.class) SysRoleParam sysRoleParam) { + sysRoleService.grantData(sysRoleParam); + return new SuccessResponseData(); + } + + /** + * 拥有菜单 + * + * @author xuyuxiang + * @date 2020/3/28 14:46 + */ + @Permission + @GetMapping("/sysRole/ownMenu") + @BusinessLog(title = "系统角色_拥有菜单", opType = LogAnnotionOpTypeEnum.DETAIL) + public ResponseData ownMenu(@Validated(SysRoleParam.detail.class) SysRoleParam sysRoleParam) { + return new SuccessResponseData(sysRoleService.ownMenu(sysRoleParam)); + } + + /** + * 拥有数据 + * + * @author xuyuxiang + * @date 2020/3/28 14:46 + */ + @Permission + @GetMapping("/sysRole/ownData") + @BusinessLog(title = "系统角色_拥有数据", opType = LogAnnotionOpTypeEnum.DETAIL) + public ResponseData ownData(@Validated(SysRoleParam.detail.class) SysRoleParam sysRoleParam) { + return new SuccessResponseData(sysRoleService.ownData(sysRoleParam)); + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/entity/SysRole.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/entity/SysRole.java new file mode 100644 index 00000000..d922f672 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/entity/SysRole.java @@ -0,0 +1,79 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.role.entity; + +import com.cn.xiaonuo.core.pojo.base.entity.BaseEntity; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 系统角色表 + * + * @author xuyuxiang + * @date 2020/3/11 11:20 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@TableName("sys_role") +public class SysRole extends BaseEntity { + + /** + * 主键 + */ + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + /** + * 名称 + */ + private String name; + + /** + * 编码 + */ + private String code; + + /** + * 排序 + */ + private Integer sort; + + /** + * 数据范围类型(字典 1全部数据 2本部门及以下数据 3本部门数据 4仅本人数据 5自定义数据) + */ + private Integer dataScopeType; + + /** + * 备注 + */ + @TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED) + private String remark; + + /** + * 状态(字典 0正常 1停用 2删除) + */ + private Integer status; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/entity/SysRoleDataScope.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/entity/SysRoleDataScope.java new file mode 100644 index 00000000..54bf0721 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/entity/SysRoleDataScope.java @@ -0,0 +1,57 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.role.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * 系统角色数据范围表 + * + * @author xuyuxiang + * @date 2020/3/11 11:47 + */ +@Data +@TableName("sys_role_data_scope") +public class SysRoleDataScope { + + /** + * 主键 + */ + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + /** + * 角色id + */ + private Long roleId; + + /** + * 机构id + */ + private Long orgId; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/entity/SysRoleMenu.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/entity/SysRoleMenu.java new file mode 100644 index 00000000..fd945963 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/entity/SysRoleMenu.java @@ -0,0 +1,57 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.role.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * 系统角色菜单表 + * + * @author xuyuxiang + * @date 2020/3/11 11:47 + */ +@Data +@TableName("sys_role_menu") +public class SysRoleMenu { + + /** + * 主键 + */ + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + /** + * 角色id + */ + private Long roleId; + + /** + * 菜单id + */ + private Long menuId; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/enums/SysRoleExceptionEnum.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/enums/SysRoleExceptionEnum.java new file mode 100644 index 00000000..559d70f0 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/enums/SysRoleExceptionEnum.java @@ -0,0 +1,75 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.role.enums; + +import com.cn.xiaonuo.core.annotion.ExpEnumType; +import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum; +import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory; +import com.cn.xiaonuo.sys.core.consts.SysExpEnumConstant; + +/** + * 系统角色相关异常枚举 + * + * @author xuyuxiang + * @date 2020/3/28 14:47 + */ +@ExpEnumType(module = SysExpEnumConstant.XIAONUO_SYS_MODULE_EXP_CODE, kind = SysExpEnumConstant.SYS_ROLE_EXCEPTION_ENUM) +public enum SysRoleExceptionEnum implements AbstractBaseExceptionEnum { + + /** + * 角色不存在 + */ + ROLE_NOT_EXIST(1, "角色不存在"), + + /** + * 角色编码重复 + */ + ROLE_CODE_REPEAT(2, "角色编码重复,请检查code参数"), + + /** + * 角色名称重复 + */ + ROLE_NAME_REPEAT(3, "角色名称重复,请检查name参数"); + + private final Integer code; + + private final String message; + + SysRoleExceptionEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return ExpEnumCodeFactory.getExpEnumCode(this.getClass(), code); + } + + @Override + public String getMessage() { + return message; + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/mapper/SysRoleDataScopeMapper.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/mapper/SysRoleDataScopeMapper.java new file mode 100644 index 00000000..66e2d4ad --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/mapper/SysRoleDataScopeMapper.java @@ -0,0 +1,38 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.role.mapper; + +import com.cn.xiaonuo.sys.modular.role.entity.SysRoleDataScope; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.cn.xiaonuo.sys.modular.role.entity.SysRoleDataScope; + +/** + * 系统角色范围mapper接口 + * + * @author xuyuxiang + * @date 2020/3/13 15:53 + */ +public interface SysRoleDataScopeMapper extends BaseMapper { +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/mapper/SysRoleMapper.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/mapper/SysRoleMapper.java new file mode 100644 index 00000000..4a1f996f --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/mapper/SysRoleMapper.java @@ -0,0 +1,37 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.role.mapper; + +import com.cn.xiaonuo.sys.modular.role.entity.SysRole; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 系统角色mapper接口 + * + * @author xuyuxiang + * @date 2020/3/13 15:51 + */ +public interface SysRoleMapper extends BaseMapper { +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/mapper/SysRoleMenuMapper.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/mapper/SysRoleMenuMapper.java new file mode 100644 index 00000000..da3a89dc --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/mapper/SysRoleMenuMapper.java @@ -0,0 +1,37 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.role.mapper; + +import com.cn.xiaonuo.sys.modular.role.entity.SysRoleMenu; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 系统角色菜单mapper接口 + * + * @author xuyuxiang + * @date 2020/3/13 15:52 + */ +public interface SysRoleMenuMapper extends BaseMapper { +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/mapper/mapping/SysRoleDataScopeMapper.xml b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/mapper/mapping/SysRoleDataScopeMapper.xml new file mode 100644 index 00000000..3b05a98b --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/mapper/mapping/SysRoleDataScopeMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/mapper/mapping/SysRoleMapper.xml b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/mapper/mapping/SysRoleMapper.xml new file mode 100644 index 00000000..74afd223 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/mapper/mapping/SysRoleMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/mapper/mapping/SysRoleMenuMapper.xml b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/mapper/mapping/SysRoleMenuMapper.xml new file mode 100644 index 00000000..40dd8ef1 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/mapper/mapping/SysRoleMenuMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/param/SysRoleParam.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/param/SysRoleParam.java new file mode 100644 index 00000000..cf23f284 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/param/SysRoleParam.java @@ -0,0 +1,93 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.role.param; + +import com.cn.xiaonuo.core.pojo.base.param.BaseParam; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.*; +import java.util.List; + +/** + * 系统角色参数 + * + * @author xuyuxiang + * @date 2020/3/26 19:02 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class SysRoleParam extends BaseParam { + + /** + * 主键 + */ + @NotNull(message = "id不能为空,请检查id参数", groups = {edit.class, delete.class, detail.class, grantMenu.class, grantData.class}) + private Long id; + + /** + * 名称 + */ + @NotBlank(message = "名称不能为空,请检查name参数", groups = {add.class, edit.class}) + private String name; + + /** + * 编码 + */ + @NotBlank(message = "编码不能为空,请检查code参数", groups = {add.class, edit.class}) + private String code; + + /** + * 排序 + */ + @NotNull(message = "排序不能为空,请检查sort参数", groups = {add.class, edit.class}) + private Integer sort; + + /** + * 数据范围类型(字典 1全部数据 2本部门及以下数据 3本部门数据 4仅本人数据 5自定义数据) + */ + @Null(message = "数据范围类型应该为空, 请移除dataScopeType参数", groups = {add.class, edit.class}) + @NotNull(message = "数据范围类型不能为空,请检查dataScopeType参数", groups = {grantData.class}) + @Min(value = 0, message = "数据范围类型格式错误,请检查dataScopeType参数", groups = {grantData.class}) + @Max(value = 5, message = "数据范围类型格式错误,请检查dataScopeType参数", groups = {grantData.class}) + private Integer dataScopeType; + + /** + * 备注 + */ + private String remark; + + /** + * 授权菜单 + */ + @NotNull(message = "授权菜单不能为空,请检查grantMenuIdList参数", groups = {grantMenu.class}) + private List grantMenuIdList; + + /** + * 授权数据 + */ + @NotNull(message = "授权数据不能为空,请检查grantOrgIdList参数", groups = {grantData.class}) + private List grantOrgIdList; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/service/SysRoleDataScopeService.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/service/SysRoleDataScopeService.java new file mode 100644 index 00000000..0bc03972 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/service/SysRoleDataScopeService.java @@ -0,0 +1,77 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.role.service; + +import com.cn.xiaonuo.sys.modular.role.entity.SysRoleDataScope; +import com.cn.xiaonuo.sys.modular.role.param.SysRoleParam; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +/** + * 系统角色数据范围service接口 + * + * @author xuyuxiang + * @date 2020/3/13 15:51 + */ +public interface SysRoleDataScopeService extends IService { + + /** + * 授权数据 + * + * @param sysRoleParam 授权参数 + * @author xuyuxiang + * @date 2020/3/28 16:36 + */ + void grantDataScope(SysRoleParam sysRoleParam); + + /** + * 根据角色id获取角色数据范围集合 + * + * @param roleIdList 角色id集合 + * @return 数据范围id集合 + * @author xuyuxiang + * @date 2020/4/5 17:44 + */ + List getRoleDataScopeIdList(List roleIdList); + + /** + * 根据机构id集合删除对应的角色-数据范围关联信息 + * + * @param orgIdList 机构id集合 + * @author xuyuxiang + * @date 2020/6/28 14:14 + */ + void deleteRoleDataScopeListByOrgIdList(List orgIdList); + + /** + * 根据角色id删除对应的角色-数据范围关联信息 + * + * @param roleId 角色id + * @author xuyuxiang + * @date 2020/6/28 14:47 + */ + void deleteRoleDataScopeListByRoleId(Long roleId); +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/service/SysRoleMenuService.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/service/SysRoleMenuService.java new file mode 100644 index 00000000..d4611e53 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/service/SysRoleMenuService.java @@ -0,0 +1,77 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.role.service; + +import com.cn.xiaonuo.sys.modular.role.entity.SysRoleMenu; +import com.cn.xiaonuo.sys.modular.role.param.SysRoleParam; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +/** + * 系统角色菜单service接口 + * + * @author xuyuxiang + * @date 2020/3/13 15:50 + */ +public interface SysRoleMenuService extends IService { + + /** + * 获取角色的菜单id集合 + * + * @param roleIdList 角色id集合 + * @return 菜单id集合 + * @author xuyuxiang + * @date 2020/3/21 10:17 + */ + List getRoleMenuIdList(List roleIdList); + + /** + * 授权菜单 + * + * @param sysRoleParam 授权参数 + * @author xuyuxiang + * @date 2020/3/28 16:36 + */ + void grantMenu(SysRoleParam sysRoleParam); + + /** + * 根据菜单id集合删除对应的角色-菜单表信息 + * + * @param menuIdList 菜单id集合 + * @author xuyuxiang + * @date 2020/6/28 14:19 + */ + void deleteRoleMenuListByMenuIdList(List menuIdList); + + /** + * 根据角色id删除对应的角色-菜单表关联信息 + * + * @param roleId 角色id + * @author xuyuxiang + * @date 2020/6/28 14:43 + */ + void deleteRoleMenuListByRoleId(Long roleId); +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/service/SysRoleService.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/service/SysRoleService.java new file mode 100644 index 00000000..7e4529d5 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/service/SysRoleService.java @@ -0,0 +1,177 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.role.service; + +import cn.hutool.core.lang.Dict; +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.modular.role.entity.SysRole; +import com.cn.xiaonuo.sys.modular.role.param.SysRoleParam; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +/** + * 系统角色service接口 + * + * @author xuyuxiang + * @date 2020/3/13 15:47 + */ +public interface SysRoleService extends IService { + + /** + * 获取用户角色相关信息 + * + * @param userId 用户id + * @return 增强版hashMap,格式:[{"id":456, "code":"zjl", "name":"总经理"}] + * @author xuyuxiang + * @date 2020/3/13 16:26 + */ + List getLoginRoles(Long userId); + + /** + * 查询系统角色 + * + * @param sysRoleParam 查询参数 + * @return 查询分页结果 + * @author xuyuxiang + * @date 2020/3/28 14:53 + */ + PageResult page(SysRoleParam sysRoleParam); + + /** + * 根据角色名模糊搜索系统角色列表 + * + * @param sysRoleParam 查询参数 + * @return 增强版hashMap,格式:[{"id":456, "name":"总经理(zjl)"}] + * @author xuyuxiang + * @date 2020/4/14 9:21 + */ + List list(SysRoleParam sysRoleParam); + + /** + * 系统角色下拉(用于授权角色时选择) + * + * @return 增强版hashMap,格式:[{"id":456, "code":"zjl", "name":"总经理"}] + * @author xuyuxiang + * @date 2020/4/5 16:47 + */ + List dropDown(); + + /** + * 添加系统角色 + * + * @param sysRoleParam 添加参数 + * @author xuyuxiang + * @date 2020/3/28 14:54 + */ + void add(SysRoleParam sysRoleParam); + + /** + * 删除系统角色 + * + * @param sysRoleParam 删除参数 + * @author xuyuxiang + * @date 2020/3/28 14:54 + */ + void delete(SysRoleParam sysRoleParam); + + /** + * 编辑系统角色 + * + * @param sysRoleParam 编辑参数 + * @author xuyuxiang + * @date 2020/3/28 14:54 + */ + void edit(SysRoleParam sysRoleParam); + + /** + * 查看系统角色 + * + * @param sysRoleParam 查看参数 + * @return 系统角色 + * @author xuyuxiang + * @date 2020/3/26 9:50 + */ + SysRole detail(SysRoleParam sysRoleParam); + + /** + * 授权菜单 + * + * @param sysRoleParam 授权参数 + * @author xuyuxiang + * @date 2020/3/28 16:19 + */ + void grantMenu(SysRoleParam sysRoleParam); + + /** + * 授权数据 + * + * @param sysRoleParam 授权参数 + * @author xuyuxiang + * @date 2020/3/28 16:20 + */ + void grantData(SysRoleParam sysRoleParam); + + /** + * 根据角色id集合获取数据范围id集合 + * + * @param roleIdList 角色id集合 + * @param orgId 机构id + * @return 数据范围id集合 + * @author xuyuxiang + * @date 2020/4/5 17:41 + */ + List getUserDataScopeIdList(List roleIdList, Long orgId); + + /** + * 根据角色id获取角色名称 + * + * @param roleId 角色id + * @return 角色名称 + * @author xuyuxiang + * @date 2020/5/22 16:15 + */ + String getNameByRoleId(Long roleId); + + /** + * 查询角色拥有菜单 + * + * @param sysRoleParam 查询参数 + * @return 菜单id集合 + * @author xuyuxiang + * @date 2020/5/29 14:03 + */ + List ownMenu(SysRoleParam sysRoleParam); + + /** + * 查询角色拥有数据 + * + * @param sysRoleParam 查询参数 + * @return 数据范围id集合 + * @author xuyuxiang + * @date 2020/5/29 14:04 + */ + List ownData(SysRoleParam sysRoleParam); +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/service/impl/SysRoleDataScopeServiceImpl.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/service/impl/SysRoleDataScopeServiceImpl.java new file mode 100644 index 00000000..81efb6f2 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/service/impl/SysRoleDataScopeServiceImpl.java @@ -0,0 +1,92 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.role.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import com.cn.xiaonuo.sys.modular.role.entity.SysRoleDataScope; +import com.cn.xiaonuo.sys.modular.role.mapper.SysRoleDataScopeMapper; +import com.cn.xiaonuo.sys.modular.role.param.SysRoleParam; +import com.cn.xiaonuo.sys.modular.role.service.SysRoleDataScopeService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.cn.xiaonuo.sys.modular.role.entity.SysRoleDataScope; +import com.cn.xiaonuo.sys.modular.role.mapper.SysRoleDataScopeMapper; +import com.cn.xiaonuo.sys.modular.role.param.SysRoleParam; +import com.cn.xiaonuo.sys.modular.role.service.SysRoleDataScopeService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 系统角色数据范围service接口实现类 + * + * @author xuyuxiang + * @date 2020/3/13 15:55 + */ +@Service +public class SysRoleDataScopeServiceImpl extends ServiceImpl implements SysRoleDataScopeService { + + @Override + public void grantDataScope(SysRoleParam sysRoleParam) { + Long roleId = sysRoleParam.getId(); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysRoleDataScope::getRoleId, roleId); + //删除所拥有数据 + this.remove(queryWrapper); + //授权数据 + sysRoleParam.getGrantOrgIdList().forEach(orgId -> { + SysRoleDataScope sysRoleDataScope = new SysRoleDataScope(); + sysRoleDataScope.setRoleId(roleId); + sysRoleDataScope.setOrgId(orgId); + this.save(sysRoleDataScope); + }); + } + + @Override + public List getRoleDataScopeIdList(List roleIdList) { + List resultList = CollectionUtil.newArrayList(); + if (ObjectUtil.isNotEmpty(roleIdList)) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.in(SysRoleDataScope::getRoleId, roleIdList); + this.list(queryWrapper).forEach(sysRoleDataScope -> resultList.add(sysRoleDataScope.getOrgId())); + } + return resultList; + } + + @Override + public void deleteRoleDataScopeListByOrgIdList(List orgIdList) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.in(SysRoleDataScope::getOrgId, orgIdList); + this.remove(queryWrapper); + } + + @Override + public void deleteRoleDataScopeListByRoleId(Long roleId) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysRoleDataScope::getRoleId, roleId); + this.remove(queryWrapper); + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/service/impl/SysRoleMenuServiceImpl.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/service/impl/SysRoleMenuServiceImpl.java new file mode 100644 index 00000000..2fd981fe --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/service/impl/SysRoleMenuServiceImpl.java @@ -0,0 +1,89 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.role.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.cn.xiaonuo.sys.modular.role.entity.SysRoleMenu; +import com.cn.xiaonuo.sys.modular.role.mapper.SysRoleMenuMapper; +import com.cn.xiaonuo.sys.modular.role.param.SysRoleParam; +import com.cn.xiaonuo.sys.modular.role.service.SysRoleMenuService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 系统角色菜单service接口实现类 + * + * @author xuyuxiang + * @date 2020/3/13 15:55 + */ +@Service +public class SysRoleMenuServiceImpl extends ServiceImpl implements SysRoleMenuService { + + @Override + public List getRoleMenuIdList(List roleIdList) { + List menuIdList = CollectionUtil.newArrayList(); + + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + + queryWrapper.in(SysRoleMenu::getRoleId, roleIdList); + + this.list(queryWrapper).forEach(sysRoleMenu -> menuIdList.add(sysRoleMenu.getMenuId())); + + return menuIdList; + } + + @Override + public void grantMenu(SysRoleParam sysRoleParam) { + Long roleId = sysRoleParam.getId(); + //删除所拥有菜单 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysRoleMenu::getRoleId, roleId); + this.remove(queryWrapper); + //授权菜单 + sysRoleParam.getGrantMenuIdList().forEach(menuId -> { + SysRoleMenu sysRoleMenu = new SysRoleMenu(); + sysRoleMenu.setRoleId(roleId); + sysRoleMenu.setMenuId(menuId); + this.save(sysRoleMenu); + }); + } + + @Override + public void deleteRoleMenuListByMenuIdList(List menuIdList) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.in(SysRoleMenu::getMenuId, menuIdList); + this.remove(queryWrapper); + } + + @Override + public void deleteRoleMenuListByRoleId(Long roleId) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysRoleMenu::getRoleId, roleId); + this.remove(queryWrapper); + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/service/impl/SysRoleServiceImpl.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/service/impl/SysRoleServiceImpl.java new file mode 100644 index 00000000..e1f2e76c --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/role/service/impl/SysRoleServiceImpl.java @@ -0,0 +1,357 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.role.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.lang.Dict; +import cn.hutool.core.util.ObjectUtil; +import com.cn.xiaonuo.core.consts.CommonConstant; +import com.cn.xiaonuo.core.consts.SymbolConstant; +import com.cn.xiaonuo.core.context.login.LoginContextHolder; +import com.cn.xiaonuo.core.enums.CommonStatusEnum; +import com.cn.xiaonuo.core.exception.PermissionException; +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.core.exception.enums.PermissionExceptionEnum; +import com.cn.xiaonuo.core.factory.PageFactory; +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.core.enums.DataScopeTypeEnum; +import com.cn.xiaonuo.sys.modular.org.service.SysOrgService; +import com.cn.xiaonuo.sys.modular.role.entity.SysRole; +import com.cn.xiaonuo.sys.modular.role.enums.SysRoleExceptionEnum; +import com.cn.xiaonuo.sys.modular.role.mapper.SysRoleMapper; +import com.cn.xiaonuo.sys.modular.role.param.SysRoleParam; +import com.cn.xiaonuo.sys.modular.role.service.SysRoleDataScopeService; +import com.cn.xiaonuo.sys.modular.role.service.SysRoleMenuService; +import com.cn.xiaonuo.sys.modular.role.service.SysRoleService; +import com.cn.xiaonuo.sys.modular.user.service.SysUserRoleService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Set; + +/** + * 系统角色service接口实现类 + * + * @author xuyuxiang + * @date 2020/3/13 15:55 + */ +@Service +public class SysRoleServiceImpl extends ServiceImpl implements SysRoleService { + + @Resource + private SysUserRoleService sysUserRoleService; + + @Resource + private SysRoleMenuService sysRoleMenuService; + + @Resource + private SysRoleDataScopeService sysRoleDataScopeService; + + @Resource + private SysOrgService sysOrgService; + + @Override + public List getLoginRoles(Long userId) { + List dictList = CollectionUtil.newArrayList(); + //获取用户角色id集合 + List roleIdList = sysUserRoleService.getUserRoleIdList(userId); + if (ObjectUtil.isNotEmpty(roleIdList)) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.in(SysRole::getId, roleIdList).eq(SysRole::getStatus, CommonStatusEnum.ENABLE.getCode()); + //根据角色id集合查询并返回结果 + this.list(queryWrapper).forEach(sysRole -> { + Dict dict = Dict.create(); + dict.put(CommonConstant.ID, sysRole.getId()); + dict.put(CommonConstant.CODE, sysRole.getCode()); + dict.put(CommonConstant.NAME, sysRole.getName()); + dictList.add(dict); + }); + } + return dictList; + } + + @Override + public PageResult page(SysRoleParam sysRoleParam) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + if (ObjectUtil.isNotNull(sysRoleParam)) { + //根据名称模糊查询 + if (ObjectUtil.isNotEmpty(sysRoleParam.getName())) { + queryWrapper.like(SysRole::getName, sysRoleParam.getName()); + } + //根据编码模糊查询 + if (ObjectUtil.isNotEmpty(sysRoleParam.getCode())) { + queryWrapper.like(SysRole::getCode, sysRoleParam.getCode()); + } + } + + queryWrapper.eq(SysRole::getStatus, CommonStatusEnum.ENABLE.getCode()); + //根据排序升序排列,序号越小越在前 + queryWrapper.orderByAsc(SysRole::getSort); + return new PageResult<>(this.page(PageFactory.defaultPage(), queryWrapper)); + } + + @Override + public List list(SysRoleParam sysRoleParam) { + List dictList = CollectionUtil.newArrayList(); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + if (ObjectUtil.isNotNull(sysRoleParam)) { + //根据角色名称或编码模糊查询 + if (ObjectUtil.isNotEmpty(sysRoleParam.getName())) { + queryWrapper.and(i -> i.like(SysRole::getName, sysRoleParam.getName()) + .or().like(SysRole::getCode, sysRoleParam.getName())); + } + } + //只查询正常状态 + queryWrapper.eq(SysRole::getStatus, CommonStatusEnum.ENABLE.getCode()); + //根据排序升序排列,序号越小越在前 + queryWrapper.orderByAsc(SysRole::getSort); + this.list(queryWrapper).forEach(sysRole -> { + Dict dict = Dict.create(); + dict.put(CommonConstant.ID, sysRole.getId()); + dict.put(CommonConstant.NAME, sysRole.getName() + SymbolConstant.LEFT_SQUARE_BRACKETS + + sysRole.getCode() + SymbolConstant.RIGHT_SQUARE_BRACKETS); + dictList.add(dict); + }); + return dictList; + } + + @Override + public List dropDown() { + List dictList = CollectionUtil.newArrayList(); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + //如果当前登录用户不是超级管理员,则查询自己拥有的 + if (!LoginContextHolder.me().isSuperAdmin()) { + + //查询自己拥有的 + List loginUserRoleIds = LoginContextHolder.me().getLoginUserRoleIds(); + if (ObjectUtil.isEmpty(loginUserRoleIds)) { + return dictList; + } + queryWrapper.in(SysRole::getId, loginUserRoleIds); + } + //只查询正常状态 + queryWrapper.eq(SysRole::getStatus, CommonStatusEnum.ENABLE.getCode()); + this.list(queryWrapper) + .forEach(sysRole -> { + Dict dict = Dict.create(); + dict.put(CommonConstant.ID, sysRole.getId()); + dict.put(CommonConstant.CODE, sysRole.getCode()); + dict.put(CommonConstant.NAME, sysRole.getName()); + dictList.add(dict); + }); + return dictList; + } + + @Override + public void add(SysRoleParam sysRoleParam) { + //校验参数,检查是否存在相同的名称和编码 + checkParam(sysRoleParam, false); + SysRole sysRole = new SysRole(); + BeanUtil.copyProperties(sysRoleParam, sysRole); + sysRole.setStatus(CommonStatusEnum.ENABLE.getCode()); + this.save(sysRole); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void delete(SysRoleParam sysRoleParam) { + SysRole sysRole = this.querySysRole(sysRoleParam); + sysRole.setStatus(CommonStatusEnum.DELETED.getCode()); + this.updateById(sysRole); + Long id = sysRole.getId(); + //级联删除该角色对应的角色-数据范围关联信息 + sysRoleDataScopeService.deleteRoleDataScopeListByRoleId(id); + + //级联删除该角色对应的用户-角色表关联信息 + sysUserRoleService.deleteUserRoleListByRoleId(id); + + //级联删除该角色对应的角色-菜单表关联信息 + sysRoleMenuService.deleteRoleMenuListByRoleId(id); + } + + @Override + public void edit(SysRoleParam sysRoleParam) { + SysRole sysRole = this.querySysRole(sysRoleParam); + //校验参数,检查是否存在相同的名称和编码 + checkParam(sysRoleParam, true); + BeanUtil.copyProperties(sysRoleParam, sysRole); + //不能修改状态,用修改状态接口修改状态 + sysRole.setStatus(null); + this.updateById(sysRole); + } + + @Override + public SysRole detail(SysRoleParam sysRoleParam) { + return this.querySysRole(sysRoleParam); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void grantMenu(SysRoleParam sysRoleParam) { + this.querySysRole(sysRoleParam); + sysRoleMenuService.grantMenu(sysRoleParam); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void grantData(SysRoleParam sysRoleParam) { + SysRole sysRole = this.querySysRole(sysRoleParam); + boolean superAdmin = LoginContextHolder.me().isSuperAdmin(); + //如果登录用户不是超级管理员,则进行数据权限校验 + if (!superAdmin) { + Integer dataScopeType = sysRoleParam.getDataScopeType(); + //如果授权的角色的数据范围类型为全部,则没权限,只有超级管理员有 + if (DataScopeTypeEnum.ALL.getCode().equals(dataScopeType)) { + throw new PermissionException(PermissionExceptionEnum.NO_PERMISSION_OPERATE); + } + //如果授权的角色数据范围类型为自定义,则要判断授权的数据范围是否在自己的数据范围内 + if (DataScopeTypeEnum.DEFINE.getCode().equals(dataScopeType)) { + List dataScope = sysRoleParam.getDataScope(); + //要授权的数据范围列表 + List grantOrgIdList = sysRoleParam.getGrantOrgIdList(); + if (ObjectUtil.isNotEmpty(grantOrgIdList)) { + //数据范围为空 + if (ObjectUtil.isEmpty(dataScope)) { + throw new PermissionException(PermissionExceptionEnum.NO_PERMISSION_OPERATE); + } else if (!dataScope.containsAll(grantOrgIdList)) { + //所要授权的数据不在自己的数据范围内 + throw new PermissionException(PermissionExceptionEnum.NO_PERMISSION_OPERATE); + } + } + } + } + sysRole.setDataScopeType(sysRoleParam.getDataScopeType()); + this.updateById(sysRole); + sysRoleDataScopeService.grantDataScope(sysRoleParam); + } + + @Override + public List getUserDataScopeIdList(List roleIdList, Long orgId) { + Set resultList = CollectionUtil.newHashSet(); + + //定义角色中最大数据范围的类型,目前系统按最大范围策略来,如果你同时拥有ALL和SELF的权限,系统最后按ALL返回 + Integer strongerDataScopeType = DataScopeTypeEnum.SELF.getCode(); + + //获取用户自定义数据范围的角色集合 + List customDataScopeRoleIdList = CollectionUtil.newArrayList(); + if (ObjectUtil.isNotEmpty(roleIdList)) { + List sysRoleList = this.listByIds(roleIdList); + for (SysRole sysRole : sysRoleList) { + if (DataScopeTypeEnum.DEFINE.getCode().equals(sysRole.getDataScopeType())) { + customDataScopeRoleIdList.add(sysRole.getId()); + } else { + if (sysRole.getDataScopeType() <= strongerDataScopeType) { + strongerDataScopeType = sysRole.getDataScopeType(); + } + } + } + } + + //自定义数据范围的角色对应的数据范围 + List roleDataScopeIdList = sysRoleDataScopeService.getRoleDataScopeIdList(customDataScopeRoleIdList); + + //角色中拥有最大数据范围类型的数据范围 + List dataScopeIdList = sysOrgService.getDataScopeListByDataScopeType(strongerDataScopeType, orgId); + + resultList.addAll(dataScopeIdList); + resultList.addAll(roleDataScopeIdList); + return CollectionUtil.newArrayList(resultList); + } + + @Override + public String getNameByRoleId(Long roleId) { + SysRole sysRole = this.getById(roleId); + if (ObjectUtil.isEmpty(sysRole)) { + throw new ServiceException(SysRoleExceptionEnum.ROLE_NOT_EXIST); + } + return sysRole.getName(); + } + + @Override + public List ownMenu(SysRoleParam sysRoleParam) { + SysRole sysRole = this.querySysRole(sysRoleParam); + return sysRoleMenuService.getRoleMenuIdList(CollectionUtil.newArrayList(sysRole.getId())); + } + + @Override + public List ownData(SysRoleParam sysRoleParam) { + SysRole sysRole = this.querySysRole(sysRoleParam); + return sysRoleDataScopeService.getRoleDataScopeIdList(CollectionUtil.newArrayList(sysRole.getId())); + } + + /** + * 校验参数,检查是否存在相同的名称和编码 + * + * @author xuyuxiang + * @date 2020/3/28 14:59 + */ + private void checkParam(SysRoleParam sysRoleParam, boolean isExcludeSelf) { + Long id = sysRoleParam.getId(); + String name = sysRoleParam.getName(); + String code = sysRoleParam.getCode(); + + LambdaQueryWrapper queryWrapperByName = new LambdaQueryWrapper<>(); + queryWrapperByName.eq(SysRole::getName, name) + .ne(SysRole::getStatus, CommonStatusEnum.DELETED.getCode()); + + LambdaQueryWrapper queryWrapperByCode = new LambdaQueryWrapper<>(); + queryWrapperByCode.eq(SysRole::getCode, code) + .ne(SysRole::getStatus, CommonStatusEnum.DELETED.getCode()); + + //是否排除自己,如果排除自己则不查询自己的id + if (isExcludeSelf) { + queryWrapperByName.ne(SysRole::getId, id); + queryWrapperByCode.ne(SysRole::getId, id); + } + int countByName = this.count(queryWrapperByName); + int countByCode = this.count(queryWrapperByCode); + + if (countByName >= 1) { + throw new ServiceException(SysRoleExceptionEnum.ROLE_NAME_REPEAT); + } + if (countByCode >= 1) { + throw new ServiceException(SysRoleExceptionEnum.ROLE_CODE_REPEAT); + } + } + + /** + * 获取系统角色 + * + * @author xuyuxiang + * @date 2020/3/28 14:59 + */ + private SysRole querySysRole(SysRoleParam sysRoleParam) { + SysRole sysRole = this.getById(sysRoleParam.getId()); + if (ObjectUtil.isNull(sysRole)) { + throw new ServiceException(SysRoleExceptionEnum.ROLE_NOT_EXIST); + } + return sysRole; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/controller/SmsSenderController.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/controller/SmsSenderController.java new file mode 100644 index 00000000..8e5803dd --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/controller/SmsSenderController.java @@ -0,0 +1,108 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.sms.controller; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.RandomUtil; +import com.cn.xiaonuo.core.annotion.BusinessLog; +import com.cn.xiaonuo.core.annotion.Permission; +import com.cn.xiaonuo.core.enums.LogAnnotionOpTypeEnum; +import com.cn.xiaonuo.core.pojo.response.ResponseData; +import com.cn.xiaonuo.core.pojo.response.SuccessResponseData; +import com.cn.xiaonuo.sys.modular.sms.enums.SmsVerifyEnum; +import com.cn.xiaonuo.sys.modular.sms.param.SysSmsInfoParam; +import com.cn.xiaonuo.sys.modular.sms.param.SysSmsSendParam; +import com.cn.xiaonuo.sys.modular.sms.param.SysSmsVerifyParam; +import com.cn.xiaonuo.sys.modular.sms.service.SmsSenderService; +import com.cn.xiaonuo.sys.modular.sms.service.SysSmsInfoService; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.HashMap; + +/** + * 短信发送控制器 + * + * @author yubaoshan + * @date 2020/6/7 16:07 + */ +@RestController +@RequestMapping +public class SmsSenderController { + + @Resource + private SmsSenderService smsSenderService; + + @Resource + private SysSmsInfoService sysSmsInfoService; + + /** + * 发送记录查询 + * + * @author xuyuxiang + * @date 2020/7/2 12:03 + */ + @Permission + @GetMapping("/sms/page") + @BusinessLog(title = "短信发送记录查询", opType = LogAnnotionOpTypeEnum.QUERY) + public ResponseData page(SysSmsInfoParam sysSmsInfoParam) { + return new SuccessResponseData(sysSmsInfoService.page(sysSmsInfoParam)); + } + + /** + * 发送验证码短信 + * + * @author yubaoshan + * @date 2020/6/7 16:07 + */ + @Permission + @PostMapping("/sms/sendLoginMessage") + @BusinessLog(title = "发送验证码短信") + public ResponseData sendLoginMessage(@RequestBody @Validated SysSmsSendParam sysSmsSendParam) { + + // 设置模板中的参数 + HashMap paramMap = CollectionUtil.newHashMap(); + paramMap.put("code", RandomUtil.randomNumbers(6)); + sysSmsSendParam.setParams(paramMap); + + return new SuccessResponseData(smsSenderService.sendShortMessage(sysSmsSendParam)); + } + + /** + * 验证短信验证码 + * + * @author yubaoshan + * @date 2020/6/7 16:07 + */ + @Permission + @PostMapping("/sms/validateMessage") + @BusinessLog(title = "验证短信验证码") + public ResponseData validateMessage(@RequestBody @Validated SysSmsVerifyParam sysSmsVerifyParam) { + SmsVerifyEnum smsVerifyEnum = smsSenderService.verifyShortMessage(sysSmsVerifyParam); + return new SuccessResponseData(smsVerifyEnum); + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/entity/SysSms.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/entity/SysSms.java new file mode 100644 index 00000000..5745f4a1 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/entity/SysSms.java @@ -0,0 +1,93 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.sms.entity; + + +import com.cn.xiaonuo.core.pojo.base.entity.BaseEntity; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.cn.xiaonuo.core.pojo.base.entity.BaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; +import java.util.Date; + +/** + * 系统短信表 + * + * @author yubaoshan + * @date 2018/7/5 13:44 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@TableName("sys_sms") +public class SysSms extends BaseEntity implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @TableId(type = IdType.ASSIGN_ID) + private Long id; + /** + * 手机号 + */ + private String phoneNumbers; + + /** + * 短信验证码 + */ + private String validateCode; + + /** + * 短信模板ID + */ + private String templateCode; + + /** + * 回执id,可根据该id查询具体的发送状态 + */ + private String bizId; + + /** + * 发送状态(字典 0 未发送,1 发送成功,2 发送失败,3 失效) + */ + private Integer status; + + /** + * 来源(字典 1 app, 2 pc, 3 其他) + */ + private Integer source; + + /** + * 失效时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date invalidTime; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/enums/SmsSendExceptionEnum.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/enums/SmsSendExceptionEnum.java new file mode 100644 index 00000000..2f9d7b4f --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/enums/SmsSendExceptionEnum.java @@ -0,0 +1,79 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.sms.enums; + +import com.cn.xiaonuo.core.annotion.ExpEnumType; +import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum; +import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory; +import com.cn.xiaonuo.sys.core.consts.SysExpEnumConstant; +import com.cn.xiaonuo.core.annotion.ExpEnumType; +import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum; +import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory; +import com.cn.xiaonuo.sys.core.consts.SysExpEnumConstant; + +/** + * 短信发送相关异常枚举 + * + * @author xuyuxiang + * @date 2020/7/7 11:30 + */ +@ExpEnumType(module = SysExpEnumConstant.XIAONUO_SYS_MODULE_EXP_CODE, kind = SysExpEnumConstant.SMS_EXCEPTION_ENUM) +public enum SmsSendExceptionEnum implements AbstractBaseExceptionEnum { + + /** + * 手机号码不能为空 + */ + PHONE_NUMBER_EMPTY(1, "手机号码不能为空,请检查phoneNumbers参数"), + + /** + * 验证码不能为空 + */ + VALIDATE_CODE_EMPTY(2, "验证码不能为空,请检查validateCode参数"), + + /** + * 模板号不能为空 + */ + TEMPLATE_CODE_EMPTY(3, "模板号不能为空,请检查templateCode参数"); + + private final Integer code; + + private final String message; + + SmsSendExceptionEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return ExpEnumCodeFactory.getExpEnumCode(this.getClass(), code); + } + + @Override + public String getMessage() { + return message; + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/enums/SmsSendSourceEnum.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/enums/SmsSendSourceEnum.java new file mode 100644 index 00000000..aaa4bfb5 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/enums/SmsSendSourceEnum.java @@ -0,0 +1,58 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.sms.enums; + +import lombok.Getter; + +/** + * 短信发送业务枚举 + * + * @author yubaoshan + * @date 2018/5/6 12:30 + */ +@Getter +public enum SmsSendSourceEnum { + + /** + * APP + */ + APP(1), + + /** + * PC + */ + PC(2), + + /** + * OTHER + */ + OTHER(3); + + private final Integer code; + + SmsSendSourceEnum(Integer code) { + this.code = code; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/enums/SmsSendStatusEnum.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/enums/SmsSendStatusEnum.java new file mode 100644 index 00000000..3d7c6451 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/enums/SmsSendStatusEnum.java @@ -0,0 +1,66 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.sms.enums; + +import lombok.Getter; + +/** + * 短信发送状态枚举 + * + * @author yubaoshan + * @date 2018/5/6 12:30 + */ +@Getter +public enum SmsSendStatusEnum { + + /** + * 未发送 + */ + WAITING(0, "未发送"), + + /** + * 发送成功 + */ + SUCCESS(1, "发送成功"), + + /** + * 发送失败 + */ + FAILED(2, "发送失败"), + + /** + * 失效 + */ + INVALID(3, "失效"); + + private final Integer code; + + private final String message; + + SmsSendStatusEnum(Integer code, String message) { + this.code = code; + this.message = message; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/enums/SmsTypeEnum.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/enums/SmsTypeEnum.java new file mode 100644 index 00000000..d44e427f --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/enums/SmsTypeEnum.java @@ -0,0 +1,56 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.sms.enums; + +import lombok.Getter; + +/** + * 短信类型枚举 + * + * @author yubaoshan + * @date 2018/5/6 12:30 + */ +@Getter +public enum SmsTypeEnum { + + /** + * 验证类短信 + */ + SMS(1, "验证类短信"), + + /** + * 纯发送短信 + */ + MESSAGE(2, "纯发送短信"); + + private final Integer code; + + private final String message; + + SmsTypeEnum(Integer code, String message) { + this.code = code; + this.message = message; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/enums/SmsVerifyEnum.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/enums/SmsVerifyEnum.java new file mode 100644 index 00000000..88802768 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/enums/SmsVerifyEnum.java @@ -0,0 +1,67 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.sms.enums; + +import lombok.Getter; + +/** + * 短信验证相关美剧 + * + * @author yubaoshan + * @date 2018/5/6 12:30 + */ +@Getter +public enum SmsVerifyEnum { + + /** + * 验证成功 + */ + SUCCESS(10, "验证成功"), + + /** + * 验证码错误 + */ + ERROR(20, "验证码错误"), + + /** + * 验证码超时 + */ + EXPIRED(30, "验证码超时"), + + /** + * 超过验证次数 + */ + TIMES_UP(40, "超过验证次数"); + + private final Integer code; + + private final String message; + + SmsVerifyEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/mapper/SysSmsMapper.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/mapper/SysSmsMapper.java new file mode 100644 index 00000000..e3bccaf4 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/mapper/SysSmsMapper.java @@ -0,0 +1,38 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.sms.mapper; + +import com.cn.xiaonuo.sys.modular.sms.entity.SysSms; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 系统短信mapper接口 + * + * @author yubaoshan + * @date 2018/7/5 13:44 + */ +public interface SysSmsMapper extends BaseMapper { + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/mapper/mapping/SysSmsMapper.xml b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/mapper/mapping/SysSmsMapper.xml new file mode 100644 index 00000000..a054d878 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/mapper/mapping/SysSmsMapper.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/param/SysSmsInfoParam.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/param/SysSmsInfoParam.java new file mode 100644 index 00000000..74d513c2 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/param/SysSmsInfoParam.java @@ -0,0 +1,84 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.sms.param; + + +import com.cn.xiaonuo.core.pojo.base.param.BaseParam; +import com.cn.xiaonuo.core.pojo.base.param.BaseParam; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + * 系统短信表 + * + * @author yubaoshan + * @date 2018/7/5 13:44 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class SysSmsInfoParam extends BaseParam { + + /** + * 主键 + */ + private Long id; + + /** + * 手机号 + */ + private String phoneNumbers; + + /** + * 短信验证码 + */ + private String validateCode; + + /** + * 短信模板ID + */ + private String templateCode; + + /** + * 回执id,可根据该id查询具体的发送状态 + */ + private String bizId; + + /** + * 发送状态(字典 0 未发送,1 发送成功,2 发送失败,3 失效) + */ + private Integer status; + + /** + * 来源(字典 1 app, 2 pc, 3 其他) + */ + private Integer source; + + /** + * 失效时间 + */ + private Date invalidTime; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/param/SysSmsSendParam.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/param/SysSmsSendParam.java new file mode 100644 index 00000000..f95965f6 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/param/SysSmsSendParam.java @@ -0,0 +1,70 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.sms.param; + +import com.cn.xiaonuo.sys.modular.sms.enums.SmsSendSourceEnum; +import com.cn.xiaonuo.sys.modular.sms.enums.SmsTypeEnum; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.util.Map; + +/** + * 发送短信的参数 + * + * @author yubaoshan + * @date 2018/7/5 21:19 + */ +@Data +public class SysSmsSendParam { + + /** + * 手机号 + */ + @NotBlank(message = "手机号码为空,请检查phoneNumbers参数") + private String phoneNumbers; + + /** + * 模板号 + */ + @NotBlank(message = "模板号为空,请检查templateCode参数") + private String templateCode; + + /** + * 模板中的参数 + */ + private Map params; + + /** + * 发送源 + */ + private SmsSendSourceEnum smsSendSourceEnum = SmsSendSourceEnum.PC; + + /** + * 消息类型,1验证码,2消息,默认不传为验证码 + */ + private SmsTypeEnum smsTypeEnum = SmsTypeEnum.SMS; + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/param/SysSmsVerifyParam.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/param/SysSmsVerifyParam.java new file mode 100644 index 00000000..a74e9d9a --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/param/SysSmsVerifyParam.java @@ -0,0 +1,65 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.sms.param; + +import com.cn.xiaonuo.sys.modular.sms.enums.SmsSendSourceEnum; +import com.cn.xiaonuo.sys.modular.sms.enums.SmsSendSourceEnum; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + * 验证短信的参数 + * + * @author yubaoshan + * @date 2018/7/5 21:19 + */ +@Data +public class SysSmsVerifyParam { + + /** + * 手机号 + */ + @NotBlank(message = "手机号不能为空") + private String phoneNumbers; + + /** + * 验证码 + */ + @NotBlank(message = "验证码不能为空") + private String code; + + /** + * 模板号 + */ + @NotBlank(message = "模板号不能为空") + private String templateCode; + + /** + * 来源 + */ + private SmsSendSourceEnum smsSendSourceEnum = SmsSendSourceEnum.PC; + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/service/SmsSenderService.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/service/SmsSenderService.java new file mode 100644 index 00000000..95591e98 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/service/SmsSenderService.java @@ -0,0 +1,71 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.sms.service; + +import com.cn.xiaonuo.sys.modular.sms.enums.SmsSendStatusEnum; +import com.cn.xiaonuo.sys.modular.sms.enums.SmsVerifyEnum; +import com.cn.xiaonuo.sys.modular.sms.param.SysSmsSendParam; +import com.cn.xiaonuo.sys.modular.sms.param.SysSmsVerifyParam; +import com.cn.xiaonuo.sys.modular.sms.enums.SmsVerifyEnum; + +/** + * 短信通知接口 + * + * @author yubaoshan + * @date 2018/7/5 21:05 + */ +public interface SmsSenderService { + + /** + * 发送短信 + * + * @param sysSmsSendParam 短信发送参数 + * @return 是否成功 + * @author yubaoshan + * @date 2018/7/6 16:32 + */ + boolean sendShortMessage(SysSmsSendParam sysSmsSendParam); + + /** + * 验证短信 + * + * @param sysSmsVerifyParam 短信验证参数 + * @return 校验结果 + * @author yubaoshan + * @date 2018/7/6 16:30 + */ + SmsVerifyEnum verifyShortMessage(SysSmsVerifyParam sysSmsVerifyParam); + + /** + * 查看短信发送状态 0=未发送,1=发送成功,2=发送失败 + * + * @param smsId 短信发送记录id + * @return 发送状态 + * @author yubaoshan + * @date 2018/7/6 16:32 + */ + SmsSendStatusEnum getMessageSendStatus(Integer smsId); + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/service/SysSmsInfoService.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/service/SysSmsInfoService.java new file mode 100644 index 00000000..d14036c0 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/service/SysSmsInfoService.java @@ -0,0 +1,86 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.sms.service; + +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.modular.sms.entity.SysSms; +import com.cn.xiaonuo.sys.modular.sms.enums.SmsSendStatusEnum; +import com.cn.xiaonuo.sys.modular.sms.enums.SmsVerifyEnum; +import com.cn.xiaonuo.sys.modular.sms.param.SysSmsInfoParam; +import com.cn.xiaonuo.sys.modular.sms.param.SysSmsSendParam; +import com.cn.xiaonuo.sys.modular.sms.param.SysSmsVerifyParam; +import com.baomidou.mybatisplus.extension.service.IService; +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.modular.sms.enums.SmsVerifyEnum; + +/** + * 系统短信service接口 + * + * @author yubaoshan + * @date 2018/7/5 13:44 + */ +public interface SysSmsInfoService extends IService { + + /** + * 存储短信验证信息 + * + * @param sysSmsSendParam 发送参数 + * @param validateCode 验证码 + * @return 短信记录id + * @author yubaoshan + * @date 2018/7/6 16:47 + */ + Long saveSmsInfo(SysSmsSendParam sysSmsSendParam, String validateCode); + + /** + * 更新短息发送状态 + * + * @param smsId 短信记录id + * @param smsSendStatusEnum 发送状态枚举 + * @author yubaoshan + * @date 2018/7/6 17:12 + */ + void updateSmsInfo(Long smsId, SmsSendStatusEnum smsSendStatusEnum); + + /** + * 校验验证码是否正确 + * + * @param sysSmsVerifyParam 短信校验参数 + * @return 短信校验结果枚举 + * @author yubaoshan + * @date 2018/7/6 17:16 + */ + SmsVerifyEnum validateSmsInfo(SysSmsVerifyParam sysSmsVerifyParam); + + /** + * 短信发送记录查询 + * + * @param sysSmsInfoParam 查询参数 + * @return 查询分页结果 + * @author xuyuxiang + * @date 2020/7/2 12:08 + */ + PageResult page(SysSmsInfoParam sysSmsInfoParam); +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/service/impl/SmsSenderServiceImpl.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/service/impl/SmsSenderServiceImpl.java new file mode 100644 index 00000000..defb9ba6 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/service/impl/SmsSenderServiceImpl.java @@ -0,0 +1,122 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.sms.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.RandomUtil; +import cn.hutool.log.Log; +import com.alibaba.fastjson.JSON; +import com.cn.xiaonuo.core.consts.CommonConstant; +import com.cn.xiaonuo.core.sms.SmsSender; +import com.cn.xiaonuo.sys.modular.sms.enums.SmsSendStatusEnum; +import com.cn.xiaonuo.sys.modular.sms.enums.SmsTypeEnum; +import com.cn.xiaonuo.sys.modular.sms.enums.SmsVerifyEnum; +import com.cn.xiaonuo.sys.modular.sms.param.SysSmsSendParam; +import com.cn.xiaonuo.sys.modular.sms.param.SysSmsVerifyParam; +import com.cn.xiaonuo.sys.modular.sms.service.SmsSenderService; +import com.cn.xiaonuo.sys.modular.sms.service.SysSmsInfoService; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.Map; + + +/** + * 短信发送接口实现类 + * + * @author yubaoshan + * @date 2018/7/5 21:05 + */ +@Component +public class SmsSenderServiceImpl implements SmsSenderService { + + private static final Log log = Log.get(); + + @Resource + private SmsSender smsSender; + + @Resource + private SysSmsInfoService sysSmsInfoService; + + @Transactional(rollbackFor = Exception.class) + @Override + public boolean sendShortMessage(SysSmsSendParam sysSmsSendParam) { + + Map params = sysSmsSendParam.getParams(); + log.info(">>> 发送短信Provider接口,参数为:" + JSON.toJSONString(sysSmsSendParam)); + + //如果是纯消息发送,直接发送 + if (SmsTypeEnum.MESSAGE.equals(sysSmsSendParam.getSmsTypeEnum())) { + smsSender.sendSms(sysSmsSendParam.getPhoneNumbers(), sysSmsSendParam.getTemplateCode(), params); + log.info(">>> 发送短信Provider接口--message,params的map具体为:" + JSON.toJSONString(params)); + } else { + + //如果是验证类消息发送,需要存储到数据库验证码信息 + String validateCode; + + //如果传的参数中没有code,就初始化一个code放到参数map里 + if (params != null && params.get(CommonConstant.CODE) != null) { + validateCode = params.get(CommonConstant.CODE).toString(); + } else { + validateCode = RandomUtil.randomNumbers(6); + if (params == null) { + params = CollectionUtil.newHashMap(); + } + params.put(CommonConstant.CODE, validateCode); + } + + log.info(">>> 发送短信Provider接口,params的map具体为:" + JSON.toJSONString(params)); + log.info(">>> 发送短信Provider接口,验证码为:" + validateCode); + + //存储短信到数据库 + Long smsId = sysSmsInfoService.saveSmsInfo(sysSmsSendParam, validateCode); + + log.info(">>> 开始发送短信:发送的电话号码= " + sysSmsSendParam.getPhoneNumbers() + ",发送的模板号=" + sysSmsSendParam.getTemplateCode() + ",发送的参数是:" + JSON.toJSONString(params)); + + //发送短信 + smsSender.sendSms(sysSmsSendParam.getPhoneNumbers(), sysSmsSendParam.getTemplateCode(), params); + + //更新短信发送状态 + sysSmsInfoService.updateSmsInfo(smsId, SmsSendStatusEnum.SUCCESS); + } + + return true; + } + + @Override + public SmsVerifyEnum verifyShortMessage(SysSmsVerifyParam sysSmsVerifyParam) { + log.info(">>> 验证短信Provider接口,参数为:" + JSON.toJSONString(sysSmsVerifyParam)); + SmsVerifyEnum smsVerifyEnum = sysSmsInfoService.validateSmsInfo(sysSmsVerifyParam); + log.info(">>> 验证短信Provider接口,响应结果为:" + JSON.toJSONString(smsVerifyEnum)); + return smsVerifyEnum; + } + + @Override + public SmsSendStatusEnum getMessageSendStatus(Integer smsId) { + return null; + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/service/impl/SysSmsInfoServiceImpl.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/service/impl/SysSmsInfoServiceImpl.java new file mode 100644 index 00000000..c804e659 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/sms/service/impl/SysSmsInfoServiceImpl.java @@ -0,0 +1,201 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.sms.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.log.Log; +import com.cn.xiaonuo.core.context.constant.ConstantContextHolder; +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.core.factory.PageFactory; +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.core.pojo.sms.AliyunSmsConfigs; +import com.cn.xiaonuo.sys.modular.sms.entity.SysSms; +import com.cn.xiaonuo.sys.modular.sms.enums.SmsSendExceptionEnum; +import com.cn.xiaonuo.sys.modular.sms.enums.SmsSendStatusEnum; +import com.cn.xiaonuo.sys.modular.sms.enums.SmsVerifyEnum; +import com.cn.xiaonuo.sys.modular.sms.mapper.SysSmsMapper; +import com.cn.xiaonuo.sys.modular.sms.param.SysSmsInfoParam; +import com.cn.xiaonuo.sys.modular.sms.param.SysSmsSendParam; +import com.cn.xiaonuo.sys.modular.sms.param.SysSmsVerifyParam; +import com.cn.xiaonuo.sys.modular.sms.service.SysSmsInfoService; +import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.cn.xiaonuo.core.context.constant.ConstantContextHolder; +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.core.factory.PageFactory; +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.core.pojo.sms.AliyunSmsConfigs; +import com.cn.xiaonuo.sys.modular.sms.enums.SmsSendExceptionEnum; +import com.cn.xiaonuo.sys.modular.sms.enums.SmsVerifyEnum; +import com.cn.xiaonuo.sys.modular.sms.service.SysSmsInfoService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Date; +import java.util.List; + +/** + * 系统短信接口实现类 + * + * @author yubaoshan + * @date 2018/7/5 13:44 + */ + +@Service +public class SysSmsInfoServiceImpl extends ServiceImpl implements SysSmsInfoService { + + private static final Log log = Log.get(); + + @Override + public Long saveSmsInfo(SysSmsSendParam sysSmsSendParam, String validateCode) { + + if (ObjectUtil.isEmpty(sysSmsSendParam.getPhoneNumbers())) { + throw new ServiceException(SmsSendExceptionEnum.PHONE_NUMBER_EMPTY); + } + if (ObjectUtil.isEmpty(validateCode)) { + throw new ServiceException(SmsSendExceptionEnum.VALIDATE_CODE_EMPTY); + } + if (ObjectUtil.isEmpty(sysSmsSendParam.getTemplateCode())) { + throw new ServiceException(SmsSendExceptionEnum.TEMPLATE_CODE_EMPTY); + } + + //当前时间 + Date nowDate = new Date(); + + //短信失效时间 + AliyunSmsConfigs aliyunSmsProperties = ConstantContextHolder.getAliyunSmsConfigs(); + long invalidateTime = nowDate.getTime() + aliyunSmsProperties.getInvalidateMinutes() * 60 * 1000; + Date invalidate = new Date(invalidateTime); + + SysSms sysSms = new SysSms(); + sysSms.setCreateTime(nowDate); + sysSms.setInvalidTime(invalidate); + sysSms.setPhoneNumbers(sysSmsSendParam.getPhoneNumbers()); + sysSms.setStatus(SmsSendStatusEnum.WAITING.getCode()); + sysSms.setSource(sysSmsSendParam.getSmsSendSourceEnum().getCode()); + sysSms.setTemplateCode(sysSmsSendParam.getTemplateCode()); + sysSms.setValidateCode(validateCode); + + this.save(sysSms); + + log.info(">>> 发送短信,存储短信到数据库,数据为:" + JSON.toJSONString(sysSms)); + + return sysSms.getId(); + } + + @Override + public void updateSmsInfo(Long smsId, SmsSendStatusEnum smsSendStatusEnum) { + SysSms sysSms = this.getById(smsId); + sysSms.setStatus(smsSendStatusEnum.getCode()); + this.updateById(sysSms); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public SmsVerifyEnum validateSmsInfo(SysSmsVerifyParam sysSmsVerifyParam) { + + if (ObjectUtil.isEmpty(sysSmsVerifyParam.getPhoneNumbers())) { + throw new ServiceException(SmsSendExceptionEnum.PHONE_NUMBER_EMPTY); + } + if (ObjectUtil.isEmpty(sysSmsVerifyParam)) { + throw new ServiceException(SmsSendExceptionEnum.VALIDATE_CODE_EMPTY); + } + if (ObjectUtil.isEmpty(sysSmsVerifyParam.getTemplateCode())) { + throw new ServiceException(SmsSendExceptionEnum.TEMPLATE_CODE_EMPTY); + } + + //查询有没有这条记录 + LambdaQueryWrapper smsQueryWrapper = new LambdaQueryWrapper<>(); + + smsQueryWrapper.eq(SysSms::getPhoneNumbers, sysSmsVerifyParam.getPhoneNumbers()) + .and(f -> f.eq(SysSms::getSource, sysSmsVerifyParam.getSmsSendSourceEnum().getCode())) + .and(f -> f.eq(SysSms::getTemplateCode, sysSmsVerifyParam.getTemplateCode())); + + smsQueryWrapper.orderByDesc(SysSms::getCreateTime); + + List sysSmsList = this.list(smsQueryWrapper); + + log.info(">>> 验证短信Provider接口,查询到sms记录:" + JSON.toJSONString(sysSmsList)); + + //如果找不到记录,提示验证失败 + if (ObjectUtil.isEmpty(sysSmsList)) { + log.info(">>> 验证短信Provider接口,找不到验证码记录,响应验证失败!"); + return SmsVerifyEnum.ERROR; + } else { + + //获取最近发送的第一条 + SysSms sysSms = sysSmsList.get(0); + + //先判断状态是不是失效的状态 + if (SmsSendStatusEnum.INVALID.getCode().equals(sysSms.getStatus())) { + log.info(">>> 验证短信Provider接口,短信状态是失效,响应验证失败!"); + return SmsVerifyEnum.ERROR; + } + + //如果验证码和传过来的不一致 + if (!sysSmsVerifyParam.getCode().equals(sysSms.getValidateCode())) { + log.info(">>> 验证短信Provider接口,验证手机号和验证码不一致,响应验证失败!"); + return SmsVerifyEnum.ERROR; + } + + //判断是否超时 + Date invalidTime = sysSms.getInvalidTime(); + if (ObjectUtil.isEmpty(invalidTime) || new Date().after(invalidTime)) { + log.info(">>> 验证短信Provider接口,验证码超时,响应验证失败!"); + return SmsVerifyEnum.EXPIRED; + } + + //验证成功把短信设置成失效 + sysSms.setStatus(SmsSendStatusEnum.INVALID.getCode()); + this.updateById(sysSms); + + log.info(">>> 验证短信Provider接口,验证码验证成功!"); + return SmsVerifyEnum.SUCCESS; + } + } + + @Override + public PageResult page(SysSmsInfoParam sysSmsInfoParam) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + if (ObjectUtil.isNotNull(sysSmsInfoParam)) { + //根据手机号模糊查询 + if (ObjectUtil.isNotEmpty(sysSmsInfoParam.getPhoneNumbers())) { + queryWrapper.like(SysSms::getPhoneNumbers, sysSmsInfoParam.getPhoneNumbers()); + } + //根据发送状态查询(字典 0 未发送,1 发送成功,2 发送失败,3 失效) + if (ObjectUtil.isNotEmpty(sysSmsInfoParam.getStatus())) { + queryWrapper.eq(SysSms::getStatus, sysSmsInfoParam.getStatus()); + } + //根据来源查询(字典 1 app, 2 pc, 3 其他) + if (ObjectUtil.isNotEmpty(sysSmsInfoParam.getSource())) { + queryWrapper.eq(SysSms::getSource, sysSmsInfoParam.getSource()); + } + } + return new PageResult<>(this.page(PageFactory.defaultPage(), queryWrapper)); + } + + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/controller/SysTimersController.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/controller/SysTimersController.java new file mode 100644 index 00000000..2634f215 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/controller/SysTimersController.java @@ -0,0 +1,168 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.timer.controller; + +import com.cn.xiaonuo.core.annotion.BusinessLog; +import com.cn.xiaonuo.core.enums.LogAnnotionOpTypeEnum; +import com.cn.xiaonuo.core.pojo.response.ResponseData; +import com.cn.xiaonuo.core.pojo.response.SuccessResponseData; +import com.cn.xiaonuo.sys.modular.timer.param.SysTimersParam; +import com.cn.xiaonuo.sys.modular.timer.service.SysTimersService; +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.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 定时任务 控制器 + * + * @author yubaoshan + * @date 2020/6/30 18:26 + */ +@RestController +public class SysTimersController { + + @Resource + private SysTimersService sysTimersService; + + /** + * 分页查询定时任务 + * + * @author yubaoshan + * @date 2020/6/30 18:26 + */ + @GetMapping("/sysTimers/page") + @BusinessLog(title = "定时任务_分页查询", opType = LogAnnotionOpTypeEnum.QUERY) + public ResponseData page(SysTimersParam sysTimersParam) { + return new SuccessResponseData(sysTimersService.page(sysTimersParam)); + } + + /** + * 获取全部定时任务 + * + * @author yubaoshan + * @date 2020/6/30 18:26 + */ + @GetMapping("/sysTimers/list") + @BusinessLog(title = "定时任务_查询所有", opType = LogAnnotionOpTypeEnum.QUERY) + public ResponseData list(SysTimersParam sysTimersParam) { + return new SuccessResponseData(sysTimersService.list(sysTimersParam)); + } + + /** + * 查看详情定时任务 + * + * @author yubaoshan + * @date 2020/6/30 18:26 + */ + @GetMapping("/sysTimers/detail") + @BusinessLog(title = "定时任务_查看详情", opType = LogAnnotionOpTypeEnum.DETAIL) + public ResponseData detail(@Validated(SysTimersParam.detail.class) SysTimersParam sysTimersParam) { + return new SuccessResponseData(sysTimersService.detail(sysTimersParam)); + } + + /** + * 添加定时任务 + * + * @author yubaoshan + * @date 2020/6/30 18:26 + */ + @PostMapping("/sysTimers/add") + @BusinessLog(title = "定时任务_增加", opType = LogAnnotionOpTypeEnum.ADD) + public ResponseData add(@RequestBody @Validated(SysTimersParam.add.class) SysTimersParam sysTimersParam) { + sysTimersService.add(sysTimersParam); + return new SuccessResponseData(); + } + + /** + * 删除定时任务 + * + * @author yubaoshan + * @date 2020/6/30 18:26 + */ + @PostMapping("/sysTimers/delete") + @BusinessLog(title = "定时任务_删除", opType = LogAnnotionOpTypeEnum.DELETE) + public ResponseData delete(@RequestBody @Validated(SysTimersParam.delete.class) SysTimersParam sysTimersParam) { + sysTimersService.delete(sysTimersParam); + return new SuccessResponseData(); + } + + /** + * 编辑定时任务 + * + * @author yubaoshan + * @date 2020/6/30 18:26 + */ + @PostMapping("/sysTimers/edit") + @BusinessLog(title = "定时任务_编辑", opType = LogAnnotionOpTypeEnum.EDIT) + public ResponseData edit(@RequestBody @Validated(SysTimersParam.edit.class) SysTimersParam sysTimersParam) { + sysTimersService.edit(sysTimersParam); + return new SuccessResponseData(); + } + + /** + * 获取系统的所有任务列表 + * + * @author yubaoshan + * @date 2020/7/1 14:34 + */ + @PostMapping("/sysTimers/getActionClasses") + @BusinessLog(title = "定时任务_任务列表", opType = LogAnnotionOpTypeEnum.OTHER) + public ResponseData getActionClasses() { + List actionClasses = sysTimersService.getActionClasses(); + return new SuccessResponseData(actionClasses); + } + + /** + * 启动定时任务 + * + * @author yubaoshan + * @date 2020/7/1 14:34 + */ + @PostMapping("/sysTimers/start") + @BusinessLog(title = "定时任务_启动", opType = LogAnnotionOpTypeEnum.OTHER) + public ResponseData start(@RequestBody @Validated(SysTimersParam.start.class) SysTimersParam sysTimersParam) { + sysTimersService.start(sysTimersParam); + return new SuccessResponseData(); + } + + /** + * 停止定时任务 + * + * @author yubaoshan + * @date 2020/7/1 14:34 + */ + @PostMapping("/sysTimers/stop") + @BusinessLog(title = "定时任务_关闭", opType = LogAnnotionOpTypeEnum.OTHER) + public ResponseData stop(@RequestBody @Validated(SysTimersParam.stop.class) SysTimersParam sysTimersParam) { + sysTimersService.stop(sysTimersParam); + return new SuccessResponseData(); + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/entity/SysTimers.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/entity/SysTimers.java new file mode 100644 index 00000000..5d79d81f --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/entity/SysTimers.java @@ -0,0 +1,77 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.timer.entity; + +import com.cn.xiaonuo.core.pojo.base.entity.BaseEntity; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 定时任务 + * + * @author yubaoshan + * @date 2020/6/30 18:26 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("sys_timers") +public class SysTimers extends BaseEntity { + + + /** + * 定时器id + */ + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + /** + * 任务名称 + */ + private String timerName; + + /** + * 执行任务的class的类名(实现了TimerTaskRunner接口的类的全称) + */ + private String actionClass; + + /** + * 定时任务表达式 + */ + private String cron; + + /** + * 状态(字典 1运行 2停止) + */ + private Integer jobStatus; + + /** + * 备注信息 + */ + private String remark; + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/enums/TimerJobStatusEnum.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/enums/TimerJobStatusEnum.java new file mode 100644 index 00000000..a8dd5d60 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/enums/TimerJobStatusEnum.java @@ -0,0 +1,54 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.timer.enums; + +import lombok.Getter; + +/** + * 定时任务的状态 + * + * @author yubaoshan + * @date 2020/6/30 20:44 + */ +@Getter +public enum TimerJobStatusEnum { + + /** + * 启动状态 + */ + RUNNING(1), + + /** + * 停止状态 + */ + STOP(2); + + private final Integer code; + + TimerJobStatusEnum(int code) { + this.code = code; + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/enums/exp/SysTimersExceptionEnum.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/enums/exp/SysTimersExceptionEnum.java new file mode 100644 index 00000000..f354d9d6 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/enums/exp/SysTimersExceptionEnum.java @@ -0,0 +1,74 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.timer.enums.exp; + +import com.cn.xiaonuo.core.annotion.ExpEnumType; +import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum; +import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory; +import com.cn.xiaonuo.sys.core.consts.SysExpEnumConstant; + +/** + * 定时任务相关枚举 + * + * @author yubaoshan + * @date 2020/6/30 18:26 + */ +@ExpEnumType(module = SysExpEnumConstant.XIAONUO_SYS_MODULE_EXP_CODE, kind = SysExpEnumConstant.TIMER_EXCEPTION_ENUM) +public enum SysTimersExceptionEnum implements AbstractBaseExceptionEnum { + + /** + * 该条记录不存在 + */ + NOT_EXISTED(1, "您查询的该条记录不存在"), + + /** + * 定时任务执行类不存在 + */ + TIMER_NOT_EXISTED(2, "定时任务执行类不存在"), + + /** + * 检查定时任务启动时候的参数是否传了 + */ + EXE_EMPTY_PARAM(3, "请检查定时器的id,定时器cron表达式,定时任务是否为空!"); + + private final Integer code; + + private final String message; + + SysTimersExceptionEnum(int code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return ExpEnumCodeFactory.getExpEnumCode(this.getClass(), code); + } + + @Override + public String getMessage() { + return message; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/mapper/SysTimersMapper.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/mapper/SysTimersMapper.java new file mode 100644 index 00000000..7e5e0eba --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/mapper/SysTimersMapper.java @@ -0,0 +1,41 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.timer.mapper; + +import com.cn.xiaonuo.sys.modular.timer.entity.SysTimers; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.cn.xiaonuo.sys.modular.timer.entity.SysTimers; + +/** + *

+ * 定时任务 Mapper 接口 + *

+ * + * @author yubaoshan + * @date 2020/6/30 18:26 + */ +public interface SysTimersMapper extends BaseMapper { + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/mapper/mapping/SysTimersMapper.xml b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/mapper/mapping/SysTimersMapper.xml new file mode 100644 index 00000000..00b27b6d --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/mapper/mapping/SysTimersMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/param/SysTimersParam.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/param/SysTimersParam.java new file mode 100644 index 00000000..dca7527f --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/param/SysTimersParam.java @@ -0,0 +1,78 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.timer.param; + +import com.cn.xiaonuo.core.pojo.base.param.BaseParam; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 定时任务 + * + * @author yubaoshan + * @date 2020/6/30 18:26 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class SysTimersParam extends BaseParam { + + /** + * 定时器id + */ + @NotNull(message = "主键id不能为空,请检查id字段", groups = {edit.class, detail.class, delete.class, start.class, stop.class}) + private Long id; + + /** + * 任务名称 + */ + @NotBlank(message = "任务名称不能为空,请检查timerName字段", groups = {add.class, edit.class}) + private String timerName; + + /** + * 执行任务的class的类名(实现了TimerTaskRunner接口的类的全称) + */ + @NotBlank(message = "任务的class的类名不能为空,请检查actionClass字段", groups = {add.class, edit.class}) + private String actionClass; + + /** + * 定时任务表达式 + */ + @NotBlank(message = "定时任务表达式不能为空,请检查cron字段", groups = {add.class, edit.class}) + private String cron; + + /** + * 状态(字典 1运行 2停止) + */ + private Integer jobStatus; + + /** + * 备注信息 + */ + private String remark; + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/service/SysTimersService.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/service/SysTimersService.java new file mode 100644 index 00000000..0297105d --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/service/SysTimersService.java @@ -0,0 +1,128 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.timer.service; + +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.modular.timer.entity.SysTimers; +import com.cn.xiaonuo.sys.modular.timer.param.SysTimersParam; +import com.baomidou.mybatisplus.extension.service.IService; +import com.cn.xiaonuo.sys.modular.timer.entity.SysTimers; +import com.cn.xiaonuo.sys.modular.timer.param.SysTimersParam; + +import java.util.List; + +/** + * 定时任务 服务类 + * + * @author yubaoshan + * @date 2020/6/30 18:26 + */ +public interface SysTimersService extends IService { + + /** + * 分页查询定时任务 + * + * @param sysTimersParam 查询参数 + * @return 查询分页结果 + * @author yubaoshan + * @date 2020/6/30 18:26 + */ + PageResult page(SysTimersParam sysTimersParam); + + /** + * 查询所有定时任务 + * + * @param sysTimersParam 查询参数 + * @return 定时任务列表 + * @author yubaoshan + * @date 2020/6/30 18:26 + */ + List list(SysTimersParam sysTimersParam); + + /** + * 添加定时任务 + * + * @param sysTimersParam 添加参数 + * @author yubaoshan + * @date 2020/6/30 18:26 + */ + void add(SysTimersParam sysTimersParam); + + /** + * 删除定时任务 + * + * @param sysTimersParam 删除参数 + * @author yubaoshan + * @date 2020/6/30 18:26 + */ + void delete(SysTimersParam sysTimersParam); + + /** + * 编辑定时任务 + * + * @param sysTimersParam 编辑参数 + * @author yubaoshan + * @date 2020/6/30 18:26 + */ + void edit(SysTimersParam sysTimersParam); + + /** + * 查看详情定时任务 + * + * @param sysTimersParam 查看参数 + * @return 定时任务 + * @author yubaoshan + * @date 2020/6/30 18:26 + */ + SysTimers detail(SysTimersParam sysTimersParam); + + /** + * 启动任务 + * + * @param sysTimersParam 启动参数 + * @author yubaoshan + * @date 2020/7/1 14:36 + */ + void start(SysTimersParam sysTimersParam); + + /** + * 停止任务 + * + * @param sysTimersParam 停止参数 + * @author yubaoshan + * @date 2020/7/1 14:36 + */ + void stop(SysTimersParam sysTimersParam); + + /** + * 获取所有可执行的任务列表 + * + * @return TimerTaskRunner的所有子类名称集合 + * @author yubaoshan + * @date 2020/7/1 14:36 + */ + List getActionClasses(); + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/service/TimerExeService.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/service/TimerExeService.java new file mode 100644 index 00000000..4b3a7e9c --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/service/TimerExeService.java @@ -0,0 +1,61 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.timer.service; + +/** + * 本接口用来,屏蔽定时任务的多样性 + *

+ * 目前用hutool,不排除以后用别的 + * + * @author yubaoshan + * @date 2020/6/30 18:26 + */ +public interface TimerExeService { + + /** + * 启动一个定时器 + *

+ * 定时任务表达式书写规范:0/2 * * * * * + *

+ * 六位数,分别是:秒 分 小时 日 月 年 + * + * @param taskId 任务id + * @param cron cron表达式 + * @param className 类的全名,必须是TimerTaskRunner的子类 + * @author yubaoshan + * @date 2020/7/1 13:51 + */ + void startTimer(String taskId, String cron, String className); + + /** + * 停止一个定时器 + * + * @param taskId 定时任务Id + * @author yubaoshan + * @date 2020/7/1 14:08 + */ + void stopTimer(String taskId); + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/service/impl/HutoolTimerExeServiceImpl.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/service/impl/HutoolTimerExeServiceImpl.java new file mode 100644 index 00000000..28037617 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/service/impl/HutoolTimerExeServiceImpl.java @@ -0,0 +1,83 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.timer.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.cron.CronUtil; +import cn.hutool.cron.task.Task; +import cn.hutool.extra.spring.SpringUtil; +import cn.hutool.log.Log; +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.core.timer.TimerTaskRunner; +import com.cn.xiaonuo.sys.modular.timer.enums.exp.SysTimersExceptionEnum; +import com.cn.xiaonuo.sys.modular.timer.service.TimerExeService; +import com.cn.xiaonuo.sys.modular.timer.enums.exp.SysTimersExceptionEnum; +import org.springframework.stereotype.Service; + +/** + * hutool方式的定时任务执行 + * + * @author yubaoshan + * @date 2020/7/1 13:48 + */ +@Service +public class HutoolTimerExeServiceImpl implements TimerExeService { + + private static final Log log = Log.get(); + + @Override + public void startTimer(String taskId, String cron, String className) { + + if (ObjectUtil.hasEmpty(taskId, cron, className)) { + throw new ServiceException(SysTimersExceptionEnum.EXE_EMPTY_PARAM); + } + + // 预加载类看是否存在此定时任务类 + try { + Class.forName(className); + } catch (ClassNotFoundException e) { + throw new ServiceException(SysTimersExceptionEnum.TIMER_NOT_EXISTED); + } + + // 定义hutool的任务 + Task task = () -> { + try { + TimerTaskRunner timerTaskRunner = (TimerTaskRunner) SpringUtil.getBean(Class.forName(className)); + timerTaskRunner.action(); + } catch (ClassNotFoundException e) { + log.error(">>> 任务执行异常:{}", e.getMessage()); + } + }; + + // 开始执行任务 + CronUtil.schedule(taskId, cron, task); + } + + @Override + public void stopTimer(String taskId) { + CronUtil.remove(taskId); + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/service/impl/SysTimersServiceImpl.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/service/impl/SysTimersServiceImpl.java new file mode 100644 index 00000000..9c66ac90 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/service/impl/SysTimersServiceImpl.java @@ -0,0 +1,219 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.timer.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.cron.CronUtil; +import cn.hutool.extra.spring.SpringUtil; +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.core.factory.PageFactory; +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.core.timer.TimerTaskRunner; +import com.cn.xiaonuo.sys.modular.timer.entity.SysTimers; +import com.cn.xiaonuo.sys.modular.timer.enums.TimerJobStatusEnum; +import com.cn.xiaonuo.sys.modular.timer.enums.exp.SysTimersExceptionEnum; +import com.cn.xiaonuo.sys.modular.timer.mapper.SysTimersMapper; +import com.cn.xiaonuo.sys.modular.timer.param.SysTimersParam; +import com.cn.xiaonuo.sys.modular.timer.service.SysTimersService; +import com.cn.xiaonuo.sys.modular.timer.service.TimerExeService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.cn.xiaonuo.sys.modular.timer.enums.TimerJobStatusEnum; +import com.cn.xiaonuo.sys.modular.timer.enums.exp.SysTimersExceptionEnum; +import com.cn.xiaonuo.sys.modular.timer.param.SysTimersParam; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 定时任务 服务实现类 + * + * @author yubaoshan + * @date 2020/6/30 18:26 + */ +@Service +public class SysTimersServiceImpl extends ServiceImpl implements SysTimersService { + + @Resource + private TimerExeService timerExeService; + + @Override + public PageResult page(SysTimersParam sysTimersParam) { + + // 构造条件 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + + if (ObjectUtil.isNotNull(sysTimersParam)) { + + // 拼接查询条件-任务名称 + if (ObjectUtil.isNotEmpty(sysTimersParam.getTimerName())) { + queryWrapper.like(SysTimers::getTimerName, sysTimersParam.getTimerName()); + } + + // 拼接查询条件-状态(字典 1运行 2停止) + if (ObjectUtil.isNotEmpty(sysTimersParam.getJobStatus())) { + queryWrapper.like(SysTimers::getJobStatus, sysTimersParam.getJobStatus()); + } + } + + // 查询分页结果 + return new PageResult<>(this.page(PageFactory.defaultPage(), queryWrapper)); + } + + @Override + public List list(SysTimersParam sysTimersParam) { + + // 构造条件 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + + if (ObjectUtil.isNotNull(sysTimersParam)) { + + // 拼接查询条件-任务名称 + if (ObjectUtil.isNotEmpty(sysTimersParam.getTimerName())) { + queryWrapper.like(SysTimers::getTimerName, sysTimersParam.getTimerName()); + } + + // 拼接查询条件-状态(字典 1运行 2停止) + if (ObjectUtil.isNotEmpty(sysTimersParam.getJobStatus())) { + queryWrapper.like(SysTimers::getJobStatus, sysTimersParam.getJobStatus()); + } + } + + return this.list(queryWrapper); + } + + @Override + public void add(SysTimersParam sysTimersParam) { + + // 将dto转为实体 + SysTimers sysTimers = new SysTimers(); + BeanUtil.copyProperties(sysTimersParam, sysTimers); + + // 设置为停止状态,点击启动时启动任务 + sysTimers.setJobStatus(TimerJobStatusEnum.STOP.getCode()); + + this.save(sysTimers); + } + + @Override + public void delete(SysTimersParam sysTimersParam) { + + // 先停止id为参数id的定时器 + CronUtil.remove(String.valueOf(sysTimersParam.getId())); + + this.removeById(sysTimersParam.getId()); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void edit(SysTimersParam sysTimersParam) { + + // 更新库中记录 + SysTimers oldTimer = this.querySysTimers(sysTimersParam); + BeanUtil.copyProperties(sysTimersParam, oldTimer); + this.updateById(oldTimer); + + // 查看被编辑的任务的状态 + Integer jobStatus = oldTimer.getJobStatus(); + + // 如果任务正在运行,则停掉这个任务,从新运行任务 + if (jobStatus.equals(TimerJobStatusEnum.RUNNING.getCode())) { + CronUtil.remove(String.valueOf(oldTimer.getId())); + timerExeService.startTimer( + String.valueOf(sysTimersParam.getId()), + sysTimersParam.getCron(), + sysTimersParam.getActionClass()); + } + } + + @Override + public SysTimers detail(SysTimersParam sysTimersParam) { + return this.querySysTimers(sysTimersParam); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void start(SysTimersParam sysTimersParam) { + + // 更新库中的状态 + LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper<>(); + wrapper.set(SysTimers::getJobStatus, TimerJobStatusEnum.RUNNING.getCode()) + .eq(SysTimers::getId, sysTimersParam.getId()); + this.update(wrapper); + + // 添加定时任务调度 + SysTimers sysTimers = this.querySysTimers(sysTimersParam); + timerExeService.startTimer(String.valueOf(sysTimers.getId()), sysTimers.getCron(), sysTimers.getActionClass()); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void stop(SysTimersParam sysTimersParam) { + + // 更新库中的状态 + LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper<>(); + wrapper.set(SysTimers::getJobStatus, TimerJobStatusEnum.STOP.getCode()) + .eq(SysTimers::getId, sysTimersParam.getId()); + this.update(wrapper); + + // 关闭定时任务调度 + SysTimers sysTimers = this.querySysTimers(sysTimersParam); + timerExeService.stopTimer(String.valueOf(sysTimers.getId())); + } + + @Override + public List getActionClasses() { + Map timerTaskRunnerMap = SpringUtil.getBeansOfType(TimerTaskRunner.class); + if (ObjectUtil.isNotEmpty(timerTaskRunnerMap)) { + Collection values = timerTaskRunnerMap.values(); + return values.stream().map(i -> i.getClass().getName()).collect(Collectors.toList()); + } else { + return CollectionUtil.newArrayList(); + } + } + + /** + * 获取定时任务 + * + * @author yubaoshan + * @date 2020/6/30 18:26 + */ + private SysTimers querySysTimers(SysTimersParam sysTimersParam) { + SysTimers sysTimers = this.getById(sysTimersParam.getId()); + if (ObjectUtil.isEmpty(sysTimers)) { + throw new ServiceException(SysTimersExceptionEnum.NOT_EXISTED); + } + return sysTimers; + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/tasks/RefreshConstantsTaskRunner.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/tasks/RefreshConstantsTaskRunner.java new file mode 100644 index 00000000..ed165ab7 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/tasks/RefreshConstantsTaskRunner.java @@ -0,0 +1,71 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.timer.tasks; + +import cn.hutool.log.Log; +import com.cn.xiaonuo.core.context.constant.ConstantContext; +import com.cn.xiaonuo.core.enums.CommonStatusEnum; +import com.cn.xiaonuo.core.timer.TimerTaskRunner; +import com.cn.xiaonuo.sys.modular.consts.entity.SysConfig; +import com.cn.xiaonuo.sys.modular.consts.service.SysConfigService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 定时器:用来根据sys_config表中的配置,刷新ConstantContextHolder中的缓存 + *

+ * 防止由于直接改动数据库,而调用缓存常量时,产生数据不一致问题 + * + * @author xuyuxiang + * @date 2020/7/30 16:41 + */ +@Component +public class RefreshConstantsTaskRunner implements TimerTaskRunner { + + private static final Log log = Log.get(); + + @Resource + private SysConfigService sysConfigService; + + @Override + public void action() { + + // 查询库中的所有配置 + LambdaQueryWrapper sysConfigLambdaQueryWrapper = new LambdaQueryWrapper<>(); + + sysConfigLambdaQueryWrapper.eq(SysConfig::getStatus, CommonStatusEnum.ENABLE.getCode()); + sysConfigLambdaQueryWrapper.select(SysConfig::getCode, SysConfig::getValue); + + List list = sysConfigService.list(sysConfigLambdaQueryWrapper); + + // 所有配置添加到缓存中,覆盖已有配置 + list.forEach(sysConfig -> ConstantContext.putConstant(sysConfig.getCode(), sysConfig.getValue())); + + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/tasks/SystemOutTaskRunner.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/tasks/SystemOutTaskRunner.java new file mode 100644 index 00000000..b231b7d4 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/timer/tasks/SystemOutTaskRunner.java @@ -0,0 +1,44 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.timer.tasks; + +import com.cn.xiaonuo.core.timer.TimerTaskRunner; +import org.springframework.stereotype.Component; + +/** + * 这是一个定时任务的示例程序 + * + * @author yubaoshan + * @date 2020/6/30 22:09 + */ +@Component +public class SystemOutTaskRunner implements TimerTaskRunner { + + @Override + public void action() { + System.out.println("一直往南方开!一直往南方开!"); + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/controller/SysUserController.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/controller/SysUserController.java new file mode 100644 index 00000000..33c2e8bb --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/controller/SysUserController.java @@ -0,0 +1,278 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.user.controller; + +import com.cn.xiaonuo.core.annotion.BusinessLog; +import com.cn.xiaonuo.core.annotion.DataScope; +import com.cn.xiaonuo.core.annotion.Permission; +import com.cn.xiaonuo.core.enums.LogAnnotionOpTypeEnum; +import com.cn.xiaonuo.core.pojo.response.ResponseData; +import com.cn.xiaonuo.core.pojo.response.SuccessResponseData; +import com.cn.xiaonuo.sys.modular.user.param.SysUserParam; +import com.cn.xiaonuo.sys.modular.user.service.SysUserService; +import com.cn.xiaonuo.sys.modular.user.param.SysUserParam; +import com.cn.xiaonuo.sys.modular.user.service.SysUserService; +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.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + * 系统用户控制器 + * + * @author xuyuxiang + * @date 2020/3/19 21:14 + */ +@RestController +public class SysUserController { + + @Resource + private SysUserService sysUserService; + + /** + * 查询系统用户 + * + * @author xuyuxiang + * @date 2020/3/20 21:00 + */ + @Permission + @DataScope + @GetMapping("/sysUser/page") + @BusinessLog(title = "系统用户_查询", opType = LogAnnotionOpTypeEnum.QUERY) + public ResponseData page(SysUserParam sysUserParam) { + return new SuccessResponseData(sysUserService.page(sysUserParam)); + } + + /** + * 增加系统用户 + * + * @author xuyuxiang + * @date 2020/3/23 16:28 + */ + @Permission + @DataScope + @PostMapping("/sysUser/add") + @BusinessLog(title = "系统用户_增加", opType = LogAnnotionOpTypeEnum.ADD) + public ResponseData add(@RequestBody @Validated(SysUserParam.add.class) SysUserParam sysUserParam) { + sysUserService.add(sysUserParam); + return new SuccessResponseData(); + } + + /** + * 删除系统用户 + * + * @author xuyuxiang + * @date 2020/3/23 16:28 + */ + @Permission + @DataScope + @PostMapping("/sysUser/delete") + @BusinessLog(title = "系统用户_删除", opType = LogAnnotionOpTypeEnum.DELETE) + public ResponseData delete(@RequestBody @Validated(SysUserParam.delete.class) SysUserParam sysUserParam) { + sysUserService.delete(sysUserParam); + return new SuccessResponseData(); + } + + /** + * 编辑系统用户 + * + * @author xuyuxiang + * @date 2020/3/23 16:28 + */ + @Permission + @DataScope + @PostMapping("/sysUser/edit") + @BusinessLog(title = "系统用户_编辑", opType = LogAnnotionOpTypeEnum.EDIT) + public ResponseData edit(@RequestBody @Validated(SysUserParam.edit.class) SysUserParam sysUserParam) { + sysUserService.edit(sysUserParam); + return new SuccessResponseData(); + } + + /** + * 查看系统用户 + * + * @author xuyuxiang + * @date 2020/3/23 16:28 + */ + @Permission + @GetMapping("/sysUser/detail") + @BusinessLog(title = "系统用户_查看", opType = LogAnnotionOpTypeEnum.DETAIL) + public ResponseData detail(@Validated(SysUserParam.detail.class) SysUserParam sysUserParam) { + return new SuccessResponseData(sysUserService.detail(sysUserParam)); + } + + /** + * 修改状态 + * + * @author xuyuxiang + * @date 2020/5/25 14:32 + */ + @Permission + @PostMapping("/sysUser/changeStatus") + @BusinessLog(title = "系统用户_修改状态", opType = LogAnnotionOpTypeEnum.CHANGE_STATUS) + public ResponseData changeStatus(@RequestBody @Validated(SysUserParam.changeStatus.class) SysUserParam sysUserParam) { + sysUserService.changeStatus(sysUserParam); + return new SuccessResponseData(); + } + + /** + * 授权角色 + * + * @author xuyuxiang + * @date 2020/3/28 16:05 + */ + @Permission + @DataScope + @PostMapping("/sysUser/grantRole") + @BusinessLog(title = "系统用户_授权角色", opType = LogAnnotionOpTypeEnum.GRANT) + public ResponseData grantRole(@RequestBody @Validated(SysUserParam.grantRole.class) SysUserParam sysUserParam) { + sysUserService.grantRole(sysUserParam); + return new SuccessResponseData(); + } + + /** + * 授权数据 + * + * @author xuyuxiang + * @date 2020/3/28 16:05 + */ + @Permission + @DataScope + @PostMapping("/sysUser/grantData") + @BusinessLog(title = "系统用户_授权数据", opType = LogAnnotionOpTypeEnum.GRANT) + public ResponseData grantData(@RequestBody @Validated(SysUserParam.grantData.class) SysUserParam sysUserParam) { + sysUserService.grantData(sysUserParam); + return new SuccessResponseData(); + } + + /** + * 更新信息 + * + * @author xuyuxiang + * @date 2020/4/1 14:27 + */ + @PostMapping("/sysUser/updateInfo") + @BusinessLog(title = "系统用户_更新信息", opType = LogAnnotionOpTypeEnum.UPDATE) + public ResponseData updateInfo(@RequestBody @Validated(SysUserParam.updateInfo.class) SysUserParam sysUserParam) { + sysUserService.updateInfo(sysUserParam); + return new SuccessResponseData(); + } + + /** + * 修改密码 + * + * @author xuyuxiang + * @date 2020/4/1 14:42 + */ + @PostMapping("/sysUser/updatePwd") + @BusinessLog(title = "系统用户_修改密码", opType = LogAnnotionOpTypeEnum.UPDATE) + public ResponseData updatePwd(@RequestBody @Validated(SysUserParam.updatePwd.class) SysUserParam sysUserParam) { + sysUserService.updatePwd(sysUserParam); + return new SuccessResponseData(); + } + + /** + * 拥有角色 + * + * @author xuyuxiang + * @date 2020/3/28 14:46 + */ + @Permission + @GetMapping("/sysUser/ownRole") + @BusinessLog(title = "系统用户_拥有角色", opType = LogAnnotionOpTypeEnum.DETAIL) + public ResponseData ownRole(@Validated(SysUserParam.detail.class) SysUserParam sysUserParam) { + return new SuccessResponseData(sysUserService.ownRole(sysUserParam)); + } + + /** + * 拥有数据 + * + * @author xuyuxiang + * @date 2020/3/28 14:46 + */ + @Permission + @GetMapping("/sysUser/ownData") + @BusinessLog(title = "系统用户_拥有数据", opType = LogAnnotionOpTypeEnum.DETAIL) + public ResponseData ownData(@Validated(SysUserParam.detail.class) SysUserParam sysUserParam) { + return new SuccessResponseData(sysUserService.ownData(sysUserParam)); + } + + /** + * 重置密码 + * + * @author xuyuxiang + * @date 2020/4/1 14:42 + */ + @Permission + @PostMapping("/sysUser/resetPwd") + @BusinessLog(title = "系统用户_重置密码", opType = LogAnnotionOpTypeEnum.UPDATE) + public ResponseData resetPwd(@RequestBody @Validated(SysUserParam.resetPwd.class) SysUserParam sysUserParam) { + sysUserService.resetPwd(sysUserParam); + return new SuccessResponseData(); + } + + /** + * 修改头像 + * + * @author xuyuxiang + * @date 2020/6/28 15:19 + */ + @PostMapping("/sysUser/updateAvatar") + @BusinessLog(title = "系统用户_修改头像", opType = LogAnnotionOpTypeEnum.UPDATE) + public ResponseData updateAvatar(@RequestBody @Validated(SysUserParam.updateAvatar.class) SysUserParam sysUserParam) { + sysUserService.updateAvatar(sysUserParam); + return new SuccessResponseData(); + } + + /** + * 导出系统用户 + * + * @author xuyuxiang + * @date 2020/6/30 16:07 + */ + @Permission + @GetMapping("/sysUser/export") + @BusinessLog(title = "系统用户_导出", opType = LogAnnotionOpTypeEnum.EXPORT) + public void export(SysUserParam sysUserParam) { + sysUserService.export(sysUserParam); + } + + + /** + * 用户选择器 + * + * @author xuyuxiang + * @date 2020/7/3 13:17 + */ + @Permission + @GetMapping("/sysUser/selector") + @BusinessLog(title = "系统用户_选择器", opType = LogAnnotionOpTypeEnum.QUERY) + public ResponseData selector(SysUserParam sysUserParam) { + return new SuccessResponseData(sysUserService.selector(sysUserParam)); + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/entity/SysUser.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/entity/SysUser.java new file mode 100644 index 00000000..da12f7f5 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/entity/SysUser.java @@ -0,0 +1,137 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.user.entity; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import com.cn.xiaonuo.core.pojo.base.entity.BaseEntity; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + * 系统用户表 + * + * @author xuyuxiang + * @date 2020/3/5 12:25 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@TableName("sys_user") +public class SysUser extends BaseEntity { + + /** + * 主键 + */ + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + /** + * 账号 + */ + @Excel(name = "账号", width = 20) + private String account; + + /** + * 密码 + */ + private String password; + + /** + * 昵称 + */ + @Excel(name = "昵称", width = 20) + private String nickName; + + /** + * 姓名 + */ + @Excel(name = "姓名", width = 20) + private String name; + + /** + * 头像 + */ + private Long avatar; + + /** + * 生日 + */ + @Excel(name = "生日", databaseFormat = "yyyy-MM-dd HH:mm:ss", format = "yyyy-MM-dd", width = 20) + private Date birthday; + + /** + * 性别(字典 1男 2女 3未知) + */ + @Excel(name = "性别", replace = {"男_1", "女_2"}, width = 20) + private Integer sex; + + /** + * 邮箱 + */ + @Excel(name = "邮箱", width = 30) + private String email; + + /** + * 手机 + */ + @Excel(name = "手机", width = 30) + private String phone; + + /** + * 电话 + */ + @Excel(name = "电话", width = 30) + private String tel; + + /** + * 最后登陆IP + */ + @Excel(name = "最后登陆IP", width = 30) + private String lastLoginIp; + + /** + * 最后登陆时间 + */ + @Excel(name = "最后登陆时间", databaseFormat = "yyyy-MM-dd HH:mm:ss", format = "yyyy-MM-dd HH:mm:ss", width = 30) + private Date lastLoginTime; + + /** + * 管理员类型(1超级管理员 2非管理员) + */ + @Excel(name = "管理员类型", replace = {"超级管理员_1", "非管理员_2"}, width = 20) + private Integer adminType; + + /** + * 状态(字典 0正常 1停用 2删除) + */ + @Excel(name = "状态", replace = {"正常_0", "停用_1", "删除_2"}, width = 20) + private Integer status; + + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/entity/SysUserDataScope.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/entity/SysUserDataScope.java new file mode 100644 index 00000000..3ef3b517 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/entity/SysUserDataScope.java @@ -0,0 +1,57 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.user.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * 系统用户数据范围表 + * + * @author xuyuxiang + * @date 2020/3/11 11:47 + */ +@Data +@TableName("sys_user_data_scope") +public class SysUserDataScope { + + /** + * 主键 + */ + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + /** + * 用户id + */ + private Long userId; + + /** + * 机构id + */ + private Long orgId; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/entity/SysUserRole.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/entity/SysUserRole.java new file mode 100644 index 00000000..fab7418e --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/entity/SysUserRole.java @@ -0,0 +1,57 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.user.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * 系统用户角色表 + * + * @author xuyuxiang + * @date 2020/3/11 11:47 + */ +@Data +@TableName("sys_user_role") +public class SysUserRole { + + /** + * 主键 + */ + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + /** + * 用户id + */ + private Long userId; + + /** + * 角色id + */ + private Long roleId; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/enums/SysUserExceptionEnum.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/enums/SysUserExceptionEnum.java new file mode 100644 index 00000000..821e2c05 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/enums/SysUserExceptionEnum.java @@ -0,0 +1,90 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.user.enums; + +import com.cn.xiaonuo.core.annotion.ExpEnumType; +import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum; +import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory; +import com.cn.xiaonuo.sys.core.consts.SysExpEnumConstant; + +/** + * 系统用户相关异常枚举 + * + * @author xuyuxiang + * @date 2020/3/23 9:32 + */ +@ExpEnumType(module = SysExpEnumConstant.XIAONUO_SYS_MODULE_EXP_CODE, kind = SysExpEnumConstant.SYS_USER_EXCEPTION_ENUM) +public enum SysUserExceptionEnum implements AbstractBaseExceptionEnum { + + /** + * 用户不存在 + */ + USER_NOT_EXIST(1, "用户不存在"), + + /** + * 账号已存在 + */ + USER_ACCOUNT_REPEAT(2, "账号已存在,请检查account参数"), + + /** + * 原密码错误 + */ + USER_PWD_ERROR(3, "原密码错误,请检查password参数"), + + /** + * 新密码与原密码相同 + */ + USER_PWD_REPEAT(4, "新密码与原密码相同,请检查newPassword参数"), + + /** + * 不能删除超级管理员 + */ + USER_CAN_NOT_DELETE_ADMIN(5, "不能删除超级管理员"), + + /** + * 不能修改超级管理员状态 + */ + USER_CAN_NOT_UPDATE_ADMIN(6, "不能修改超级管理员状态"); + + private final Integer code; + + private final String message; + + SysUserExceptionEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return ExpEnumCodeFactory.getExpEnumCode(this.getClass(), code); + } + + @Override + public String getMessage() { + return message; + } + +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/factory/SysUserFactory.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/factory/SysUserFactory.java new file mode 100644 index 00000000..283df1fc --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/factory/SysUserFactory.java @@ -0,0 +1,80 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.user.factory; + +import cn.hutool.core.util.ObjectUtil; +import com.cn.xiaonuo.core.context.constant.ConstantContextHolder; +import com.cn.xiaonuo.core.enums.CommonStatusEnum; +import com.cn.xiaonuo.sys.core.enums.AdminTypeEnum; +import com.cn.xiaonuo.sys.core.enums.SexEnum; +import com.cn.xiaonuo.sys.modular.user.entity.SysUser; +import org.springframework.security.crypto.bcrypt.BCrypt; + +/** + * 填充用户附加信息工厂 + * + * @author xuyuxiang + * @date 2020/3/23 16:40 + */ +public class SysUserFactory { + + /** + * 管理员类型(1超级管理员 2非管理员) + * 新增普通用户时填充相关信息 + * + * @author xuyuxiang + * @date 2020/3/23 16:41 + */ + public static void fillAddCommonUserInfo(SysUser sysUser) { + fillBaseUserInfo(sysUser); + sysUser.setAdminType(AdminTypeEnum.NONE.getCode()); + } + + /** + * 填充用户基本字段 + * + * @author xuyuxiang + * @date 2020/3/23 16:50 + */ + public static void fillBaseUserInfo(SysUser sysUser) { + //密码为空则设置密码 + if (ObjectUtil.isEmpty(sysUser.getPassword())) { + //没有密码则设置默认密码 + String password = ConstantContextHolder.getDefaultPassWord(); + //设置密码为Md5加密后的密码 + sysUser.setPassword(BCrypt.hashpw(password, BCrypt.gensalt())); + } + + if (ObjectUtil.isEmpty(sysUser.getAvatar())) { + sysUser.setAvatar(null); + } + + if (ObjectUtil.isEmpty(sysUser.getSex())) { + sysUser.setSex(SexEnum.NONE.getCode()); + } + + sysUser.setStatus(CommonStatusEnum.ENABLE.getCode()); + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/mapper/SysUserDataScopeMapper.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/mapper/SysUserDataScopeMapper.java new file mode 100644 index 00000000..689558e0 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/mapper/SysUserDataScopeMapper.java @@ -0,0 +1,38 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.user.mapper; + +import com.cn.xiaonuo.sys.modular.user.entity.SysUserDataScope; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.cn.xiaonuo.sys.modular.user.entity.SysUserDataScope; + +/** + * 系统用户数据范围mapper接口 + * + * @author xuyuxiang + * @date 2020/3/13 15:46 + */ +public interface SysUserDataScopeMapper extends BaseMapper { +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/mapper/SysUserMapper.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/mapper/SysUserMapper.java new file mode 100644 index 00000000..63371404 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/mapper/SysUserMapper.java @@ -0,0 +1,54 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.user.mapper; + +import com.cn.xiaonuo.sys.modular.user.entity.SysUser; +import com.cn.xiaonuo.sys.modular.user.result.SysUserResult; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.cn.xiaonuo.sys.modular.user.entity.SysUser; +import com.cn.xiaonuo.sys.modular.user.result.SysUserResult; +import org.apache.ibatis.annotations.Param; + +/** + * 系统用户mapper接口 + * + * @author xuyuxiang + * @date 2020/3/12 9:48 + */ +public interface SysUserMapper extends BaseMapper { + + /** + * 获取用户分页列表 + * + * @param page 分页参数 + * @param queryWrapper 查询参数 + * @return 查询分页结果 + * @author xuyuxiang + * @date 2020/4/7 21:14 + */ + Page page(@Param("page") Page page, @Param("ew") QueryWrapper queryWrapper); +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/mapper/SysUserRoleMapper.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/mapper/SysUserRoleMapper.java new file mode 100644 index 00000000..cd3762ed --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/mapper/SysUserRoleMapper.java @@ -0,0 +1,38 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.user.mapper; + +import com.cn.xiaonuo.sys.modular.user.entity.SysUserRole; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.cn.xiaonuo.sys.modular.user.entity.SysUserRole; + +/** + * 系统用户角色mapper接口 + * + * @author xuyuxiang + * @date 2020/3/13 15:46 + */ +public interface SysUserRoleMapper extends BaseMapper { +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/mapper/mapping/SysUserDataScopeMapper.xml b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/mapper/mapping/SysUserDataScopeMapper.xml new file mode 100644 index 00000000..bc576e1d --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/mapper/mapping/SysUserDataScopeMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/mapper/mapping/SysUserMapper.xml b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/mapper/mapping/SysUserMapper.xml new file mode 100644 index 00000000..d6e498e9 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/mapper/mapping/SysUserMapper.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/mapper/mapping/SysUserRoleMapper.xml b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/mapper/mapping/SysUserRoleMapper.xml new file mode 100644 index 00000000..f1794728 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/mapper/mapping/SysUserRoleMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/param/SysUserParam.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/param/SysUserParam.java new file mode 100644 index 00000000..cb2eb3ae --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/param/SysUserParam.java @@ -0,0 +1,146 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.user.param; + +import com.cn.xiaonuo.core.pojo.base.param.BaseParam; +import com.cn.xiaonuo.core.validation.date.DateValue; +import com.cn.xiaonuo.sys.modular.emp.param.SysEmpParam; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.Valid; +import javax.validation.constraints.*; +import java.util.List; + +/** + * 系统用户参数 + * + * @author xuyuxiang + * @date 2020/3/23 9:21 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class SysUserParam extends BaseParam { + + /** + * 主键 + */ + @NotNull(message = "id不能为空,请检查id参数", + groups = {edit.class, delete.class, detail.class, start.class, + stop.class, grantRole.class, grantData.class, updateInfo.class, + updatePwd.class, resetPwd.class, changeStatus.class, updateAvatar.class}) + private Long id; + + /** + * 账号 + */ + @NotBlank(message = "账号不能为空,请检查account参数", groups = {add.class, edit.class}) + private String account; + + /** + * 密码 + */ + @NotBlank(message = "密码不能为空,请检查password参数", groups = {updatePwd.class}) + private String password; + + /** + * 新密码 + */ + @NotBlank(message = "新密码不能为空,请检查newPassword参数", groups = {updatePwd.class}) + private String newPassword; + + /** + * 昵称 + */ + private String nickName; + + /** + * 姓名 + */ + @NotBlank(message = "姓名不能为空,请检查name参数", groups = {add.class, edit.class}) + private String name; + + /** + * 头像 + */ + @NotNull(message = "头像不能为空,请检查avatar参数", groups = {updateAvatar.class}) + private Long avatar; + + /** + * 生日 + */ + @DateValue(message = "生日格式不正确,请检查birthday参数", groups = {add.class, edit.class, updateInfo.class}) + private String birthday; + + /** + * 性别(字典 1男 2女) + */ + @NotNull(message = "性别不能为空,请检查sex参数", groups = {updateInfo.class}) + @Min(value = 1, message = "性别格式错误,请检查sex参数", groups = {updateInfo.class}) + @Max(value = 2, message = "性别格式错误,请检查sex参数", groups = {updateInfo.class}) + private Integer sex; + + /** + * 邮箱 + */ + @Email(message = "邮箱格式错误,请检查email参数", groups = {updateInfo.class}) + private String email; + + /** + * 手机 + */ + @NotNull(message = "手机号码不能为空,请检查phone参数", groups = {add.class, edit.class, updateInfo.class}) + @Size(min = 11, max = 11, message = "手机号码格式错误,请检查phone参数", groups = {add.class, edit.class, updateInfo.class}) + private String phone; + + /** + * 电话 + */ + private String tel; + + /** + * 授权角色 + */ + @NotNull(message = "授权角色不能为空,请检查grantRoleIdList参数", groups = {grantRole.class}) + private List grantRoleIdList; + + /** + * 授权数据 + */ + @NotNull(message = "授权数据不能为空,请检查grantOrgIdList参数", groups = {grantData.class}) + private List grantOrgIdList; + + /*==============员工相关信息==========*/ + + @NotNull(message = "员工信息不能为空,请检查sysEmpParam参数", groups = {add.class, edit.class}) + @Valid + private SysEmpParam sysEmpParam; + + /** + * 状态(字典 0正常 1停用 2删除) + */ + @NotNull(message = "状态不能为空,请检查status参数", groups = changeStatus.class) + private Integer status; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/result/SysUserResult.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/result/SysUserResult.java new file mode 100644 index 00000000..b711c9c5 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/result/SysUserResult.java @@ -0,0 +1,102 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.user.result; + +import com.cn.xiaonuo.sys.modular.emp.result.SysEmpInfo; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.util.Date; + +/** + * 系统用户结果 + * + * @author xuyuxiang + * @date 2020/4/2 9:19 + */ +@Data +public class SysUserResult { + + /** + * 主键 + */ + private Long id; + + /** + * 账号 + */ + private String account; + + /** + * 昵称 + */ + private String nickName; + + /** + * 姓名 + */ + private String name; + + /** + * 头像 + */ + private Long avatar; + + /** + * 生日 + */ + @JsonFormat(pattern = "yyyy-MM-dd") + private Date birthday; + + /** + * 性别(字典 1男 2女 3未知) + */ + private Integer sex; + + /** + * 邮箱 + */ + private String email; + + /** + * 手机 + */ + private String phone; + + /** + * 电话 + */ + private String tel; + + /** + * 用户员工信息 + */ + private SysEmpInfo sysEmpInfo; + + /** + * 状态(字典 0正常 1停用 2删除) + */ + private Integer status; +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/service/SysUserDataScopeService.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/service/SysUserDataScopeService.java new file mode 100644 index 00000000..c2aa9741 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/service/SysUserDataScopeService.java @@ -0,0 +1,77 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.user.service; + +import com.cn.xiaonuo.sys.modular.user.entity.SysUserDataScope; +import com.cn.xiaonuo.sys.modular.user.param.SysUserParam; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +/** + * 系统用户数据范围service接口 + * + * @author xuyuxiang + * @date 2020/3/13 15:45 + */ +public interface SysUserDataScopeService extends IService { + + /** + * 授权数据 + * + * @param sysUserParam 授权参数 + * @author xuyuxiang + * @date 2020/3/28 16:57 + */ + void grantData(SysUserParam sysUserParam); + + /** + * 获取用户的数据范围id集合 + * + * @param uerId 用户id + * @return 数据范围id集合 + * @author xuyuxiang + * @date 2020/4/5 17:27 + */ + List getUserDataScopeIdList(Long uerId); + + /** + * 根据机构id集合删除对应的用户-数据范围关联信息 + * + * @param orgIdList 机构id集合 + * @author xuyuxiang + * @date 2020/6/28 14:15 + */ + void deleteUserDataScopeListByOrgIdList(List orgIdList); + + /** + * 根据用户id删除对应的用户-数据范围关联信息 + * + * @param userId 用户id + * @author xuyuxiang + * @date 2020/6/28 14:52 + */ + void deleteUserDataScopeListByUserId(Long userId); +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/service/SysUserRoleService.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/service/SysUserRoleService.java new file mode 100644 index 00000000..711a12d2 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/service/SysUserRoleService.java @@ -0,0 +1,90 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.user.service; + +import com.cn.xiaonuo.sys.modular.user.entity.SysUserRole; +import com.cn.xiaonuo.sys.modular.user.param.SysUserParam; +import com.baomidou.mybatisplus.extension.service.IService; +import com.cn.xiaonuo.sys.modular.user.entity.SysUserRole; +import com.cn.xiaonuo.sys.modular.user.param.SysUserParam; + +import java.util.List; + +/** + * 系统用户角色service接口 + * + * @author xuyuxiang + * @date 2020/3/13 15:44 + */ +public interface SysUserRoleService extends IService { + + /** + * 获取用户的角色id集合 + * + * @param userId 用户id + * @return 角色id集合 + * @author xuyuxiang + * @date 2020/3/20 22:29 + */ + List getUserRoleIdList(Long userId); + + /** + * 授权角色 + * + * @param sysUserParam 授权参数 + * @author xuyuxiang + * @date 2020/3/28 16:57 + */ + void grantRole(SysUserParam sysUserParam); + + /** + * 获取用户所有角色的数据范围(组织机构id集合) + * + * @param userId 用户id + * @param orgId 组织机构id + * @return 数据范围id集合(组织机构id集合) + * @author xuyuxiang + * @date 2020/4/5 17:31 + */ + List getUserRoleDataScopeIdList(Long userId, Long orgId); + + /** + * 根据角色id删除对应的用户-角色表关联信息 + * + * @param roleId 角色id + * @author xuyuxiang + * @date 2020/6/28 14:22 + */ + void deleteUserRoleListByRoleId(Long roleId); + + /** + * 根据用户id删除对应的用户-角色表关联信息 + * + * @param userId 用户id + * @author xuyuxiang + * @date 2020/6/28 14:52 + */ + void deleteUserRoleListByUserId(Long userId); +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/service/SysUserService.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/service/SysUserService.java new file mode 100644 index 00000000..c7d8e871 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/service/SysUserService.java @@ -0,0 +1,266 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.user.service; + +import cn.hutool.core.lang.Dict; +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.sys.modular.user.entity.SysUser; +import com.cn.xiaonuo.sys.modular.user.param.SysUserParam; +import com.cn.xiaonuo.sys.modular.user.result.SysUserResult; +import com.baomidou.mybatisplus.extension.service.IService; +import com.cn.xiaonuo.sys.modular.user.param.SysUserParam; +import com.cn.xiaonuo.sys.modular.user.result.SysUserResult; +import me.zhyd.oauth.model.AuthUser; + +import java.util.List; + +/** + * 系统用户service接口 + * + * @author xuyuxiang + * @date 2020/3/11 17:49 + */ +public interface SysUserService extends IService { + + /** + * 根据账号获取用户 + * + * @param account 账号 + * @return 用户 + * @author xuyuxiang + * @date 2020/3/11 17:51 + */ + SysUser getUserByCount(String account); + + /** + * 查询系统用户 + * + * @param sysUserParam 查询参数 + * @return 查询分页结果 + * @author xuyuxiang + * @date 2020/3/23 9:23 + */ + PageResult page(SysUserParam sysUserParam); + + /** + * 根据用户账号模糊搜索系统用户列表 + * + * @param sysUserParam 查询参数 + * @return 增强版hashMap 格式:[{"id:":123, "firstName":"张三"}] + * @author xuyuxiang + * @date 2020/4/14 9:21 + */ + List list(SysUserParam sysUserParam); + + /** + * 增加系统用户 + * + * @param sysUserParam 添加参数 + * @author xuyuxiang + * @date 2020/3/23 9:26 + */ + void add(SysUserParam sysUserParam); + + /** + * 删除系统用户 + * + * @param sysUserParam 删除参数 + * @author xuyuxiang + * @date 2020/3/23 9:26 + */ + void delete(SysUserParam sysUserParam); + + /** + * 编辑系统用户 + * + * @param sysUserParam 编辑参数 + * @author xuyuxiang + * @date 2020/3/23 9:26 + */ + void edit(SysUserParam sysUserParam); + + /** + * 查看系统用户 + * + * @param sysUserParam 查看参数 + * @return 用户结果集 + * @author xuyuxiang + * @date 2020/3/26 9:52 + */ + SysUserResult detail(SysUserParam sysUserParam); + + /** + * 修改状态 + * + * @param sysUserParam 修改参数 + * @author xuyuxiang + * @date 2020/5/25 14:34 + */ + void changeStatus(SysUserParam sysUserParam); + + /** + * 授权角色 + * + * @param sysUserParam 授权参数 + * @author xuyuxiang + * @date 2020/3/28 16:54 + */ + void grantRole(SysUserParam sysUserParam); + + /** + * 授权数据 + * + * @param sysUserParam 授权参数 + * @author xuyuxiang + * @date 2020/3/28 16:54 + */ + void grantData(SysUserParam sysUserParam); + + /** + * 更新信息 + * + * @param sysUserParam 更新参数 + * @author xuyuxiang + * @date 2020/4/1 14:43 + */ + void updateInfo(SysUserParam sysUserParam); + + /** + * 修改密码 + * + * @param sysUserParam 修改密码参数 + * @author xuyuxiang + * @date 2020/4/1 14:44 + */ + void updatePwd(SysUserParam sysUserParam); + + /** + * 获取用户的数据范围(组织机构id集合) + * + * @param userId 用户id + * @param orgId 组织机构id + * @return 数据范围id集合(组织机构id集合) + * @author xuyuxiang + * @date 2020/4/5 17:23 + */ + List getUserDataScopeIdList(Long userId, Long orgId); + + /** + * 根据用户id获取姓名 + * + * @param userId 用户id + * @return 用户姓名 + * @author xuyuxiang + * @date 2020/5/6 15:02 + */ + String getNameByUserId(Long userId); + + /** + * 拥有角色 + * + * @param sysUserParam 查询参数 + * @return 角色id集合 + * @author xuyuxiang + * @date 2020/5/29 14:10 + */ + List ownRole(SysUserParam sysUserParam); + + /** + * 拥有数据 + * + * @param sysUserParam 查询参数 + * @return 数据范围id集合 + * @author xuyuxiang + * @date 2020/5/29 14:10 + */ + List ownData(SysUserParam sysUserParam); + + /** + * 重置密码 + * + * @param sysUserParam 重置参数 + * @author xuyuxiang + * @date 2020/5/29 14:57 + */ + void resetPwd(SysUserParam sysUserParam); + + /** + * 修改头像 + * + * @param sysUserParam 修改头像参数 + * @author xuyuxiang + * @date 2020/6/28 15:21 + */ + void updateAvatar(SysUserParam sysUserParam); + + /** + * 导出用户 + * + * @param sysUserParam 导出参数 + * @author xuyuxiang + * @date 2020/6/30 16:08 + */ + void export(SysUserParam sysUserParam); + + /** + * 用户选择器 + * + * @param sysUserParam 查询参数 + * @return 用户列表集合,格式[{"id":123,"name":"张三"},{"id":456,"name":"李四"}] + * @author xuyuxiang + * @date 2020/7/3 13:17 + */ + List selector(SysUserParam sysUserParam); + + /** + * 根据用户id获取用户 + * + * @param userId 用户id + * @return 用户实体 + * @author xuyuxiang + * @date 2020/7/29 10:07 + **/ + SysUser getUserById(Long userId); + + /** + * 将授权的用户信息保存到用户表 + * + * @param authUser 授权的用户信息 + * @param sysUser 用户表信息 + * @return void + * @author xuyuxiang + * @date 2020/7/29 10:26 + **/ + void saveAuthUserToUser(AuthUser authUser, SysUser sysUser); + + /** + * 获取用户id集合 + * + * @return 用户id集合 + * @author xuyuxiang + * @date 2020/9/11 17:54 + **/ + List getAllUserIdList(); +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/service/impl/SysUserDataScopeServiceImpl.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/service/impl/SysUserDataScopeServiceImpl.java new file mode 100644 index 00000000..34ed7a23 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/service/impl/SysUserDataScopeServiceImpl.java @@ -0,0 +1,89 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.user.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.cn.xiaonuo.sys.modular.user.entity.SysUserDataScope; +import com.cn.xiaonuo.sys.modular.user.mapper.SysUserDataScopeMapper; +import com.cn.xiaonuo.sys.modular.user.param.SysUserParam; +import com.cn.xiaonuo.sys.modular.user.service.SysUserDataScopeService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.cn.xiaonuo.sys.modular.user.entity.SysUserDataScope; +import com.cn.xiaonuo.sys.modular.user.param.SysUserParam; +import com.cn.xiaonuo.sys.modular.user.service.SysUserDataScopeService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 系统用户数据范围service接口实现类 + * + * @author xuyuxiang + * @date 2020/3/13 15:49 + */ +@Service +public class SysUserDataScopeServiceImpl extends ServiceImpl + implements SysUserDataScopeService { + + @Override + public void grantData(SysUserParam sysUserParam) { + Long userId = sysUserParam.getId(); + //删除所拥有数据 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysUserDataScope::getUserId, userId); + this.remove(queryWrapper); + //授权数据 + sysUserParam.getGrantOrgIdList().forEach(orgId -> { + SysUserDataScope sysUserDataScope = new SysUserDataScope(); + sysUserDataScope.setUserId(userId); + sysUserDataScope.setOrgId(orgId); + this.save(sysUserDataScope); + }); + } + + @Override + public List getUserDataScopeIdList(Long uerId) { + List userDataScopeIdList = CollectionUtil.newArrayList(); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysUserDataScope::getUserId, uerId); + this.list(queryWrapper).forEach(sysUserDataScope -> userDataScopeIdList.add(sysUserDataScope.getOrgId())); + return userDataScopeIdList; + } + + @Override + public void deleteUserDataScopeListByOrgIdList(List orgIdList) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.in(SysUserDataScope::getOrgId, orgIdList); + this.remove(queryWrapper); + } + + @Override + public void deleteUserDataScopeListByUserId(Long userId) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysUserDataScope::getUserId, userId); + this.remove(queryWrapper); + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/service/impl/SysUserRoleServiceImpl.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/service/impl/SysUserRoleServiceImpl.java new file mode 100644 index 00000000..c3062382 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/service/impl/SysUserRoleServiceImpl.java @@ -0,0 +1,112 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.user.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import com.cn.xiaonuo.sys.modular.role.service.SysRoleService; +import com.cn.xiaonuo.sys.modular.user.entity.SysUserRole; +import com.cn.xiaonuo.sys.modular.user.mapper.SysUserRoleMapper; +import com.cn.xiaonuo.sys.modular.user.param.SysUserParam; +import com.cn.xiaonuo.sys.modular.user.service.SysUserRoleService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.cn.xiaonuo.sys.modular.role.service.SysRoleService; +import com.cn.xiaonuo.sys.modular.user.entity.SysUserRole; +import com.cn.xiaonuo.sys.modular.user.mapper.SysUserRoleMapper; +import com.cn.xiaonuo.sys.modular.user.param.SysUserParam; +import com.cn.xiaonuo.sys.modular.user.service.SysUserRoleService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 系统用户角色service接口实现类 + * + * @author xuyuxiang + * @date 2020/3/13 15:48 + */ +@Service +public class SysUserRoleServiceImpl extends ServiceImpl implements SysUserRoleService { + + @Resource + private SysRoleService sysRoleService; + + @Override + public List getUserRoleIdList(Long userId) { + List roleIdList = CollectionUtil.newArrayList(); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysUserRole::getUserId, userId); + this.list(queryWrapper).forEach(sysUserRole -> roleIdList.add(sysUserRole.getRoleId())); + return roleIdList; + } + + @Override + public void grantRole(SysUserParam sysUserParam) { + Long userId = sysUserParam.getId(); + //删除所拥有角色 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysUserRole::getUserId, userId); + this.remove(queryWrapper); + //授权角色 + sysUserParam.getGrantRoleIdList().forEach(roleId -> { + SysUserRole sysUserRole = new SysUserRole(); + sysUserRole.setUserId(userId); + sysUserRole.setRoleId(roleId); + this.save(sysUserRole); + }); + } + + @Override + public List getUserRoleDataScopeIdList(Long userId, Long orgId) { + List roleIdList = CollectionUtil.newArrayList(); + + // 获取用户所有角色 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysUserRole::getUserId, userId); + this.list(queryWrapper).forEach(sysUserRole -> roleIdList.add(sysUserRole.getRoleId())); + + // 获取这些角色对应的数据范围 + if (ObjectUtil.isNotEmpty(roleIdList)) { + return sysRoleService.getUserDataScopeIdList(roleIdList, orgId); + } + return CollectionUtil.newArrayList(); + } + + @Override + public void deleteUserRoleListByRoleId(Long roleId) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysUserRole::getRoleId, roleId); + this.remove(queryWrapper); + } + + @Override + public void deleteUserRoleListByUserId(Long userId) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysUserRole::getUserId, userId); + this.remove(queryWrapper); + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/service/impl/SysUserServiceImpl.java b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/service/impl/SysUserServiceImpl.java new file mode 100644 index 00000000..a2f230b9 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/java/com/cn/xiaonuo/sys/modular/user/service/impl/SysUserServiceImpl.java @@ -0,0 +1,544 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.sys.modular.user.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.lang.Dict; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.RandomUtil; +import com.cn.xiaonuo.core.consts.CommonConstant; +import com.cn.xiaonuo.core.consts.SymbolConstant; +import com.cn.xiaonuo.core.context.constant.ConstantContextHolder; +import com.cn.xiaonuo.core.context.login.LoginContextHolder; +import com.cn.xiaonuo.core.enums.CommonStatusEnum; +import com.cn.xiaonuo.core.exception.PermissionException; +import com.cn.xiaonuo.core.exception.ServiceException; +import com.cn.xiaonuo.core.exception.enums.PermissionExceptionEnum; +import com.cn.xiaonuo.core.exception.enums.StatusExceptionEnum; +import com.cn.xiaonuo.core.factory.PageFactory; +import com.cn.xiaonuo.core.pojo.page.PageResult; +import com.cn.xiaonuo.core.util.PoiUtil; +import com.cn.xiaonuo.sys.core.enums.AdminTypeEnum; +import com.cn.xiaonuo.sys.core.enums.OauthSexEnum; +import com.cn.xiaonuo.sys.core.enums.SexEnum; +import com.cn.xiaonuo.sys.modular.emp.param.SysEmpParam; +import com.cn.xiaonuo.sys.modular.emp.result.SysEmpInfo; +import com.cn.xiaonuo.sys.modular.emp.service.SysEmpService; +import com.cn.xiaonuo.sys.modular.file.service.SysFileInfoService; +import com.cn.xiaonuo.sys.modular.user.entity.SysUser; +import com.cn.xiaonuo.sys.modular.user.enums.SysUserExceptionEnum; +import com.cn.xiaonuo.sys.modular.user.factory.SysUserFactory; +import com.cn.xiaonuo.sys.modular.user.mapper.SysUserMapper; +import com.cn.xiaonuo.sys.modular.user.param.SysUserParam; +import com.cn.xiaonuo.sys.modular.user.result.SysUserResult; +import com.cn.xiaonuo.sys.modular.user.service.SysUserDataScopeService; +import com.cn.xiaonuo.sys.modular.user.service.SysUserRoleService; +import com.cn.xiaonuo.sys.modular.user.service.SysUserService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import me.zhyd.oauth.enums.AuthUserGender; +import me.zhyd.oauth.model.AuthUser; +import org.springframework.security.crypto.bcrypt.BCrypt; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Set; + +/** + * 系统用户service接口实现类 + * + * @author xuyuxiang + * @date 2020/3/11 17:49 + */ +@Service +public class SysUserServiceImpl extends ServiceImpl implements SysUserService { + + @Resource + private SysEmpService sysEmpService; + + @Resource + private SysUserRoleService sysUserRoleService; + + @Resource + private SysUserDataScopeService sysUserDataScopeService; + + @Resource + private SysFileInfoService sysFileInfoService; + + @Override + public SysUser getUserByCount(String account) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysUser::getAccount, account); + queryWrapper.ne(SysUser::getStatus, CommonStatusEnum.DELETED.getCode()); + return this.getOne(queryWrapper); + } + + @Override + public PageResult page(SysUserParam sysUserParam) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + if (ObjectUtil.isNotNull(sysUserParam)) { + //根据关键字模糊查询(姓名,账号,手机号) + if (ObjectUtil.isNotEmpty(sysUserParam.getSearchValue())) { + queryWrapper.and(q -> q.like("sys_user.account", sysUserParam.getSearchValue()) + .or().like("sys_user.name", sysUserParam.getSearchValue()) + .or().like("sys_user.phone", sysUserParam.getSearchValue())); + } + //根据员工所属机构查询 + if (ObjectUtil.isNotEmpty(sysUserParam.getSysEmpParam())) { + SysEmpParam sysEmpParam = sysUserParam.getSysEmpParam(); + if (ObjectUtil.isNotEmpty(sysEmpParam.getOrgId())) { + //查询属于该机构的,或该机构下级所有的人员 + queryWrapper.and(q -> q.eq("sys_emp.org_id", sysEmpParam.getOrgId()) + .or().like("sys_org.pids", sysEmpParam.getOrgId())); + } + } + //根据状态查询(0正常 1停用),删除的不会展示在列表 + if (ObjectUtil.isNotEmpty(sysUserParam.getSearchStatus())) { + queryWrapper.eq("sys_user.status", sysUserParam.getSearchStatus()); + } + } + //查询非删除状态,排除超级管理员 + queryWrapper.ne("sys_user.status", CommonStatusEnum.DELETED.getCode()) + .ne("sys_user.admin_type", AdminTypeEnum.SUPER_ADMIN.getCode()); + + //如果是超级管理员则获取所有用户,否则只获取其数据范围的用户 + boolean superAdmin = LoginContextHolder.me().isSuperAdmin(); + if (!superAdmin) { + List dataScope = sysUserParam.getDataScope(); + if (ObjectUtil.isEmpty(dataScope)) { + return new PageResult<>(new Page<>()); + } else { + Set dataScopeSet = CollectionUtil.newHashSet(dataScope); + queryWrapper.in("sys_emp.org_id", dataScopeSet); + } + } + return new PageResult<>(this.baseMapper.page(PageFactory.defaultPage(), queryWrapper)); + } + + @Override + public List list(SysUserParam sysUserParam) { + List dictList = CollectionUtil.newArrayList(); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + if (ObjectUtil.isNotNull(sysUserParam)) { + //根据账号,姓名模糊查询 + if (ObjectUtil.isNotEmpty(sysUserParam.getAccount())) { + queryWrapper.and(i -> i.like(SysUser::getAccount, sysUserParam.getAccount()) + .or().like(SysUser::getName, sysUserParam.getAccount())); + } + } + //查询正常状态,排除超级管理员 + queryWrapper.eq(SysUser::getStatus, CommonStatusEnum.ENABLE.getCode()) + .ne(SysUser::getAdminType, AdminTypeEnum.SUPER_ADMIN.getCode()); + this.list(queryWrapper).forEach(sysUser -> { + Dict dict = Dict.create(); + dict.put("id", sysUser.getId().toString()); + dict.put("firstName", sysUser.getName() + SymbolConstant.LEFT_SQUARE_BRACKETS + + sysUser.getAccount() + SymbolConstant.RIGHT_SQUARE_BRACKETS); + dictList.add(dict); + }); + return dictList; + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void add(SysUserParam sysUserParam) { + checkParam(sysUserParam, false); + boolean superAdmin = LoginContextHolder.me().isSuperAdmin(); + //如果登录用户不是超级管理员,则进行数据权限校验 + if (!superAdmin) { + List dataScope = sysUserParam.getDataScope(); + //获取添加的用户的所属机构 + Long orgId = sysUserParam.getSysEmpParam().getOrgId(); + //数据范围为空 + if (ObjectUtil.isEmpty(dataScope)) { + throw new PermissionException(PermissionExceptionEnum.NO_PERMISSION_OPERATE); + } else if (!dataScope.contains(orgId)) { + //所添加的用户的所属机构不在自己的数据范围内 + throw new PermissionException(PermissionExceptionEnum.NO_PERMISSION_OPERATE); + } + } + SysUser sysUser = new SysUser(); + BeanUtil.copyProperties(sysUserParam, sysUser); + SysUserFactory.fillAddCommonUserInfo(sysUser); + sysUser.setPassword(BCrypt.hashpw(sysUser.getPassword(), BCrypt.gensalt())); + this.save(sysUser); + Long sysUserId = sysUser.getId(); + //增加员工信息 + SysEmpParam sysEmpParam = sysUserParam.getSysEmpParam(); + sysEmpParam.setId(sysUserId); + sysEmpService.addOrUpdate(sysEmpParam); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void delete(SysUserParam sysUserParam) { + SysUser sysUser = this.querySysUser(sysUserParam); + //不能删除超级管理员 + if (AdminTypeEnum.SUPER_ADMIN.getCode().equals(sysUser.getAdminType())) { + throw new ServiceException(SysUserExceptionEnum.USER_CAN_NOT_DELETE_ADMIN); + } + boolean superAdmin = LoginContextHolder.me().isSuperAdmin(); + //如果登录用户不是超级管理员,则进行数据权限校验 + if (!superAdmin) { + List dataScope = sysUserParam.getDataScope(); + //获取要删除的用户的所属机构 + SysEmpInfo sysEmpInfo = sysEmpService.getSysEmpInfo(sysUser.getId()); + Long orgId = sysEmpInfo.getOrgId(); + //数据范围为空 + if (ObjectUtil.isEmpty(dataScope)) { + throw new PermissionException(PermissionExceptionEnum.NO_PERMISSION_OPERATE); + } else if (!dataScope.contains(orgId)) { + //所要删除的用户的所属机构不在自己的数据范围内 + throw new PermissionException(PermissionExceptionEnum.NO_PERMISSION_OPERATE); + } + } + sysUser.setStatus(CommonStatusEnum.DELETED.getCode()); + this.updateById(sysUser); + Long id = sysUser.getId(); + //删除该用户对应的员工表信息 + sysEmpService.deleteEmpInfoByUserId(id); + + //删除该用户对应的用户-角色表关联信息 + sysUserRoleService.deleteUserRoleListByUserId(id); + + //删除该用户对应的用户-数据范围表关联信息 + sysUserDataScopeService.deleteUserDataScopeListByUserId(id); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void edit(SysUserParam sysUserParam) { + SysUser sysUser = this.querySysUser(sysUserParam); + checkParam(sysUserParam, true); + boolean superAdmin = LoginContextHolder.me().isSuperAdmin(); + //如果登录用户不是超级管理员,则进行数据权限校验 + if (!superAdmin) { + List dataScope = sysUserParam.getDataScope(); + //获取要编辑的用户的所属机构 + Long orgId = sysUserParam.getSysEmpParam().getOrgId(); + //数据范围为空 + if (ObjectUtil.isEmpty(dataScope)) { + throw new PermissionException(PermissionExceptionEnum.NO_PERMISSION_OPERATE); + } else if (!dataScope.contains(orgId)) { + //所要编辑的用户的所属机构不在自己的数据范围内 + throw new PermissionException(PermissionExceptionEnum.NO_PERMISSION_OPERATE); + } + } + + BeanUtil.copyProperties(sysUserParam, sysUser); + //不能修改状态,用修改状态接口修改状态 + sysUser.setStatus(null); + //设置密码 + SysUserFactory.fillBaseUserInfo(sysUser); + this.updateById(sysUser); + Long sysUserId = sysUser.getId(); + //编辑员工信息 + SysEmpParam sysEmpParam = sysUserParam.getSysEmpParam(); + BeanUtil.copyProperties(sysUserParam, sysEmpParam); + sysEmpParam.setId(sysUserId); + sysEmpService.addOrUpdate(sysEmpParam); + } + + @Override + public SysUserResult detail(SysUserParam sysUserParam) { + SysUserResult sysUserResult = new SysUserResult(); + //获取系统用户 + SysUser sysUser = this.querySysUser(sysUserParam); + BeanUtil.copyProperties(sysUser, sysUserResult); + //获取对应员工信息 + SysEmpInfo sysEmpInfo = sysEmpService.getSysEmpInfo(sysUser.getId()); + //设置员工信息 + sysUserResult.setSysEmpInfo(sysEmpInfo); + return sysUserResult; + } + + @Override + public void changeStatus(SysUserParam sysUserParam) { + SysUser sysUser = this.querySysUser(sysUserParam); + //不能修改超级管理员状态 + if (AdminTypeEnum.SUPER_ADMIN.getCode().equals(sysUser.getAdminType())) { + throw new ServiceException(SysUserExceptionEnum.USER_CAN_NOT_UPDATE_ADMIN); + } + + Long id = sysUser.getId(); + + Integer status = sysUserParam.getStatus(); + //校验状态在不在枚举值里 + CommonStatusEnum.validateStatus(status); + + //更新枚举,更新只能更新未删除状态的 + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.eq(SysUser::getId, id) + .and(i -> i.ne(SysUser::getStatus, CommonStatusEnum.DELETED.getCode())) + .set(SysUser::getStatus, status); + boolean update = this.update(updateWrapper); + if (!update) { + throw new ServiceException(StatusExceptionEnum.UPDATE_STATUS_ERROR); + } + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void grantRole(SysUserParam sysUserParam) { + SysUser sysUser = this.querySysUser(sysUserParam); + boolean superAdmin = LoginContextHolder.me().isSuperAdmin(); + //如果登录用户不是超级管理员,则进行数据权限校验 + if (!superAdmin) { + List dataScope = sysUserParam.getDataScope(); + //获取要授权角色的用户的所属机构 + SysEmpInfo sysEmpInfo = sysEmpService.getSysEmpInfo(sysUser.getId()); + Long orgId = sysEmpInfo.getOrgId(); + //数据范围为空 + if (ObjectUtil.isEmpty(dataScope)) { + throw new PermissionException(PermissionExceptionEnum.NO_PERMISSION_OPERATE); + } else if (!dataScope.contains(orgId)) { + //所要授权角色的用户的所属机构不在自己的数据范围内 + throw new PermissionException(PermissionExceptionEnum.NO_PERMISSION_OPERATE); + } + } + sysUserRoleService.grantRole(sysUserParam); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void grantData(SysUserParam sysUserParam) { + SysUser sysUser = this.querySysUser(sysUserParam); + boolean superAdmin = LoginContextHolder.me().isSuperAdmin(); + //如果登录用户不是超级管理员,则进行数据权限校验 + if (!superAdmin) { + List dataScope = sysUserParam.getDataScope(); + //获取要授权数据的用户的所属机构 + SysEmpInfo sysEmpInfo = sysEmpService.getSysEmpInfo(sysUser.getId()); + Long orgId = sysEmpInfo.getOrgId(); + //数据范围为空 + if (ObjectUtil.isEmpty(dataScope)) { + throw new PermissionException(PermissionExceptionEnum.NO_PERMISSION_OPERATE); + } else if (!dataScope.contains(orgId)) { + //所要授权数据的用户的所属机构不在自己的数据范围内 + throw new PermissionException(PermissionExceptionEnum.NO_PERMISSION_OPERATE); + } + } + sysUserDataScopeService.grantData(sysUserParam); + } + + @Override + public void updateInfo(SysUserParam sysUserParam) { + SysUser sysUser = this.querySysUser(sysUserParam); + BeanUtil.copyProperties(sysUserParam, sysUser); + this.updateById(sysUser); + } + + @Override + public void updatePwd(SysUserParam sysUserParam) { + SysUser sysUser = this.querySysUser(sysUserParam); + //新密码与原密码相同 + if (sysUserParam.getNewPassword().equals(sysUserParam.getPassword())) { + throw new ServiceException(SysUserExceptionEnum.USER_PWD_REPEAT); + } + //原密码错误 + if (!BCrypt.checkpw(sysUserParam.getPassword(), sysUser.getPassword())) { + throw new ServiceException(SysUserExceptionEnum.USER_PWD_ERROR); + } + sysUser.setPassword(BCrypt.hashpw(sysUserParam.getNewPassword(), BCrypt.gensalt())); + this.updateById(sysUser); + } + + @Override + public List getUserDataScopeIdList(Long userId, Long orgId) { + Set userDataScopeIdSet = CollectionUtil.newHashSet(); + if (ObjectUtil.isAllNotEmpty(userId, orgId)) { + + //获取该用户对应的数据范围集合 + List userDataScopeIdListForUser = sysUserDataScopeService.getUserDataScopeIdList(userId); + + //获取该用户的角色对应的数据范围集合 + List userDataScopeIdListForRole = sysUserRoleService.getUserRoleDataScopeIdList(userId, orgId); + + userDataScopeIdSet.addAll(userDataScopeIdListForUser); + userDataScopeIdSet.addAll(userDataScopeIdListForRole); + } + return CollectionUtil.newArrayList(userDataScopeIdSet); + } + + @Override + public String getNameByUserId(Long userId) { + SysUser sysUser = this.getById(userId); + if (ObjectUtil.isNull(sysUser)) { + throw new ServiceException(SysUserExceptionEnum.USER_NOT_EXIST); + } + return sysUser.getName(); + } + + @Override + public List ownRole(SysUserParam sysUserParam) { + SysUser sysUser = this.querySysUser(sysUserParam); + return sysUserRoleService.getUserRoleIdList(sysUser.getId()); + } + + @Override + public List ownData(SysUserParam sysUserParam) { + SysUser sysUser = this.querySysUser(sysUserParam); + return sysUserDataScopeService.getUserDataScopeIdList(sysUser.getId()); + } + + @Override + public void resetPwd(SysUserParam sysUserParam) { + SysUser sysUser = this.querySysUser(sysUserParam); + String password = ConstantContextHolder.getDefaultPassWord(); + sysUser.setPassword(BCrypt.hashpw(password, BCrypt.gensalt())); + this.updateById(sysUser); + } + + @Override + public void updateAvatar(SysUserParam sysUserParam) { + SysUser sysUser = this.querySysUser(sysUserParam); + Long avatar = sysUserParam.getAvatar(); + sysFileInfoService.assertFile(avatar); + sysUser.setAvatar(avatar); + this.updateById(sysUser); + } + + @Override + public void export(SysUserParam sysUserParam) { + List list = this.list(); + PoiUtil.exportExcelWithStream("XiaoNuoUsers.xls", SysUser.class, list); + } + + @Override + public List selector(SysUserParam sysUserParam) { + List dictList = CollectionUtil.newArrayList(); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + if (ObjectUtil.isNotNull(sysUserParam)) { + //根据姓名模糊查询 + if (ObjectUtil.isNotEmpty(sysUserParam.getName())) { + queryWrapper.like(SysUser::getName, sysUserParam.getName()); + } + } + //查询非删除状态,排除超级管理员 + queryWrapper.ne(SysUser::getStatus, CommonStatusEnum.DELETED.getCode()) + .ne(SysUser::getAdminType, AdminTypeEnum.SUPER_ADMIN.getCode()); + this.list(queryWrapper).forEach(sysUser -> { + Dict dict = Dict.create(); + dict.put(CommonConstant.ID, sysUser.getId()); + dict.put(CommonConstant.NAME, sysUser.getName()); + dictList.add(dict); + }); + return dictList; + } + + @Override + public SysUser getUserById(Long userId) { + SysUser sysUser = this.getById(userId); + if (ObjectUtil.isNull(sysUser)) { + throw new ServiceException(SysUserExceptionEnum.USER_NOT_EXIST); + } + return sysUser; + } + + @Override + public void saveAuthUserToUser(AuthUser authUser, SysUser sysUser) { + SysUserFactory.fillAddCommonUserInfo(sysUser); + //获取oauth用户的账号 + String username = authUser.getUsername(); + //判断账号是否在用户表中有重复的 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysUser::getAccount, username); + SysUser existUser = this.getOne(queryWrapper); + if (ObjectUtil.isNotNull(existUser)) { + //如果该账号已经存在了,则将oauth用户的账号后缀拼接随机数 + username = username + RandomUtil.randomString(5); + } + sysUser.setAccount(username); + sysUser.setName(authUser.getNickname()); + sysUser.setNickName(authUser.getNickname()); + sysUser.setEmail(authUser.getEmail()); + if (ObjectUtil.isNotNull(authUser.getGender())) { + AuthUserGender gender = authUser.getGender(); + //性别转换 + if (OauthSexEnum.MAN.getCode().equals(gender.getCode())) { + sysUser.setSex(SexEnum.MAN.getCode()); + } else if (OauthSexEnum.WOMAN.getCode().equals(gender.getCode())) { + sysUser.setSex(SexEnum.WOMAN.getCode()); + } else { + sysUser.setSex(SexEnum.NONE.getCode()); + } + } + this.save(sysUser); + } + + @Override + public List getAllUserIdList() { + List resultList = CollectionUtil.newArrayList(); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.ne(SysUser::getAdminType, AdminTypeEnum.SUPER_ADMIN); + this.list(queryWrapper).forEach(sysUser -> { + resultList.add(sysUser.getId()); + }); + return resultList; + } + + /** + * 校验参数,检查是否存在相同的账号 + * + * @author xuyuxiang + * @date 2020/3/27 16:04 + */ + private void checkParam(SysUserParam sysUserParam, boolean isExcludeSelf) { + Long id = sysUserParam.getId(); + String account = sysUserParam.getAccount(); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysUser::getAccount, account) + .ne(SysUser::getStatus, CommonStatusEnum.DELETED.getCode()); + //是否排除自己,如果是则查询条件排除自己id + if (isExcludeSelf) { + queryWrapper.ne(SysUser::getId, id); + } + int countByAccount = this.count(queryWrapper); + //大于等于1个则表示重复 + if (countByAccount >= 1) { + throw new ServiceException(SysUserExceptionEnum.USER_ACCOUNT_REPEAT); + } + } + + /** + * 获取系统用户 + * + * @author xuyuxiang + * @date 2020/3/26 9:54 + */ + private SysUser querySysUser(SysUserParam sysUserParam) { + SysUser sysUser = this.getById(sysUserParam.getId()); + if (ObjectUtil.isNull(sysUser)) { + throw new ServiceException(SysUserExceptionEnum.USER_NOT_EXIST); + } + return sysUser; + } +} diff --git a/xiaonuo-base/xiaonuo-system/src/main/resources/META-INF/spring.factories b/xiaonuo-base/xiaonuo-system/src/main/resources/META-INF/spring.factories new file mode 100644 index 00000000..a29b1bf2 --- /dev/null +++ b/xiaonuo-base/xiaonuo-system/src/main/resources/META-INF/spring.factories @@ -0,0 +1,4 @@ +org.springframework.context.ApplicationListener=\ +com.cn.xiaonuo.sys.core.listener.ConstantsInitListener,\ +com.cn.xiaonuo.sys.core.listener.TimerTaskRunListener,\ +com.cn.xiaonuo.sys.core.listener.RemoveRequestParamListener diff --git a/xiaonuo-main/README.md b/xiaonuo-main/README.md new file mode 100644 index 00000000..43436909 --- /dev/null +++ b/xiaonuo-main/README.md @@ -0,0 +1,3 @@ +## 本模块为项目的启动模块,运行XiaoNuoApplication启动程序 + +## 在此模块下开发业务即可 diff --git a/xiaonuo-main/pom.xml b/xiaonuo-main/pom.xml new file mode 100644 index 00000000..c8cc08c7 --- /dev/null +++ b/xiaonuo-main/pom.xml @@ -0,0 +1,53 @@ + + + 4.0.0 + + + cn.xiaonuo + xiaonuo-vue + 1.1.0 + ../pom.xml + + + xiaonuo-main + + jar + + + + + cn.xiaonuo + xiaonuo-system + 1.1.0 + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + xiaonuo-vue + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + true + + + + + + diff --git a/xiaonuo-main/src/main/docker/docker-assembly.xml b/xiaonuo-main/src/main/docker/docker-assembly.xml new file mode 100644 index 00000000..b77e47fb --- /dev/null +++ b/xiaonuo-main/src/main/docker/docker-assembly.xml @@ -0,0 +1,10 @@ + + + + target/${project.artifactId}.jar + ${project.artifactId}.jar + + + \ No newline at end of file diff --git a/xiaonuo-main/src/main/java/com/cn/xiaonuo/XiaoNuoApplication.java b/xiaonuo-main/src/main/java/com/cn/xiaonuo/XiaoNuoApplication.java new file mode 100644 index 00000000..674a6527 --- /dev/null +++ b/xiaonuo-main/src/main/java/com/cn/xiaonuo/XiaoNuoApplication.java @@ -0,0 +1,47 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo; + +import cn.hutool.log.Log; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * SpringBoot方式启动类 + * + * @author yubaoshan + * @date 2017/5/21 12:06 + */ +@SpringBootApplication +public class XiaoNuoApplication { + + private static final Log log = Log.get(); + + public static void main(String[] args) { + SpringApplication.run(XiaoNuoApplication.class, args); + log.info(">>> " + XiaoNuoApplication.class.getSimpleName() + " is success!"); + } + +} diff --git a/xiaonuo-main/src/main/java/com/cn/xiaonuo/XiaoNuoServletInitializer.java b/xiaonuo-main/src/main/java/com/cn/xiaonuo/XiaoNuoServletInitializer.java new file mode 100644 index 00000000..f4c00ec5 --- /dev/null +++ b/xiaonuo-main/src/main/java/com/cn/xiaonuo/XiaoNuoServletInitializer.java @@ -0,0 +1,19 @@ +package com.cn.xiaonuo; + +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +/** + * XiaoNuo Web程序启动类 + * + * @author xuyuxiang + * @date 2017-05-21 9:43 + */ +public class XiaoNuoServletInitializer extends SpringBootServletInitializer { + + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { + return builder.sources(XiaoNuoApplication.class); + } + +} diff --git a/xiaonuo-main/src/main/java/com/cn/xiaonuo/modular/controller/DatasourceExampleController.java b/xiaonuo-main/src/main/java/com/cn/xiaonuo/modular/controller/DatasourceExampleController.java new file mode 100644 index 00000000..8086edf3 --- /dev/null +++ b/xiaonuo-main/src/main/java/com/cn/xiaonuo/modular/controller/DatasourceExampleController.java @@ -0,0 +1,76 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.modular.controller; + +import com.cn.xiaonuo.core.pojo.response.ResponseData; +import com.cn.xiaonuo.core.pojo.response.SuccessResponseData; +import com.cn.xiaonuo.modular.service.DatasourceExampleService; +import com.cn.xiaonuo.modular.service.DatasourceExampleService; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + * 一个示例接口 + * + * @author yubaoshan + * @date 2020/4/9 18:09 + */ +@RestController +@RequestMapping("/example") +public class DatasourceExampleController { + + @Resource + private DatasourceExampleService datasourceService; + + @RequestMapping("/niceDay") + public ResponseData niceDay() { + return new SuccessResponseData("nice day"); + } + + @RequestMapping("/masterDatasource") + public ResponseData masterDatasource() { + return new SuccessResponseData(datasourceService.masterDatasource()); + } + + @RequestMapping("/backupDatasource") + public ResponseData backupDatasource() { + return new SuccessResponseData(datasourceService.backupDatasource()); + } + + @RequestMapping("/datasourceTransactionNone") + public ResponseData datasourceTransactionNone() { + datasourceService.datasourceTransactionNone(); + return new SuccessResponseData(); + } + + @RequestMapping("/datasourceTransaction") + public ResponseData datasourceTransaction() { + datasourceService.datasourceTransaction(); + return new SuccessResponseData(); + } + +} diff --git a/xiaonuo-main/src/main/java/com/cn/xiaonuo/modular/model/AbModel.java b/xiaonuo-main/src/main/java/com/cn/xiaonuo/modular/model/AbModel.java new file mode 100644 index 00000000..6d07d500 --- /dev/null +++ b/xiaonuo-main/src/main/java/com/cn/xiaonuo/modular/model/AbModel.java @@ -0,0 +1,45 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.modular.model; + +/** + * 一个示例model + * + * @author yubaoshan + * @date 2020/4/9 18:10 + */ +public class AbModel { + + /** + * 字段a + */ + private String a; + + /** + * 字段b + */ + private String b; + +} diff --git a/xiaonuo-main/src/main/java/com/cn/xiaonuo/modular/service/DatasourceExampleService.java b/xiaonuo-main/src/main/java/com/cn/xiaonuo/modular/service/DatasourceExampleService.java new file mode 100644 index 00000000..ba790322 --- /dev/null +++ b/xiaonuo-main/src/main/java/com/cn/xiaonuo/modular/service/DatasourceExampleService.java @@ -0,0 +1,88 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.modular.service; + +import cn.hutool.core.util.RandomUtil; +import com.cn.xiaonuo.sys.modular.app.param.SysAppParam; +import com.cn.xiaonuo.sys.modular.app.service.SysAppService; +import com.cn.xiaonuo.sys.modular.log.entity.SysVisLog; +import com.cn.xiaonuo.sys.modular.log.service.SysVisLogService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import javax.annotation.Resource; +import java.util.List; + +/** + * 一个service实现 + * + * @author yubaoshan + * @date 2020/4/9 18:11 + */ +@Service +public class DatasourceExampleService { + + @Resource + private SysVisLogService sysVisLogService; + + @Resource + private SysAppService sysAppService; + + public List masterDatasource() { + return sysVisLogService.list(); + } + + public List backupDatasource() { + return sysVisLogService.list(); + } + + public void datasourceTransactionNone() { + + SysAppParam sysAppParam = new SysAppParam(); + sysAppParam.setName(RandomUtil.randomNumbers(5)); + sysAppParam.setCode(RandomUtil.randomNumbers(5)); + sysAppParam.setActive("N"); + + sysAppService.add(sysAppParam); + + //抛异常测试 + int i = 1 / 0; + } + + //@DataSource(name = "master") + @Transactional(rollbackFor = Exception.class) + public void datasourceTransaction() { + + SysAppParam sysAppParam = new SysAppParam(); + sysAppParam.setName(RandomUtil.randomNumbers(5)); + sysAppParam.setCode(RandomUtil.randomNumbers(5)); + sysAppParam.setActive("N"); + + sysAppService.add(sysAppParam); + + //抛异常测试 + int i = 1 / 0; + } + +} diff --git a/xiaonuo-main/src/main/resources/application-dev.yml b/xiaonuo-main/src/main/resources/application-dev.yml new file mode 100644 index 00000000..b1eea189 --- /dev/null +++ b/xiaonuo-main/src/main/resources/application-dev.yml @@ -0,0 +1,10 @@ +# Mysql数据库 +spring: + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/xiaonuo-vue?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=CTT&nullCatalogMeansCurrent=true + username: root + password: 123456 + # 连接池大小根据实际情况调整 + max-active: 20 + max-pool-prepared-statement-per-connection-size: 20 diff --git a/xiaonuo-main/src/main/resources/application-local.yml b/xiaonuo-main/src/main/resources/application-local.yml new file mode 100644 index 00000000..4f09317f --- /dev/null +++ b/xiaonuo-main/src/main/resources/application-local.yml @@ -0,0 +1,10 @@ +# Mysql数据库 +spring: + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/xiaonuo-vue-pub?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=CTT&nullCatalogMeansCurrent=true + username: root + password: 123456 + # 连接池大小根据实际情况调整 + max-active: 20 + max-pool-prepared-statement-per-connection-size: 20 diff --git a/xiaonuo-main/src/main/resources/application-prod.yml b/xiaonuo-main/src/main/resources/application-prod.yml new file mode 100644 index 00000000..b1eea189 --- /dev/null +++ b/xiaonuo-main/src/main/resources/application-prod.yml @@ -0,0 +1,10 @@ +# Mysql数据库 +spring: + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/xiaonuo-vue?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=CTT&nullCatalogMeansCurrent=true + username: root + password: 123456 + # 连接池大小根据实际情况调整 + max-active: 20 + max-pool-prepared-statement-per-connection-size: 20 diff --git a/xiaonuo-main/src/main/resources/application.yml b/xiaonuo-main/src/main/resources/application.yml new file mode 100644 index 00000000..366c8251 --- /dev/null +++ b/xiaonuo-main/src/main/resources/application.yml @@ -0,0 +1,57 @@ +#服务配置 +server: + port: 82 + max-http-header-size: 10240 + +#spring相关配置 +spring: + profiles: + active: @spring.active@ + servlet: + multipart: + max-request-size: 100MB + max-file-size: 100MB + jackson: + time-zone: GMT+8 + date-format: yyyy-MM-dd HH:mm:ss.SSS + locale: zh_CN + serialization: + # 格式化输出 + indent_output: false + +#mybaits相关配置 +mybatis-plus: + mapper-locations: classpath*:com/cn/**/mapping/*.xml, classpath:/META-INF/modeler-mybatis-mappings/*.xml + configuration: + map-underscore-to-camel-case: true + cache-enabled: true + lazy-loading-enabled: true + multiple-result-sets-enabled: true + log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl + global-config: + banner: false + db-config: + id-type: assign_id + table-underline: true + enable-sql-runner: true + configuration-properties: + prefix: + blobType: BLOB + boolValue: TRUE + +#libreoffice文档在线预览配置 +# CentOS 下安装 libreoffice: +# 安装:yum -y install libreoffice +# Linux 中文字体乱码解决: +# 1、上传 C:\Windows\Fonts 下的字体到 /usr/share/fonts/windows 目录 +# 2、执行命令: chmod 644 /usr/share/fonts/windows/* && fc-cache -fv +jodconverter: + local: + #暂时关闭预览,启动时会有点慢 + enabled: false + #设置libreoffice主目录 linux地址如:/usr/lib64/libreoffice + office-home: C:\Program Files\LibreOffice + #开启多个libreoffice进程,每个端口对应一个进程 + port-numbers: 8100 + #libreoffice进程重启前的最大进程数 + max-tasks-per-process: 100 diff --git a/xiaonuo-main/src/main/resources/banner.txt b/xiaonuo-main/src/main/resources/banner.txt new file mode 100644 index 00000000..0b521811 --- /dev/null +++ b/xiaonuo-main/src/main/resources/banner.txt @@ -0,0 +1,8 @@ + __ _______ ____ _ _ _ _ ____ + \ \ / /_ _| /\ / __ \| \ | | | | |/ __ \ + \ V / | | / \ | | | | \| | | | | | | | + > < | | / /\ \| | | | . ` | | | | | | | + / . \ _| |_ / ____ \ |__| | |\ | |__| | |__| | + /_/ \_\_____/_/ \_\____/|_| \_|\____/ \____/ + + :: Spring Boot :: (v2.3.1.RELEASE) \ No newline at end of file diff --git a/xiaonuo-main/src/main/resources/logback-spring.xml b/xiaonuo-main/src/main/resources/logback-spring.xml new file mode 100644 index 00000000..6f5c3d14 --- /dev/null +++ b/xiaonuo-main/src/main/resources/logback-spring.xml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + ${CONSOLE_LOG_PATTERN} + utf-8 + + + + + + + + + + + + + + + + + + + + + + ${CONSOLE_LOG_PATTERN} + utf-8 + + + + + + + + ${LOG_PATH}/log_error.log + + + + + + ${LOG_PATH}/error/log-error-%d{yyyy-MM-dd}.%i.log + + + + 10MB + + + + + true + + + + ${FILE_LOG_PATTERN} + utf-8 + + + + + error + ACCEPT + DENY + + + + + + + + ${LOG_PATH}/log_total.log + + + + + + ${LOG_PATH}/total/log-total-%d{yyyy-MM-dd}.%i.log + + + + 10MB + + + + + true + + + + ${FILE_LOG_PATTERN} + utf-8 + + + + + + + + + + + + + + + diff --git a/xiaonuo-main/src/test/java/com/cn/xiaonuo/core/BaseJunit.java b/xiaonuo-main/src/test/java/com/cn/xiaonuo/core/BaseJunit.java new file mode 100644 index 00000000..a35fbd65 --- /dev/null +++ b/xiaonuo-main/src/test/java/com/cn/xiaonuo/core/BaseJunit.java @@ -0,0 +1,67 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core; + +import com.cn.xiaonuo.XiaoNuoApplication; +import org.junit.Before; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import javax.annotation.Resource; + + +/** + * 基础测试类 + * + * @author yubaoshan + * @date 2017/5/21 16:10 + */ +@RunWith(SpringRunner.class) +@SpringBootTest(classes = XiaoNuoApplication.class) +@WebAppConfiguration +//@Transactional(rollbackFor = Exception.class) //打开的话测试之后数据可自动回滚 +public class BaseJunit { + + @Resource + private WebApplicationContext webApplicationContext; + + private MockMvc mockMvc; + + @Before + public void setupMockMvc() { + mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); + } + + @Before + public void initDatabase() { + } + + +} diff --git a/xiaonuo-main/src/test/java/com/cn/xiaonuo/core/Test.java b/xiaonuo-main/src/test/java/com/cn/xiaonuo/core/Test.java new file mode 100644 index 00000000..3ae632a6 --- /dev/null +++ b/xiaonuo-main/src/test/java/com/cn/xiaonuo/core/Test.java @@ -0,0 +1,40 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core; + + +/** + * v + * 测试类 + * + * @author xuyuxiang + * @date 2020/3/16 11:25 + */ +public class Test extends BaseJunit { + + @org.junit.Test + public void test() { + } +} diff --git a/xiaonuo-main/src/test/java/com/cn/xiaonuo/core/Test2.java b/xiaonuo-main/src/test/java/com/cn/xiaonuo/core/Test2.java new file mode 100644 index 00000000..546a50dd --- /dev/null +++ b/xiaonuo-main/src/test/java/com/cn/xiaonuo/core/Test2.java @@ -0,0 +1,41 @@ +/* +Copyright [2020] [https://www.xiaonuo.vip] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + +1.请不要删除和修改根目录下的LICENSE文件。 +2.请不要删除和修改XiaoNuo源码头部的版权声明。 +3.请保留源码和相关描述文件的项目出处,作者声明等。 +4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuo/xiaonuo-vue +6.若您的项目无法满足以上几点,可申请商业授权,获取XiaoNuo商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip + */ +package com.cn.xiaonuo.core; +import cn.hutool.core.date.DateUtil; +import com.cn.xiaonuo.core.util.PastTimeFormatUtil; + +/** + * 纯test + * + * @author xuyuxiang + * @date 2020/5/2014:29 + */ +public class Test2 { + + public static void main(String[] args) { + String s = PastTimeFormatUtil.formatPastTime(DateUtil.parseDateTime("2020-08-05 19:24:33")); + System.out.println(s); + } +} diff --git a/xiaonuo-main/src/test/sql/test.sql b/xiaonuo-main/src/test/sql/test.sql new file mode 100644 index 00000000..a7adf0f9 --- /dev/null +++ b/xiaonuo-main/src/test/sql/test.sql @@ -0,0 +1,19 @@ +DROP DATABASE IF EXISTS xiaonuo_test; +CREATE DATABASE IF NOT EXISTS xiaonuo_test DEFAULT CHARSET utf8 COLLATE utf8_general_ci; + +use xiaonuo_test; + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ---------------------------- +-- Table structure for test +-- ---------------------------- +DROP TABLE IF EXISTS `test`; +CREATE TABLE `test` ( + `aaa` int(11) NOT NULL AUTO_INCREMENT, + `bbb` varchar(255) DEFAULT NULL, + PRIMARY KEY (`aaa`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; + +SET FOREIGN_KEY_CHECKS = 1;