Compare commits

...

61 Commits

Author SHA1 Message Date
xijue
a679a728c4 关联子模块 2025-09-17 10:27:01 +08:00
xijue
0a801900b4 关联子模块 2025-09-17 10:21:57 +08:00
xijue
97b413cbc1 关联子模块 2025-09-17 10:20:50 +08:00
xijue
da8215f761 关联子模块 2025-09-17 10:13:13 +08:00
xijue
ae3cc0867f 关联子模块 2025-09-17 10:11:30 +08:00
xijue
0a30709d71 Merge remote-tracking branch 'origin/master' into mall 2025-09-17 10:07:04 +08:00
xijue
b68afe8048 Merge remote-tracking branch 'origin/master' into mall 2025-09-17 09:58:43 +08:00
xijue
e67a7457cb Merge remote-tracking branch 'origin/master' into mall
# Conflicts:
#	pom.xml   resolved by origin/master(远端) version
2025-09-17 09:52:16 +08:00
MMS
a0d733d87d 更新系统介绍 2025-09-15 21:56:12 +08:00
MMS
997af8ba1a 更新系统介绍 2025-09-15 21:54:10 +08:00
MMS
b57b34838e 更新系统介绍 2025-09-15 21:21:24 +08:00
MMS
7647bd8701 更新系统介绍 2025-09-15 21:16:09 +08:00
MMS
a01d3d6ef4 更新系统介绍 2025-09-15 21:00:41 +08:00
MMS
1e46b9eab0 修复ExcelUil 导出于Springboot 3.2.6 版本不兼容问题,指定poi 2025-09-15 20:26:27 +08:00
MMS
32a2704bb5 发布 2025-09-14 22:52:07 +08:00
xijue
2dd5f5e9d2 数据库脚本更新 2025-09-08 13:17:10 +08:00
MMS
21109d4a8b 优化doc 2025-09-01 23:38:36 +08:00
MMS
1a9f233704 mms 2025-09-01 22:59:43 +08:00
MMS
53d0780fcf mms 2025-09-01 22:50:56 +08:00
MMS
9bd352e335 Commit submodule changes - by UGit 2025-09-01 22:49:11 +08:00
MMS
04ba8d1539 优化doc 2025-09-01 22:48:39 +08:00
MMS
94f19d5e9c Merge remote-tracking branch 'origin/master' into doc 2025-08-31 00:28:27 +08:00
MMS
ea762f8a64 优化doc 2025-08-31 00:28:04 +08:00
MMS
56fb568eaf 优化doc 2025-08-30 21:56:27 +08:00
xijue
eb1f00701e 数据模型 2025-08-29 16:20:53 +08:00
xijue
ec16b3dd8d 简化 2025-08-28 11:49:43 +08:00
MMS
b6f9f09c05 Merge remote-tracking branch 'origin/master' into doc 2025-08-26 01:27:55 +08:00
MMS
03e404ab51 配置查询优化 2025-08-26 01:27:42 +08:00
MMS
bf61aebced Merge remote-tracking branch 'origin/master' into doc 2025-08-26 01:08:09 +08:00
MMS
35f2af3131 首页接口 2025-08-26 01:07:47 +08:00
MMS
0e37ccb2dd Merge remote-tracking branch 'origin/master' into doc
# Conflicts:
#	mms-admin/src/main/java/com/sxpcwlkj/system/controller/HomeController.java   resolved by origin/master(远端) version
2025-08-26 00:41:26 +08:00
MMS
d6dbcdc7b7 首页接口 2025-08-26 00:41:03 +08:00
MMS
7038102329 Merge remote-tracking branch 'origin/master' into doc
# Conflicts:
#	mms-modules/mms-common/src/main/java/com/sxpcwlkj/common/properties/MssAdminProperties.java   resolved by origin/master(远端) version
2025-08-26 00:34:57 +08:00
MMS
a30152797e 优化doc 2025-08-26 00:34:36 +08:00
MMS
383c52e79c 优化doc 2025-08-26 00:31:16 +08:00
xijue
d5c03818f9 简化 2025-08-25 17:27:10 +08:00
xijue
1233984764 Merge remote-tracking branch 'origin/master' into doc 2025-08-25 17:07:20 +08:00
xijue
e2cd5a05ce 首页信息 2025-08-25 17:06:56 +08:00
xijue
713247066f Merge remote-tracking branch 'origin/master' into doc 2025-08-25 13:21:26 +08:00
xijue
5b9708a199 演示模式 2025-08-25 13:20:59 +08:00
xijue
74676a97d8 关联子模块 2025-08-25 10:59:38 +08:00
xijue
3fcbe2fa6c Merge remote-tracking branch 'origin/master' into doc 2025-08-25 10:44:35 +08:00
xijue
b45d9e892a 清理多余的包 2025-08-25 10:44:14 +08:00
xijue
fa6dac1057 简化 2025-08-25 10:40:10 +08:00
xijue
0c0db2d2bc Merge remote-tracking branch 'origin/master' into doc
# Conflicts:
#	mms-admin/src/main/resources/application.yml   resolved by origin/master(远端) version
2025-08-25 09:41:52 +08:00
xijue
7df50a2d1c 验证码开启升级 2025-08-25 09:41:03 +08:00
xijue
684039cc20 简化 2025-08-25 08:25:05 +08:00
MMS
3c55bd1b2c Merge remote-tracking branch 'origin/master' into doc 2025-08-25 01:04:30 +08:00
MMS
04cfe055ec 优化 SysSign 2025-08-25 01:04:16 +08:00
MMS
69501b5574 优化doc 2025-08-25 01:03:32 +08:00
MMS
346987106e Merge remote-tracking branch 'origin/master' into doc 2025-08-24 22:43:20 +08:00
MMS
57fdb22006 新增:Dockerfile 2025-08-24 22:43:00 +08:00
MMS
a2d36832be Merge remote-tracking branch 'origin/master' into doc 2025-08-24 22:25:39 +08:00
xijue
bc9565a7a3 关联子模块 2025-06-09 08:25:02 +08:00
MMS
8bff73ddc1 Merge remote-tracking branch 'origin/master' into doc 2025-06-06 16:54:51 +08:00
MMS
c6a32fca9f 安装mms-docs 模块 2025-06-06 16:54:24 +08:00
MMS
34df200280 安装mms-docs 模块 2025-06-06 16:53:38 +08:00
xijue
a087d73cff 关联子模块 2025-06-06 12:55:28 +08:00
xijue
6ad6cb3460 新增:文档模块 2025-06-06 12:53:03 +08:00
xijue
a78eb75e1d 新增:文档模块 2025-06-06 12:50:52 +08:00
xijue
e479fe9a5f 新增:文档模块 2025-06-06 12:46:39 +08:00
105 changed files with 60733 additions and 935 deletions

1
.gitmodules vendored
View File

@ -1,3 +1,4 @@
[submodule "mms-malls"]
path = mms-malls
url = https://gitee.com/mmsAdmin/mms-malls.git
branch = mall

535
README.md
View File

@ -9,28 +9,28 @@
## ⚡️系统介绍
🔥🔥🔥模块化管理系统Modular management
system简称MMS是一款基于多应用模块用户、商品、支付、订单、分销、日志、定时、通信、直播、广告、文章等多模块应用开源系统可快速的应用与各类项目研发中定期更新功能修复、上新、技术栈分享 (
十年磨一剑,做最有价值的开源项目)
🔥🔥🔥 MMS模块化管理系统Modular Management System基于Spring Boot 3.x构建采用前后端分离的现代化架构设计。该系统集成了用户管理、商品管理、支付系统、订单处理、分销体系、日志监控、定时任务、通信服务、直播支持、广告管理与内容发布等多个功能模块致力于为开发者提供高效、稳定且可扩展的开发脚手架显著提升项目开发效率助力各类应用快速落地与迭代。
🚀🚀🚀 我们将作为持续更新迭代定期发布功能更新、Bug修复和技术栈升级确保系统始终处于技术前沿打造最有价值的开源项目为开发者社区贡献力量。
> 项目代码、文档 均开源免费可商用 ,活到老写到老 为兴趣而开源 为学习而开源.
> 项目代码和文档完全开源免费,支持商业使用。🚀
> 我们秉承"活到老,写到老"的开源精神,为兴趣而开源,为学习而开源。🚀
🍃系统演示: [传送门](https://mmsadmin.cn/index/demo.html)
🍃MMS文档: [mmsAdmin](https://mmsadmin.cn/)
🍃MMS文档: [mms](https://mmsadmin.cn/)
## 🧩系统版本
<img src="https://img.shields.io/badge/MMS-V1.X-green"/>
| 名称 | 别名 | 项目地址 | 注意事项 |
|--------|:---:|:--------------------------------------------:|---------------------------------------------------------------------|
| mms | 标准版 | - [Gitee](https://gitee.com/mmsAdmin/mms) | 🙋功能齐全的手架系统 <br/> 📢完全具备高效的项目开发<br/> 📢完多租户模式灵活开启<br/>📢支持低代码自动生成模式 |
| mms-ui | 标准版 | - [Gitee](https://gitee.com/mmsAdmin/mms-ui) | 🙋适配mms后端系统的管理界面项目 |
## 📦开发语言
| 名称 | 别名 | 项目地址 | 注意事项 |
| ------ | :----: | :-----------------------------------------: | ----------------------------------------------------------------------------------------------------------- |
| mms | 标准版 | -[Gitee](https://gitee.com/mmsAdmin/mms) | 🙋功能齐全的手架系统<br/> 📢完全具备高效的项目开发<br/> 📢完多租户模式灵活开启<br/>📢支持低代码自动生成模式 |
| mms-ui | 标准版 | -[Gitee](https://gitee.com/mmsAdmin/mms-ui) | 🙋适配mms后端系统的管理界面项目 |
## 📦开发语言与技术栈
<div style="text-align: center;float: left;width: 100%;">
<img style="margin: 5px ;float: left;height: 20px" src="https://img.shields.io/badge/language-JAVA-<COLOR>.svg" alt=""/>
@ -48,69 +48,278 @@ system简称MMS是一款基于多应用模块用户、商品、支
🙋高效安全、组件解耦、灵活扩展 模块化扩展内置代码生成引擎加速后台系统构建。
### 核心特性
1. **模块化设计**:采用 Maven 多模块架构,各功能模块独立开发、部署和维护
2. **多租户支持**:灵活的多租户架构,支持数据隔离和资源共享
3. **权限管理**:基于 Sa-Token 的 RBAC 权限控制,支持菜单、按钮级别权限
4. **代码生成**:内置低代码生成引擎,支持前后端代码一键生成
5. **多数据源**:支持 MySQL、Oracle、PostgreSQL、SQL Server 等多种数据库
6. **对象存储**:集成 x-file-storage支持阿里云、腾讯云、华为云等主流云存储
7. **消息队列**:支持 RabbitMQ、RocketMQ、Kafka 等消息中间件
8. **定时任务**:集成 PowerJob支持分布式定时任务调度
9. **监控管理**:集成 Spring Boot Admin提供应用健康监控
10. **安全防护**:支持 XSS、SQL 注入防护,接口加签验签等安全机制
11. **国际化支持**:支持多语言切换
12. **数据字典**:统一数据字典管理,支持动态配置
13. **操作日志**:完善的操作日志记录和查询功能
14. **通知公告**:系统公告和消息通知功能
15. **个人中心**:用户个人信息管理、密码修改、头像设置等
### 功能模块
1. **系统管理**
- 用户管理:用户增删改查、导入导出、密码重置
- 角色管理:角色权限分配、角色用户管理
- 菜单管理:菜单配置、权限标识设置
- 部门管理:组织架构管理
- 岗位管理:岗位信息维护
- 字典管理:数据字典配置
- 配置管理:系统参数配置
- 通知公告:系统消息发布
2. **系统监控**
- 操作日志:用户操作记录查询
- 登录日志:用户登录信息查询
- 服务监控:服务器状态监控
- 缓存监控Redis 缓存信息查看
3. **工具箱**
- 代码生成:数据库表结构自动生成前后端代码
- 系统接口Swagger API 文档
- 定时任务:任务调度管理
- 对象存储:文件上传和管理
4. **扩展功能**
- 短信服务:短信发送和配置
- 邮件服务:邮件发送和配置
- 微信集成:微信公众号、小程序接入
- 阿里云服务:阿里云相关服务集成
## 🍃部署方式
<img src="https://img.shields.io/docker/automated/tsund/tianchi_docker_practice.svg" alt=""/>
### 环境要求
- JDK 17+
- MySQL 8.0+
- Redis 6.x+
- Node.js 16+ (前端项目)
- Docker (可选,用于容器化部署)
### 部署步骤
1. **数据库初始化**
- 执行 `script/db/mms.sql` 脚本创建数据库表结构和初始数据
- 根据实际环境修改数据库连接配置
2. **后端服务部署**
- 修改 `mms-admin/src/main/resources/application.yml` 配置文件
- 根据不同环境激活对应的 profile (local/dev/prod)
- 执行 Maven 命令打包:`mvn clean package -DskipTests`
- 运行 jar 包:`java -jar mms-admin.jar`
3. **前端服务部署**
- 进入前端项目目录
- 安装依赖:`pnpm install`
- 构建生产环境:`pnpm build`
- 部署构建产物到 Web 服务器
4. **Docker 部署**
- 使用 `script/docker/docker-compose.yml` 文件一键部署
- 根据实际环境修改配置文件中的参数
- 执行 `docker-compose up -d` 启动所有服务
### 配置文件说明
项目支持多种环境配置:
- `application-local.yml`:本地开发环境
- `application-dev.yml`:开发环境
- `application-prod.yml`:生产环境
配置主要包括:
- 数据源配置MySQL、Oracle、PostgreSQL等
- Redis 配置
- Sa-Token 权限配置
- MyBatis-Plus 配置
- 多租户配置
- 对象存储配置
## 🤝模块介绍
| 序号 | 目录 | 子模块名称 | 模块名称 | 备注 |
|----|-------------|-------------------|----------------------------------|-------|
| 1 | mms-admin | | 系统管理启动模块 | 已完成 |
| 1 | mms-docs | | VitePress会员主题知识付费<br>MMS适配接口服务 | 已完成 |
| 5 | ________ | mms-doc-admin | 会员主题后端模块 | 已完成 |
| 6 | ________ | mms-doc-api | 会员主题接口模块 | 已完成 |
| 2 | mms-malls | | 商城 | 开发中 |
| 5 | ________ | mms-mall-admin | 商城后端模块 | 开发中 |
| 6 | ________ | mms-mall-api | 商城接口模块 | 开发中 |
| 5 | ________ | mms-mall-merchant | 商城商户模块 | 开发中 |
| 6 | ________ | mms-doc-uni-x | 商城移动模块 | 开发中 |
| 4 | mms-modules | | MMS模块集 | 持续增加中 |
| 5 | ________ | mms-ai | 大模型模块 | 已完成 |
| 5 | ________ | mms-aliyun | 阿里云模块 | 已完成 |
| 5 | ________ | mms-authority | 安全认证模块 | 已完成 |
| 5 | ________ | mms-common | 公共模块 | 已完成 |
| 5 | ________ | mms-datasource | 数据源模块 | 已完成 |
| 5 | ________ | mms-demo | 演示模块 | 已完成 |
| 5 | ________ | mms-email | 邮箱模块 | 已完成 |
| 6 | ________ | mms-framework | 核心模块 | 已完成 |
| 5 | ________ | mms-gen | 代码生成模块 | 已完成 |
| 7 | ________ | mms-mq | 消息队列 | 已完成 |
| 5 | ________ | mms-oss | 对象存储模块 | 已完成 |
| 5 | ________ | mms-redis | 缓存模块 | 已完成 |
| 5 | ________ | mms-sms | 短信模块 | 已完成 |
| 5 | ________ | mms-thymeleaf | 模版引擎渲染模块 | 已完成 |
| 8 | ________ | mms-websocket | 长连接通信管理 | 已完成 |
| 5 | ________ | mms-wx | 微信模块 | 已完成 |
| 9 | mms-zoom | | 快速激增模块集 | 已完成 |
| 10 | ________ | mms-monitor | 安全监控 | 已完成 |
| 11 | ________ | mms-powerjob | 定时任务 | 已完成 |
| 12 | script | | 项目配置文件 | 已完成 |
| 序号 | 目录 | 子模块名称 | 模块名称 | 备注 |
| ---- | ----------- | ----------------- | ------------------------------------------------ | ---------- |
| 1 | mms-admin | | 系统管理启动模块 | 已完成 |
| 1 | mms-docs | | VitePress会员主题知识付费<br>MMS适配接口服务 | 已完成 |
| 5 | ________ | mms-doc-admin | 会员主题后端模块 | 已完成 |
| 6 | ________ | mms-doc-api | 会员主题接口模块 | 已完成 |
| 2 | mms-malls | | 商城 | 开发中 |
| 5 | ________ | mms-mall-admin | 商城后端模块 | 开发中 |
| 6 | ________ | mms-mall-api | 商城接口模块 | 开发中 |
| 5 | ________ | mms-mall-merchant | 商城商户模块 | 开发中 |
| 6 | ________ | mms-doc-uni-x | 商城移动模块 | 开发中 |
| 4 | mms-modules | | MMS模块集 | 持续增加中 |
| 5 | ________ | mms-ai | 大模型模块 | 已完成 |
| 5 | ________ | mms-aliyun | 阿里云模块 | 已完成 |
| 5 | ________ | mms-authority | 安全认证模块 | 已完成 |
| 5 | ________ | mms-common | 公共模块 | 已完成 |
| 5 | ________ | mms-datasource | 数据源模块 | 已完成 |
| 5 | ________ | mms-demo | 演示模块 | 已完成 |
| 5 | ________ | mms-email | 邮箱模块 | 已完成 |
| 6 | ________ | mms-framework | 核心模块 | 已完成 |
| 5 | ________ | mms-gen | 代码生成模块 | 已完成 |
| 7 | ________ | mms-mq | 消息队列 | 已完成 |
| 5 | ________ | mms-oss | 对象存储模块 | 已完成 |
| 5 | ________ | mms-redis | 缓存模块 | 已完成 |
| 5 | ________ | mms-sms | 短信模块 | 已完成 |
| 5 | ________ | mms-thymeleaf | 模版引擎渲染模块 | 已完成 |
| 8 | ________ | mms-websocket | 长连接通信管理 | 已完成 |
| 5 | ________ | mms-wx | 微信模块 | 已完成 |
| 9 | mms-zoom | | 快速激增模块集 | 已完成 |
| 10 | ________ | mms-monitor | 安全监控 | 已完成 |
| 11 | ________ | mms-powerjob | 定时任务 | 已完成 |
| 12 | script | | 项目配置文件 | 已完成 |
## 📄软件架构
## 📄软件架构与核心技术栈
软件架构说明
| 框架 | 说明 | 版本 | 说明 |
|----------------------------------------------------------------------|-----------------------|---------------|-------|
| [SpringBoot](https://spring.io/projects/spring-boot/#learn) | 后端主框架 | 3.X | 3.1.5 |
| [Undertow](https://undertow.io/) | 基于 XNIO 的高性能容器 | 2.7.6 | |
| [Sa-Token](https://sa-token.dev33.cn/) | Sa-Token、Jwt(强解耦、强扩展) | 1.33.0 | |
| [MySQL](https://dev.mysql.com/) | 关系数据库 | 适配 8.X 最低 5.7 | |
| [Redis](https://redis.io/) | 缓存数据库 | 适配 6.X 最低 4.X | |
| [Mybatis-Plus](https://baomidou.com/guide/) | 快速 CRUD 增加开发效率 | 3.5.4 | |
| [Vue](https://staging-cn.vuejs.org/) | vue 框架 | 3.2.45 | |
| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 4.0.4 | |
| [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.2.28 | |
| [TypeScript](https://www.typescriptlang.org/docs/) | JavaScript 的超集 | 4.9.4 | |
| [pinia](https://pinia.vuejs.org/) | Vue 存储库 替代 vuex5 | 2.0.28 | |
| [vueuse](https://vueuse.org/) | 常用工具集 | 9.10.0 | |
| [vxe-table](https://vxetable.cn/) | vue 最强表单 | 4.3.7 | |
| [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 9.2.2 | |
| [vue-router](https://router.vuejs.org/) | vue 路由 | 4.1.6 | |
| [windicss](https://cn.windicss.org/) | 下一代工具优先的 CSS 框架 | 3.5.6 | |
| [iconify](https://icon-sets.iconify.design/) | 在线图标库 | 3.0.1 | |
| [wangeditor](https://www.wangeditor.com/) | 富文本编辑器 | 5.1.23 | |
| 框架 | 说明 | 版本 | 说明 |
| -------------------------------------------------------------------- | ----------------------------- | ----------------- | ----- |
| [SpringBoot](https://spring.io/projects/spring-boot/#learn) | 后端主框架 | 3.X | 3.2.6 |
| [Undertow](https://undertow.io/) | 基于 XNIO 的高性能容器 | 2.7.6 | |
| [Sa-Token](https://sa-token.dev33.cn/) | Sa-Token、Jwt(强解耦、强扩展) | 1.35.0.RC | |
| [MySQL](https://dev.mysql.com/) | 关系数据库 | 适配 8.X 最低 5.7 | |
| [Redis](https://redis.io/) | 缓存数据库 | 适配 6.X 最低 4.X | |
| [Mybatis-Plus](https://baomidou.com/guide/) | 快速 CRUD 增加开发效率 | 3.5.7 | |
| [Vue](https://staging-cn.vuejs.org/) | vue 框架 | 3.2.45 | |
| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 4.0.4 | |
| [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.2.28 | |
| [TypeScript](https://www.typescriptlang.org/docs/) | JavaScript 的超集 | 4.9.4 | |
| [pinia](https://pinia.vuejs.org/) | Vue 存储库 替代 vuex5 | 2.0.28 | |
| [vueuse](https://vueuse.org/) | 常用工具集 | 9.10.0 | |
| [vxe-table](https://vxetable.cn/) | vue 最强表单 | 4.3.7 | |
| [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 9.2.2 | |
| [vue-router](https://router.vuejs.org/) | vue 路由 | 4.1.6 | |
| [windicss](https://cn.windicss.org/) | 下一代工具优先的 CSS 框架 | 3.5.6 | |
| [iconify](https://icon-sets.iconify.design/) | 在线图标库 | 3.0.1 | |
| [wangeditor](https://www.wangeditor.com/) | 富文本编辑器 | 5.1.23 | |
## 🏗️项目架构说明
### 整体架构
MMS模块化管理系统采用前后端分离的架构设计后端基于 Spring Boot 3.x 构建,前端使用 Vue 3.x 技术栈。
### 后端架构特点
1. **多模块 Maven 项目结构**:项目采用 Maven 多模块结构,便于模块化开发和维护
2. **Spring Boot 3.x**:基于最新稳定版本的 Spring Boot 框架
3. **多数据源支持**:集成 dynamic-datasource-spring-boot-starter支持多数据源切换
4. **权限认证**:使用 Sa-Token 进行权限控制,支持 JWT
5. **ORM 框架**:集成 MyBatis-Plus提供强大的 CRUD 操作能力
6. **缓存支持**:集成 Redis支持分布式缓存
7. **多租户架构**:支持多租户模式,可灵活开启或关闭
8. **代码生成**:内置低代码生成引擎,加速后台系统构建
9. **对象存储**:集成 x-file-storage支持多种云存储平台
10. **消息队列**:支持多种消息队列中间件
11. **定时任务**:集成 PowerJob支持分布式定时任务
12. **监控管理**:集成 Spring Boot Admin提供应用监控能力
### 核心模块说明
1. **mms-admin**:系统管理启动模块,整合各业务模块
2. **mms-modules**:核心业务模块集合
- mms-common公共模块包含通用工具类和枚举
- mms-framework核心框架模块包含基础配置和工具
- mms-datasource数据源模块包含基础实体类和分页工具
- mms-authority安全认证模块基于 Sa-Token 实现
- mms-gen代码生成模块支持低代码开发
- mms-oss对象存储模块支持多种云存储
- mms-redisRedis 缓存模块
- mms-sms短信服务模块
- mms-email邮件服务模块
3. **mms-zoom**:扩展模块集合
- mms-monitor系统监控模块
- mms-powerjob分布式定时任务模块
## 👨‍💻开发指南
### 开发环境搭建
1. 安装 JDK 17+ 并配置环境变量
2. 安装 Maven 3.6+ 并配置环境变量
3. 安装 MySQL 8.0+ 并创建数据库
4. 安装 Redis 6.x+ 并启动服务
5. 导入 IDE (推荐 IntelliJ IDEA)
### 项目结构说明
```
mms
├── mms-admin # 系统管理启动模块
├── mms-modules # 核心业务模块集合
│ ├── mms-common # 公共模块
│ ├── mms-framework # 核心框架模块
│ ├── mms-datasource # 数据源模块
│ ├── mms-authority # 安全认证模块
│ ├── mms-gen # 代码生成模块
│ └── ... # 其他业务模块
├── mms-zoom # 扩展模块集合
│ ├── mms-monitor # 系统监控模块
│ └── mms-powerjob # 定时任务模块
└── script # 脚本文件
├── db # 数据库脚本
└── docker # Docker 部署文件
```
### 代码规范
1. 遵循阿里巴巴 Java 开发手册
2. 使用 Lombok 简化代码
3. 统一使用 MapStruct 进行对象转换
4. 控制器层统一返回 R<T> 格式
5. 服务层统一处理业务逻辑
6. 数据访问层使用 MyBatis-Plus
### 新增业务模块步骤
1. 在 `mms-modules` 目录下创建新模块
2. 在模块中创建对应的 entity、mapper、service、controller 层
3. 在 `mms-admin` 的 pom.xml 中添加模块依赖
4. 在数据库中创建对应的表结构
5. 在菜单管理中添加对应的菜单和权限
## 🤝如何贡献
我们欢迎任何形式的贡献,包括但不限于:
1. **提交 Issue**:报告 bug 或提出新功能建议
2. **提交 Pull Request**:修复 bug、添加新功能或改进文档
3. **完善文档**:补充使用说明、开发指南等文档
4. **代码优化**:优化现有代码结构和性能
### 贡献流程
1. Fork 项目到自己的 GitHub 账户
2. Clone 到本地开发环境
3. 创建新的分支进行开发
4. 提交代码并推送至 GitHub
5. 发起 Pull Request
### 代码规范
- 遵循项目现有的代码风格
- 添加必要的单元测试
- 确保代码通过所有测试
- 编写清晰的提交信息
## 🎳演示图例
@ -216,3 +425,201 @@ system简称MMS是一款基于多应用模块用户、商品、支
## 🧪学习 & 商用
&emsp;&emsp;[mms](https://gitee.com/mmsAdmin/mms),[mms-ui](https://gitee.com/mmsAdmin/mms-ui) 是免费和开源的,可免费用于 `学习``商业使用`
## 🔧 技术架构与核心组件
### 核心技术栈
MMS基于Spring Boot 3.x构建采用Maven多模块架构整合了众多优秀的开源技术框架
| 技术框架 | 说明 | 版本 |
| ------------------ | -------------- | --------- |
| Spring Boot | 后端主框架 | 3.2.6 |
| MyBatis-Plus | ORM框架 | 3.5.7 |
| Sa-Token | 权限认证框架 | 1.35.0.RC |
| Redisson | Redis客户端 | 3.31.0 |
| Dynamic-Datasource | 多数据源支持 | 4.3.1 |
| MapStruct Plus | 对象映射工具 | 1.4.3 |
| Hutool | Java工具库 | 5.8.32 |
| Lombok | Java简化工具 | 1.8.32 |
| EasyExcel | Excel处理 | 4.0.3 |
| SpringDoc | API文档 | 2.5.0 |
| X-File-Storage | 对象存储 | 2.1.0 |
| PowerJob | 分布式任务调度 | 4.3.9 |
| SMS4J | 短信服务 | 3.2.0 |
### 数据库支持
系统支持多种主流数据库:
- MySQL 8.0+
- Oracle
- PostgreSQL
- SQL Server
- 达梦数据库
- 人大金仓
### 消息队列支持
系统支持多种消息队列中间件:
- RabbitMQ
- RocketMQ
- Kafka
### 对象存储支持
系统集成了X-File-Storage支持多种云存储平台
- 阿里云OSS
- 腾讯云COS
- 华为云OBS
- 七牛云Kodo
- 百度云BOS
- Amazon S3
- MinIO
## 📦 项目模块结构
```
mms
├── mms-admin # 系统管理启动模块
├── mms-modules # 核心业务模块集合
│ ├── mms-common # 公共模块
│ ├── mms-framework # 核心框架模块
│ ├── mms-datasource # 数据源模块
│ ├── mms-authority # 安全认证模块
│ ├── mms-gen # 代码生成模块
│ └── ... # 其他业务模块
├── mms-zoom # 扩展模块集合
│ ├── mms-monitor # 系统监控模块
│ └── mms-powerjob # 定时任务模块
└── script # 脚本文件
├── db # 数据库脚本
└── docker # Docker 部署文件
```
## 🔐 安全特性
1. **权限控制**基于Sa-Token实现RBAC权限模型支持菜单、按钮级别权限控制
2. **数据加密**支持AES/RSA加密算法对敏感数据进行加密存储
3. **密码安全**MD5加盐加密支持密码强度检测
4. **接口安全**:支持接口签名验证,防止数据篡改
5. **XSS防护**内置XSS攻击防护机制
6. **SQL注入防护**通过MyBatis-Plus和参数绑定防止SQL注入
7. **CSRF防护**支持CSRF攻击防护
## 🌐 多租户架构
系统采用多租户架构设计,支持以下特性:
1. **数据隔离**:不同租户数据完全隔离
2. **资源共享**:可灵活配置租户间资源共享策略
3. **租户管理**:支持租户创建、配置、停用等管理功能
4. **套餐管理**:支持租户套餐配置,限制功能权限
## 📊 系统监控
1. **健康检查**集成Spring Boot Actuator提供应用健康监控
2. **性能监控**:支持接口调用统计、响应时间分析
3. **日志管理**:完善的操作日志和登录日志记录
4. **服务监控**集成Spring Boot Admin提供可视化监控界面
## 🛠️ 开发工具
1. **代码生成**:内置低代码生成引擎,支持前后端代码一键生成
2. **API文档**集成SpringDoc自动生成Swagger API文档
3. **数据字典**:统一数据字典管理,支持动态配置
4. **定时任务**集成PowerJob支持分布式定时任务调度
5. **消息队列**:支持多种消息队列中间件
6. **缓存管理**集成Redis支持分布式缓存
## 📱 前端技术栈
| 技术框架 | 说明 | 版本 |
| ------------ | -------- | ------ |
| Vue | 前端框架 | 3.2.45 |
| Vite | 构建工具 | 4.0.4 |
| Element Plus | UI组件库 | 2.2.28 |
| TypeScript | 编程语言 | 4.9.4 |
| Pinia | 状态管理 | 2.0.28 |
| Vue Router | 路由管理 | 4.1.6 |
| Windi CSS | CSS框架 | 3.5.6 |
## 🚀 部署架构
系统支持多种部署方式:
1. **传统部署**直接运行jar包
2. **Docker部署**使用Docker容器化部署
3. **Kubernetes部署**支持K8s集群部署
4. **微服务部署**:支持拆分为微服务架构
## 📈 性能优化
1. **数据库优化**:支持读写分离、分库分表
2. **缓存优化**:多级缓存设计,提升系统响应速度
3. **连接池优化**使用HikariCP高性能连接池
4. **异步处理**:支持异步任务处理,提升系统吞吐量
5. **压缩传输**支持GZIP压缩减少网络传输数据量
## 📞 技术支持
如有问题可以通过以下方式联系技术支持:
- 官方网站:[https://www.mmsadmin.cn](https://www.mmsadmin.cn)
- Gitee仓库[https://gitee.com/mmsAdmin/mms](https://gitee.com/mmsAdmin/mms)
- 邮箱sxpcwlkj@163.com
- QQ群待定
## 📄 更新日志
### v1.0.6 (2025-02-03)
- [新增] 微信二维码扫描登录
- [新增] 个人中心手机号绑定
- [新增] 个人中心邮箱绑定
- [修复] 个人中心微信号绑定
- [预告] 修复已知BUG
### v1.0.5 (2024-11-14)
- [新增] mms-admin整合easyexcel支持数据的导入/导出(支持字典的自动翻译和导入的逆翻译)
- [新增] mms-ui对Table列表页面进行工具栏的封装表格数据的导出导入打印等功能
- [优化] 系统整体的架构布局优化
- [预告] 接口加密,接口防抖,接口限流等技术
### v1.0.4 (2024-10-20)
- [更新] mms-ui sass文件的引入方式`@import`换为`@use`
- [注意] Dart Sass originally used an API based on the one used by Node Sass, but replaced it with a new, modern API in Dart Sass 1.45.0. The legacy JS API is now deprecated and will be removed in Dart Sass 2.0.0.
### v1.0.3 (2024-08-02)
- [升级] mms-generator代码生产模块
- [新增] mms-power job分布式定时任务模块
- [新增] mms-mq消息队列模块
- [新增] mms-monitor健康检测扩展模块
- [优化] mms-ui优化适配
### v1.0.2 (2024-05-10)
- [新增] mms-aliyun阿里云生态模块
- [新增] mms-wx微信生态模块
- [新增] mms-demo Demo模块
### v1.0.1 (2024-02-10)
- [新增] mms-system管理系统模块
- [新增] mms-common公共模块抽取
- [新增] mms-redis独立redis模块
- [新增] mms-framework系统核心模块
- [新增] mms-sms短信模块
- [新增] mms-email邮件模块
- [新增] mms-oss对象存储模块
### v1.0.0 (2023-12-01)
- [发布] MMS模块化管理系统正式开源发布

View File

@ -21,7 +21,7 @@ public class GeneratePassword {
//加密内容
System.out.println("url: " + CryptoUtils.encrypt(arr[0], "jdbc:mysql://localhost:3306/mms"));
System.out.println("username: " + CryptoUtils.encrypt(arr[0], "root"));
System.out.println("password: " + CryptoUtils.encrypt(arr[0], "123456"));
System.out.println("password: " + CryptoUtils.encrypt(arr[0], "ieHsBpEdmKcDfMtm"));
//备注: 生成的密文 要和 publicKey 一起更新到配置文件中否则会造成解密失败
}

View File

@ -35,7 +35,7 @@ import java.util.Map;
* @author mmsAdmin
* @Doc <a href='https://www.mmsadmin.com'>MMS文档</a>
*/
@Tag(name = "系统登录",description = "系统登录,鉴权")
@Tag(name = "系统管理模块-登录,鉴权",description = "系统管理模块-登录,鉴权")
@Slf4j
@Validated
@RequiredArgsConstructor
@ -81,6 +81,7 @@ public class AuthController extends BaseController {
* @return 退出结果
*/
@Operation(summary = "退出登录", description = "退出当前登录会话")
@SaIgnore
@PostMapping("/logout")
public R<String> logout() {
loginService.logout();

View File

@ -3,11 +3,12 @@ package com.sxpcwlkj.system.controller;
import cn.dev33.satoken.annotation.SaIgnore;
import com.sxpcwlkj.common.code.controller.BaseController;
import com.sxpcwlkj.common.code.entity.CaptchaEntity;
import com.sxpcwlkj.common.properties.MsProperties;
import com.sxpcwlkj.common.properties.MmsAdminProperties;
import com.sxpcwlkj.common.utils.DataUtil;
import com.sxpcwlkj.common.utils.R;
import com.sxpcwlkj.system.service.CaptchaService;
import com.sxpcwlkj.system.service.SysTenantService;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@ -26,7 +27,7 @@ import java.util.Map;
* @author mmsAdmin
* @Doc <a href='https://www.mmsadmin.com'>MMS文档</a>
*/
@Tag(name = "系统管理模块-验证码处理",description = "系统管理模块-验证码处理")
@Slf4j
@Validated
@RequiredArgsConstructor
@ -35,7 +36,7 @@ import java.util.Map;
public class CaptchaController extends BaseController {
private final SysTenantService sysTenantService;
private final CaptchaService captchaService;
private final MsProperties msProperties;
private final MmsAdminProperties msProperties;
/**
* 系统配置

View File

@ -1,14 +1,5 @@
package com.sxpcwlkj.system.controller;
import com.sxpcwlkj.common.code.entity.WxCodeBo;
import com.sxpcwlkj.common.constant.Constants;
import com.sxpcwlkj.common.enums.DeviceEnum;
import com.sxpcwlkj.common.enums.WxCodeStatusEnum;
import com.sxpcwlkj.common.utils.MapstructUtil;
import com.sxpcwlkj.framework.sercice.SysSignService;
import com.sxpcwlkj.redis.constant.RedisConstant;
import com.sxpcwlkj.system.entity.SysUser;
import com.sxpcwlkj.system.service.SysLoginService;
import com.sxpcwlkj.wx.service.WxCodeService;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.convert.Convert;
@ -16,26 +7,37 @@ import cn.hutool.core.util.RandomUtil;
import com.sxpcwlkj.authority.LoginObject;
import com.sxpcwlkj.common.code.controller.BaseController;
import com.sxpcwlkj.common.code.entity.ConfigEntity;
import com.sxpcwlkj.common.code.entity.WxCodeBo;
import com.sxpcwlkj.common.constant.Constants;
import com.sxpcwlkj.common.enums.ConfigKeyNum;
import com.sxpcwlkj.common.enums.DeviceEnum;
import com.sxpcwlkj.common.enums.SystemCommonEnum;
import com.sxpcwlkj.common.enums.WxCodeStatusEnum;
import com.sxpcwlkj.common.exception.MmsException;
import com.sxpcwlkj.common.properties.DemoModeProperties;
import com.sxpcwlkj.common.utils.DataUtil;
import com.sxpcwlkj.common.utils.IPUtil;
import com.sxpcwlkj.common.utils.MapstructUtil;
import com.sxpcwlkj.common.utils.R;
import com.sxpcwlkj.email.service.EmailService;
import com.sxpcwlkj.common.utils.IPUtil;
import com.sxpcwlkj.framework.sercice.SysSignService;
import com.sxpcwlkj.redis.RedisUtil;
import com.sxpcwlkj.redis.constant.RedisConstant;
import com.sxpcwlkj.sms.service.SmsService;
import com.sxpcwlkj.system.entity.AdminMenuTree;
import com.sxpcwlkj.system.entity.SysUser;
import com.sxpcwlkj.system.entity.bo.EmailBo;
import com.sxpcwlkj.system.entity.bo.SmsBo;
import com.sxpcwlkj.system.entity.vo.SysUserVo;
import com.sxpcwlkj.system.service.SysDictService;
import com.sxpcwlkj.system.service.SysLoginService;
import com.sxpcwlkj.system.service.SysUserService;
import com.sxpcwlkj.wx.service.WxCodeService;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.*;
@ -49,6 +51,7 @@ import java.util.*;
* @author mmsAdmin
* @Doc <a href='https://www.mmsadmin.com'>MMS文档</a>
*/
@Tag(name = "系统管理模块-公共接口",description = "系统管理模块-公共接口")
@RestController
@RequiredArgsConstructor
@Slf4j
@ -62,6 +65,7 @@ public class CommonController extends BaseController {
private final SysDictService sysDictService;
private final WxCodeService wxCodeService;
private final SysSignService sysSignService;
private final DemoModeProperties demoModeProperties;
@Value("${server.port}")
private String port;
@ -95,7 +99,7 @@ public class CommonController extends BaseController {
map.put("loginType", DataUtil.getStringToList(smsConfigEntity.getConfigValue()));
}
if("sys_base_tenant_state".equals(smsConfigEntity.getConfigKey())){
map.put("tenantState", Convert.toInt(smsConfigEntity.getConfigValue()) == 1);
map.put("tenantState", Convert.toInt(smsConfigEntity.getConfigValue()).equals(SystemCommonEnum.SYS_COMMON_STATE_OPEN.getValue()));
}
if("sys_base_login_bg".equals(smsConfigEntity.getConfigKey())){
map.put("loginBg",smsConfigEntity.getConfigValue());
@ -105,7 +109,9 @@ public class CommonController extends BaseController {
}
});
map.put("demoMode",demoModeProperties.isEnabled());
map.put("demoAccount",demoModeProperties.isEnabled()?"mms":"");
map.put("demoPassword",demoModeProperties.isEnabled()?"123456":"");
return R.success("base system config.",map);
}

View File

@ -7,17 +7,22 @@ import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.sxpcwlkj.authority.LoginObject;
import com.sxpcwlkj.common.code.controller.BaseController;
import com.sxpcwlkj.common.properties.MmsAdminProperties;
import com.sxpcwlkj.common.utils.R;
import com.sxpcwlkj.system.entity.vo.SysConfigVo;
import com.sxpcwlkj.system.entity.vo.SysFunctionVo;
import com.sxpcwlkj.system.service.SysConfigService;
import com.sxpcwlkj.system.service.SysFunctionService;
import com.sxpcwlkj.system.service.SysNoticeService;
import com.sxpcwlkj.system.service.SysUserService;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
/**
* 首页控制台
@ -25,11 +30,40 @@ import java.util.Map;
* @author mmsAdmin
* @Doc <a href='https://www.mmsadmin.com'>MMS文档</a>
*/
@Tag(name = "系统管理模块-首页控制台",description = "系统管理模块-首页控制台")
@RestController
@RequiredArgsConstructor
@RequestMapping("system/home")
public class HomeController extends BaseController {
private final SysUserService sysUserService;
private final SysFunctionService functionService;
private final SysConfigService configService;
private final MmsAdminProperties mmsAdminProperties;
private final SysNoticeService sysNoticeService;
/**
* 控制台默认数据
* @return 数据
*/
@SaCheckLogin
@GetMapping("/homeInit")
public R<Object> homeInit(){
Map<String,Object> map=new HashMap<>();
map.put("userName",sysUserService.selectVoById(LoginObject.getLoginId()).getUserName());
int week = DateUtil.dayOfWeek(new Date());
map.put("week",week==1?"星期日":week==2?"星期一":week==3?"星期二":week==4?"星期三":week==5?"星期四":week==6?"星期五":"星期六");
List<SysFunctionVo> fastList= functionService.selectIsFast(9);
map.put("fastList",fastList);
List<SysConfigVo> eventList = configService.selectEventList(12);
map.put("eventList",eventList);
map.put("systemInfo",mmsAdminProperties);
map.put("userTool",sysUserService.selectTool());
map.put("newsTool",sysNoticeService.selectTool());
map.put("task","0/0");
return R.success(map);
}
/**
* 会员类别
*/

View File

@ -12,6 +12,7 @@ import com.sxpcwlkj.sms.service.SmsService;
import com.sxpcwlkj.system.entity.bo.SysConfigBo;
import com.sxpcwlkj.system.entity.vo.SysConfigVo;
import com.sxpcwlkj.system.service.SysConfigService;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
@ -26,6 +27,7 @@ import java.util.List;
* @author mmsAdmin
* @Doc <a href='https://www.mmsadmin.com'>MMS文档</a>
*/
@Tag(name = "系统管理模块-系统配置",description = "系统管理模块-系统配置")
@Slf4j
@Validated
@RequiredArgsConstructor

View File

@ -3,16 +3,17 @@ package com.sxpcwlkj.system.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.sxpcwlkj.common.annotation.MssSafety;
import com.sxpcwlkj.common.code.controller.BaseController;
import com.sxpcwlkj.common.code.entity.PrintObject;
import com.sxpcwlkj.common.code.entity.ThreeQueryBo;
import com.sxpcwlkj.common.utils.MapstructUtil;
import com.sxpcwlkj.common.utils.R;
import com.sxpcwlkj.common.code.entity.PrintObject;
import com.sxpcwlkj.framework.config.ValidatedGroupConfig;
import com.sxpcwlkj.framework.utils.ExcelUtil;
import com.sxpcwlkj.common.code.entity.ThreeQueryBo;
import com.sxpcwlkj.system.entity.bo.SysDeptBo;
import com.sxpcwlkj.system.entity.vo.SysDeptVo;
import com.sxpcwlkj.system.entity.export.SysDeptExport;
import com.sxpcwlkj.system.entity.vo.SysDeptVo;
import com.sxpcwlkj.system.service.SysDeptService;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -31,6 +32,7 @@ import java.util.Set;
* @author mmsAdmin
* @Doc <a href='https://www.mmsadmin.com'>MMS文档</a>
*/
@Tag(name = "系统管理模块-系统部门",description = "系统管理模块-系统部门")
@Slf4j
@Validated
@RequiredArgsConstructor

View File

@ -4,12 +4,12 @@ import cn.dev33.satoken.annotation.SaCheckPermission;
import com.sxpcwlkj.common.annotation.MssSafety;
import com.sxpcwlkj.common.code.controller.BaseController;
import com.sxpcwlkj.common.utils.R;
import com.sxpcwlkj.datasource.entity.page.PageQuery;
import com.sxpcwlkj.datasource.entity.page.TableDataInfo;
import com.sxpcwlkj.framework.config.ValidatedGroupConfig;
import com.sxpcwlkj.system.entity.bo.SysDictBo;
import com.sxpcwlkj.system.entity.vo.SysDictVo;
import com.sxpcwlkj.system.service.SysDictService;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@ -20,6 +20,7 @@ import org.springframework.web.bind.annotation.*;
* @author mmsAdmin
* @Doc <a href='https://www.mmsadmin.com'>MMS文档</a>
*/
@Tag(name = "系统管理模块-系统字典",description = "系统管理模块-系统字典")
@RequestMapping("system/dict")
@RestController
@RequiredArgsConstructor
@ -31,7 +32,6 @@ public class SysDictController extends BaseController {
* 分页查询字典列表
*
* @param bo 查询条件
* @param pageQuery 分页条件
* @return 分页结果
*/
@MssSafety

View File

@ -9,6 +9,7 @@ import com.sxpcwlkj.system.entity.AdminMenuTree;
import com.sxpcwlkj.system.entity.bo.SysFunctionBo;
import com.sxpcwlkj.system.entity.vo.SysFunctionVo;
import com.sxpcwlkj.system.service.SysFunctionService;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
@ -22,6 +23,7 @@ import java.util.List;
* @author mmsAdmin
* @Doc <a href='https://www.mmsadmin.com'>MMS文档</a>
*/
@Tag(name = "系统管理模块-系统资源",description = "系统管理模块-系统资源")
@RequestMapping("system/function")
@RestController
@RequiredArgsConstructor

View File

@ -3,16 +3,17 @@ package com.sxpcwlkj.system.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.sxpcwlkj.common.annotation.MssSafety;
import com.sxpcwlkj.common.code.controller.BaseController;
import com.sxpcwlkj.common.code.entity.PrintObject;
import com.sxpcwlkj.common.utils.MapstructUtil;
import com.sxpcwlkj.common.utils.R;
import com.sxpcwlkj.common.code.entity.PrintObject;
import com.sxpcwlkj.datasource.entity.page.TableDataInfo;
import com.sxpcwlkj.framework.config.ValidatedGroupConfig;
import com.sxpcwlkj.framework.utils.ExcelUtil;
import com.sxpcwlkj.system.entity.bo.SysNoticeBo;
import com.sxpcwlkj.system.entity.vo.SysNoticeVo;
import com.sxpcwlkj.system.entity.export.SysNoticeExport;
import com.sxpcwlkj.system.entity.vo.SysNoticeVo;
import com.sxpcwlkj.system.service.SysNoticeService;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -31,6 +32,7 @@ import java.util.Set;
* @author mmsAdmin
* @Doc <a href='https://www.mmsadmin.com'>MMS文档</a>
*/
@Tag(name = "系统管理模块-系统公告",description = "系统管理模块-系统公告")
@Slf4j
@Validated
@RequiredArgsConstructor

View File

@ -5,6 +5,7 @@ import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaCheckRole;
import com.sxpcwlkj.common.annotation.MssSafety;
import com.sxpcwlkj.common.code.controller.BaseController;
import com.sxpcwlkj.common.enums.SystemCommonEnum;
import com.sxpcwlkj.common.utils.R;
import com.sxpcwlkj.datasource.entity.page.TableDataInfo;
import com.sxpcwlkj.framework.config.ValidatedGroupConfig;
@ -15,6 +16,7 @@ import com.sxpcwlkj.system.entity.vo.SysOssConfigVo;
import com.sxpcwlkj.system.entity.vo.SysOssVo;
import com.sxpcwlkj.system.service.SysOssConfigService;
import com.sxpcwlkj.system.service.SysOssService;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.dromara.x.file.storage.core.FileInfo;
import org.dromara.x.file.storage.core.FileStorageService;
@ -28,6 +30,7 @@ import org.springframework.web.multipart.MultipartFile;
* @author mmsAdmin
* @Doc <a href='https://www.mmsadmin.com'>MMS文档</a>
*/
@Tag(name = "系统管理模块-对象存储",description = "系统管理模块-对象存储")
@RequestMapping("system/oss")
@RestController
@RequiredArgsConstructor
@ -87,7 +90,7 @@ public class SysOssController extends BaseController {
sysOssBo.setPlatform(fileInfo.getPlatform());
sysOssBo.setContentType(fileInfo.getContentType());
sysOssBo.setBasePath(fileInfo.getBasePath());
sysOssBo.setStatus(0);
sysOssBo.setStatus(SystemCommonEnum.SYS_COMMON_STATE_OPEN.getValue());
sysOssBo.setSort(0);
return success(baseService.insert(sysOssBo));
}

View File

@ -9,6 +9,7 @@ import com.sxpcwlkj.framework.config.ValidatedGroupConfig;
import com.sxpcwlkj.system.entity.bo.SysRoleBo;
import com.sxpcwlkj.system.entity.vo.SysRoleVo;
import com.sxpcwlkj.system.service.SysRoleService;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
@ -20,6 +21,7 @@ import org.springframework.web.bind.annotation.*;
* @author mmsAdmin
* @Doc <a href='https://www.mmsadmin.com'>MMS文档</a>
*/
@Tag(name = "系统管理模块-系统角色",description = "系统管理模块-系统角色")
@RequestMapping("system/role")
@RestController
@RequiredArgsConstructor

View File

@ -21,6 +21,7 @@ import com.sxpcwlkj.system.entity.export.SysUserExportVo;
import com.sxpcwlkj.system.entity.vo.SysUserVo;
import com.sxpcwlkj.system.service.SysUserService;
import com.sxpcwlkj.wx.service.WxCodeService;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotBlank;
import lombok.RequiredArgsConstructor;
@ -31,7 +32,10 @@ import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
/**
* 系统用户
@ -39,6 +43,7 @@ import java.util.*;
* @author mmsAdmin
* @Doc <a href='https://www.mmsadmin.com'>MMS文档</a>
*/
@Tag(name = "系统管理模块-系统用户",description = "系统管理模块-系统用户")
@Slf4j
@Validated
@RequiredArgsConstructor
@ -138,13 +143,15 @@ public class SysUserController extends BaseController {
* 导出系统用户
*/
@MssSafety
@Transactional
//@Transactional
@SaCheckPermission("system:user:export")
@PostMapping("/export")
public void export(SysUserBo user, PageQuery pageQuery,HttpServletResponse response) throws IOException {
List<SysUserVo> list= baseService.selectPageUserList(user, pageQuery).getRows();
List<SysUserExportVo> data= MapstructUtil.convert(list,SysUserExportVo.class);
ExcelUtil.export(response, SysUserExportVo.class, "系统用户",data);
public void export(SysUserBo user, PageQuery pageQuery, HttpServletResponse response) throws IOException {
List<SysUserVo> list = baseService.selectPageUserList(user, pageQuery).getRows();
List<SysUserExportVo> data = MapstructUtil.convert(list, SysUserExportVo.class);
// 使用封装后的安全导出方法
ExcelUtil.safeExport(response, SysUserExportVo.class, "系统用户", data, pageQuery);
}
/**

View File

@ -1,13 +1,12 @@
package com.sxpcwlkj.system.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.sxpcwlkj.datasource.entity.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import com.baomidou.mybatisplus.annotation.*;
import com.sxpcwlkj.datasource.entity.BaseEntity;
import java.util.Date;
/**
* 系统部门

View File

@ -94,4 +94,8 @@ public class SysFunction extends BaseEntity {
* 是否总是显示
*/
private Integer alwaysShow;
/**
* 是否快捷菜单
*/
private Integer isFast;
}

View File

@ -1,14 +1,12 @@
package com.sxpcwlkj.system.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.sxpcwlkj.datasource.entity.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import com.baomidou.mybatisplus.annotation.*;
import com.sxpcwlkj.datasource.entity.BaseEntity;
import java.util.Date;
/**
* 系统公告

View File

@ -2,7 +2,6 @@ package com.sxpcwlkj.system.entity.bo;
import com.sxpcwlkj.framework.config.ValidatedGroupConfig;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;

View File

@ -1,15 +1,16 @@
package com.sxpcwlkj.system.entity.bo;
import java.io.Serial;
import com.sxpcwlkj.datasource.entity.BaseEntity;
import com.sxpcwlkj.framework.config.ValidatedGroupConfig;
import com.sxpcwlkj.system.entity.SysDept;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
import io.github.linpeilie.annotations.AutoMapper;
import com.sxpcwlkj.system.entity.SysDept;
import java.util.Date;
import com.sxpcwlkj.datasource.entity.BaseEntity;
import java.io.Serial;
/**
* 系统部门Bo

View File

@ -97,6 +97,12 @@ public class SysFunctionBo extends BaseEntity {
* 是否总是显示
*/
private Integer alwaysShow;
/**
* 级别
*/
private Integer level=0;
/**
* 是否快捷菜单
*/
private Integer isFast;
}

View File

@ -1,13 +1,14 @@
package com.sxpcwlkj.system.entity.bo;
import java.io.Serial;
import com.sxpcwlkj.datasource.entity.BaseEntity;
import com.sxpcwlkj.system.entity.SysNotice;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
import io.github.linpeilie.annotations.AutoMapper;
import com.sxpcwlkj.system.entity.SysNotice;
import java.util.Date;
import com.sxpcwlkj.datasource.entity.BaseEntity;
import java.io.Serial;
/**
* 系统公告Bo

View File

@ -1,14 +1,14 @@
package com.sxpcwlkj.system.entity.export;
import java.io.Serial;
import com.alibaba.excel.annotation.ExcelProperty;
import com.sxpcwlkj.framework.entity.BaseEntityVo;
import com.sxpcwlkj.system.entity.SysDept;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import io.github.linpeilie.annotations.AutoMapper;
import com.sxpcwlkj.system.entity.SysDept;
import com.sxpcwlkj.framework.entity.BaseEntityVo;
import com.alibaba.excel.annotation.ExcelProperty;
import java.util.Date;
import java.io.Serial;
/**
* 系统部门Export

View File

@ -1,14 +1,14 @@
package com.sxpcwlkj.system.entity.export;
import java.io.Serial;
import com.alibaba.excel.annotation.ExcelProperty;
import com.sxpcwlkj.framework.entity.BaseEntityVo;
import com.sxpcwlkj.system.entity.SysNotice;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import io.github.linpeilie.annotations.AutoMapper;
import com.sxpcwlkj.system.entity.SysNotice;
import com.sxpcwlkj.framework.entity.BaseEntityVo;
import com.alibaba.excel.annotation.ExcelProperty;
import java.util.Date;
import java.io.Serial;
/**
* 系统公告Export

View File

@ -1,15 +1,15 @@
package com.sxpcwlkj.system.entity.vo;
import java.io.Serial;
import com.alibaba.excel.annotation.ExcelProperty;
import com.sxpcwlkj.framework.entity.BaseEntityVo;
import com.sxpcwlkj.system.entity.SysDept;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import io.github.linpeilie.annotations.AutoMapper;
import com.sxpcwlkj.system.entity.SysDept;
import com.sxpcwlkj.framework.entity.BaseEntityVo;
import com.alibaba.excel.annotation.ExcelProperty;
import java.io.Serial;
import java.util.List;
import java.util.Date;
/**
* 系统部门Vo

View File

@ -25,7 +25,7 @@ public class SysDictDataVo {
private Integer sort;
private String status;
private Integer status;
private String colorType;

View File

@ -29,9 +29,9 @@ public class SysDictVo {
*/
private Integer type;
/**
* 状态;0正常 1停用
* 状态;1正常 0停用
*/
private String status;
private Integer status;
/**
* 排序
*/

View File

@ -63,7 +63,7 @@ public class SysFunctionVo {
*/
private String componentName;
/**
* 状态;0正常 1停用
* 状态;1正常 0停用
*/
private Integer status;
/**
@ -91,7 +91,10 @@ public class SysFunctionVo {
* 是否总是显示
*/
private Integer alwaysShow;
/**
* 是否快捷菜单
*/
private Integer isFast;
private String revision;

View File

@ -1,15 +1,14 @@
package com.sxpcwlkj.system.entity.vo;
import java.io.Serial;
import com.alibaba.excel.annotation.ExcelProperty;
import com.sxpcwlkj.framework.entity.BaseEntityVo;
import com.sxpcwlkj.system.entity.SysNotice;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import io.github.linpeilie.annotations.AutoMapper;
import com.sxpcwlkj.system.entity.SysNotice;
import com.sxpcwlkj.framework.entity.BaseEntityVo;
import com.alibaba.excel.annotation.ExcelProperty;
import java.util.List;
import java.util.Date;
import java.io.Serial;
/**
* 系统公告Vo

View File

@ -1,7 +1,7 @@
package com.sxpcwlkj.system.entity.vo;
import com.sxpcwlkj.common.properties.MsProperties;
import com.sxpcwlkj.common.properties.MmsAdminProperties;
import lombok.Data;
@ -23,7 +23,7 @@ public class SysTenantVo {
*/
private String name;
private MsProperties properties;
private MmsAdminProperties properties;
private String revision;
}

View File

@ -27,4 +27,11 @@ public interface SysConfigService extends BaseService<SysConfig, SysConfigVo, Sy
Boolean initEmail();
Boolean initWx();
/**
* 查询项目列表
* @param size 数量
* @return 数据
*/
List<SysConfigVo> selectEventList(int size);
}

View File

@ -3,8 +3,9 @@ package com.sxpcwlkj.system.service;
import com.sxpcwlkj.framework.sercice.BaseService;
import com.sxpcwlkj.system.entity.SysDept;
import com.sxpcwlkj.system.entity.bo.SysDeptBo;
import com.sxpcwlkj.system.entity.vo.SysDeptVo;
import com.sxpcwlkj.system.entity.export.SysDeptExport;
import com.sxpcwlkj.system.entity.vo.SysDeptVo;
import java.util.List;
import java.util.Set;

View File

@ -45,4 +45,10 @@ public interface SysFunctionService {
List<AdminMenuTree> getAllMenuTree();
/**
* 快捷菜单
* @param size 查询数量
* @return 数据
*/
List<SysFunctionVo> selectIsFast(int size);
}

View File

@ -3,9 +3,9 @@ package com.sxpcwlkj.system.service;
import com.sxpcwlkj.framework.sercice.BaseService;
import com.sxpcwlkj.system.entity.SysNotice;
import com.sxpcwlkj.system.entity.bo.SysNoticeBo;
import com.sxpcwlkj.system.entity.vo.SysNoticeVo;
import com.sxpcwlkj.system.entity.export.SysNoticeExport;
import java.util.List;
import com.sxpcwlkj.system.entity.vo.SysNoticeVo;
import java.util.Set;
/**
@ -22,4 +22,6 @@ public interface SysNoticeService extends BaseService<SysNotice, SysNoticeVo, Sy
* @return true成功 false 失败
*/
Boolean imports(Set<SysNoticeExport> list);
Long selectTool();
}

View File

@ -182,4 +182,6 @@ public interface SysUserService {
* @return true成功 false 失败
*/
boolean bindingOpenId(String openId);
Long selectTool();
}

View File

@ -9,6 +9,7 @@ import com.sxpcwlkj.common.code.entity.CaptchaEntity;
import com.sxpcwlkj.common.code.entity.ConfigEntity;
import com.sxpcwlkj.common.constant.Constants;
import com.sxpcwlkj.common.enums.ConfigKeyNum;
import com.sxpcwlkj.common.enums.SystemCommonEnum;
import com.sxpcwlkj.common.properties.CaptchaProperties;
import com.sxpcwlkj.common.utils.DataUtil;
import com.sxpcwlkj.redis.RedisUtil;
@ -22,6 +23,7 @@ import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
@Slf4j
@ -39,18 +41,18 @@ public class CaptchaServiceImpl implements CaptchaService {
// msg验证码未开启
List<ConfigEntity> convert = RedisUtil.getCacheList(ConfigKeyNum.config_base.getKey());
AtomicBoolean isOpen= new AtomicBoolean(false);
Map<String, Object> map = new HashMap<>();
if(convert.isEmpty()){
return data;
}
convert.forEach(smsConfigEntity -> {
if("sys_base_captcha_state".equals(smsConfigEntity.getConfigKey())){
if(Convert.toInt(smsConfigEntity.getConfigValue()) == 1){
if(Objects.equals(Convert.toInt(smsConfigEntity.getConfigValue()), SystemCommonEnum.SYS_COMMON_STATE_OPEN.getValue())){
isOpen.set(true);
}
}
});
if (!captchaProperties.isStatus()||!isOpen.get()) {
if (!isOpen.get()) {
data.put(CaptchaEntity.CODE.CAPTCHA_MSG.getValue(), "系统验证码未开启!");
return data;
}
@ -70,7 +72,7 @@ public class CaptchaServiceImpl implements CaptchaService {
//初始化验证码背景
if (!code.equals("000000")) {
if (!"000000".equals(code)) {
switch (captchaProperties.getType()) {
case "LINE":

View File

@ -5,7 +5,6 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sxpcwlkj.common.code.entity.ConfigEntity;
import com.sxpcwlkj.common.constant.CacheConstants;
import com.sxpcwlkj.common.enums.ConfigKeyNum;
import com.sxpcwlkj.common.enums.SystemCommonEnum;
import com.sxpcwlkj.common.exception.MmsException;
@ -139,7 +138,14 @@ public class SysConfigServiceImpl extends BaseServiceImpl<SysConfig, SysConfigVo
LambdaQueryWrapper<SysConfig> wrapper = Wrappers.lambdaQuery();
wrapper.like(StringUtil.isNotEmpty(query.getConfigName()), SysConfig::getConfigName, query.getConfigName());
wrapper.eq(StringUtil.isNotEmpty(query.getConfigKey()), SysConfig::getConfigKey, query.getConfigKey());
wrapper.eq(StringUtil.isNotEmpty(query.getConfigType()), SysConfig::getConfigType, query.getConfigType());
if(StringUtil.isNotEmpty(query.getConfigType())&&query.getConfigType()==2){
//查询 configType=2 自定义 or configType=3 项目
wrapper.or().eq(SysConfig::getConfigType,2);
wrapper.or().eq(SysConfig::getConfigType,3);
}else {
wrapper.eq(StringUtil.isNotEmpty(query.getConfigType()), SysConfig::getConfigType, query.getConfigType());
}
wrapper.eq(StringUtil.isNotEmpty(query.getStatus()), SysConfig::getStatus, query.getStatus());
return wrapper;
}
@ -173,7 +179,7 @@ public class SysConfigServiceImpl extends BaseServiceImpl<SysConfig, SysConfigVo
if (bo.getConfigKey() == null || bo.getConfigKey().isEmpty()) {
continue;
}
bo.setStatus(0);
bo.setStatus(SystemCommonEnum.SYS_COMMON_STATE_OPEN.getValue());
bo.setConfigType(1);
this.insert(bo);
} else {
@ -254,4 +260,12 @@ public class SysConfigServiceImpl extends BaseServiceImpl<SysConfig, SysConfigVo
RedisUtil.expire(ConfigKeyNum.config_wx.getKey(), Duration.ofDays(99999999));
return true;
}
@Override
public List<SysConfigVo> selectEventList(int size) {
return baseMapper.selectVoList(new LambdaQueryWrapper<SysConfig>()
.eq(SysConfig::getConfigType,3)
.last("LIMIT "+size)
);
}
}

View File

@ -4,8 +4,8 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sxpcwlkj.common.enums.SystemCommonEnum;
import com.sxpcwlkj.common.utils.MapstructUtil;
import com.sxpcwlkj.common.utils.DataUtil;
import com.sxpcwlkj.common.utils.MapstructUtil;
import com.sxpcwlkj.common.utils.StringUtil;
import com.sxpcwlkj.datasource.entity.page.PageQuery;
import com.sxpcwlkj.datasource.entity.page.TableDataInfo;
@ -13,19 +13,20 @@ import com.sxpcwlkj.datasource.mapper.BaseMapperPlus;
import com.sxpcwlkj.framework.sercice.impl.BaseServiceImpl;
import com.sxpcwlkj.system.entity.SysDept;
import com.sxpcwlkj.system.entity.bo.SysDeptBo;
import com.sxpcwlkj.system.entity.vo.SysDeptVo;
import com.sxpcwlkj.system.entity.export.SysDeptExport;
import com.sxpcwlkj.system.entity.vo.SysDeptVo;
import com.sxpcwlkj.system.mapper.SysDeptMapper;
import com.sxpcwlkj.system.service.SysDeptService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.Serializable;
import java.util.Set;
import java.util.ArrayList;
import java.util.List;
import java.util.Collections;
import java.util.List;
import java.util.Set;
/**
* 系统部门-接口实现
*

View File

@ -69,7 +69,7 @@ public class SysDictServiceImpl implements SysDictService {
vos = new ArrayList<>();
SysDictDataVo sysDictDataVo = new SysDictDataVo();
sysDictDataVo.setDictType("0");
sysDictDataVo.setStatus("0");
sysDictDataVo.setStatus(SystemCommonEnum.SYS_COMMON_STATE_OPEN.getValue());
vos.add(sysDictDataVo);
}
sysDictVo.setList(vos);
@ -124,12 +124,12 @@ public class SysDictServiceImpl implements SysDictService {
@Override
public Integer initSysDict(String code) {
List<SysDict> dicts = baseMapper.selectList(new LambdaQueryWrapper<SysDict>().eq(SysDict::getStatus, 0).orderByAsc(SysDict::getSort));
List<SysDict> dicts = baseMapper.selectList(new LambdaQueryWrapper<SysDict>().eq(SysDict::getStatus, SystemCommonEnum.SYS_COMMON_STATE_OPEN.getValue()).orderByAsc(SysDict::getSort));
int i = 0;
for (SysDict d : dicts) {
List<SysDictData> data = sysDictDataMapper.selectList(new LambdaQueryWrapper<SysDictData>()
.eq(SysDictData::getFieldName, d.getFieldName())
.eq(SysDictData::getStatus, 0)
.eq(SysDictData::getStatus, SystemCommonEnum.SYS_COMMON_STATE_OPEN.getValue())
.orderByAsc(SysDictData::getSort)
);
RedisUtil.deleteObject(CacheConstants.SYS_DICT_KEY + d.getFieldName());
@ -146,12 +146,14 @@ public class SysDictServiceImpl implements SysDictService {
@Override
public List<SysDictDataVo> getSysDictByCode(String code) {
return sysDictDataMapper.selectVoList(new LambdaQueryWrapper<SysDictData>().eq(SysDictData::getFieldName, code)
.eq(SysDictData::getStatus, 0).orderByAsc(SysDictData::getSort));
.eq(SysDictData::getStatus, SystemCommonEnum.SYS_COMMON_STATE_OPEN.getValue()).orderByAsc(SysDictData::getSort));
}
@Override
public List<Map<String, Object>> selectAll() {
List<SysDictVo> dataVos = baseMapper.selectVoList(new LambdaQueryWrapper<SysDict>().eq(SysDict::getStatus, 0).orderByAsc(SysDict::getSort));
List<SysDictVo> dataVos = baseMapper.selectVoList(new LambdaQueryWrapper<SysDict>()
.eq(SysDict::getStatus, SystemCommonEnum.SYS_COMMON_STATE_OPEN.getValue())
.orderByAsc(SysDict::getSort));
List<Map<String, Object>> end = new ArrayList<>();
for (SysDictVo dict : dataVos) {

View File

@ -17,9 +17,7 @@ import org.springframework.stereotype.Service;
import java.util.*;
/**
* @Description TODO
* @Author sxpcwlkj
* @Version v1.0.0
* 系统菜单
*/
@RequiredArgsConstructor
@Service("sysFunction")
@ -86,6 +84,15 @@ public class SysFunctionServiceImpl implements SysFunctionService {
return getAdminMenuTree(functionVos, "0");
}
@Override
public List<SysFunctionVo> selectIsFast(int size) {
return baseMapper.selectVoList(new LambdaQueryWrapper<SysFunction>()
.eq(SysFunction::getIsFast, 1)
.ne(SysFunction::getComponent,"")
.last("LIMIT "+size)
);
}
/**
* 资源格式化
*

View File

@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.sxpcwlkj.authority.LoginObject;
import com.sxpcwlkj.common.code.entity.CaptchaEntity;
import com.sxpcwlkj.common.enums.DeviceEnum;
import com.sxpcwlkj.common.enums.SystemCommonEnum;
import com.sxpcwlkj.common.exception.LoginException;
import com.sxpcwlkj.common.exception.MmsException;
import com.sxpcwlkj.common.exception.TenantException;
@ -13,7 +14,6 @@ import com.sxpcwlkj.common.utils.IPUtil;
import com.sxpcwlkj.common.utils.StringUtil;
import com.sxpcwlkj.framework.utils.SignUtil;
import com.sxpcwlkj.redis.RedisUtil;
import com.sxpcwlkj.redis.constant.RedisConstant;
import com.sxpcwlkj.system.entity.SysTenant;
import com.sxpcwlkj.system.entity.SysUser;
import com.sxpcwlkj.system.entity.bo.LoginBodyBo;
@ -27,13 +27,11 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.time.Duration;
import java.util.Date;
import java.util.Map;
/**
* @ClassName SysLoginServiceImpl
* @Description TODO
* 系统登录
* @Author mmsAdmin
* @Date 2022/12/25 12:06
*/
@ -64,7 +62,7 @@ public class SysLoginServiceImpl implements SysLoginService {
throw new LoginException("账号不存在!");
}
// 账号是否禁用
if (sysUser.getStatus() != 0) {
if (!sysUser.getStatus().equals(SystemCommonEnum.SYS_COMMON_STATE_OPEN.getValue())) {
throw new LoginException("账号已禁用!");
}
//解密数据库的密码
@ -123,7 +121,7 @@ public class SysLoginServiceImpl implements SysLoginService {
/**
* 验证租户
*
* @param sysUser
* @param sysUser 用户
*/
@Override
public void verfyTenement(SysUser sysUser) {
@ -134,7 +132,7 @@ public class SysLoginServiceImpl implements SysLoginService {
log.info("登录用户ID{} 租户不存在.", sysUser.getUserId());
throw new TenantException("tenant.not.exists");
}
if (sysTenant.getStatus() != 0) {
if (!sysTenant.getStatus().equals(SystemCommonEnum.SYS_COMMON_STATE_OPEN.getValue())) {
log.info("登录用户ID{} 租户状态为禁用.", sysUser.getUserId());
throw new TenantException("tenant off state");
}

View File

@ -4,8 +4,8 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sxpcwlkj.common.enums.SystemCommonEnum;
import com.sxpcwlkj.common.utils.MapstructUtil;
import com.sxpcwlkj.common.utils.DataUtil;
import com.sxpcwlkj.common.utils.MapstructUtil;
import com.sxpcwlkj.common.utils.StringUtil;
import com.sxpcwlkj.datasource.entity.page.PageQuery;
import com.sxpcwlkj.datasource.entity.page.TableDataInfo;
@ -13,19 +13,19 @@ import com.sxpcwlkj.datasource.mapper.BaseMapperPlus;
import com.sxpcwlkj.framework.sercice.impl.BaseServiceImpl;
import com.sxpcwlkj.system.entity.SysNotice;
import com.sxpcwlkj.system.entity.bo.SysNoticeBo;
import com.sxpcwlkj.system.entity.vo.SysNoticeVo;
import com.sxpcwlkj.system.entity.export.SysNoticeExport;
import com.sxpcwlkj.system.entity.vo.SysNoticeVo;
import com.sxpcwlkj.system.mapper.SysNoticeMapper;
import com.sxpcwlkj.system.service.SysNoticeService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.Serializable;
import java.util.Set;
import java.util.ArrayList;
import java.util.List;
import java.util.Collections;
import java.util.Set;
/**
* 系统公告-接口实现
*
@ -96,4 +96,9 @@ public class SysNoticeServiceImpl extends BaseServiceImpl<SysNotice, SysNoticeVo
public Boolean imports(Set<SysNoticeExport> list) {
return true;
}
@Override
public Long selectTool() {
return baseMapper.selectCount(new LambdaQueryWrapper<SysNotice>().eq(SysNotice::getStatus, SystemCommonEnum.SYS_COMMON_STATE_OPEN.getValue()));
}
}

View File

@ -30,7 +30,6 @@ import java.io.Serializable;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
@ -124,6 +123,7 @@ public class SysOssConfigServiceImpl extends BaseServiceImpl<SysOssConfig, SysOs
baseMapper.update(null, new LambdaUpdateWrapper<SysOssConfig>().set(SysOssConfig::getStatus, SystemCommonEnum.SYS_COMMON_STATE_CLOSE.getValue()).eq(SysOssConfig::getStatus, SystemCommonEnum.SYS_COMMON_STATE_OPEN.getValue()));
}
bo.setId(configVo.getId());
bo.setRevision(configVo.getRevision());
row = baseMapper.updateById(MapstructUtil.convert(bo, SysOssConfig.class));
} else {
if (bo.getStatus().toString().equals(SystemCommonEnum.SYS_COMMON_STATE_OPEN.getValue().toString()) ) {
@ -142,7 +142,7 @@ public class SysOssConfigServiceImpl extends BaseServiceImpl<SysOssConfig, SysOs
@Override
public List<FileStorageConfig> getOss() {
//
List<SysOssConfigVo> vos = baseMapper.selectVoList(new LambdaQueryWrapper<SysOssConfig>().orderByAsc(SysOssConfig::getStatus));
List<SysOssConfigVo> vos = baseMapper.selectVoList(new LambdaQueryWrapper<SysOssConfig>().orderByDesc(SysOssConfig::getStatus));
List<FileStorageConfig> list = new ArrayList<>();
for (SysOssConfigVo configVo : vos) {
if (configVo != null) {

View File

@ -103,7 +103,7 @@ public class SysRoleServiceImpl implements SysRoleService {
SysRoleFunction roleFunction = new SysRoleFunction();
roleFunction.setRoleId(bo.getId());
roleFunction.setFunctionId(aLong);
roleFunction.setStatus(1);
roleFunction.setStatus(SystemCommonEnum.SYS_COMMON_STATE_OPEN.getValue());
sysRoleFunctionMapper.insert(roleFunction);
}
}
@ -129,7 +129,7 @@ public class SysRoleServiceImpl implements SysRoleService {
SysRoleFunction role = new SysRoleFunction();
role.setRoleId(roleId);
role.setFunctionId(sysRoleFunction.getParentId());
role.setStatus(0);
role.setStatus(SystemCommonEnum.SYS_COMMON_STATE_OPEN.getValue());
sysRoleFunctionMapper.insert(role);
checkFunction(sysRoleFunction.getParentId(), roleId);
}

View File

@ -25,7 +25,10 @@ import com.sxpcwlkj.system.entity.bo.ResetPwdSuperBo;
import com.sxpcwlkj.system.entity.bo.SetUserRoleSuperBo;
import com.sxpcwlkj.system.entity.bo.SysUserBo;
import com.sxpcwlkj.system.entity.export.SysUserExportVo;
import com.sxpcwlkj.system.entity.vo.*;
import com.sxpcwlkj.system.entity.vo.SysDeptVo;
import com.sxpcwlkj.system.entity.vo.SysFunctionVo;
import com.sxpcwlkj.system.entity.vo.SysRoleVo;
import com.sxpcwlkj.system.entity.vo.SysUserVo;
import com.sxpcwlkj.system.mapper.*;
import com.sxpcwlkj.system.service.SysDeptService;
import com.sxpcwlkj.system.service.SysUserService;
@ -192,7 +195,7 @@ public class SysUserServiceImpl implements SysUserService {
// 账号查询
.like(StringUtil.isNotEmpty(bo.getUserName()), "u.user_name", bo.getUserName())
// 账号状态
.eq(StringUtil.isNotEmpty(bo.getStatus()), "u.status", bo.getStatus())
// .eq(StringUtil.isNotEmpty(bo.getStatus()), "u.status", bo.getStatus())
// 手机号
.like(StringUtil.isNotEmpty(bo.getPhoneNumber()), "u.phonenumber", bo.getPhoneNumber())
.and(ObjectUtil.isNotNull(bo.getDeptId()), w -> {
@ -255,8 +258,11 @@ public class SysUserServiceImpl implements SysUserService {
//资源集
userVo.setButCodes(list.toArray(String[]::new));
//===================超级管理员拥有所有==========================
if (userVo.getUserId().toString().equals(SystemCommonEnum.SUPER_ADMIN.getValue().toString())) {
sysRoles = sysRoleMapper.selectList(new LambdaQueryWrapper<SysRole>().eq(SysRole::getCode, SystemCommonEnum.SYS_COMMON_STATE_OPEN.getValue()).like(SysRole::getCode, SystemCommonEnum.SUPER_ADMIN.getCode()).orderByAsc(SysRole::getSort).last("LIMIT 1"));
if (userVo.getUserId().equals(SystemCommonEnum.SUPER_ADMIN.getValue().toString())) {
sysRoles = sysRoleMapper.selectList(new LambdaQueryWrapper<SysRole>()
.eq(SysRole::getStatus, SystemCommonEnum.SYS_COMMON_STATE_OPEN.getValue())
.like(SysRole::getCode, SystemCommonEnum.SUPER_ADMIN.getCode())
.orderByAsc(SysRole::getSort).last("LIMIT 1"));
sysRoleVos = BeanCopyUtil.convert(sysRoles, SysRoleVo.class);
List<SysFunction> functionList = sysFunctionMapper.selectList(new LambdaQueryWrapper<SysFunction>().eq(SysFunction::getStatus, SystemCommonEnum.SYS_COMMON_STATE_OPEN.getValue()).orderByAsc(SysFunction::getSort));
@ -442,6 +448,11 @@ public class SysUserServiceImpl implements SysUserService {
return baseMapper.update(null, new LambdaUpdateWrapper<SysUser>().set(SysUser::getWxOpenid, openId).eq(SysUser::getUserId, LoginObject.getLoginId())) > 0;
}
@Override
public Long selectTool() {
return baseMapper.selectCount(new LambdaQueryWrapper<SysUser>().eq(SysUser::getStatus, SystemCommonEnum.SYS_COMMON_STATE_OPEN.getValue()));
}
@Override
public List<AdminMenuTree> getAdminMenuTree(String userId) {

View File

@ -1,8 +1,3 @@
--- # 项目基础信息
sxpcwlkj:
# 开启验证码: true开启 false 关闭
isOpenCaptcha: false
--- # powerjob 配置
powerjob:
worker:
@ -10,7 +5,6 @@ powerjob:
enabled: false
# 需要先在 powerjob 登录页执行应用注册后才能使用
app-name: mms
enable-test-mode: false
max-appended-wf-context-length: 4096
max-result-length: 4096
# 28080 端口 随着主应用端口飘逸 避免集群冲突
@ -44,42 +38,45 @@ spring:
primary: master
# 严格模式 匹配不到数据源则报错
strict: true
public-key: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJssgtfcBfc+d8Et0FBGQRBonRRQBD8jB1UHTRbk3diOliGlec9lJxbGR/qp7Jp8uYozCr96lvpnIIJM59fNoeUCAwEAAQ==
# 账号密码
datasource:
# 主库数据源
master:
type: ${spring.datasource.type}
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mms?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
username: root
password: 123456
# 从库数据源
slave:
lazy: true
type: ${spring.datasource.type}
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mms?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
username: root
password: 123456
# oracle:
# type: ${spring.datasource.type}
# driverClassName: oracle.jdbc.OracleDriver
# url: jdbc:oracle:thin:@//localhost:1521/XE
# username: ROOT
# password: root
# hikari:
# connectionTestQuery: SELECT 1 FROM DUAL
# postgres:
# type: ${spring.datasource.type}
# driverClassName: org.postgresql.Driver
# url: jdbc:postgresql://localhost:5432/postgres?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true
# username: root
# password: root
# sqlserver:
# type: ${spring.datasource.type}
# driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
# url: jdbc:sqlserver://localhost:1433;DatabaseName=tempdb;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true
# username: SA
# password: root
url: jdbc:mysql://119.28.10.247:3306/mms?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
username: mms
# 由GeneratePassword.java 生成, public-key 和 password 要匹配
password: ENC(c6FYwkk1dtKxfAcOED4g4mAgzCoK6XTr6+VTXVfQYly9I02yiND8aK5vTeYJ+oJCGH4beQyZLl9H2kt1ZCXqJg==)
# # 从库数据源
# slave:
# lazy: true
# type: ${spring.datasource.type}
# driverClassName: com.mysql.cj.jdbc.Driver
# url: jdbc:mysql://localhost:3306/mms?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
# username: root
# password: 123456
# oracle:
# type: ${spring.datasource.type}
# driverClassName: oracle.jdbc.OracleDriver
# url: jdbc:oracle:thin:@//localhost:1521/XE
# username: ROOT
# password: root
# hikari:
# connectionTestQuery: SELECT 1 FROM DUAL
# postgres:
# type: ${spring.datasource.type}
# driverClassName: org.postgresql.Driver
# url: jdbc:postgresql://localhost:5432/postgres?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true
# username: root
# password: root
# sqlserver:
# type: ${spring.datasource.type}
# driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
# url: jdbc:sqlserver://localhost:1433;DatabaseName=tempdb;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true
# username: SA
# password: root
hikari:
# 最大连接池数量
maxPoolSize: 20

View File

@ -1,8 +1,3 @@
--- # 项目基础信息
sxpcwlkj:
# 开启验证码: true开启 false 关闭
isOpenCaptcha: false
--- # powerjob 配置
powerjob:
worker:
@ -43,8 +38,7 @@ spring:
primary: master
# 严格模式 匹配不到数据源则报错
strict: true
# 账号加密,公钥
# 账号密码
datasource:
# 主库数据源
master:

View File

@ -1,8 +1,3 @@
--- # 项目基础信息
sxpcwlkj:
# 开启验证码: true开启 false 关闭
isOpenCaptcha: true
--- # powerjob 配置
powerjob:
worker:
@ -10,7 +5,6 @@ powerjob:
enabled: false
# 需要先在 powerjob 登录页执行应用注册后才能使用
app-name: mms
enable-test-mode: false
max-appended-wf-context-length: 4096
max-result-length: 4096
# 28080 端口 随着主应用端口飘逸 避免集群冲突

View File

@ -1,7 +1,7 @@
--- # 项目基础信息
sxpcwlkj:
#名称
name: MMS
name: mmsAdmin
#描述
describe: 一款多模块化管理系统Modular management system简称MMS是一款基于多应用模块用户、商品、支付、订单、分销、日志、定时、通信、直播、广告、文章等多模块应用开源系统可快速的应用与各类项目研发中定期更新功能修复、上新、技术栈分享 (十年磨一剑,我们的目标是做最优价值的开源项目)
#版本
@ -12,23 +12,20 @@ sxpcwlkj:
copyrightYear: 2018
# 机构团队
organization: 陕西品创网络
# 开启验证码: true开启 false 关闭
isOpenCaptcha: false
# 演示模式配置
demo:
mode:
enabled: false # 默认开启演示模式
enabled: true # 默认开启演示模式
message-template: "演示模式下禁止{operation}操作 [实体: {entity}, 方法: {method}]"
allowed-users: # 白名单用户
- admin
allowed-methods:
- initSign
- updateIpById
--- # 验证码配置
captcha:
# 是否开启验证码: true 开启 false 关闭
status: true
# 页面 <参数设置> 可开启关闭 验证码校验
# 线段干扰 LINE 圆圈干扰 CIRCLE 扭曲干扰 SHEAR 计算题型 CALCULATE
type: LINE

View File

@ -5,36 +5,36 @@
#菜单
INSERT INTO `sys_function`(`parent_id`,`path`,`name`,`component`,`language_code`,`type`,`sort`,`icon`,`status`,`visible`,`is_iframe`,`is_open_link`,`is_link`,`keep_alive`,`always_show`,`tenant_id`,`created_time`,`updated_time`,`revision`)
values (${menuId},'/${moduleName}/${functionName}','${tableComment}','${moduleName}/${functionName}/index','${tableComment}',1,1,'',0,-1,-1,-1,'',1,-1,'000000',${dbTime},${dbTime},1);
values (${menuId},'/${moduleName}/${functionName}','${tableComment}','${moduleName}/${functionName}/index','${tableComment}',1,1,'',1,-1,-1,-1,'',1,-1,'000000',${dbTime},${dbTime},1);
#列表
INSERT INTO `sys_function`(`parent_id`,`name`,`permission`,`type`,`sort`,`status`,`tenant_id`,`created_time`,`updated_time`,`revision`)
values ((SELECT `min_id` FROM (SELECT MAX(id) AS min_id FROM `sys_function` WHERE `name` = '${tableComment}') AS a),'${tableComment}-列表','${moduleName}:${functionName}:list',2,2,0,'000000',${dbTime},${dbTime},1);
values ((SELECT `min_id` FROM (SELECT MAX(id) AS min_id FROM `sys_function` WHERE `name` = '${tableComment}') AS a),'${tableComment}-列表','${moduleName}:${functionName}:list',2,2,1,'000000',${dbTime},${dbTime},1);
#新增
INSERT INTO `sys_function`(`parent_id`,`name`,`permission`,`type`,`sort`,`status`,`tenant_id`,`created_time`,`updated_time`,`revision`)
values ((SELECT `min_id` FROM (SELECT MAX(id) AS min_id FROM `sys_function` WHERE `name` = '${tableComment}') AS a),'${tableComment}-新增','${moduleName}:${functionName}:insert',2,3,0,'000000',${dbTime},${dbTime},1);
values ((SELECT `min_id` FROM (SELECT MAX(id) AS min_id FROM `sys_function` WHERE `name` = '${tableComment}') AS a),'${tableComment}-新增','${moduleName}:${functionName}:insert',2,3,1,'000000',${dbTime},${dbTime},1);
#删除
INSERT INTO `sys_function`(`parent_id`,`name`,`permission`,`type`,`sort`,`status`,`tenant_id`,`created_time`,`updated_time`,`revision`)
values ((SELECT `min_id` FROM (SELECT MAX(id) AS min_id FROM `sys_function` WHERE `name` = '${tableComment}') AS a),'${tableComment}-删除','${moduleName}:${functionName}:delete',2,4,0,'000000',${dbTime},${dbTime},1);
values ((SELECT `min_id` FROM (SELECT MAX(id) AS min_id FROM `sys_function` WHERE `name` = '${tableComment}') AS a),'${tableComment}-删除','${moduleName}:${functionName}:delete',2,4,1,'000000',${dbTime},${dbTime},1);
#编辑
INSERT INTO `sys_function`(`parent_id`,`name`,`permission`,`type`,`sort`,`status`,`tenant_id`,`created_time`,`updated_time`,`revision`)
values ((SELECT `min_id` FROM (SELECT MAX(id) AS min_id FROM `sys_function` WHERE `name` = '${tableComment}') AS a),'${tableComment}-编辑','${moduleName}:${functionName}:edit',2,5,0,'000000',${dbTime},${dbTime},1);
values ((SELECT `min_id` FROM (SELECT MAX(id) AS min_id FROM `sys_function` WHERE `name` = '${tableComment}') AS a),'${tableComment}-编辑','${moduleName}:${functionName}:edit',2,5,1,'000000',${dbTime},${dbTime},1);
#查询
INSERT INTO `sys_function`(`parent_id`,`name`,`permission`,`type`,`sort`,`status`,`tenant_id`,`created_time`,`updated_time`,`revision`)
values ((SELECT `min_id` FROM (SELECT MAX(id) AS min_id FROM `sys_function` WHERE `name` = '${tableComment}') AS a),'${tableComment}-查询','${moduleName}:${functionName}:query',2,6,0,'000000',${dbTime},${dbTime},1);
values ((SELECT `min_id` FROM (SELECT MAX(id) AS min_id FROM `sys_function` WHERE `name` = '${tableComment}') AS a),'${tableComment}-查询','${moduleName}:${functionName}:query',2,6,1,'000000',${dbTime},${dbTime},1);
#导入
INSERT INTO `sys_function`(`parent_id`,`name`,`permission`,`type`,`sort`,`status`,`tenant_id`,`created_time`,`updated_time`,`revision`)
values ((SELECT `min_id` FROM (SELECT MAX(id) AS min_id FROM `sys_function` WHERE `name` = '${tableComment}') AS a),'${tableComment}-导入','${moduleName}:${functionName}:import',2,6,0,'000000',${dbTime},${dbTime},1);
values ((SELECT `min_id` FROM (SELECT MAX(id) AS min_id FROM `sys_function` WHERE `name` = '${tableComment}') AS a),'${tableComment}-导入','${moduleName}:${functionName}:import',2,7,1,'000000',${dbTime},${dbTime},1);
#导出
INSERT INTO `sys_function`(`parent_id`,`name`,`permission`,`type`,`sort`,`status`,`tenant_id`,`created_time`,`updated_time`,`revision`)
values ((SELECT `min_id` FROM (SELECT MAX(id) AS min_id FROM `sys_function` WHERE `name` = '${tableComment}') AS a),'${tableComment}-导出','${moduleName}:${functionName}:export',2,6,0,'000000',${dbTime},${dbTime},1);
values ((SELECT `min_id` FROM (SELECT MAX(id) AS min_id FROM `sys_function` WHERE `name` = '${tableComment}') AS a),'${tableComment}-导出','${moduleName}:${functionName}:export',2,8,1,'000000',${dbTime},${dbTime},1);
#打印
INSERT INTO `sys_function`(`parent_id`,`name`,`permission`,`type`,`sort`,`status`,`tenant_id`,`created_time`,`updated_time`,`revision`)
values ((SELECT `min_id` FROM (SELECT MAX(id) AS min_id FROM `sys_function` WHERE `name` = '${tableComment}') AS a),'${tableComment}-打印','${moduleName}:${functionName}:print',2,6,0,'000000',${dbTime},${dbTime},1);
values ((SELECT `min_id` FROM (SELECT MAX(id) AS min_id FROM `sys_function` WHERE `name` = '${tableComment}') AS a),'${tableComment}-打印','${moduleName}:${functionName}:print',2,9,1,'000000',${dbTime},${dbTime},1);

View File

@ -3,14 +3,14 @@ import {getEnv} from "/@/utils/mms";
import {AxiosPromise} from "axios";
import {SysEnum} from "/@/enums/SysEnum";
import {EncryptTypeEnum} from "/@/enums/EncryptTypeEnum";
import {${FunctionName}Bo,${FunctionName}Vo,${FunctionName}Table } from '/@/views/${moduleName}/${functionName}/type';
import {${FunctionName}Bo,${FunctionName}Vo} from '/@/views/${moduleName}/${functionName}/type';
/**
* ${tableComment}-Api
* ${FunctionName}
*/
export function ${functionName}Api() {
return {
list: (params?: object): AxiosPromise<${FunctionName}Vo[]> => {
list: (params?: object): AxiosPromise<Array<${FunctionName}Vo>> => {
return request({
url: getEnv()+'/${moduleName}/${functionName}/list',
method: 'post',

View File

@ -133,26 +133,35 @@
</template>
//ModuleName ${tableComment}
<script setup lang="ts" name="${moduleName}${FunctionName}Dialog">
import { reactive, ref, nextTick } from "vue";
import { CURDEnum } from '/@/enums/CURDEnum';
import {${FunctionName}Bo,${FunctionName}Vo } from '/@/views/${moduleName}/${functionName}/type';
import {nextTick, reactive, ref} from "vue";
import {CURDEnum} from '/@/enums/CURDEnum';
import {ElMessage} from "element-plus";
import {${FunctionName}Bo, ${FunctionName}Vo} from '/@/views/${moduleName}/${functionName}/type';
<#if formLayout==2 >
import {${functionName}Api} from '/@/views/${moduleName}/${functionName}';
const baseApi = ${functionName}Api();
</#if>
const dialogWidth = ref('50vw');
<#list fastList as field>
<#if field == 'editor'>
dialogWidth.value = '75vw';
import FastEditor from "/@/components/fast-editor/src/fast-editor.vue";
import FastEditor from '/@/components/fast-editor/src/fast-editor.vue';
<#elseif field == 'select'>
import FastSelect from "/@/components/fast-select/src/fast-select.vue";
import FastSelect from '/@/components/fast-select/src/fast-select.vue';
<#elseif field == 'file'>
import FastFile from "/@/components/fast-upload/file.vue";
import FastFile from "/@/components/fast-upload/file.vue"
<#elseif field == 'image'>
import FastImg from "/@/components/fast-upload/img.vue";
import FastImg from "/@/components/fast-upload/img.vue"
<#elseif field == 'images'>
import FastImgs from "/@/components/fast-upload/imgs.vue";
import FastImgs from "/@/components/fast-upload/imgs.vue"
<#elseif field == 'radio'>
import FastSwitch from "/@/components/fast-switch/src/fast-switch.vue";
</#if>
</#list>
// 定义子组件向父组件传值/事件
const emit = defineEmits(['refresh']);
const dialogFormRef = ref();
@ -175,7 +184,9 @@
<#list fieldList as field>
<#if !field.baseField||field.attrName =='status'||field.attrName =='sort'||field.attrName =='remark'>
<#if field.fieldType == 'int'>
<#if field.attrName =='sort'>
<#if field.attrName =='status'>
${field.attrName}: 1<#sep>,
<#elseif field.attrName =='sort'>
${field.attrName}: 1<#sep>,
<#else>
${field.attrName}: 0<#sep>,
@ -236,7 +247,7 @@
}
<#if formLayout==2 >
// 选择监听
const change = (arr: number[]) => {
const change = (arr: string[]) => {
state.ruleForm.${tableParentId} = arr[arr.length - 1];
};
</#if>

View File

@ -184,18 +184,18 @@
</template>
//ModuleName ${tableComment}
<script setup lang="ts" name="${moduleName}${FunctionName}">
import { defineAsyncComponent, reactive, onMounted, ref } from "vue";
import { ElMessageBox, ElMessage } from "element-plus";
import { CURDEnum } from "/@/enums/CURDEnum";
import { isEmpty, generateUUID } from "/@/utils/mms";
import {defineAsyncComponent, onMounted, reactive, ref} from "vue";
import {ElMessage, ElMessageBox} from "element-plus";
import {CURDEnum} from "/@/enums/CURDEnum";
import {generateUUID, isEmpty} from "/@/utils/mms";
import {NextLoading} from "/@/utils/loading";
import FastSelect from "/@/components/fast-select/src/fast-select.vue";
import {${FunctionName}Bo, ${FunctionName}Vo} from '/@/views/${moduleName}/${functionName}/type';
import {${functionName}Api} from '/@/views/${moduleName}/${functionName}';
import {${FunctionName}Bo,${FunctionName}Vo } from '/@/views/${moduleName}/${functionName}/type';
const baseApi = ${functionName}Api();
<#list formList as field>
<#if field.formDict??>
import FastTableColumn from "/@/components/fast-table-column";
<#break>
</#if>
</#list>
@ -227,7 +227,7 @@
</#if>
</#list>
<#if formLayout==2 >
,isAll:true,
isAll:true,
</#if>
}
}

View File

@ -15,7 +15,7 @@ export declare interface ${FunctionName}Vo extends BaseEntity {
||field.attrName == 'createdTime'
||field.attrName == 'updatedBy'
||field.attrName == 'updatedTime')>
${field.attrName}: string|number<#sep>; </#sep>
${field.attrName}: <#if field.attrType=='Integer'>number</#if><#if field.attrType!='Integer'>string</#if><#sep>; </#sep>
</#if>
</#list>
<#if formLayout==2 >
@ -39,7 +39,7 @@ export declare interface ${FunctionName}Bo extends BaseEntity {
||field.attrName == 'createdTime'
||field.attrName == 'updatedBy'
||field.attrName == 'updatedTime')>
${field.attrName}: string|number<#sep>; </#sep>
${field.attrName}: <#if field.attrType=='Integer'>number</#if><#if field.attrType!='Integer'>string</#if><#sep>; </#sep>
</#if>
</#list>
<#if formLayout==2 >

@ -1 +1 @@
Subproject commit 0a89ee7b792944d17e835c331e6077dfa0862ba9
Subproject commit 840ab9fcab2e6c913a8d07b160bf02bb4390243a

View File

@ -1,24 +1,16 @@
package com.sxpcwlkj.ai.service;
import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.sxpcwlkj.ai.type.AIProvider;
import com.sxpcwlkj.ai.utils.DequeUtil;
import com.sxpcwlkj.ai.utils.FileParserUtil;
import com.sxpcwlkj.common.utils.DataUtil;
import com.sxpcwlkj.common.utils.IPUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import okhttp3.sse.EventSource;
import okhttp3.sse.EventSourceListener;
import okhttp3.sse.EventSources;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

View File

@ -1,6 +1,5 @@
package com.sxpcwlkj.ai.type;
import com.sxpcwlkj.common.enums.DeviceEnum;
import com.sxpcwlkj.common.utils.StringUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;

View File

@ -9,7 +9,6 @@ import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Set;

View File

@ -20,7 +20,6 @@ import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.time.Duration;
import java.util.Objects;
/**

View File

@ -8,8 +8,12 @@ import lombok.Data;
*/
@Data
public class ThreeQueryBo {
//true全部数据 false有效数据(status=0)
/**
* true全部数据 false有效数据(status=0)
*/
private Boolean isAll=false;
//显示级别0全部 1一级 2二级 3三级
/**
* 显示级别0全部 1一级 2二级 3三级
*/
private Integer showLevel=0;
}

View File

@ -1,7 +1,6 @@
package com.sxpcwlkj.common.code.entity;
import cn.hutool.json.JSONUtil;
import com.sxpcwlkj.common.enums.SystemCommonEnum;
import com.sxpcwlkj.common.enums.WxCodeStatusEnum;
import lombok.Data;
import lombok.Getter;

View File

@ -20,12 +20,12 @@ public enum SystemCommonEnum implements IEnum<Integer> {
/**
* 系统状态启用
*/
SYS_COMMON_STATE_OPEN(0, "common_state","系统状态-启用/有效"),
SYS_COMMON_STATE_OPEN(1, "common_state","系统状态-启用/有效"),
/**
* 系统状态禁用
*/
SYS_COMMON_STATE_CLOSE(1, "common_state","系统状态-关闭/失效"),
SYS_COMMON_STATE_CLOSE(0, "common_state","系统状态-关闭/失效"),
/**
* 系统默认头像

View File

@ -14,12 +14,6 @@ import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "captcha")
public class CaptchaProperties {
/**
* 是否开启验证码
*/
private boolean status;
/**
* 验证码类型
*/

View File

@ -3,6 +3,7 @@ package com.sxpcwlkj.common.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Set;
/**
* @author mmsAdmin

View File

@ -13,7 +13,7 @@ import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "sxpcwlkj")
public class MsProperties {
public class MmsAdminProperties {
/**
* 名称
*/
@ -34,7 +34,11 @@ public class MsProperties {
*/
private String organization;
/**
* 是否开启验证码
* 版本
*/
private Boolean isOpenCaptcha;
private String version;
/**
* 描述
*/
private String describe;
}

View File

@ -1,7 +1,6 @@
package com.sxpcwlkj.common.utils;
import com.baomidou.mybatisplus.annotation.IEnum;
import lombok.Getter;
/**
* 计算密码强度

View File

@ -3,7 +3,6 @@ package com.sxpcwlkj.common.utils;
import cn.hutool.core.convert.Convert;
import cn.hutool.extra.servlet.JakartaServletUtil;
import cn.hutool.http.HttpStatus;
import com.sxpcwlkj.common.utils.StringUtil;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@ -22,7 +21,6 @@ import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* web服务工具

View File

@ -1,6 +1,8 @@
package com.sxpcwlkj.datasource.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.Version;
import com.sxpcwlkj.datasource.entity.page.PageQuery;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ -38,7 +40,7 @@ public class BaseEntity extends PageQuery {
/* --------------- 业务状态控制字段 --------------- */
/**
* 数据状态1=禁用0=启用
* 数据状态0=禁用1=启用
*/
@TableField(fill = FieldFill.INSERT)
private Integer status = 0;

View File

@ -5,7 +5,6 @@ import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import com.sxpcwlkj.authority.LoginObject;
import com.sxpcwlkj.common.exception.DemoModeException;
import com.sxpcwlkj.common.properties.DemoModeProperties;
import lombok.RequiredArgsConstructor;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
@ -17,10 +16,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
/**
* @author mmsAdmin
*/

View File

@ -5,6 +5,7 @@ import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpStatus;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.sxpcwlkj.authority.LoginObject;
import com.sxpcwlkj.common.enums.SystemCommonEnum;
import com.sxpcwlkj.common.exception.MmsException;
import com.sxpcwlkj.datasource.entity.BaseEntity;
import lombok.RequiredArgsConstructor;
@ -35,7 +36,7 @@ public class MybatisPlusMetaObjectHandler implements MetaObjectHandler {
baseEntity.setCreatedTime(current);
baseEntity.setUpdatedTime(current);
if(baseEntity.getStatus()==null){
baseEntity.setStatus(0);
baseEntity.setStatus(SystemCommonEnum.SYS_COMMON_STATE_OPEN.getValue());
}
if(baseEntity.getSort()==null){
baseEntity.setSort(0);

View File

@ -1,9 +1,6 @@
package com.sxpcwlkj.demo.controller;
import lombok.RequiredArgsConstructor;
import org.dromara.sms4j.api.SmsBlend;
import org.dromara.sms4j.api.entity.SmsResponse;
import org.dromara.sms4j.core.factory.SmsFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

View File

@ -6,16 +6,13 @@ import com.sxpcwlkj.common.enums.ConfigKeyNum;
import com.sxpcwlkj.redis.RedisUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.email.jakarta.api.MailClient;
import org.dromara.email.jakarta.comm.config.MailSmtpConfig;
import org.dromara.email.jakarta.core.factory.MailFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.EventListener;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
/**
* JavaMail 配置

View File

@ -1,7 +1,6 @@
package com.sxpcwlkj.email.config;
import lombok.Data;
import org.springframework.stereotype.Component;
/**
* JavaMail 配置属性

View File

@ -97,6 +97,15 @@
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
</dependency>
<!-- 明确添加POI依赖 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>

View File

@ -1,5 +1,7 @@
package com.sxpcwlkj.framework.config;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
@ -14,6 +16,8 @@ import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.util.TimeZone;
/**
@ -34,13 +38,26 @@ public class JacksonConfig {
javaTimeModule.addSerializer(Long.TYPE, BigNumberSerializer.INSTANCE);
javaTimeModule.addSerializer(BigInteger.class, BigNumberSerializer.INSTANCE);
javaTimeModule.addSerializer(BigDecimal.class, ToStringSerializer.instance);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// 创建支持多种格式的 DateTimeFormatter
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendPattern("yyyy-MM-dd[['T'][ ]HH:mm:ss[.SSS]][XXX]")
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
.toFormatter();
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(formatter));
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter));
builder.modules(javaTimeModule);
builder.timeZone(TimeZone.getDefault());
// 配置日期相关特性
builder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
builder.featuresToEnable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);
log.info("初始化 jackson 配置已加载!");
};
}
}

View File

@ -1,15 +1,12 @@
package com.sxpcwlkj.framework.controller;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.lang.Console;
import com.sxpcwlkj.common.annotation.RateLimit;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
/**
* 系统框架

View File

@ -1,12 +1,6 @@
package com.sxpcwlkj.framework.entity;
import com.alibaba.excel.annotation.ExcelProperty;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.Version;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.sxpcwlkj.common.annotation.IgnoreSign;
import com.sxpcwlkj.common.utils.DateUtil;
import lombok.Data;
import lombok.EqualsAndHashCode;

View File

@ -7,17 +7,12 @@ import com.alibaba.ttl.TransmittableThreadLocal;
import com.sxpcwlkj.common.utils.JsonUtil;
import com.sxpcwlkj.common.utils.SpringUtil;
import com.sxpcwlkj.common.utils.StringUtil;
import com.sxpcwlkj.common.properties.DemoModeProperties;
import com.sxpcwlkj.datasource.handler.DemoModeContextHolder;
import com.sxpcwlkj.datasource.handler.DemoModeInterceptor;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.StopWatch;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
@ -26,7 +21,6 @@ import org.springframework.web.servlet.ModelAndView;
import java.io.BufferedReader;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Objects;
/**
* @author mmsAdmin

View File

@ -4,7 +4,6 @@ package com.sxpcwlkj.framework.handler;
import com.sxpcwlkj.common.properties.WebThymeleafProperties;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.autoconfigure.web.WebProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;

View File

@ -2,6 +2,7 @@ package com.sxpcwlkj.framework.mapper;
import com.sxpcwlkj.datasource.mapper.BaseMapperPlus;
import com.sxpcwlkj.framework.entity.SysSign;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@ -13,4 +14,6 @@ import org.springframework.stereotype.Repository;
@Repository
public interface SysSignMapper extends BaseMapperPlus<SysSign,SysSign> {
@Insert("insert into sys_sign(id,user_id,app_id,secret_key,public_key,private_key,time_out,created_time,created_by) values(#{id},#{userId},#{appId},#{secretKey},#{publicKey},#{privateKey},#{timeOut},#{createdTime},#{createdBy})")
int initSign(SysSign sysSign);
}

View File

@ -2,15 +2,16 @@ package com.sxpcwlkj.framework.sercice.impl;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.sxpcwlkj.authority.LoginObject;
import com.sxpcwlkj.common.constant.Constants;
import com.sxpcwlkj.common.exception.MmsException;
import com.sxpcwlkj.common.utils.CookieUtil;
import com.sxpcwlkj.common.utils.StringUtil;
import com.sxpcwlkj.framework.entity.SysSign;
import com.sxpcwlkj.framework.mapper.SysSignMapper;
import com.sxpcwlkj.framework.sercice.SysSignService;
import com.sxpcwlkj.common.utils.CookieUtil;
import com.sxpcwlkj.framework.utils.SignUtil;
import com.sxpcwlkj.redis.RedisUtil;
import com.sxpcwlkj.redis.constant.RedisConstant;
@ -53,11 +54,14 @@ public class SysSignServiceImpl implements SysSignService {
SysSign sysSign = getSign();
if(sysSign==null){
sysSign=new SysSign();
sysSign.setId(IdUtil.getSnowflakeNextId());
sysSign.setAppId(appid);
sysSign.setSecretKey(Objects.requireNonNull(SignUtil.getAesKey()).getSecretKey());
sysSign.setTimeOut(DateUtil.offset(new Date(), DateField.SECOND, timeOut));
sysSign.setUserId(LoginObject.getLoginId());
boolean flag = sysSignMapper.insert(sysSign)>0;
sysSign.setCreatedBy(LoginObject.isLogin()?Long.parseLong(Objects.requireNonNull(LoginObject.getLoginId())):0);
sysSign.setCreatedTime(new Date());
boolean flag = sysSignMapper.initSign(sysSign)>0;
if(flag){
RedisUtil.setCacheObject(RedisConstant.ENCRYPTION_APP_ID+LoginObject.getLoginId(), sysSign);
RedisUtil.expire(RedisConstant.ENCRYPTION_APP_ID+LoginObject.getLoginId(), Duration.ofSeconds(10));

View File

@ -2,7 +2,9 @@ package com.sxpcwlkj.framework.utils;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.listener.PageReadListener;
import com.sxpcwlkj.datasource.entity.page.PageQuery;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
@ -18,6 +20,7 @@ import java.util.Set;
* @author mmsAdmin
* @Doc mmsadmin.cn
*/
@Slf4j
public class ExcelUtil {
@ -32,7 +35,30 @@ public class ExcelUtil {
response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode("模版文件", "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
EasyExcel.write(response.getOutputStream(), clazz).sheet("模板").doWrite(new ArrayList<>());
// 设置防止浏览器缓存的响应头
response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
response.addHeader("Cache-Control", "post-check=0, pre-check=0");
response.setHeader("Pragma", "no-cache");
try {
EasyExcel.write(response.getOutputStream(), clazz)
.autoCloseStream(false)
.useDefaultStyle(false)
.inMemory(true)
.sheet("模板")
.doWrite(new ArrayList<>());
} catch (Exception e) {
e.printStackTrace();
try {
response.reset();
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
response.getWriter().println("{\"code\":500,\"msg\":\"下载模板失败,请联系管理员\"}");
} catch (Exception ex) {
// 忽略重置响应时的异常
}
}
}
/**
@ -47,7 +73,30 @@ public class ExcelUtil {
response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode(sheetName, "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
EasyExcel.write(response.getOutputStream(), clazz).sheet("模板").doWrite(new ArrayList<>());
// 设置防止浏览器缓存的响应头
response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
response.addHeader("Cache-Control", "post-check=0, pre-check=0");
response.setHeader("Pragma", "no-cache");
try {
EasyExcel.write(response.getOutputStream(), clazz)
.autoCloseStream(false)
.useDefaultStyle(false)
.inMemory(true)
.sheet(sheetName)
.doWrite(new ArrayList<>());
} catch (Exception e) {
e.printStackTrace();
try {
response.reset();
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
response.getWriter().println("{\"code\":500,\"msg\":\"下载模板失败,请联系管理员\"}");
} catch (Exception ex) {
// 忽略重置响应时的异常
}
}
}
/**
@ -62,7 +111,34 @@ public class ExcelUtil {
response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode(sheetName, "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
EasyExcel.write(response.getOutputStream(), clazz).sheet("模板").doWrite(list);
// 设置防止浏览器缓存的响应头
response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
response.addHeader("Cache-Control", "post-check=0, pre-check=0");
response.setHeader("Pragma", "no-cache");
try {
// 使用不依赖POI内部方法的配置
EasyExcel.write(response.getOutputStream(), clazz)
.autoCloseStream(false) // 不自动关闭流
.useDefaultStyle(false) // 不使用默认样式避免调用可能不存在的POI方法
.inMemory(true) // 使用内存模式避免临时文件IO问题
.sheet(sheetName) // 使用传入的sheetName作为表名
.doWrite(list);
} catch (Exception e) {
// 记录异常
e.printStackTrace();
// 重置响应并返回错误信息
try {
response.reset();
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
response.getWriter().println("{\"code\":500,\"msg\":\"导出Excel失败请联系管理员\"}");
} catch (Exception ex) {
// 忽略重置响应时的异常
}
}
}
/**
@ -94,4 +170,39 @@ public class ExcelUtil {
EasyExcel.read(file.getInputStream(), clazz, new PageReadListener<T>(data::addAll)).sheet().doRead();
return data;
}
/**
* 安全导出数据封装分页限制和异常处理
*
* @param response 响应对象
* @param clazz 数据类
* @param sheetName 表名
* @param data 数据列表
* @param pageQuery 分页查询条件
*/
public static <T> void safeExport(HttpServletResponse response, Class<T> clazz, String sheetName, List<T> data, PageQuery pageQuery) throws IOException {
// 限制导出数据量避免内存溢出
if (pageQuery == null) {
pageQuery = new PageQuery();
}
// 设置合理的导出数量上限
if (pageQuery.getPageSize() > 5000 || pageQuery.getPageSize() <= 0) {
pageQuery.setPageSize(5000);
}
try {
export(response, clazz, sheetName, data);
} catch (Exception e) {
log.error("导出Excel异常", e);
try {
// 重置响应并返回错误信息
response.reset();
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
response.getWriter().println("{\"code\":500,\"msg\":\"导出失败,请联系管理员\"}");
} catch (Exception ex) {
log.error("处理导出异常时出错", ex);
}
}
}
}

View File

@ -1,6 +1,5 @@
package com.sxpcwlkj.gen.controller;
import cn.dev33.satoken.annotation.SaCheckRole;
import com.sxpcwlkj.common.utils.R;
import com.sxpcwlkj.datasource.entity.page.TableDataInfo;
import com.sxpcwlkj.gen.common.GenQueryBo;
@ -23,36 +22,36 @@ import java.util.List;
@AllArgsConstructor
public class BaseClassController {
private final BaseClassService baseClassService;
@SaCheckRole("super_admin")
@GetMapping("page")
public TableDataInfo<BaseClassEntity> page(GenQueryBo query) {
return baseClassService.page(query);
}
@SaCheckRole("super_admin")
@GetMapping("list")
public R<List<BaseClassEntity>> list() {
List<BaseClassEntity> list = baseClassService.getList();
return R.success(list);
}
@SaCheckRole("super_admin")
@GetMapping("{id}")
public R<BaseClassEntity> get(@PathVariable("id") Long id) {
BaseClassEntity data = baseClassService.getById(id);
return R.success(data);
}
@SaCheckRole("super_admin")
@PostMapping
public R<String> save(@RequestBody BaseClassEntity entity) {
baseClassService.save(entity);
return R.success();
}
@SaCheckRole("super_admin")
@PutMapping
public R<String> update(@RequestBody BaseClassEntity entity) {
baseClassService.updateById(entity);
return R.success();
}
@SaCheckRole("super_admin")
@DeleteMapping
public R<String> delete(@RequestBody Long[] ids) {
baseClassService.removeBatchByIds(Arrays.asList(ids));

View File

@ -1,6 +1,5 @@
package com.sxpcwlkj.gen.controller;
import cn.dev33.satoken.annotation.SaCheckRole;
import com.sxpcwlkj.common.utils.R;
import com.sxpcwlkj.datasource.entity.page.TableDataInfo;
import com.sxpcwlkj.gen.common.GenQueryBo;
@ -23,36 +22,36 @@ import java.util.Set;
@AllArgsConstructor
public class FieldTypeController {
private final FieldTypeService fieldTypeService;
@SaCheckRole("super_admin")
@GetMapping("page")
public TableDataInfo<FieldTypeEntity> page(GenQueryBo query) {
return fieldTypeService.page(query);
}
@SaCheckRole("super_admin")
@GetMapping("{id}")
public R<FieldTypeEntity> get(@PathVariable("id") Long id) {
FieldTypeEntity data = fieldTypeService.getById(id);
return R.success(data);
}
@SaCheckRole("super_admin")
@GetMapping("list")
public R<Set<String>> list() {
Set<String> set = fieldTypeService.getList();
return R.success(set);
}
@SaCheckRole("super_admin")
@PostMapping
public R<String> save(@RequestBody FieldTypeEntity entity) {
fieldTypeService.save(entity);
return R.success();
}
@SaCheckRole("super_admin")
@PutMapping
public R<String> update(@RequestBody FieldTypeEntity entity) {
fieldTypeService.updateById(entity);
return R.success();
}
@SaCheckRole("super_admin")
@DeleteMapping
public R<String> delete(@RequestBody Long[] ids) {
fieldTypeService.removeBatchByIds(Arrays.asList(ids));

View File

@ -1,6 +1,5 @@
package com.sxpcwlkj.gen.controller;
import cn.dev33.satoken.annotation.SaCheckRole;
import cn.hutool.core.io.IoUtil;
import com.sxpcwlkj.common.utils.R;
import com.sxpcwlkj.gen.entity.Preview;
@ -28,7 +27,7 @@ public class GeneratorController {
/**
* 生成代码zip压缩包
*/
@SaCheckRole("super_admin")
@PostMapping("download")
public void download(String tableIds, HttpServletResponse response) throws Exception {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
@ -54,7 +53,6 @@ public class GeneratorController {
/**
* 生成代码自定义目录
*/
@SaCheckRole("super_admin")
@ResponseBody
@PostMapping("code")
public R<String> code(@RequestBody Long[] tableIds) throws Exception {
@ -68,7 +66,6 @@ public class GeneratorController {
/**
* 预览代码
*/
@SaCheckRole("super_admin")
@GetMapping("/preview/{tableId}")
public R<List<Preview>> preview(@PathVariable("tableId") Long tableId) throws Exception {
List<Preview> results = generatorService.preview(tableId);

View File

@ -1,6 +1,5 @@
package com.sxpcwlkj.gen.controller;
import cn.dev33.satoken.annotation.SaCheckRole;
import cn.hutool.core.io.IoUtil;
import com.sxpcwlkj.common.utils.R;
import com.sxpcwlkj.datasource.entity.page.TableDataInfo;
@ -24,30 +23,30 @@ import java.util.List;
@AllArgsConstructor
public class ProjectModifyController {
private final ProjectModifyService projectModifyService;
@SaCheckRole("super_admin")
@GetMapping("page")
public TableDataInfo<ProjectModifyEntity> page(GenQueryBo query) {
return projectModifyService.page(query);
}
@SaCheckRole("super_admin")
@GetMapping("{id}")
public R<ProjectModifyEntity> get(@PathVariable("id") Long id) {
ProjectModifyEntity entity = projectModifyService.getById(id);
return R.success(entity);
}
@SaCheckRole("super_admin")
@PostMapping
public R<String> save(@RequestBody ProjectModifyEntity entity) {
projectModifyService.save(entity);
return R.success();
}
@SaCheckRole("super_admin")
@PutMapping
public R<String> update(@RequestBody ProjectModifyEntity entity) {
projectModifyService.updateById(entity);
return R.success();
}
@SaCheckRole("super_admin")
@DeleteMapping
public R<String> delete(@RequestBody List<Long> idList) {
projectModifyService.removeByIds(idList);
@ -57,7 +56,7 @@ public class ProjectModifyController {
/**
* 源码下载
*/
@SaCheckRole("super_admin")
@GetMapping("download/{id}")
public void download(@PathVariable("id") Long id, HttpServletResponse response) throws Exception {
// 项目信息

View File

@ -1,6 +1,5 @@
package com.sxpcwlkj.gen.controller;
import cn.dev33.satoken.annotation.SaCheckRole;
import com.sxpcwlkj.common.code.controller.BaseController;
import com.sxpcwlkj.common.enums.SystemCommonEnum;
import com.sxpcwlkj.common.utils.R;
@ -36,7 +35,6 @@ public class TableController extends BaseController {
*
* @param query 查询参数
*/
@SaCheckRole("super_admin")
@GetMapping("page")
public TableDataInfo<TableEntity> page(GenQueryBo query) {
return baseService.page(query);
@ -47,7 +45,6 @@ public class TableController extends BaseController {
*
* @param id 表ID
*/
@SaCheckRole("super_admin")
@GetMapping("{id}")
public R<TableEntity> get(@PathVariable("id") Long id) {
TableEntity table = baseService.selectVoById(id);
@ -63,7 +60,6 @@ public class TableController extends BaseController {
*
* @param table 表信息
*/
@SaCheckRole("super_admin")
@PutMapping
public R<String> update(@RequestBody TableEntity table) {
baseService.updateById(table);
@ -75,7 +71,6 @@ public class TableController extends BaseController {
*
* @param ids 表id数组
*/
@SaCheckRole("super_admin")
@DeleteMapping
public R<String> delete(@RequestBody Long[] ids) {
baseService.deleteBatchIds(ids);
@ -87,7 +82,6 @@ public class TableController extends BaseController {
*
* @param id 表ID
*/
@SaCheckRole("super_admin")
@PostMapping("sync/{id}")
public R<String> sync(@PathVariable("id") Long id) {
baseService.sync(id);
@ -100,7 +94,6 @@ public class TableController extends BaseController {
* @param datasourceId 数据源ID
* @param tableNameList 表名列表
*/
@SaCheckRole("super_admin")
@PostMapping("import/{datasourceId}")
public R<String> tableImport(@PathVariable("datasourceId") Long datasourceId, @RequestBody List<String> tableNameList) {
for (String tableName : tableNameList) {
@ -115,7 +108,6 @@ public class TableController extends BaseController {
* @param tableId 表ID
* @param tableFieldList 字段列表
*/
@SaCheckRole("super_admin")
@PutMapping("field/{tableId}")
public R<String> updateTableField(@PathVariable("tableId") Long tableId, @RequestBody List<TableFieldEntity> tableFieldList) {
tableFieldService.updateTableField(tableId, tableFieldList);

View File

@ -2,7 +2,6 @@ package com.sxpcwlkj.gen.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.sxpcwlkj.gen.common.annotation.EncryptParameter;
import lombok.Data;
import java.util.Date;

View File

@ -1,9 +1,7 @@
package com.sxpcwlkj.gen.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sxpcwlkj.datasource.mapper.BaseMapperPlus;
import com.sxpcwlkj.gen.entity.TableEntity;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

View File

@ -19,7 +19,6 @@ import com.sxpcwlkj.gen.service.*;
import com.sxpcwlkj.gen.utils.TemplateUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

View File

@ -1,6 +1,5 @@
package com.sxpcwlkj.gen.service.impl;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.text.NamingCase;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;

View File

@ -11,9 +11,7 @@ import com.sxpcwlkj.gen.entity.TableEntity;
import com.sxpcwlkj.gen.entity.TableFieldEntity;
import lombok.extern.slf4j.Slf4j;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
@ -185,4 +183,130 @@ public class GenUtils {
return NamingCase.toCamelCase(className);
}
}
/**
* 执行更新SQLINSERT/UPDATE/DELETE
* @param datasource 数据源
* @param sql SQL语句
* @param params SQL参数
* @return 受影响的行数
*/
// 示例增加 编辑 删除
// int affectedRows = executeUpdate(datasource,
// "UPDATE users SET name = ? WHERE id = ?",
// new Object[]{"张三", 1});
public static int executeUpdate(GenDataSource datasource, String sql, Object[] params) {
try (Connection conn = datasource.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
// 设置参数
if (params != null) {
for (int i = 0; i < params.length; i++) {
pstmt.setObject(i + 1, params[i]);
}
}
return pstmt.executeUpdate();
} catch (Exception e) {
log.error("执行更新失败: {}", sql, e);
throw new MmsException("执行更新操作失败", e);
}
}
/**
* 批量执行SQL
* @param datasource 数据源
* @param sql SQL语句
* @param batchParams 批量参数列表
* @return 每个操作的受影响行数数组
*/
// 示例批量插入
// List<Object[]> batchParams = new ArrayList<>();
// batchParams.add(new Object[]{"user1", "user1@example.com"});
// batchParams.add(new Object[]{"user2", "user2@example.com"});
// int[] batchResult = executeBatch(datasource,
// "INSERT INTO users (name, email) VALUES (?, ?)",
// batchParams);
public static int[] executeBatch(GenDataSource datasource, String sql, List<Object[]> batchParams) {
try (Connection conn = datasource.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
// 禁用自动提交开启事务
conn.setAutoCommit(false);
for (Object[] params : batchParams) {
if (params != null) {
for (int i = 0; i < params.length; i++) {
pstmt.setObject(i + 1, params[i]);
}
}
pstmt.addBatch();
}
int[] result = pstmt.executeBatch();
// 提交事务
conn.commit();
// 恢复自动提交
conn.setAutoCommit(true);
return result;
} catch (Exception e) {
log.error("批量执行失败: {}", sql, e);
throw new MmsException("批量执行操作失败", e);
}
}
/**
* 执行查询SQL并返回对象列表
* @param datasource 数据源
* @param sql SQL语句
* @param params SQL参数
* @param mapper 结果映射器
* @param <T> 返回类型
* @return 查询结果列表
*/
//示例查询
// List<User> users = queryForList(datasource,
// "SELECT * FROM users WHERE status = ?",
// new Object[]{"active"},
// rs -> {
// User u = new User();
// u.setId(rs.getInt("id"));
// u.setName(rs.getString("name"));
// return u;
// });
public static <T> List<T> queryForList(GenDataSource datasource, String sql, Object[] params,
ResultSetMapper<T> mapper) {
List<T> resultList = new ArrayList<>();
try (Connection conn = datasource.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
// 设置参数
if (params != null) {
for (int i = 0; i < params.length; i++) {
pstmt.setObject(i + 1, params[i]);
}
}
try (ResultSet rs = pstmt.executeQuery()) {
while (rs.next()) {
resultList.add(mapper.mapRow(rs));
}
}
return resultList;
} catch (Exception e) {
log.error("执行查询失败: {}", sql, e);
throw new MmsException("查询数据失败", e);
}
}
// 结果映射器接口
public interface ResultSetMapper<T> {
T mapRow(ResultSet rs) throws SQLException;
}
}

View File

@ -1,9 +1,5 @@
package com.sxpcwlkj.oss.service;
import com.sxpcwlkj.common.code.entity.FileStorageConfig;
import java.util.List;
/**
* @author mms
*/

View File

@ -1,7 +1,6 @@
package com.sxpcwlkj.sms.enums;
import com.baomidou.mybatisplus.annotation.IEnum;
import lombok.Getter;
/**
* 短信服务商

View File

@ -1,19 +1,6 @@
package com.sxpcwlkj.wx.config;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.config.WxMaConfig;
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import io.swagger.v3.oas.models.security.SecurityScheme;
import lombok.Data;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
@ -52,7 +39,7 @@ public class WxProperties {
private Integer modelType=1;
// 支付回调
private String notifyUrl;
private String token;
private String aesKey;

View File

@ -142,12 +142,12 @@ public class WeChatController {
if (encType == null) {
// 明文传输的消息
WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(requestBody);
log.error("\n消息内容为:\n{} ", inMessage.toString());
log.error("\n微信公众号扫码后的回调消息内容为:\n{} ", inMessage.toString());
return wxCodeService.scanCallBack(inMessage);
} else if ("aes".equalsIgnoreCase(encType)) {
// aes加密的消息
WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(requestBody, wxService.getWxMpService().getWxMpConfigStorage(), timestamp, nonce, msgSignature);
log.error("\n消息解密后内容为:\n{} ", inMessage.toString());
log.error("\n微信公众号扫码后的回调消息解密后内容为:\n{} ", inMessage.toString());
return wxCodeService.scanCallBack(inMessage);
}
return "";

View File

@ -4,7 +4,6 @@ import cn.binarywang.wx.miniapp.api.WxMaService;
import com.github.binarywang.wxpay.service.WxPayService;
import com.sxpcwlkj.wx.config.WxProperties;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
/**
* @author mmsAdmin

View File

@ -4,13 +4,12 @@ import cn.hutool.core.convert.Convert;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sxpcwlkj.common.code.entity.WxCodeBo;
import com.sxpcwlkj.common.enums.WxCodeStatusEnum;
import com.sxpcwlkj.common.utils.DataUtil;
import com.sxpcwlkj.common.utils.R;
import com.sxpcwlkj.redis.RedisUtil;
import com.sxpcwlkj.redis.constant.RedisConstant;
import com.sxpcwlkj.wx.config.WxProperties;
import com.sxpcwlkj.common.code.entity.WxCodeBo;
import com.sxpcwlkj.wx.entity.WechatEventEnum;
import com.sxpcwlkj.wx.service.WxCodeService;
import com.sxpcwlkj.wx.service.WxService;
@ -25,7 +24,6 @@ import org.springframework.stereotype.Service;
import java.time.Duration;
import java.util.Date;
import java.util.Map;
/**
*

View File

@ -3,11 +3,9 @@ package com.sxpcwlkj.wx.service.impl;
import cn.hutool.extra.qrcode.QrCodeUtil;
import com.ijpay.core.enums.SignType;
import com.ijpay.core.enums.TradeType;
import com.ijpay.core.kit.QrCodeKit;
import com.ijpay.core.kit.WxPayKit;
import com.ijpay.wxpay.WxPayApi;
import com.ijpay.wxpay.WxPayApiConfig;
import com.ijpay.wxpay.WxPayApiConfigKit;
import com.ijpay.wxpay.model.UnifiedOrderModel;
import com.sxpcwlkj.common.utils.FileUtil;
import com.sxpcwlkj.common.utils.JsonUtil;

View File

@ -0,0 +1,27 @@
#FROM findepi/graalvm:java17-native
FROM openjdk:17.0.2-oraclelinux8
MAINTAINER SXPCWLKJ
RUN mkdir -p /sxpcwlkj \
/sxpcwlkj/mms-monitor \
/sxpcwlkj/mms-monitor/logs \
/sxpcwlkj/mms-monitor/files \
/sxpcwlkj/mms-monitor/temp \
/sxpcwlkj/mms-monitor/skywalking/agent
WORKDIR /sxpcwlkj/mms-monitor
ENV SERVER_PORT=9001 LANG=C.UTF-8 LC_ALL=C.UTF-8 JAVA_OPTS=""
EXPOSE ${SERVER_PORT}
ADD ./target/mms-monitor.jar ./app.jar
ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -Dserver.port=${SERVER_PORT} \
# 应用名称 如果想区分集群节点监控 改成不同的名称即可
#-Dskywalking.agent.service_name=sxpcwlkj-mms \
#-javaagent:/sxpcwlkj/mms/skywalking/agent/skywalking-agent.jar \
-jar app.jar \
-XX:+HeapDumpOnOutOfMemoryError -Xlog:gc*,:time,tags,level -XX:+UseZGC ${JAVA_OPTS}

Some files were not shown because too many files have changed in this diff Show More