Commit 3e02f69c authored by 林洋洋's avatar 林洋洋

调整项目结构

parent 52b71166
root = true
[*.{groovy,java,kt,xml}]
indent_style = tab
indent_size = 4
continuation_indent_size = 8
### gradle ###
.gradle
/build/
!gradle/wrapper/gradle-wrapper.jar
### STS ###
.settings/
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
bin/
### IntelliJ IDEA ###
!.idea/icon.png
.idea
*.iws
*.iml
*.ipr
rebel.xml
### NetBeans ###
nbproject/private/
build/
nbbuild/
nbdist/
.nb-gradle/
### maven ###
target/
*.war
*.ear
*.zip
*.tar
*.tar.gz
*.versionsBackup
### vscode ###
.vscode
### logs ###
/logs/
*.log
### temp ignore ###
*.cache
*.diff
*.patch
*.tmp
*.java~
*.properties~
*.xml~
### system ignore ###
.DS_Store
Thumbs.db
Servers
.metadata
.flattened-pom.xml
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright (c) 2020 pig4cloud Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
<p align="center">
<img src="https://img.shields.io/badge/Pig-3.9-success.svg" alt="Build Status">
<img src="https://img.shields.io/badge/Spring%20Cloud-2025-blue.svg" alt="Coverage Status">
<img src="https://img.shields.io/badge/Spring%20Boot-3.5-blue.svg" alt="Downloads">
<img src="https://img.shields.io/badge/Vue-3.5-blue.svg" alt="Downloads">
<img src="https://img.shields.io/github/license/pig-mesh/pig"/>
<img src="https://gitcode.com/pig-mesh/pig/star/badge.svg"/>
</p>
## 系统说明
- 基于 Spring Cloud 、Spring Boot、 OAuth2 的 RBAC **企业快速开发平台**, 同时支持微服务架构和单体架构
- 提供对 Spring Authorization Server 生产级实践,支持多种安全授权模式
- 提供对常见容器化方案支持 Kubernetes、Rancher2 、Kubesphere、EDAS、SAE 支持
#### 使用文档
PIG 提供了详尽的部署文档 👉 [wiki.pig4cloud.com](https://wiki.pig4cloud.com),涵盖开发环境配置、服务端启动、前端运行等关键步骤。
重要的事情说三遍:
- 🔥 [ 配套文档 wiki.pig4cloud.com](https://wiki.pig4cloud.com)
- 🔥 [ 配套文档 wiki.pig4cloud.com](https://wiki.pig4cloud.com)
- 🔥 [ 配套文档 wiki.pig4cloud.com](https://wiki.pig4cloud.com)
#### 其他产品
- 👉🏻 [PIGX 在线体验](http://home.pig4cloud.com:38081)
- 👉🏻 [自研BPMN工作流引擎](http://home.pig4cloud.com:38082)
- 👉🏻 [大模型 RAG 知识库](http://home.pig4cloud.com:38083)
## 微信群 [禁广告]
<img src='https://minio.pigx.vip/oss/202412/1735262426.png' alt='1735262426'/>
## 快速开始
#### Docker 快速体验
```shell
# 可用内存大于4G
curl -o docker-compose.yaml https://try.pig4cloud.com
# 等待5分钟
docker compose up
```
### 核心依赖
| 依赖 | 版本 |
|-----------------------------|------|
| Spring Boot | 3.5 |
| Spring Cloud | 2025 |
| Spring Cloud Alibaba | 2023 |
| Spring Authorization Server | 1.5 |
| Mybatis Plus | 3.5 |
| Vue | 3.5 |
| Element Plus | 2.7 |
### 模块说明
```lua
pig-ui -- https://gitee.com/log4j/pig-ui
pig
├── pig-boot -- 单体模式启动器[9999]
├── pig-auth -- 授权服务提供[3000]
└── pig-common -- 系统公共模块
├── pig-common-bom -- 全局依赖管理控制
├── pig-common-core -- 公共工具类核心包
├── pig-common-datasource -- 动态数据源包
├── pig-common-log -- 日志服务
├── pig-common-oss -- 文件上传工具类
├── pig-common-mybatis -- mybatis 扩展封装
├── pig-common-seata -- 分布式事务
├── pig-common-security -- 安全工具类
├── pig-common-swagger -- 接口文档
├── pig-common-feign -- feign 扩展封装
└── pig-common-xss -- xss 安全封装
├── pig-register -- Nacos Server[8848]
├── pig-gateway -- Spring Cloud Gateway网关[9999]
└── pig-upms -- 通用用户权限管理模块
└── pig-upms-api -- 通用用户权限管理系统公共api模块
└── pig-upms-biz -- 通用用户权限管理系统业务处理模块[4000]
└── pig-visual
└── pig-monitor -- 服务监控 [5001]
├── pig-codegen -- 图形化代码生成 [5002]
└── pig-quartz -- 定时任务管理台 [5007]
```
## 免费公开课
<table>
<tr>
<td><a href="https://www.bilibili.com/video/av45084065" target="_blank"><img src="https://foruda.gitee.com/images/1731647304254897555/88a9c2fa_441246.jpeg"></a></td>
<td><a href="https://www.bilibili.com/video/av77344954" target="_blank"><img src="https://foruda.gitee.com/images/1731647324953921510/39689640_441246.jpeg"></a></td>
</tr>
<tr>
<td><a href="https://www.bilibili.com/video/BV1J5411476V" target="_blank"><img src="https://foruda.gitee.com/images/1731647357502030768/7f31f392_441246.jpeg"></a></td>
<td><a href="https://www.bilibili.com/video/BV14p4y197K5" target="_blank"><img src="https://foruda.gitee.com/images/1731647375444479120/2b8fd494_441246.jpeg"></a></td>
</tr>
</table>
## 开源共建
### 开源协议
pig 开源软件遵循 [Apache 2.0 协议](https://www.apache.org/licenses/LICENSE-2.0.html)
允许商业使用,但务必保留类作者、Copyright 信息。
![](https://foruda.gitee.com/images/1731647419204307063/91217172_441246.jpeg)
### 其他说明
1. 欢迎提交 [PR](https://dwz.cn/2KURd5Vf),注意对应提交对应 `dev` 分支
代码规范 [spring-javaformat](https://github.com/spring-io/spring-javaformat)
<details>
<summary>代码规范说明</summary>
1. 由于 <a href="https://github.com/spring-io/spring-javaformat" target="_blank">spring-javaformat</a>
强制所有代码按照指定格式排版,未按此要求提交的代码将不能通过合并(打包)
2. 如果使用 IntelliJ IDEA
开发,请安装自动格式化软件 <a href="https://repo1.maven.org/maven2/io/spring/javaformat/spring-javaformat-intellij-idea-plugin/" target="_blank">
spring-javaformat-intellij-idea-plugin</a>
3. 其他开发工具,请参考 <a href="https://github.com/spring-io/spring-javaformat" target="_blank">
spring-javaformat</a>
说明,或`提交代码前`在项目根目录运行下列命令(需要开发者电脑支持`mvn`命令)进行代码格式化
```
mvn spring-javaformat:apply
```
</details>
2. 欢迎提交 [issue](https://gitee.com/log4j/pig/issues),请写清楚遇到问题的原因、开发环境、复显步骤。
services:
pig-mysql:
build:
context: ./db
environment:
MYSQL_ROOT_HOST: "%"
MYSQL_ROOT_PASSWORD: root
restart: always
container_name: pig-mysql
image: pig-mysql
ports:
- 33306:3306
networks:
- spring_cloud_default
pig-redis:
image: registry.cn-hangzhou.aliyuncs.com/dockerhub_mirror/redis
ports:
- 36379:6379
restart: always
container_name: pig-redis
hostname: pig-redis
networks:
- spring_cloud_default
pig-register:
build:
context: ./pig-register
restart: always
ports:
- 8848:8848
- 9848:9848
- 8080:8080
environment:
MYSQL_HOST: pig-mysql
REDIS_HOST: pig-redis
container_name: pig-register
hostname: pig-register
image: pig-register
networks:
- spring_cloud_default
pig-gateway:
build:
context: ./pig-gateway
restart: always
ports:
- 9999:9999
container_name: pig-gateway
hostname: pig-gateway
image: pig-gateway
environment:
REDIS_HOST: pig-redis
NACOS_HOST: pig-register
networks:
- spring_cloud_default
pig-auth:
build:
context: ./pig-auth
restart: always
container_name: pig-auth
hostname: pig-auth
image: pig-auth
environment:
REDIS_HOST: pig-redis
NACOS_HOST: pig-register
networks:
- spring_cloud_default
pig-upms:
build:
context: ./pig-upms/pig-upms-biz
restart: always
container_name: pig-upms
hostname: pig-upms
image: pig-upms
environment:
MYSQL_HOST: pig-mysql
REDIS_HOST: pig-redis
NACOS_HOST: pig-register
networks:
- spring_cloud_default
pig-monitor:
build:
context: ./pig-visual/pig-monitor
restart: always
ports:
- 5001:5001
container_name: pig-monitor
hostname: pig-monitor
image: pig-monitor
environment:
NACOS_HOST: pig-register
networks:
- spring_cloud_default
pig-codegen:
build:
context: ./pig-visual/pig-codegen
restart: always
container_name: pig-codegen
hostname: pig-codegen
image: pig-codegen
environment:
MYSQL_HOST: pig-mysql
REDIS_HOST: pig-redis
NACOS_HOST: pig-register
networks:
- spring_cloud_default
pig-quartz:
build:
context: ./pig-visual/pig-quartz
restart: always
image: pig-quartz
container_name: pig-quartz
environment:
MYSQL_HOST: pig-mysql
REDIS_HOST: pig-redis
NACOS_HOST: pig-register
networks:
- spring_cloud_default
networks:
spring_cloud_default:
name: spring_cloud_default
driver: bridge
FROM registry.cn-hangzhou.aliyuncs.com/dockerhub_mirror/java:17-anolis
WORKDIR /pig-boot
ARG JAR_FILE=target/pig-boot.jar
COPY ${JAR_FILE} app.jar
EXPOSE 9999
ENV TZ=Asia/Shanghai JAVA_OPTS="-Xms512m -Xmx1024m -Djava.security.egd=file:/dev/./urandom"
CMD sleep 60; java $JAVA_OPTS -jar app.jar
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2020 pig4cloud Authors. All Rights Reserved.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pig</artifactId>
<version>${revision}</version>
</parent>
<artifactId>pig-boot</artifactId>
<packaging>jar</packaging>
<description>pig 单体版本启动</description>
<dependencies>
<!--必备:认证中心模块-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-auth</artifactId>
<version>${revision}</version>
</dependency>
<!--必备:用户管理模块-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-upms-biz</artifactId>
<version>${revision}</version>
</dependency>
<!--必备:AI模块-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-ask-biz</artifactId>
<version>${revision}</version>
</dependency>
<!--安全模块-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common-security</artifactId>
</dependency>
<!-- 接口文档UI -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-api</artifactId>
</dependency>
<dependency>
<groupId>io.springboot</groupId>
<artifactId>knife4j-boot-openapi3-ui</artifactId>
<version>${knife4j.version}</version>
</dependency>
<!--接口文档-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common-swagger</artifactId>
</dependency>
<!--undertow容器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
/*
* Copyright (c) 2020 pig4cloud Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.pig4cloud.pig;
import com.pig4cloud.pig.common.security.annotation.EnablePigResourceServer;
import com.pig4cloud.pig.common.swagger.annotation.EnablePigDoc;
import com.pig4cloud.pig.common.datasource.annotation.EnableDynamicDataSource;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 单体版本启动器,运行此模块即可启动整个系统
*
* @author lengleng
* @date 2025/05/30
*/
@EnablePigDoc(value = "admin", isMicro = false)
@EnablePigResourceServer
@EnableDynamicDataSource
@SpringBootApplication
public class PigBootApplication {
public static void main(String[] args) {
SpringApplication.run(PigBootApplication.class, args);
}
}
spring:
cache:
type: redis # 缓存类型 Redis
data:
redis:
database: 7
host: 81.70.183.25
port: 16379
password: '123qwe!@#'
# 数据库相关配置
datasource:
dynamic:
primary: master
strict: true
datasource:
master:
url: jdbc:postgresql://81.70.183.25:25432/ask_data_ai_db
username: postgres
password: postgres123
driver-class-name: org.postgresql.Driver
ai:
vectorstore:
pgvector:
index-type: HNSW
distance-type: COSINE_DISTANCE
dimensions: 1024
max-document-batch-size: 10000 # Optional: Maximum number of documents per batch
schema-name: public
table-name: vector_store
chat:
memory:
repository:
jdbc:
initialize-schema: never # 开发环境可以使用 always,方便调试
platform: postgresql
openai:
base-url: https://dashscope.aliyuncs.com/compatible-mode
api-key: sk-ae96ff281ff644c992843c64a711a950
chat:
options:
model: qwen-plus
embedding:
base-url: https://dashscope.aliyuncs.com/compatible-mode
api-key: sk-ae96ff281ff644c992843c64a711a950
options:
model: text-embedding-v4
# 本地文件系统
file:
local:
enable: true
base-path: /Users/lengleng/Downloads/img
## 登录配置
security:
# 登录报文加密根密钥 ,必须是16位
encodeKey: thanks,pig4cloud
# 跳过验证码校验的客户端
ignore-clients:
- test
# 配置文件加密根密码
jasypt:
encryptor:
password: pig # 加密根密码
algorithm: PBEWithMD5AndDES # 加密算法
iv-generator-classname: org.jasypt.iv.NoIvGenerator # 无向量生成器
# 短信插件配置:https://www.yuque.com/vxixfq/pig/zw8udk
sms:
is-print: false # 是否打印日志
config-type: yaml # 配置类型,yaml
\ No newline at end of file
server:
port: 9999 # 项目端口
servlet:
context-path: /admin # 项目访问路径
spring:
application:
name: @project.artifactId@ # 服务名称,取 pom.xml 中的 artifactId
# 上传文件大小限制
servlet:
multipart:
max-file-size: 100MB # 单个文件最大
max-request-size: 100MB # 接收的最大请求大小
cloud:
nacos: # 单机版本关闭nacos 服务发现和配置管理的能力
config:
enabled: false
discovery:
enabled: false
freemarker: # freemarker 配置,授权码模式页面渲染使用
suffix: .ftl
template-loader-path: classpath:/templates/
request-context-attribute: request
main:
allow-bean-definition-overriding: true # 允许覆盖bean定义
profiles:
active: dev # 激活dev,对应 application-dev.yml
## spring security 对外暴露接口设置(不鉴权直接可访问)
security:
micro: false
oauth2:
ignore:
urls:
- /webjars/**
- /v3/api-docs/**
- /doc.html
- /swagger-ui.html
- /swagger-ui/**
- /swagger-resources
- /code/image
- /error
- /token/**
- /actuator/**
#--------------如下配置尽量不要变动-------------
# mybatis-plus 配置
mybatis-plus:
mapper-locations: classpath*:/mapper/*Mapper.xml # mapper文件位置
global-config:
banner: false # 是否打印 mybatis-plus banner
db-config:
id-type: auto # 主键类型
where-strategy: not_empty # where 条件策略
insert-strategy: not_empty # 插入策略
update-strategy: not_null # 更新策略
type-handlers-package: com.pig4cloud.pig.common.mybatis.handler # 类型处理器包
configuration:
jdbc-type-for-null: 'null' # 是否设置字段为null
call-setters-on-nulls: true # 是否调用set方法时传入null值
shrink-whitespaces-in-sql: true # 去掉sql中多余的空格
<?xml version="1.0" encoding="UTF-8"?>
<!--
小技巧: 在根pom里面设置统一存放路径,统一管理方便维护
<properties>
<log-path>/Users/lengleng</log-path>
</properties>
1. 其他模块加日志输出,直接copy本文件放在resources 目录即可
2. 注意修改 <property name="${log-path}/log.path" value=""/> 的value模块
-->
<configuration debug="false" scan="false">
<property name="log.path" value="logs/${project.artifactId}"/>
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN"
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!-- 彩色日志依赖的渲染类 -->
<conversionRule conversionWord="clr" class="org.springframework.boot.logging.logback.ColorConverter"/>
<conversionRule conversionWord="wex"
class="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
<conversionRule conversionWord="wEx"
class="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
<!-- Console log output -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- Log file debug output -->
<appender name="debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/debug.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.path}/%d{yyyy-MM, aux}/debug.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>50MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- Log file error output -->
<appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.path}/%d{yyyy-MM}/error.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>50MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
</appender>
<!--nacos 心跳 INFO 屏蔽-->
<logger name="com.alibaba.nacos" level="OFF">
<appender-ref ref="error"/>
</logger>
<!-- Level: FATAL 0 ERROR 3 WARN 4 INFO 6 DEBUG 7 -->
<root level="INFO">
<appender-ref ref="console"/>
<appender-ref ref="debug"/>
<appender-ref ref="error"/>
</root>
</configuration>
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2020 pig4cloud Authors. All Rights Reserved.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-upms</artifactId>
<version>${revision}</version>
</parent>
<artifactId>pig-upms-api</artifactId>
<packaging>jar</packaging>
<description>pig 通用用户权限管理系统公共api模块</description>
<dependencies>
<!--core 工具类-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common-core</artifactId>
</dependency>
<!--feign 注解依赖-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common-feign</artifactId>
</dependency>
<!--mybatis 依赖-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common-mybatis</artifactId>
</dependency>
<!-- excel 导入导出 -->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common-excel</artifactId>
</dependency>
</dependencies>
</project>
package com.pig4cloud.pig.admin.api.dto;
import lombok.Data;
/**
* 注册用户 DTO
*
* @author lengleng
* @date 2024/12/23
*/
@Data
public class RegisterUserDTO {
/**
* 用户名
*/
private String username;
/**
* 新密码
*/
private String password;
/**
* 电话
*/
private String phone;
}
package com.pig4cloud.pig.admin.api.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import java.time.LocalDateTime;
/**
* @author lengleng
* @date 2020/10/9
* <p>
* 日志查询传输对象
*/
@Data
@Schema(description = "日志查询对象")
public class SysLogDTO {
/**
* 编号
*/
private Long id;
/**
* 日志类型
*/
@NotBlank(message = "日志类型不能为空")
private String logType;
/**
* 日志标题
*/
@NotBlank(message = "日志标题不能为空")
private String title;
/**
* 创建者
*/
private String createBy;
/**
* 更新时间
*/
private LocalDateTime updateTime;
/**
* 操作IP地址
*/
private String remoteAddr;
/**
* 用户代理
*/
private String userAgent;
/**
* 请求URI
*/
private String requestUri;
/**
* 操作方式
*/
private String method;
/**
* 操作提交的数据
*/
private String params;
/**
* 执行时间
*/
private Long time;
/**
* 异常信息
*/
private String exception;
/**
* 服务ID
*/
private String serviceId;
/**
* 创建时间区间 [开始时间,结束时间]
*/
private LocalDateTime[] createTime;
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.api.dto;
import com.pig4cloud.pig.admin.api.entity.SysUser;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
/**
* @author lengleng
* @date 2017/11/5
*/
@Data
@Schema(description = "系统用户传输对象")
@EqualsAndHashCode(callSuper = true)
public class UserDTO extends SysUser {
/**
* 角色ID
*/
@Schema(description = "角色id集合")
private List<Long> role;
/**
* 部门id
*/
@Schema(description = "部门id")
private Long deptId;
/**
* 岗位ID
*/
private List<Long> post;
/**
* 新密码
*/
@Schema(description = "新密码")
private String newpassword1;
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.api.dto;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.pig4cloud.pig.admin.api.vo.UserVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* 用户信息实体类,继承自UserVO并实现Serializable接口 , spring security
*
* @author lengleng
* @date 2025/06/28
*/
@Data
@Schema(description = "spring security 用户信息")
@EqualsAndHashCode(callSuper = true)
public class UserInfo extends UserVO implements Serializable {
/**
* 密码
*/
@JsonIgnore(value = false)
private String password;
/**
* 随机盐
*/
@JsonIgnore(value = false)
private String salt;
/**
* 权限标识集合
*/
@Schema(description = "权限标识集合")
private List<String> permissions = new ArrayList<>();
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.api.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.FieldNameConstants;
import java.time.LocalDateTime;
/**
* <p>
* 部门管理
* </p>
*
* @author lengleng
* @since 2018-01-22
*/
@Data
@Schema(description = "部门")
@FieldNameConstants
@EqualsAndHashCode(callSuper = true)
public class SysDept extends Model<SysDept> {
private static final long serialVersionUID = 1L;
@TableId(value = "dept_id", type = IdType.AUTO)
@Schema(description = "部门id")
private Long deptId;
/**
* 部门名称
*/
@NotBlank(message = "部门名称不能为空")
@Schema(description = "部门名称")
private String name;
/**
* 排序
*/
@NotNull(message = "排序值不能为空")
@Schema(description = "排序值")
private Integer sortOrder;
/**
* 创建人
*/
@TableField(fill = FieldFill.INSERT)
@Schema(description = "创建人")
private String createBy;
/**
* 修改人
*/
@TableField(fill = FieldFill.UPDATE)
@Schema(description = "修改人")
private String updateBy;
/**
* 创建时间
*/
@Schema(description = "创建时间")
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
/**
* 修改时间
*/
@Schema(description = "修改时间")
@TableField(fill = FieldFill.UPDATE)
private LocalDateTime updateTime;
/**
* 父级部门id
*/
@Schema(description = "父级部门id")
private Long parentId;
/**
* 是否删除 1:已删除 0:正常
*/
@TableLogic
@Schema(description = "删除标记,1:已删除,0:正常")
@TableField(fill = FieldFill.INSERT)
private String delFlag;
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.api.entity;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
* 部门关系表
* </p>
*
* @author lengleng
* @since 2018-01-22
*/
@Data
@Schema(description = "部门关系")
@EqualsAndHashCode(callSuper = true)
public class SysDeptRelation extends Model<SysDeptRelation> {
private static final long serialVersionUID = 1L;
/**
* 祖先节点
*/
@Schema(description = "祖先节点")
private Long ancestor;
/**
* 后代节点
*/
@Schema(description = "后代节点")
private Long descendant;
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pig.admin.api.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;
/**
* 字典表
*
* @author lengleng
* @date 2019/03/19
*/
@Data
@Schema(description = "字典类型")
@EqualsAndHashCode(callSuper = true)
public class SysDict extends Model<SysDict> {
private static final long serialVersionUID = 1L;
/**
* 编号
*/
@TableId(type = IdType.AUTO)
@Schema(description = "字典编号")
private Long id;
/**
* 类型
*/
@Schema(description = "字典类型")
private String dictType;
/**
* 描述
*/
@Schema(description = "字典描述")
private String description;
/**
* 创建时间
*/
@Schema(description = "创建时间")
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
/**
* 更新时间
*/
@Schema(description = "更新时间")
@TableField(fill = FieldFill.UPDATE)
private LocalDateTime updateTime;
/**
* 是否是系统内置
*/
@Schema(description = "是否系统内置")
private String systemFlag;
/**
* 备注信息
*/
@Schema(description = "备注信息")
private String remarks;
/**
* 创建人
*/
@TableField(fill = FieldFill.INSERT)
@Schema(description = "创建人")
private String createBy;
/**
* 修改人
*/
@TableField(fill = FieldFill.UPDATE)
@Schema(description = "修改人")
private String updateBy;
/**
* 删除标记
*/
@TableLogic
@TableField(fill = FieldFill.INSERT)
@Schema(description = "删除标记,1:已删除,0:正常")
private String delFlag;
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pig.admin.api.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;
/**
* 字典项
*
* @author lengleng
* @date 2019/03/19
*/
@Data
@Schema(description = "字典项")
@EqualsAndHashCode(callSuper = true)
public class SysDictItem extends Model<SysDictItem> {
private static final long serialVersionUID = 1L;
/**
* 编号
*/
@TableId(type = IdType.AUTO)
@Schema(description = "字典项id")
private Long id;
/**
* 所属字典类id
*/
@Schema(description = "所属字典类id")
private Long dictId;
/**
* 数据值
*/
@Schema(description = "数据值")
@JsonProperty(value = "value")
private String itemValue;
/**
* 标签名
*/
@Schema(description = "标签名")
private String label;
/**
* 类型
*/
@Schema(description = "类型")
private String dictType;
/**
* 描述
*/
@Schema(description = "描述")
private String description;
/**
* 排序(升序)
*/
@Schema(description = "排序值,默认升序")
private Integer sortOrder;
/**
* 创建人
*/
@TableField(fill = FieldFill.INSERT)
@Schema(description = "创建人")
private String createBy;
/**
* 修改人
*/
@TableField(fill = FieldFill.UPDATE)
@Schema(description = "修改人")
private String updateBy;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
@Schema(description = "创建时间")
private LocalDateTime createTime;
/**
* 更新时间
*/
@TableField(fill = FieldFill.UPDATE)
@Schema(description = "更新时间")
private LocalDateTime updateTime;
/**
* 备注信息
*/
@Schema(description = "备注信息")
private String remarks;
/**
* 删除标记
*/
@TableLogic
@TableField(fill = FieldFill.INSERT)
@Schema(description = "删除标记,1:已删除,0:正常")
private String delFlag;
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pig.admin.api.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;
/**
* 文件管理
*
* @author Luckly
* @date 2019-06-18 17:18:42
*/
@Data
@Schema(description = "文件")
@EqualsAndHashCode(callSuper = true)
public class SysFile extends Model<SysFile> {
private static final long serialVersionUID = 1L;
/**
* 编号
*/
@TableId(type = IdType.AUTO)
@Schema(description = "文件编号")
private Long id;
/**
* 文件名
*/
@Schema(description = "文件名")
private String fileName;
/**
* 原文件名
*/
@Schema(description = "原始文件名")
private String original;
/**
* 容器名称
*/
@Schema(description = "存储桶名称")
private String bucketName;
/**
* 文件类型
*/
@Schema(description = "文件类型")
private String type;
/**
* 文件大小
*/
@Schema(description = "文件大小")
private Long fileSize;
/**
* 上传人
*/
@TableField(fill = FieldFill.INSERT)
@Schema(description = "创建者")
private String createBy;
/**
* 上传时间
*/
@TableField(fill = FieldFill.INSERT)
@Schema(description = "创建时间")
private LocalDateTime createTime;
/**
* 更新人
*/
@TableField(fill = FieldFill.INSERT)
@Schema(description = "更新者")
private String updateBy;
/**
* 更新时间
*/
@TableField(fill = FieldFill.UPDATE)
@Schema(description = "更新时间")
private LocalDateTime updateTime;
/**
* 删除标识:1-删除,0-正常
*/
@TableLogic
@TableField(fill = FieldFill.INSERT)
@Schema(description = "删除标记,1:已删除,0:正常")
private String delFlag;
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.api.entity;
import cn.idev.excel.annotation.ExcelIgnore;
import cn.idev.excel.annotation.ExcelProperty;
import com.baomidou.mybatisplus.annotation.*;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* <p>
* 日志表
* </p>
*
* @author lengleng
* @since 2017-11-20
*/
@Data
@Schema(description = "日志")
public class SysLog implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 编号
*/
@TableId(type = IdType.AUTO)
@ExcelProperty("日志编号")
@Schema(description = "日志编号")
private Long id;
/**
* 日志类型
*/
@NotBlank(message = "日志类型不能为空")
@ExcelProperty("日志类型(0-正常 9-错误)")
@Schema(description = "日志类型")
private String logType;
/**
* 日志标题
*/
@NotBlank(message = "日志标题不能为空")
@ExcelProperty("日志标题")
@Schema(description = "日志标题")
private String title;
/**
* 创建者
*/
@ExcelProperty("创建人")
@TableField(fill = FieldFill.INSERT)
@Schema(description = "创建人")
private String createBy;
/**
* 创建时间
*/
@ExcelProperty("创建时间")
@TableField(fill = FieldFill.INSERT)
@Schema(description = "创建时间")
private LocalDateTime createTime;
/**
* 更新时间
*/
@ExcelIgnore
@TableField(fill = FieldFill.UPDATE)
@Schema(description = "更新时间")
private LocalDateTime updateTime;
/**
* 操作IP地址
*/
@ExcelProperty("操作ip地址")
@Schema(description = "操作ip地址")
private String remoteAddr;
/**
* 用户代理
*/
@Schema(description = "用户代理")
private String userAgent;
/**
* 请求URI
*/
@ExcelProperty("浏览器")
@Schema(description = "请求uri")
private String requestUri;
/**
* 操作方式
*/
@ExcelProperty("操作方式")
@Schema(description = "操作方式")
private String method;
/**
* 操作提交的数据
*/
@ExcelProperty("提交数据")
@Schema(description = "提交数据")
private String params;
/**
* 执行时间
*/
@ExcelProperty("执行时间")
@Schema(description = "方法执行时间")
private Long time;
/**
* 异常信息
*/
@ExcelProperty("异常信息")
@Schema(description = "异常信息")
private String exception;
/**
* 服务ID
*/
@ExcelProperty("应用标识")
@Schema(description = "应用标识")
private String serviceId;
/**
* 删除标记
*/
@TableLogic
@ExcelIgnore
@TableField(fill = FieldFill.INSERT)
@Schema(description = "删除标记,1:已删除,0:正常")
private String delFlag;
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.api.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.FieldNameConstants;
import java.time.LocalDateTime;
/**
* <p>
* 菜单权限表
* </p>
*
* @author lengleng
* @since 2017-11-08
*/
@Data
@Schema(description = "菜单")
@FieldNameConstants
@EqualsAndHashCode(callSuper = true)
public class SysMenu extends Model<SysMenu> {
private static final long serialVersionUID = 1L;
/**
* 菜单ID
*/
@TableId(value = "menu_id", type = IdType.AUTO)
@Schema(description = "菜单id")
private Long menuId;
/**
* 菜单名称
*/
@NotBlank(message = "菜单名称不能为空")
@Schema(description = "菜单名称")
private String name;
/**
* 菜单名称
*/
@Schema(description = "菜单名称")
private String enName;
/**
* 菜单权限标识
*/
@Schema(description = "菜单权限标识")
private String permission;
/**
* 父菜单ID
*/
@NotNull(message = "菜单父ID不能为空")
@Schema(description = "菜单父id")
private Long parentId;
/**
* 图标
*/
@Schema(description = "菜单图标")
private String icon;
/**
* 前端路由标识路径,默认和 comment 保持一致 过期
*/
@Schema(description = "前端路由标识路径")
private String path;
/**
* 菜单显示隐藏控制
*/
@Schema(description = "菜单是否显示")
private String visible;
/**
* 排序值
*/
@Schema(description = "排序值")
private Integer sortOrder;
/**
* 菜单类型 (0菜单 1按钮)
*/
@NotNull(message = "菜单类型不能为空")
@Schema(description = "菜单类型,0:菜单 1:按钮")
private String menuType;
/**
* 路由缓冲
*/
@Schema(description = "路由缓冲")
private String keepAlive;
@Schema(description = "菜单是否内嵌")
private String embedded;
/**
* 创建人
*/
@TableField(fill = FieldFill.INSERT)
@Schema(description = "创建人")
private String createBy;
/**
* 修改人
*/
@TableField(fill = FieldFill.UPDATE)
@Schema(description = "修改人")
private String updateBy;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
@Schema(description = "创建时间")
private LocalDateTime createTime;
/**
* 更新时间
*/
@TableField(fill = FieldFill.UPDATE)
@Schema(description = "更新时间")
private LocalDateTime updateTime;
/**
* 0--正常 1--删除
*/
@TableLogic
@TableField(fill = FieldFill.INSERT)
@Schema(description = "删除标记,1:已删除,0:正常")
private String delFlag;
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.api.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;
/**
* <p>
* 客户端信息
* </p>
*
* @author lengleng
* @since 2018-05-15
*/
@Data
@Schema(description = "客户端信息")
@EqualsAndHashCode(callSuper = true)
public class SysOauthClientDetails extends Model<SysOauthClientDetails> {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
@Schema(description = "id")
private Long id;
/**
* 客户端ID
*/
@NotBlank(message = "client_id 不能为空")
@Schema(description = "客户端id")
private String clientId;
/**
* 客户端密钥
*/
@NotBlank(message = "client_secret 不能为空")
@Schema(description = "客户端密钥")
private String clientSecret;
/**
* 资源ID
*/
@Schema(description = "资源id列表")
private String resourceIds;
/**
* 作用域
*/
@NotBlank(message = "scope 不能为空")
@Schema(description = "作用域")
private String scope;
/**
* 授权方式[A,B,C]
*/
@Schema(description = "授权方式")
private String[] authorizedGrantTypes;
/**
* 回调地址
*/
@Schema(description = "回调地址")
private String webServerRedirectUri;
/**
* 权限
*/
@Schema(description = "权限列表")
private String authorities;
/**
* 请求令牌有效时间
*/
@Schema(description = "请求令牌有效时间")
private Integer accessTokenValidity;
/**
* 刷新令牌有效时间
*/
@Schema(description = "刷新令牌有效时间")
private Integer refreshTokenValidity;
/**
* 扩展信息
*/
@Schema(description = "扩展信息")
private String additionalInformation;
/**
* 是否自动放行
*/
@Schema(description = "是否自动放行")
private String autoapprove;
/**
* 删除标记
*/
@TableLogic
@TableField(fill = FieldFill.INSERT)
@Schema(description = "删除标记,1:已删除,0:正常")
private String delFlag;
/**
* 创建人
*/
@TableField(fill = FieldFill.INSERT)
@Schema(description = "创建人")
private String createBy;
/**
* 修改人
*/
@TableField(fill = FieldFill.UPDATE)
@Schema(description = "修改人")
private String updateBy;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
@Schema(description = "创建时间")
private LocalDateTime createTime;
/**
* 更新时间
*/
@TableField(fill = FieldFill.UPDATE)
@Schema(description = "更新时间")
private LocalDateTime updateTime;
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pig.admin.api.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;
/**
* 岗位信息表
*
* @author fxz
* @date 2022-03-26 12:50:43
*/
@Data
@TableName("sys_post")
@EqualsAndHashCode(callSuper = true)
@Schema(description = "岗位信息表")
public class SysPost extends Model<SysPost> {
private static final long serialVersionUID = 1L;
/**
* 岗位ID
*/
@TableId(value = "post_id", type = IdType.AUTO)
@Schema(description = "岗位ID")
private Long postId;
/**
* 岗位编码
*/
@NotBlank(message = "岗位编码不能为空")
@Schema(description = "岗位编码")
private String postCode;
/**
* 岗位名称
*/
@NotBlank(message = "岗位名称不能为空")
@Schema(description = "岗位名称")
private String postName;
/**
* 岗位排序
*/
@NotNull(message = "排序值不能为空")
@Schema(description = "岗位排序")
private Integer postSort;
/**
* 岗位描述
*/
@Schema(description = "岗位描述")
private String remark;
/**
* 创建人
*/
@TableField(fill = FieldFill.INSERT)
@Schema(description = "创建人")
private String createBy;
/**
* 修改人
*/
@TableField(fill = FieldFill.UPDATE)
@Schema(description = "修改人")
private String updateBy;
/**
* 是否删除 -1:已删除 0:正常
*/
@TableLogic
@TableField(fill = FieldFill.INSERT)
@Schema(description = "是否删除 -1:已删除 0:正常")
private String delFlag;
/**
* 创建时间
*/
@Schema(description = "创建时间")
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
/**
* 更新时间
*/
@Schema(description = "更新时间")
@TableField(fill = FieldFill.UPDATE)
private LocalDateTime updateTime;
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pig.admin.api.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;
/**
* 公共参数配置
*
* @author Lucky
* @date 2019-04-29
*/
@Data
@Schema(description = "公共参数")
@EqualsAndHashCode(callSuper = true)
public class SysPublicParam extends Model<SysPublicParam> {
private static final long serialVersionUID = 1L;
/**
* 编号
*/
@TableId(type = IdType.AUTO)
@Schema(description = "公共参数编号")
private Long publicId;
/**
* 公共参数名称
*/
@Schema(description = "公共参数名称", required = true, example = "公共参数名称")
private String publicName;
/**
* 公共参数地址值,英文大写+下划线
*/
@Schema(description = "键[英文大写+下划线]", required = true, example = "PIGX_PUBLIC_KEY")
private String publicKey;
/**
* 值
*/
@Schema(description = "值", required = true, example = "999")
private String publicValue;
/**
* 状态(1有效;2无效;)
*/
@Schema(description = "标识[1有效;2无效]", example = "1")
private String status;
/**
* 公共参数编码
*/
@Schema(description = "编码", example = "^(PIG|PIGX)$")
private String validateCode;
/**
* 是否是系统内置
*/
@Schema(description = "是否是系统内置")
private String systemFlag;
/**
* 配置类型:0-默认;1-检索;2-原文;3-报表;4-安全;5-文档;6-消息;9-其他
*/
@Schema(description = "类型[1-检索;2-原文...]", example = "1")
private String publicType;
/**
* 创建人
*/
@TableField(fill = FieldFill.INSERT)
@Schema(description = "创建人")
private String createBy;
/**
* 修改人
*/
@TableField(fill = FieldFill.UPDATE)
@Schema(description = "修改人")
private String updateBy;
/**
* 删除标记
*/
@TableLogic
@TableField(fill = FieldFill.INSERT)
@Schema(description = "删除标记,1:已删除,0:正常")
private String delFlag;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
@Schema(description = "创建时间")
private LocalDateTime createTime;
/**
* 更新时间
*/
@TableField(fill = FieldFill.UPDATE)
@Schema(description = "更新时间")
private LocalDateTime updateTime;
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.api.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;
/**
* <p>
* 角色表
* </p>
*
* @author lengleng
* @since 2017-10-29
*/
@Data
@Schema(description = "角色")
@EqualsAndHashCode(callSuper = true)
public class SysRole extends Model<SysRole> {
private static final long serialVersionUID = 1L;
@TableId(value = "role_id", type = IdType.AUTO)
@Schema(description = "角色编号")
private Long roleId;
@NotBlank(message = "角色名称不能为空")
@Schema(description = "角色名称")
private String roleName;
@NotBlank(message = "角色标识不能为空")
@Schema(description = "角色标识")
private String roleCode;
@Schema(description = "角色描述")
private String roleDesc;
/**
* 创建人
*/
@TableField(fill = FieldFill.INSERT)
@Schema(description = "创建人")
private String createBy;
/**
* 修改人
*/
@TableField(fill = FieldFill.UPDATE)
@Schema(description = "修改人")
private String updateBy;
/**
* 创建时间
*/
@Schema(description = "创建时间")
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
/**
* 修改时间
*/
@Schema(description = "修改时间")
@TableField(fill = FieldFill.UPDATE)
private LocalDateTime updateTime;
/**
* 删除标识(0-正常,1-删除)
*/
@TableLogic
@TableField(fill = FieldFill.INSERT)
@Schema(description = "删除标记,1:已删除,0:正常")
private String delFlag;
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.api.entity;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
* 角色菜单表
* </p>
*
* @author lengleng
* @since 2017-10-29
*/
@Data
@Schema(description = "角色菜单")
@EqualsAndHashCode(callSuper = true)
public class SysRoleMenu extends Model<SysRoleMenu> {
private static final long serialVersionUID = 1L;
/**
* 角色ID
*/
@Schema(description = "角色id")
private Long roleId;
/**
* 菜单ID
*/
@Schema(description = "菜单id")
private Long menuId;
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.api.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* <p>
* 用户表
* </p>
*
* @author lengleng
* @since 2017-10-29
*/
@Data
@Schema(description = "用户")
public class SysUser implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(value = "user_id", type = IdType.AUTO)
@Schema(description = "主键id")
private Long userId;
/**
* 用户名
*/
@Schema(description = "用户名")
private String username;
/**
* 密码
*/
@Schema(description = "密码")
private String password;
/**
* 随机盐
*/
@JsonIgnore
@Schema(description = "随机盐")
private String salt;
/**
* 创建人
*/
@TableField(fill = FieldFill.INSERT)
@Schema(description = "创建人")
private String createBy;
/**
* 修改人
*/
@TableField(fill = FieldFill.UPDATE)
@Schema(description = "修改人")
private String updateBy;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
@Schema(description = "创建时间")
private LocalDateTime createTime;
/**
* 修改时间
*/
@TableField(fill = FieldFill.UPDATE)
@Schema(description = "修改时间")
private LocalDateTime updateTime;
/**
* 0-正常,1-删除
*/
@TableLogic
@TableField(fill = FieldFill.INSERT)
@Schema(description = "删除标记,1:已删除,0:正常")
private String delFlag;
/**
* 锁定标记
*/
@Schema(description = "锁定标记")
private String lockFlag;
/**
* 手机号
*/
@Schema(description = "手机号")
private String phone;
/**
* 头像
*/
@Schema(description = "头像地址")
private String avatar;
/**
* 部门ID
*/
@Schema(description = "用户所属部门id")
private Long deptId;
/**
* 微信openid
*/
@Schema(description = "微信openid")
private String wxOpenid;
/**
* 微信小程序openId
*/
@Schema(description = "微信小程序openid")
private String miniOpenid;
/**
* QQ openid
*/
@Schema(description = "QQ openid")
private String qqOpenid;
/**
* 码云唯一标识
*/
@Schema(description = "码云唯一标识")
private String giteeLogin;
/**
* 开源中国唯一标识
*/
@Schema(description = "开源中国唯一标识")
private String oscId;
/**
* 昵称
*/
@Schema(description = "昵称")
private String nickname;
/**
* 姓名
*/
@Schema(description = "姓名")
private String name;
/**
* 邮箱
*/
@Schema(description = "邮箱")
private String email;
}
/*
* Copyright (c) 2020 pig4cloud Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.pig4cloud.pig.admin.api.entity;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
* 用户岗位表
* </p>
*
* @author fxz
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class SysUserPost extends Model<SysUserPost> {
private static final long serialVersionUID = 1L;
/**
* 用户ID
*/
@Schema(description = "用户id")
private Long userId;
/**
* 岗位ID
*/
@Schema(description = "岗位id")
private Long postId;
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.api.entity;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
* 用户角色表
* </p>
*
* @author lengleng
* @since 2017-10-29
*/
@Data
@Schema(description = "用户角色")
@EqualsAndHashCode(callSuper = true)
public class SysUserRole extends Model<SysUserRole> {
private static final long serialVersionUID = 1L;
/**
* 用户ID
*/
@Schema(description = "用户id")
private Long userId;
/**
* 角色ID
*/
@Schema(description = "角色id")
private Long roleId;
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.api.feign;
import com.pig4cloud.pig.admin.api.entity.SysOauthClientDetails;
import com.pig4cloud.pig.common.core.constant.ServiceNameConstants;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.feign.annotation.NoToken;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
* 远程客户端详情服务接口
*
* @author lengleng
* @date 2025/05/30
*/
@FeignClient(contextId = "remoteClientDetailsService", value = ServiceNameConstants.UPMS_SERVICE)
public interface RemoteClientDetailsService {
/**
* 通过clientId 查询客户端信息 (未登录,需要无token 内部调用)
* @param clientId 用户名
* @return R
*/
@NoToken
@GetMapping("/client/getClientDetailsById/{clientId}")
R<SysOauthClientDetails> getClientDetailsById(@PathVariable("clientId") String clientId);
}
package com.pig4cloud.pig.admin.api.feign;
import com.pig4cloud.pig.admin.api.entity.SysDictItem;
import com.pig4cloud.pig.common.core.constant.ServiceNameConstants;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.feign.annotation.NoToken;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import java.util.List;
/**
* 远程字典服务接口
*
* @author lengleng
* @date 2025/05/30
*/
@FeignClient(contextId = "remoteDictService", value = ServiceNameConstants.UPMS_SERVICE)
public interface RemoteDictService {
/**
* 通过字典类型查找字典
* @param type 字典类型
* @return 同类型字典
*/
@NoToken
@GetMapping("/dict/remote/type/{type}")
R<List<SysDictItem>> getDictByType(@PathVariable("type") String type);
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.api.feign;
import com.pig4cloud.pig.admin.api.entity.SysLog;
import com.pig4cloud.pig.common.core.constant.ServiceNameConstants;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.feign.annotation.NoToken;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
/**
* 远程日志服务接口
*
* @author lengleng
* @date 2025/05/30
*/
@FeignClient(contextId = "remoteLogService", value = ServiceNameConstants.UPMS_SERVICE)
public interface RemoteLogService {
/**
* 保存日志 (异步多线程调用,无token)
* @param sysLog 日志实体
* @return succes、false
*/
@NoToken
@PostMapping("/log/save")
R<Boolean> saveLog(@RequestBody SysLog sysLog);
}
package com.pig4cloud.pig.admin.api.feign;
import com.pig4cloud.pig.common.core.constant.ServiceNameConstants;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.feign.annotation.NoToken;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
* 远程参数服务接口
* <p>
* 通过Feign客户端调用UPMS服务获取参数配置
* </p>
*
* @author lengleng
* @date 2025/05/30
* @see FeignClient
*/
@FeignClient(contextId = "remoteParamService", value = ServiceNameConstants.UPMS_SERVICE)
public interface RemoteParamService {
/**
* 通过key 查询参数配置
* @param key key
* @NoToken 声明成内部调用,避免MQ 等无法调用
*/
@NoToken
@GetMapping("/param/publicValue/{key}")
R<String> getByKey(@PathVariable("key") String key);
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pig.admin.api.feign;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.pig.common.core.constant.ServiceNameConstants;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.feign.annotation.NoToken;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
/**
* 远程令牌服务接口
*
* @author lengleng
* @date 2025/05/30
*/
@FeignClient(contextId = "remoteTokenService", value = ServiceNameConstants.AUTH_SERVICE)
public interface RemoteTokenService {
/**
* 分页查询token 信息
* @param params 分页参数
* @return page
*/
@NoToken
@PostMapping("/token/page")
R<Page> getTokenPage(@RequestBody Map<String, Object> params);
/**
* 根据token删除token信息
* @param token 要删除的token
* @return 删除操作结果,包含是否成功的布尔值
*/
@NoToken
@DeleteMapping("/token/remove/{token}")
R<Boolean> removeTokenById(@PathVariable("token") String token);
/**
* 根据令牌查询用户信息
* @param token 用户令牌
* @return 包含用户信息的响应结果
*/
@NoToken
@GetMapping("/token/query-token")
R<Map<String, Object>> queryToken(@RequestParam("token") String token);
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.api.feign;
import com.pig4cloud.pig.admin.api.dto.UserDTO;
import com.pig4cloud.pig.admin.api.dto.UserInfo;
import com.pig4cloud.pig.common.core.constant.ServiceNameConstants;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.feign.annotation.NoToken;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.openfeign.SpringQueryMap;
import org.springframework.web.bind.annotation.GetMapping;
/**
* 远程用户服务接口:提供用户信息查询功能
*
* @author lengleng
* @date 2025/05/30
*/
@FeignClient(contextId = "remoteUserService", value = ServiceNameConstants.UPMS_SERVICE)
public interface RemoteUserService {
/**
* (未登录状态调用,需要加 @NoToken) 通过用户名查询用户、角色信息
* @param user 用户查询对象
* @return R
*/
@NoToken
@GetMapping("/user/info/query")
R<UserInfo> info(@SpringQueryMap UserDTO user);
}
package com.pig4cloud.pig.admin.api.util;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.pig4cloud.pig.admin.api.entity.SysDictItem;
import com.pig4cloud.pig.admin.api.feign.RemoteDictService;
import com.pig4cloud.pig.common.core.util.SpringContextHolder;
import lombok.experimental.UtilityClass;
import java.util.List;
/**
* 字典解析工具类:提供字典数据的查询和解析功能
*
* @author lengleng
* @date 2025/05/30
*/
@UtilityClass
public class DictResolver {
/**
* 根据字典类型获取所有字典项
* @param type 字典类型
* @return 字典数据项集合
*/
public List<SysDictItem> getDictItemsByType(String type) {
Assert.isTrue(StringUtils.isNotBlank(type), "参数不合法");
RemoteDictService remoteDictService = SpringContextHolder.getBean(RemoteDictService.class);
return remoteDictService.getDictByType(type).getData();
}
/**
* 根据字典类型以及字典项字典值获取字典标签
* @param type 字典类型
* @param itemValue 字典项字典值
* @return 字典项标签值
*/
public String getDictItemLabel(String type, String itemValue) {
Assert.isTrue(StringUtils.isNotBlank(type) && StringUtils.isNotBlank(itemValue), "参数不合法");
SysDictItem sysDictItem = getDictItemByItemValue(type, itemValue);
return ObjectUtils.isNotEmpty(sysDictItem) ? sysDictItem.getLabel() : StringPool.EMPTY;
}
/**
* 根据字典类型以及字典标签获取字典值
* @param type 字典类型
* @param itemLabel 字典数据标签
* @return 字典数据项值
*/
public String getDictItemValue(String type, String itemLabel) {
Assert.isTrue(StringUtils.isNotBlank(type) && StringUtils.isNotBlank(itemLabel), "参数不合法");
SysDictItem sysDictItem = getDictItemByItemLabel(type, itemLabel);
return ObjectUtils.isNotEmpty(sysDictItem) ? sysDictItem.getItemValue() : StringPool.EMPTY;
}
/**
* 根据字典类型以及字典值获取字典项
* @param type 字典类型
* @param itemValue 字典数据值
* @return 字典数据项
*/
public SysDictItem getDictItemByItemValue(String type, String itemValue) {
Assert.isTrue(StringUtils.isNotBlank(type) && StringUtils.isNotBlank(itemValue), "参数不合法");
List<SysDictItem> dictItemList = getDictItemsByType(type);
if (CollectionUtils.isNotEmpty(dictItemList)) {
return dictItemList.stream().filter(item -> itemValue.equals(item.getItemValue())).findFirst().orElse(null);
}
return null;
}
/**
* 根据字典类型以及字典标签获取字典项
* @param type 字典类型
* @param itemLabel 字典数据项标签
* @return 字典数据项
*/
public SysDictItem getDictItemByItemLabel(String type, String itemLabel) {
Assert.isTrue(StringUtils.isNotBlank(type) && StringUtils.isNotBlank(itemLabel), "参数不合法");
List<SysDictItem> dictItemList = getDictItemsByType(type);
if (CollectionUtils.isNotEmpty(dictItemList)) {
return dictItemList.stream().filter(item -> itemLabel.equals(item.getLabel())).findFirst().orElse(null);
}
return null;
}
}
package com.pig4cloud.pig.admin.api.util;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.pig4cloud.pig.admin.api.feign.RemoteParamService;
import com.pig4cloud.pig.common.core.util.SpringContextHolder;
import lombok.experimental.UtilityClass;
/**
* 系统参数配置解析器工具类
*
* @author lengleng
* @date 2025/05/30
*/
@UtilityClass
public class ParamResolver {
/**
* 根据key 查询value 配置
* @param key key
* @param defaultVal 默认值
* @return value
*/
public Long getLong(String key, Long... defaultVal) {
return checkAndGet(key, Long.class, defaultVal);
}
/**
* 根据key 查询value 配置
* @param key key
* @param defaultVal 默认值
* @return value
*/
public String getStr(String key, String... defaultVal) {
return checkAndGet(key, String.class, defaultVal);
}
/**
* 根据key获取远程参数值并转换为指定类型
* @param key 参数key
* @param clazz 目标类型
* @param defaultVal 默认值(可选,最多一个)
* @param <T> 泛型类型
* @return 转换后的参数值,未找到且无默认值时返回null
* @throws IllegalArgumentException 参数不合法时抛出异常
*/
private <T> T checkAndGet(String key, Class<T> clazz, T... defaultVal) {
// 校验入参是否合法
if (StrUtil.isBlank(key) || defaultVal.length > 1) {
throw new IllegalArgumentException("参数不合法");
}
RemoteParamService remoteParamService = SpringContextHolder.getBean(RemoteParamService.class);
String result = remoteParamService.getByKey(key).getData();
if (StrUtil.isNotBlank(result)) {
return Convert.convert(clazz, result);
}
if (defaultVal.length == 1) {
return Convert.convert(clazz, defaultVal.clone()[0]);
}
return null;
}
}
package com.pig4cloud.pig.admin.api.vo;
import cn.idev.excel.annotation.ExcelIgnore;
import cn.idev.excel.annotation.ExcelProperty;
import com.pig4cloud.plugin.excel.annotation.ExcelLine;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import java.io.Serializable;
/**
* 部门导入导出
*/
@Data
public class DeptExcelVo implements Serializable {
/**
* 导入时候回显行号
*/
@ExcelLine
@ExcelIgnore
private Long lineNum;
/**
* 上级部门
*/
@NotBlank(message = "上级部门不能为空")
@ExcelProperty("上级部门")
private String parentName;
/**
* 部门名称
*/
@NotBlank(message = "部门名称不能为空")
@ExcelProperty("部门名称")
private String name;
/**
* 排序
*/
@ExcelProperty(value = "排序值")
private Integer sortOrder;
}
package com.pig4cloud.pig.admin.api.vo;
import cn.idev.excel.annotation.ExcelIgnore;
import cn.idev.excel.annotation.ExcelProperty;
import cn.idev.excel.annotation.write.style.ColumnWidth;
import com.pig4cloud.plugin.excel.annotation.ExcelLine;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 岗位excel 对应的实体
*
* @author fxz
* @date 2022/3/21
*/
@Data
@ColumnWidth(30)
public class PostExcelVO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 导入时候回显行号
*/
@ExcelLine
@ExcelIgnore
private Long lineNum;
/**
* 主键ID
*/
@ExcelProperty("岗位编号")
private Long postId;
/**
* 岗位名称
*/
@NotBlank(message = "岗位名称不能为空")
@ExcelProperty("岗位名称")
private String postName;
/**
* 岗位标识
*/
@NotBlank(message = "岗位标识不能为空")
@ExcelProperty("岗位标识")
private String postCode;
/**
* 岗位排序
*/
@NotNull(message = "岗位排序不能为空")
@ExcelProperty("岗位排序")
private Integer postSort;
/**
* 岗位描述
*/
@NotBlank(message = "岗位描述不能为空")
@ExcelProperty(value = "岗位描述")
private String remark;
/**
* 创建时间
*/
@ExcelProperty(value = "创建时间")
private LocalDateTime createTime;
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pig.admin.api.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* @author lengleng
* @date 2018/8/27 前端日志vo
*/
@Data
@Schema(description = "前端日志展示对象")
public class PreLogVO {
/**
* 请求url
*/
@Schema(description = "请求url")
private String url;
/**
* 请求耗时
*/
@Schema(description = "请求耗时")
private String time;
/**
* 请求用户
*/
@Schema(description = "请求用户")
private String user;
/**
* 请求结果
*/
@Schema(description = "请求结果0:成功9:失败")
private String type;
/**
* 请求传递参数
*/
@Schema(description = "请求传递参数")
private String message;
/**
* 异常信息
*/
@Schema(description = "异常信息")
private String stack;
/**
* 日志标题
*/
@Schema(description = "日志标题")
private String info;
}
package com.pig4cloud.pig.admin.api.vo;
import cn.idev.excel.annotation.ExcelIgnore;
import cn.idev.excel.annotation.ExcelProperty;
import cn.idev.excel.annotation.write.style.ColumnWidth;
import com.pig4cloud.plugin.excel.annotation.ExcelLine;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 角色excel 对应的实体
*
* @author fxz
* @date 2022/3/21
*/
@Data
@ColumnWidth(30)
public class RoleExcelVO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 导入时候回显行号
*/
@ExcelLine
@ExcelIgnore
private Long lineNum;
/**
* 主键ID
*/
@ExcelProperty("角色编号")
private Long roleId;
/**
* 角色名称
*/
@NotBlank(message = "角色名称不能为空")
@ExcelProperty("角色名称")
private String roleName;
/**
* 角色标识
*/
@NotBlank(message = "角色标识不能为空")
@ExcelProperty("角色标识")
private String roleCode;
/**
* 角色描述
*/
@NotBlank(message = "角色描述不能为空")
@ExcelProperty("角色描述")
private String roleDesc;
/**
* 创建时间
*/
@ExcelProperty(value = "创建时间")
private LocalDateTime createTime;
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pig.admin.api.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* @author lengleng
* @date 2020/2/10
*/
@Data
@Schema(description = "前端角色展示对象")
public class RoleVO {
/**
* 角色id
*/
private Long roleId;
/**
* 菜单列表
*/
private String menuIds;
}
package com.pig4cloud.pig.admin.api.vo;
import lombok.Data;
/**
* 前端展示令牌管理
*
* @author lengleng
* @date 2022/6/2
*/
@Data
public class TokenVo {
private String id;
private Long userId;
private String clientId;
private String username;
private String accessToken;
private String issuedAt;
private String expiresAt;
}
package com.pig4cloud.pig.admin.api.vo;
import cn.idev.excel.annotation.ExcelIgnore;
import cn.idev.excel.annotation.ExcelProperty;
import cn.idev.excel.annotation.write.style.ColumnWidth;
import com.pig4cloud.plugin.excel.annotation.DictTypeProperty;
import com.pig4cloud.plugin.excel.annotation.ExcelLine;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 用户excel 对应的实体
*
* @author lengleng
* @date 2021/8/4
*/
@Data
@ColumnWidth(30)
public class UserExcelVO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 导入时候回显行号
*/
@ExcelLine
@ExcelIgnore
private Long lineNum;
/**
* 主键ID
*/
@ExcelProperty("用户编号")
private Long userId;
/**
* 用户名
*/
@NotBlank(message = "用户名不能为空")
@ExcelProperty("用户名")
private String username;
/**
* 手机号
*/
@NotBlank(message = "手机号不能为空")
@ExcelProperty("手机号")
private String phone;
/**
* 手机号
*/
@NotBlank(message = "昵称不能为空")
@ExcelProperty("昵称")
private String nickname;
/**
* 手机号
*/
@NotBlank(message = "姓名不能为空")
@ExcelProperty("姓名")
private String name;
/**
* 手机号
*/
@NotBlank(message = "邮箱不能为空")
@ExcelProperty("邮箱")
private String email;
/**
* 部门名称
*/
@NotBlank(message = "部门名称不能为空")
@ExcelProperty("部门名称")
private String deptName;
/**
* 角色列表
*/
@NotBlank(message = "角色不能为空")
@ExcelProperty("角色")
private String roleNameList;
/**
* 角色列表
*/
@NotBlank(message = "岗位不能为空")
@ExcelProperty("岗位名称")
private String postNameList;
/**
* 锁定标记
*/
@ExcelProperty("锁定标记,0:正常,9:已锁定")
@DictTypeProperty("lock_flag")
private String lockFlag;
/**
* 创建时间
*/
@ExcelProperty(value = "创建时间")
private LocalDateTime createTime;
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.api.vo;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.pig4cloud.pig.admin.api.entity.SysDept;
import com.pig4cloud.pig.admin.api.entity.SysPost;
import com.pig4cloud.pig.admin.api.entity.SysRole;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
/**
* @author lengleng
* @date 2017/10/29
*/
@Data
@Schema(description = "前端用户展示对象")
public class UserVO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@Schema(description = "主键")
private Long userId;
/**
* 用户名
*/
@Schema(description = "用户名")
private String username;
/**
* 密码
*/
@JsonIgnore
private String password;
/**
* 随机盐
*/
@JsonIgnore
private String salt;
/**
* 微信openid
*/
@Schema(description = "微信open id")
private String wxOpenid;
/**
* QQ openid
*/
@Schema(description = "qq open id")
private String qqOpenid;
/**
* gitee openid
*/
@Schema(description = "gitee open id")
private String giteeOpenId;
/**
* 开源中国 openid
*/
@Schema(description = "开源中国 open id")
private String oscOpenId;
/**
* 创建时间
*/
@Schema(description = "创建时间")
private LocalDateTime createTime;
/**
* 修改时间
*/
@Schema(description = "修改时间")
private LocalDateTime updateTime;
/**
* 0-正常,1-删除
*/
@Schema(description = "删除标记,1:已删除,0:正常")
private String delFlag;
/**
* 锁定标记
*/
@Schema(description = "锁定标记,0:正常,9:已锁定")
private String lockFlag;
/**
* 手机号
*/
@Schema(description = "手机号")
private String phone;
/**
* 头像
*/
@Schema(description = "头像")
private String avatar;
/**
* 部门名称
*/
@Schema(description = "所属部门名称")
private SysDept dept;
/**
* 角色列表
*/
@Schema(description = "拥有的角色列表")
private List<SysRole> roleList;
/**
* 岗位列表
*/
private List<SysPost> postList;
/**
* 昵称
*/
@Schema(description = "昵称")
private String nickname;
/**
* 姓名
*/
@Schema(description = "姓名")
private String name;
/**
* 邮箱
*/
@Schema(description = "邮箱")
private String email;
}
com.pig4cloud.pig.admin.api.feign.RemoteClientDetailsService
com.pig4cloud.pig.admin.api.feign.RemoteDictService
com.pig4cloud.pig.admin.api.feign.RemoteLogService
com.pig4cloud.pig.admin.api.feign.RemoteParamService
com.pig4cloud.pig.admin.api.feign.RemoteTokenService
com.pig4cloud.pig.admin.api.feign.RemoteUserService
FROM registry.cn-hangzhou.aliyuncs.com/dockerhub_mirror/java:21-anolis
WORKDIR /pig-upms-biz
ARG JAR_FILE=target/pig-upms-biz.jar
COPY ${JAR_FILE} app.jar
EXPOSE 4000
ENV TZ=Asia/Shanghai JAVA_OPTS="-Xms128m -Xmx256m -Djava.security.egd=file:/dev/./urandom"
CMD sleep 60; java $JAVA_OPTS -jar app.jar
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2020 pig4cloud Authors. All Rights Reserved.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-upms</artifactId>
<version>${revision}</version>
</parent>
<artifactId>pig-upms-biz</artifactId>
<packaging>jar</packaging>
<description>pig 通用用户权限管理系统业务处理模块</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-ai.version>1.1.0-SNAPSHOT</spring-ai.version>
</properties>
<dependencies>
<!--upms api、model 模块-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-upms-api</artifactId>
</dependency>
<!--文件管理-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common-oss</artifactId>
</dependency>
<!--feign 调用-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common-feign</artifactId>
</dependency>
<!--安全模块-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common-security</artifactId>
</dependency>
<!--日志处理-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common-log</artifactId>
</dependency>
<!--接口文档-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common-swagger</artifactId>
</dependency>
<!-- orm 模块-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
</dependency>
<!-- PostgreSQL驱动 -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<!--注册中心客户端-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--配置中心客户端-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- 短信下发 -->
<dependency>
<groupId>org.dromara.sms4j</groupId>
<artifactId>sms4j-spring-boot-starter</artifactId>
</dependency>
<!--xss 过滤-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common-xss</artifactId>
</dependency>
<!--undertow容器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
</dependencies>
<profiles>
<profile>
<id>boot</id>
</profile>
<profile>
<id>cloud</id>
<activation>
<!-- 默认环境 -->
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<excludes>
<exclude>**/*.xlsx</exclude>
<exclude>**/*.xls</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<includes>
<include>**/*.xlsx</include>
<include>**/*.xls</include>
</includes>
</resource>
</resources>
</build>
</project>
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin;
import com.pig4cloud.pig.common.feign.annotation.EnablePigFeignClients;
import com.pig4cloud.pig.common.security.annotation.EnablePigResourceServer;
import com.pig4cloud.pig.common.swagger.annotation.EnablePigDoc;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* 用户统一管理系统
*
* @author lengleng
* @date 2025/05/30
*/
@EnablePigDoc(value = "admin")
@EnablePigFeignClients
@EnablePigResourceServer
@EnableDiscoveryClient
@SpringBootApplication
public class PigAdminApplication {
public static void main(String[] args) {
SpringApplication.run(PigAdminApplication.class, args);
}
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.controller;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
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.pig4cloud.pig.admin.api.entity.SysOauthClientDetails;
import com.pig4cloud.pig.admin.service.SysOauthClientDetailsService;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.log.annotation.SysLog;
import com.pig4cloud.pig.common.security.annotation.HasPermission;
import com.pig4cloud.pig.common.security.annotation.Inner;
import com.pig4cloud.plugin.excel.annotation.ResponseExcel;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 客户端管理模块前端控制器
*
* @author lengleng
* @date 2025/05/30
* @since 2018-05-15
*/
@RestController
@AllArgsConstructor
@RequestMapping("/client")
@Tag(description = "client", name = "客户端管理模块")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysClientController {
private final SysOauthClientDetailsService clientDetailsService;
/**
* 通过客户端ID查询客户端详情
* @param clientId 客户端ID
* @return 包含客户端详情的响应对象
*/
@GetMapping("/{clientId}")
public R getByClientId(@PathVariable String clientId) {
SysOauthClientDetails details = clientDetailsService
.getOne(Wrappers.<SysOauthClientDetails>lambdaQuery().eq(SysOauthClientDetails::getClientId, clientId));
return R.ok(details);
}
/**
* 分页查询系统终端信息
* @param page 分页参数对象
* @param sysOauthClientDetails 系统终端查询条件
* @return 分页查询结果
*/
@GetMapping("/page")
public R getClientPage(@ParameterObject Page page, @ParameterObject SysOauthClientDetails sysOauthClientDetails) {
LambdaQueryWrapper<SysOauthClientDetails> wrapper = Wrappers.<SysOauthClientDetails>lambdaQuery()
.like(StrUtil.isNotBlank(sysOauthClientDetails.getClientId()), SysOauthClientDetails::getClientId,
sysOauthClientDetails.getClientId())
.like(StrUtil.isNotBlank(sysOauthClientDetails.getClientSecret()), SysOauthClientDetails::getClientSecret,
sysOauthClientDetails.getClientSecret());
return R.ok(clientDetailsService.page(page, wrapper));
}
/**
* 添加客户端终端
* @param clientDetails 客户端详情实体
* @return 操作结果,成功返回success,失败返回false
*/
@SysLog("添加终端")
@PostMapping
@HasPermission("sys_client_add")
public R saveClient(@Valid @RequestBody SysOauthClientDetails clientDetails) {
return R.ok(clientDetailsService.saveClient(clientDetails));
}
/**
* 根据ID列表批量删除终端
* @param ids 要删除的终端ID数组
* @return 操作结果,成功返回success
*/
@SysLog("删除终端")
@DeleteMapping
@HasPermission("sys_client_del")
public R removeById(@RequestBody Long[] ids) {
clientDetailsService.removeBatchByIds(CollUtil.toList(ids));
return R.ok();
}
/**
* 编辑终端信息
* @param clientDetails 终端实体信息
* @return 操作结果
*/
@SysLog("编辑终端")
@PutMapping
@HasPermission("sys_client_edit")
public R updateClient(@Valid @RequestBody SysOauthClientDetails clientDetails) {
return R.ok(clientDetailsService.updateClientById(clientDetails));
}
/**
* 根据客户端ID获取客户端详情
* @param clientId 客户端ID
* @return 包含客户端详情的响应结果
*/
@Inner
@GetMapping("/getClientDetailsById/{clientId}")
public R getClientDetailsById(@PathVariable String clientId) {
return R.ok(clientDetailsService.getOne(
Wrappers.<SysOauthClientDetails>lambdaQuery().eq(SysOauthClientDetails::getClientId, clientId), false));
}
/**
* 同步缓存字典
* @return 操作结果
*/
@SysLog("同步终端")
@PutMapping("/sync")
public R syncClient() {
return clientDetailsService.syncClientCache();
}
/**
* 导出客户端信息到Excel
* @param sysOauthClientDetails 客户端查询条件
* @return 符合条件的客户端列表
*/
@ResponseExcel
@SysLog("导出excel")
@GetMapping("/export")
public List<SysOauthClientDetails> exportClients(SysOauthClientDetails sysOauthClientDetails) {
return clientDetailsService.list(Wrappers.query(sysOauthClientDetails));
}
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.controller;
import com.pig4cloud.pig.admin.api.entity.SysDept;
import com.pig4cloud.pig.admin.api.vo.DeptExcelVo;
import com.pig4cloud.pig.admin.service.SysDeptService;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.log.annotation.SysLog;
import com.pig4cloud.pig.common.security.annotation.HasPermission;
import com.pig4cloud.plugin.excel.annotation.RequestExcel;
import com.pig4cloud.plugin.excel.annotation.ResponseExcel;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.List;
/**
* 部门管理前端控制器
*
* @author lengleng
* @date 2025/05/30
* @since 2018-01-20
*/
@RestController
@AllArgsConstructor
@RequestMapping("/dept")
@Tag(description = "dept", name = "部门管理模块")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysDeptController {
private final SysDeptService sysDeptService;
/**
* 通过ID查询部门信息
* @param id 部门ID
* @return 包含部门信息的响应对象
*/
@GetMapping("/{id}")
public R getById(@PathVariable Long id) {
return R.ok(sysDeptService.getById(id));
}
/**
* 查询全部部门列表
* @return 包含全部部门列表的响应结果
*/
@GetMapping("/list")
public R listDepts() {
return R.ok(sysDeptService.list());
}
/**
* 获取树形菜单
* @param deptName 部门名称
* @return 包含树形菜单的响应结果
*/
@GetMapping(value = "/tree")
public R getDeptTree(String deptName) {
return R.ok(sysDeptService.getDeptTree(deptName));
}
/**
* 保存部门信息
* @param sysDept 部门实体
* @return 操作结果
*/
@SysLog("添加部门")
@PostMapping
@HasPermission("sys_dept_add")
public R saveDept(@Valid @RequestBody SysDept sysDept) {
return R.ok(sysDeptService.save(sysDept));
}
/**
* 根据ID删除部门
* @param id 部门ID
* @return 操作结果,成功返回true,失败返回false
*/
@SysLog("删除部门")
@DeleteMapping("/{id}")
@HasPermission("sys_dept_del")
public R removeById(@PathVariable Long id) {
return R.ok(sysDeptService.removeDeptById(id));
}
/**
* 编辑部门信息
* @param sysDept 部门实体对象
* @return 操作结果,成功返回success,失败返回false
*/
@SysLog("编辑部门")
@PutMapping
@HasPermission("sys_dept_edit")
public R updateDept(@Valid @RequestBody SysDept sysDept) {
sysDept.setUpdateTime(LocalDateTime.now());
return R.ok(sysDeptService.updateById(sysDept));
}
/**
* 获取部门子级列表
* @param deptId 部门ID
* @return 包含子级部门列表的响应结果
*/
@GetMapping(value = "/getDescendantList/{deptId}")
public R getDescendantList(@PathVariable Long deptId) {
return R.ok(sysDeptService.listDescendants(deptId));
}
/**
* 导出部门数据
* @return 部门数据列表
*/
@ResponseExcel
@GetMapping("/export")
public List<DeptExcelVo> exportDepts() {
return sysDeptService.exportDepts();
}
/**
* 导入部门信息
* @param excelVOList 部门Excel数据列表
* @param bindingResult 数据校验结果
* @return 导入结果
*/
@PostMapping("import")
public R importDept(@RequestExcel List<DeptExcelVo> excelVOList, BindingResult bindingResult) {
return sysDeptService.importDept(excelVOList, bindingResult);
}
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.controller;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.pig.admin.api.entity.SysDict;
import com.pig4cloud.pig.admin.api.entity.SysDictItem;
import com.pig4cloud.pig.admin.service.SysDictItemService;
import com.pig4cloud.pig.admin.service.SysDictService;
import com.pig4cloud.pig.common.core.constant.CacheConstants;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.log.annotation.SysLog;
import com.pig4cloud.pig.common.security.annotation.Inner;
import com.pig4cloud.plugin.excel.annotation.ResponseExcel;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.http.HttpHeaders;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 字典表前端控制器
*
* @author lengleng
* @date 2025/05/30
* @since 2019-03-19
*/
@RestController
@AllArgsConstructor
@RequestMapping("/dict")
@Tag(description = "dict", name = "字典管理模块")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysDictController {
private final SysDictService sysDictService;
private final SysDictItemService sysDictItemService;
/**
* 通过ID查询字典信息
* @param id 字典ID
* @return 包含字典信息的响应对象
*/
@GetMapping("/details/{id}")
public R getById(@PathVariable Long id) {
return R.ok(sysDictService.getById(id));
}
/**
* 查询字典详细信息
* @param query 字典查询条件对象
* @return 包含字典信息的响应结果
*/
@GetMapping("/details")
public R getDetails(@ParameterObject SysDict query) {
return R.ok(sysDictService.getOne(Wrappers.query(query), false));
}
/**
* 分页查询字典信息
* @param page 分页对象
* @param sysDict 字典查询条件
* @return 包含分页结果的响应对象
*/
@GetMapping("/page")
public R<IPage> getDictPage(@ParameterObject Page page, @ParameterObject SysDict sysDict) {
return R.ok(sysDictService.page(page,
Wrappers.<SysDict>lambdaQuery()
.eq(StrUtil.isNotBlank(sysDict.getSystemFlag()), SysDict::getSystemFlag, sysDict.getSystemFlag())
.like(StrUtil.isNotBlank(sysDict.getDictType()), SysDict::getDictType, sysDict.getDictType())));
}
/**
* 保存字典信息
* @param sysDict 字典信息对象
* @return 操作结果,包含保存的字典信息
*/
@SysLog("添加字典")
@PostMapping
@PreAuthorize("@pms.hasPermission('sys_dict_add')")
public R saveDict(@Valid @RequestBody SysDict sysDict) {
sysDictService.save(sysDict);
return R.ok(sysDict);
}
/**
* 删除字典并清除字典缓存
* @param ids 字典ID数组
* @return 操作结果
*/
@SysLog("删除字典")
@DeleteMapping
@PreAuthorize("@pms.hasPermission('sys_dict_del')")
@CacheEvict(value = CacheConstants.DICT_DETAILS, allEntries = true)
public R removeById(@RequestBody Long[] ids) {
return R.ok(sysDictService.removeDictByIds(ids));
}
/**
* 修改字典信息
* @param sysDict 字典信息
* @return 操作结果 success/false
*/
@PutMapping
@SysLog("修改字典")
@PreAuthorize("@pms.hasPermission('sys_dict_edit')")
public R updateDict(@Valid @RequestBody SysDict sysDict) {
return sysDictService.updateDict(sysDict);
}
/**
* 分页查询字典列表
* @param name 字典类型名称或描述
* @return 包含字典列表的响应结果
*/
@GetMapping("/list")
public R listDicts(String name) {
return R.ok(sysDictService.list(Wrappers.<SysDict>lambdaQuery()
.like(StrUtil.isNotBlank(name), SysDict::getDictType, name)
.or()
.like(StrUtil.isNotBlank(name), SysDict::getDescription, name)));
}
/**
* 分页查询字典项
* @param page 分页对象
* @param sysDictItem 字典项查询条件
* @return 分页查询结果
*/
@GetMapping("/item/page")
public R getDictItemPage(Page page, SysDictItem sysDictItem) {
return R.ok(sysDictItemService.page(page, Wrappers.query(sysDictItem)));
}
/**
* 通过id查询字典项详情
* @param id 字典项id
* @return 包含字典项详情的响应结果
*/
@GetMapping("/item/details/{id}")
public R getDictItemById(@PathVariable("id") Long id) {
return R.ok(sysDictItemService.getById(id));
}
/**
* 获取字典项详情
* @param query 字典项查询条件
* @return 包含字典项详情的响应结果
*/
@GetMapping("/item/details")
public R getDictItemDetails(SysDictItem query) {
return R.ok(sysDictItemService.getOne(Wrappers.query(query), false));
}
/**
* 新增字典项
* @param sysDictItem 字典项对象
* @return 操作结果
*/
@SysLog("新增字典项")
@PostMapping("/item")
@CacheEvict(value = CacheConstants.DICT_DETAILS, allEntries = true)
public R saveDictItem(@RequestBody SysDictItem sysDictItem) {
return R.ok(sysDictItemService.save(sysDictItem));
}
/**
* 修改字典项
* @param sysDictItem 要修改的字典项对象
* @return 操作结果
*/
@SysLog("修改字典项")
@PutMapping("/item")
public R updateDictItem(@RequestBody SysDictItem sysDictItem) {
return sysDictItemService.updateDictItem(sysDictItem);
}
/**
* 通过id删除字典项
* @param id 字典项id
* @return 操作结果
*/
@SysLog("删除字典项")
@DeleteMapping("/item/{id}")
public R removeDictItemById(@PathVariable Long id) {
return sysDictItemService.removeDictItem(id);
}
/**
* 同步字典缓存
* @return 操作结果
*/
@SysLog("同步字典")
@PutMapping("/sync")
public R syncDict() {
return sysDictService.syncDictCache();
}
/**
* 导出字典项数据
* @param sysDictItem 字典项查询条件
* @return 符合条件的字典项列表
*/
@ResponseExcel
@GetMapping("/export")
public List<SysDictItem> exportDictItems(SysDictItem sysDictItem) {
return sysDictItemService.list(Wrappers.query(sysDictItem));
}
/**
* 通过字典类型查找字典
* @param type 类型
* @return 同类型字典
*/
@GetMapping("/type/{type}")
@Cacheable(value = CacheConstants.DICT_DETAILS, key = "#type", unless = "#result.data.isEmpty()")
public R<List<SysDictItem>> getDictByType(@PathVariable String type) {
return R.ok(sysDictItemService.list(Wrappers.<SysDictItem>query().lambda().eq(SysDictItem::getDictType, type)));
}
/**
* 通过字典类型查找字典 (针对feign调用) TODO: 兼容性方案,代码重复
* @param type 类型
* @return 同类型字典
*/
@Inner
@GetMapping("/remote/type/{type}")
@Cacheable(value = CacheConstants.DICT_DETAILS, key = "#type", unless = "#result.data.isEmpty()")
public R<List<SysDictItem>> getRemoteDictByType(@PathVariable String type) {
return R.ok(sysDictItemService.list(Wrappers.<SysDictItem>query().lambda().eq(SysDictItem::getDictType, type)));
}
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pig.admin.controller;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
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.pig4cloud.pig.admin.api.entity.SysFile;
import com.pig4cloud.pig.admin.service.SysFileService;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.log.annotation.SysLog;
import com.pig4cloud.pig.common.security.annotation.HasPermission;
import com.pig4cloud.pig.common.security.annotation.Inner;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
/**
* 文件管理控制器
*
* @author lengleng
* @date 2025/05/30
*/
@RestController
@AllArgsConstructor
@RequestMapping("/sys-file")
@Tag(description = "sys-file", name = "文件管理")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysFileController {
private final SysFileService sysFileService;
/**
* 分页查询文件信息
* @param page 分页参数对象
* @param sysFile 文件查询条件对象
* @return 分页查询结果
*/
@Operation(summary = "分页查询", description = "分页查询")
@GetMapping("/page")
public R getFilePage(@ParameterObject Page page, @ParameterObject SysFile sysFile) {
LambdaQueryWrapper<SysFile> wrapper = Wrappers.<SysFile>lambdaQuery()
.like(StrUtil.isNotBlank(sysFile.getOriginal()), SysFile::getOriginal, sysFile.getOriginal());
return R.ok(sysFileService.page(page, wrapper));
}
/**
* 通过id删除文件管理
* @param ids 要删除的文件id数组
* @return 操作结果
*/
@Operation(summary = "通过id删除文件管理", description = "通过id删除文件管理")
@SysLog("删除文件管理")
@DeleteMapping
@HasPermission("sys_file_del")
public R removeById(@RequestBody Long[] ids) {
for (Long id : ids) {
sysFileService.removeFile(id);
}
return R.ok();
}
/**
* 上传文件
* @param file 上传的文件资源
* @return 包含文件路径的R对象,格式为(/admin/bucketName/filename)
*/
@PostMapping(value = "/upload")
public R upload(@RequestPart("file") MultipartFile file) {
return sysFileService.uploadFile(file);
}
/**
* 获取文件并写入响应流
* @param bucket 桶名称
* @param fileName 文件路径/名称
* @param response HTTP响应对象
*/
@Inner(false)
@GetMapping("/{bucket}/{fileName}")
public void file(@PathVariable String bucket, @PathVariable String fileName, HttpServletResponse response) {
sysFileService.getFile(bucket, fileName, response);
}
/**
* 获取本地resources目录下的文件并写入响应流
* @param fileName 文件名称
* @param response HTTP响应对象,用于输出文件内容
* @throws IOException 文件操作异常
*/
@SneakyThrows
@GetMapping("/local/file/{fileName}")
public void localFile(@PathVariable String fileName, HttpServletResponse response) {
ClassPathResource resource = new ClassPathResource("file/" + fileName);
response.setContentType("application/octet-stream; charset=UTF-8");
IoUtil.copy(resource.getInputStream(), response.getOutputStream());
}
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.controller;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.pig.admin.api.dto.SysLogDTO;
import com.pig4cloud.pig.admin.api.entity.SysLog;
import com.pig4cloud.pig.admin.service.SysLogService;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.security.annotation.HasPermission;
import com.pig4cloud.pig.common.security.annotation.Inner;
import com.pig4cloud.plugin.excel.annotation.ResponseExcel;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 系统日志前端控制器
*
* @author lengleng
* @since 2017-11-20
*/
@RestController
@AllArgsConstructor
@RequestMapping("/log")
@Tag(description = "log", name = "日志管理模块")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysLogController {
private final SysLogService sysLogService;
/**
* 分页查询系统日志
* @param page 分页参数对象
* @param sysLog 系统日志查询条件
* @return 包含分页结果的响应对象
*/
@GetMapping("/page")
public R getLogPage(@ParameterObject Page page, @ParameterObject SysLogDTO sysLog) {
return R.ok(sysLogService.getLogPage(page, sysLog));
}
/**
* 批量删除日志
* @param ids 要删除的日志ID数组
* @return 操作结果,成功返回success,失败返回false
*/
@DeleteMapping
@HasPermission("sys_log_del")
public R removeByIds(@RequestBody Long[] ids) {
return R.ok(sysLogService.removeBatchByIds(CollUtil.toList(ids)));
}
/**
* 保存日志
* @param sysLog 日志实体
* @return 操作结果,成功返回success,失败返回false
*/
@Inner
@PostMapping("/save")
public R saveLog(@Valid @RequestBody SysLog sysLog) {
return R.ok(sysLogService.saveLog(sysLog));
}
/**
* 导出系统日志到Excel表格
* @param sysLog 系统日志查询条件DTO
* @return 符合查询条件的系统日志列表
*/
@ResponseExcel
@GetMapping("/export")
@HasPermission("sys_log_export")
public List<SysLog> exportLogs(SysLogDTO sysLog) {
return sysLogService.listLogs(sysLog);
}
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.controller;
import com.pig4cloud.pig.admin.api.entity.SysMenu;
import com.pig4cloud.pig.admin.service.SysMenuService;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.log.annotation.SysLog;
import com.pig4cloud.pig.common.security.annotation.HasPermission;
import com.pig4cloud.pig.common.security.util.SecurityUtils;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.*;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 菜单管理控制器
*
* @author lengleng
* @date 2025/05/30
*/
@RestController
@AllArgsConstructor
@RequestMapping("/menu")
@Tag(description = "menu", name = "菜单管理模块")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysMenuController {
private final SysMenuService sysMenuService;
/**
* 获取当前用户的树形菜单集合
* @param type 菜单类型
* @param parentId 父菜单ID
* @return 包含菜单数据的响应对象
*/
@GetMapping
public R getUserMenu(String type, Long parentId) {
// 获取符合条件的菜单
Set<SysMenu> all = new HashSet<>();
SecurityUtils.getRoles().forEach(roleId -> all.addAll(sysMenuService.findMenuByRoleId(roleId)));
return R.ok(sysMenuService.filterMenu(all, type, parentId));
}
/**
* 获取树形菜单集合
* @param parentId 父节点ID
* @param menuName 菜单名称
* @param type 菜单类型
* @return 包含树形菜单的响应结果
*/
@GetMapping(value = "/tree")
public R getMenuTree(Long parentId, String menuName, String type) {
return R.ok(sysMenuService.getMenuTree(parentId, menuName, type));
}
/**
* 根据角色ID获取菜单树
* @param roleId 角色ID
* @return 包含菜单ID列表的响应结果
*/
@GetMapping("/tree/{roleId}")
public R getRoleTree(@PathVariable Long roleId) {
return R.ok(sysMenuService.findMenuByRoleId(roleId).stream().map(SysMenu::getMenuId).toList());
}
/**
* 通过ID查询菜单的详细信息
* @param id 菜单ID
* @return 包含菜单详细信息的响应对象
*/
@GetMapping("/{id}")
public R getById(@PathVariable Long id) {
return R.ok(sysMenuService.getById(id));
}
/**
* 新增菜单
* @param sysMenu 菜单信息
* @return 操作结果
*/
@SysLog("新增菜单")
@PostMapping
@HasPermission("sys_menu_add")
public R saveMenu(@Valid @RequestBody SysMenu sysMenu) {
sysMenuService.save(sysMenu);
return R.ok(sysMenu);
}
/**
* 根据菜单ID删除菜单
* @param id 要删除的菜单ID
* @return 操作结果,成功返回success,失败返回false
*/
@SysLog("删除菜单")
@DeleteMapping("/{id}")
@HasPermission("sys_menu_del")
public R removeById(@PathVariable Long id) {
return sysMenuService.removeMenuById(id);
}
/**
* 更新菜单信息
* @param sysMenu 菜单对象
* @return 操作结果
*/
@SysLog("更新菜单")
@PutMapping
@HasPermission("sys_menu_edit")
public R updateMenu(@Valid @RequestBody SysMenu sysMenu) {
return R.ok(sysMenuService.updateMenuById(sysMenu));
}
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pig.admin.controller;
import com.pig4cloud.pig.admin.service.SysMobileService;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.security.annotation.Inner;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 手机管理模块控制器:提供手机验证码相关服务
*
* @author lengleng
* @date 2018/11/14
*/
@RestController
@AllArgsConstructor
@RequestMapping("/mobile")
@Tag(description = "mobile", name = "手机管理模块")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysMobileController {
private final SysMobileService mobileService;
/**
* 发送短信验证码
* @param mobile 手机号码
* @return 操作结果
*/
@Inner(value = false)
@GetMapping("/{mobile}")
public R sendSmsCode(@PathVariable String mobile) {
return mobileService.sendSmsCode(mobile);
}
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pig.admin.controller;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.pig.admin.api.entity.SysPost;
import com.pig4cloud.pig.admin.api.vo.PostExcelVO;
import com.pig4cloud.pig.admin.service.SysPostService;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.log.annotation.SysLog;
import com.pig4cloud.pig.common.security.annotation.HasPermission;
import com.pig4cloud.plugin.excel.annotation.RequestExcel;
import com.pig4cloud.plugin.excel.annotation.ResponseExcel;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.http.HttpHeaders;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 岗位信息表管理控制器
*
* @author lengleng
* @date 2025/05/30
*/
@RestController
@RequiredArgsConstructor
@RequestMapping("/post")
@Tag(description = "post", name = "岗位信息表管理")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysPostController {
private final SysPostService sysPostService;
/**
* 获取岗位列表
* @return 包含岗位列表的响应结果
*/
@GetMapping("/list")
public R<List<SysPost>> listPosts() {
return R.ok(sysPostService.list(Wrappers.emptyWrapper()));
}
/**
* 分页查询岗位信息
* @param page 分页参数对象
* @param sysPost 岗位查询条件对象
* @return 分页查询结果
*/
@Operation(description = "分页查询", summary = "分页查询")
@GetMapping("/page")
@HasPermission("sys_post_view")
public R getPostPage(@ParameterObject Page page, @ParameterObject SysPost sysPost) {
return R.ok(sysPostService.page(page, Wrappers.<SysPost>lambdaQuery()
.like(StrUtil.isNotBlank(sysPost.getPostName()), SysPost::getPostName, sysPost.getPostName())));
}
/**
* 通过id查询岗位信息
* @param postId 岗位id
* @return 包含岗位信息的响应结果
*/
@Operation(description = "通过id查询", summary = "通过id查询")
@GetMapping("/details/{postId}")
@HasPermission("sys_post_view")
public R getById(@PathVariable("postId") Long postId) {
return R.ok(sysPostService.getById(postId));
}
/**
* 查询岗位详细信息
* @param query 查询条件
* @return 统一响应结果R,包含查询到的岗位信息
*/
@Operation(description = "查询角色信息", summary = "查询角色信息")
@GetMapping("/details")
@HasPermission("sys_post_view")
public R getDetails(SysPost query) {
return R.ok(sysPostService.getOne(Wrappers.query(query), false));
}
/**
* 新增岗位信息
* @param sysPost 岗位信息对象
* @return 操作结果
*/
@Operation(description = "新增岗位信息表", summary = "新增岗位信息表")
@SysLog("新增岗位信息表")
@PostMapping
@HasPermission("sys_post_add")
public R savePost(@RequestBody SysPost sysPost) {
return R.ok(sysPostService.save(sysPost));
}
/**
* 修改岗位信息
* @param sysPost 岗位信息对象
* @return 操作结果
*/
@Operation(description = "修改岗位信息表", summary = "修改岗位信息表")
@SysLog("修改岗位信息表")
@PutMapping
@HasPermission("sys_post_edit")
public R updatePost(@RequestBody SysPost sysPost) {
return R.ok(sysPostService.updateById(sysPost));
}
/**
* 通过id批量删除岗位信息
* @param ids 岗位id数组
* @return 统一返回结果
*/
@Operation(description = "通过id删除岗位信息表", summary = "通过id删除岗位信息表")
@SysLog("通过id删除岗位信息表")
@DeleteMapping
@HasPermission("sys_post_del")
public R removeById(@RequestBody Long[] ids) {
return R.ok(sysPostService.removeBatchByIds(CollUtil.toList(ids)));
}
/**
* 导出岗位信息到Excel表格
* @return 岗位信息Excel文件流
*/
@ResponseExcel
@GetMapping("/export")
@HasPermission("sys_post_export")
public List<PostExcelVO> exportPosts() {
return sysPostService.listPosts();
}
/**
* 导入岗位信息
* @param excelVOList 岗位Excel数据列表
* @param bindingResult 数据校验结果
* @return 导入结果
*/
@PostMapping("/import")
@HasPermission("sys_post_export")
public R importRole(@RequestExcel List<PostExcelVO> excelVOList, BindingResult bindingResult) {
return sysPostService.importPost(excelVOList, bindingResult);
}
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pig.admin.controller;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.pig.admin.api.entity.SysPublicParam;
import com.pig4cloud.pig.admin.service.SysPublicParamService;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.log.annotation.SysLog;
import com.pig4cloud.pig.common.security.annotation.HasPermission;
import com.pig4cloud.pig.common.security.annotation.Inner;
import com.pig4cloud.plugin.excel.annotation.ResponseExcel;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 公共参数控制器:提供公共参数的增删改查及同步功能
*
* @author lengleng
* @date 2025/05/30
*/
@RestController
@AllArgsConstructor
@RequestMapping("/param")
@Tag(description = "param", name = "公共参数配置")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysPublicParamController {
private final SysPublicParamService sysPublicParamService;
/**
* 根据key查询公共参数值
* @param publicKey 公共参数key
* @return 公共参数值
*/
@Inner(value = false)
@Operation(description = "查询公共参数值", summary = "根据key查询公共参数值")
@GetMapping("/publicValue/{publicKey}")
public R publicKey(@PathVariable("publicKey") String publicKey) {
return R.ok(sysPublicParamService.getParamValue(publicKey));
}
/**
* 分页查询系统公共参数
* @param page 分页对象
* @param sysPublicParam 公共参数查询条件
* @return 分页查询结果
*/
@Operation(description = "分页查询", summary = "分页查询")
@GetMapping("/page")
public R getParamPage(@ParameterObject Page page, @ParameterObject SysPublicParam sysPublicParam) {
LambdaUpdateWrapper<SysPublicParam> wrapper = Wrappers.<SysPublicParam>lambdaUpdate()
.like(StrUtil.isNotBlank(sysPublicParam.getPublicName()), SysPublicParam::getPublicName,
sysPublicParam.getPublicName())
.like(StrUtil.isNotBlank(sysPublicParam.getPublicKey()), SysPublicParam::getPublicKey,
sysPublicParam.getPublicKey())
.eq(StrUtil.isNotBlank(sysPublicParam.getSystemFlag()), SysPublicParam::getSystemFlag,
sysPublicParam.getSystemFlag());
return R.ok(sysPublicParamService.page(page, wrapper));
}
/**
* 通过id查询公共参数
* @param publicId 公共参数id
* @return 包含查询结果的响应对象
*/
@Operation(description = "通过id查询公共参数", summary = "通过id查询公共参数")
@GetMapping("/details/{publicId}")
public R getById(@PathVariable("publicId") Long publicId) {
return R.ok(sysPublicParamService.getById(publicId));
}
/**
* 获取系统公共参数详情
* @param param 系统公共参数查询对象
* @return 包含查询结果的响应对象
*/
@GetMapping("/details")
public R getDetail(@ParameterObject SysPublicParam param) {
return R.ok(sysPublicParamService.getOne(Wrappers.query(param), false));
}
/**
* 新增公共参数
* @param sysPublicParam 公共参数对象
* @return 操作结果
*/
@Operation(description = "新增公共参数", summary = "新增公共参数")
@SysLog("新增公共参数")
@PostMapping
@HasPermission("sys_syspublicparam_add")
public R saveParam(@RequestBody SysPublicParam sysPublicParam) {
return R.ok(sysPublicParamService.save(sysPublicParam));
}
/**
* 修改公共参数
* @param sysPublicParam 公共参数对象
* @return 操作结果
*/
@Operation(description = "修改公共参数", summary = "修改公共参数")
@SysLog("修改公共参数")
@PutMapping
@HasPermission("sys_syspublicparam_edit")
public R updateParam(@RequestBody SysPublicParam sysPublicParam) {
return sysPublicParamService.updateParam(sysPublicParam);
}
/**
* 通过id数组删除公共参数
* @param ids 要删除的公共参数id数组
* @return 操作结果
*/
@Operation(description = "删除公共参数", summary = "删除公共参数")
@SysLog("删除公共参数")
@DeleteMapping
@HasPermission("sys_syspublicparam_del")
public R removeById(@RequestBody Long[] ids) {
return R.ok(sysPublicParamService.removeParamByIds(ids));
}
/**
* 导出excel 表格
* @return
*/
@ResponseExcel
@GetMapping("/export")
@HasPermission("sys_syspublicparam_edit")
public List<SysPublicParam> exportParams() {
return sysPublicParamService.list();
}
/**
* 同步参数到缓存
* @return 操作结果
*/
@SysLog("同步参数")
@PutMapping("/sync")
@HasPermission("sys_syspublicparam_edit")
public R syncParam() {
return sysPublicParamService.syncParamCache();
}
}
package com.pig4cloud.pig.admin.controller;
import com.pig4cloud.pig.admin.api.dto.RegisterUserDTO;
import com.pig4cloud.pig.admin.service.SysUserService;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.log.annotation.SysLog;
import com.pig4cloud.pig.common.security.annotation.Inner;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 用户注册控制器:提供用户注册功能
*
* @author lengleng
* @date 2025/05/30
* @see RegisterUserDTO 注册用户信息传输对象
* @see R 通用返回结果封装
*/
@RestController
@RequestMapping("/register")
@RequiredArgsConstructor
@Tag(description = "register", name = "注册用户管理模块")
@ConditionalOnProperty(name = "register.user", matchIfMissing = true)
public class SysRegisterController {
private final SysUserService userService;
/**
* 注册用户
* @param registerUserDTO 注册用户信息DTO
* @return 注册结果封装对象
*/
@Inner(value = false)
@SysLog("注册用户")
@PostMapping("/user")
public R<Boolean> registerUser(@RequestBody RegisterUserDTO registerUserDTO) {
return userService.registerUser(registerUserDTO);
}
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.controller;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.pig.admin.api.entity.SysRole;
import com.pig4cloud.pig.admin.api.vo.RoleExcelVO;
import com.pig4cloud.pig.admin.api.vo.RoleVO;
import com.pig4cloud.pig.admin.service.SysRoleService;
import com.pig4cloud.pig.common.core.constant.CacheConstants;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.log.annotation.SysLog;
import com.pig4cloud.pig.common.security.annotation.HasPermission;
import com.pig4cloud.plugin.excel.annotation.RequestExcel;
import com.pig4cloud.plugin.excel.annotation.ResponseExcel;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.http.HttpHeaders;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 角色管理控制器:提供角色相关的增删改查及权限管理功能
*
* @author lengleng
* @date 2025/05/30
*/
@RestController
@AllArgsConstructor
@RequestMapping("/role")
@Tag(description = "role", name = "角色管理模块")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysRoleController {
private final SysRoleService sysRoleService;
/**
* 通过ID查询角色信息
* @param id 角色ID
* @return 包含角色信息的响应对象
*/
@GetMapping("/details/{id}")
public R getById(@PathVariable Long id) {
return R.ok(sysRoleService.getById(id));
}
/**
* 查询角色详细信息
* @param query 角色查询条件对象
* @return 包含角色信息的响应结果
*/
@GetMapping("/details")
public R getDetails(@ParameterObject SysRole query) {
return R.ok(sysRoleService.getOne(Wrappers.query(query), false));
}
/**
* 添加角色
* @param sysRole 角色信息
* @return 操作结果,成功返回success,失败返回false
*/
@SysLog("添加角色")
@PostMapping
@HasPermission("sys_role_add")
@CacheEvict(value = CacheConstants.ROLE_DETAILS, allEntries = true)
public R saveRole(@Valid @RequestBody SysRole sysRole) {
return R.ok(sysRoleService.save(sysRole));
}
/**
* 修改角色信息
* @param sysRole 角色信息
* @return 操作结果,成功返回success,失败返回false
*/
@SysLog("修改角色")
@PutMapping
@HasPermission("sys_role_edit")
@CacheEvict(value = CacheConstants.ROLE_DETAILS, allEntries = true)
public R updateRole(@Valid @RequestBody SysRole sysRole) {
return R.ok(sysRoleService.updateById(sysRole));
}
/**
* 根据ID数组删除角色
* @param ids 角色ID数组
* @return 操作结果
*/
@SysLog("删除角色")
@DeleteMapping
@HasPermission("sys_role_del")
@CacheEvict(value = CacheConstants.ROLE_DETAILS, allEntries = true)
public R removeById(@RequestBody Long[] ids) {
return R.ok(sysRoleService.removeRoleByIds(ids));
}
/**
* 获取角色列表
* @return 包含角色列表的响应结果
*/
@GetMapping("/list")
public R listRoles() {
return R.ok(sysRoleService.list(Wrappers.emptyWrapper()));
}
/**
* 分页查询角色信息
* @param page 分页对象
* @param role 查询条件对象
* @return 包含分页结果的响应对象
*/
@GetMapping("/page")
public R getRolePage(Page page, SysRole role) {
return R.ok(sysRoleService.page(page, Wrappers.<SysRole>lambdaQuery()
.like(StrUtil.isNotBlank(role.getRoleName()), SysRole::getRoleName, role.getRoleName())));
}
/**
* 更新角色菜单
* @param roleVo 角色VO对象
* @return 操作结果,成功返回success,失败返回false
*/
@SysLog("更新角色菜单")
@PutMapping("/menu")
@HasPermission("sys_role_perm")
public R saveRoleMenus(@RequestBody RoleVO roleVo) {
return R.ok(sysRoleService.updateRoleMenus(roleVo));
}
/**
* 通过角色ID列表查询角色信息
* @param roleIdList 角色ID列表
* @return 包含查询结果的响应对象
*/
@PostMapping("/getRoleList")
public R getRoleList(@RequestBody List<Long> roleIdList) {
return R.ok(sysRoleService.listRolesByRoleIds(roleIdList, CollUtil.join(roleIdList, StrUtil.UNDERLINE)));
}
/**
* 导出角色数据到Excel表格
* @return 角色数据列表
*/
@ResponseExcel
@GetMapping("/export")
@HasPermission("sys_role_export")
public List<RoleExcelVO> exportRoles() {
return sysRoleService.listRoles();
}
/**
* 导入角色
* @param excelVOList 角色Excel数据列表
* @param bindingResult 数据校验结果
* @return 导入结果
*/
@PostMapping("/import")
@HasPermission("sys_role_export")
public R importRole(@RequestExcel List<RoleExcelVO> excelVOList, BindingResult bindingResult) {
return sysRoleService.importRole(excelVOList, bindingResult);
}
}
package com.pig4cloud.pig.admin.controller;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.core.util.RedisUtils;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.connection.RedisServerCommands;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
/**
* 系统监控控制器:提供系统监控相关接口
*
* @author lengleng
* @date 2025/05/30
*/
@RestController
@RequestMapping("/system")
@RequiredArgsConstructor
@Tag(description = "system", name = "系统监控")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysSystemInfoController {
/**
* 获取Redis缓存监控信息
* @return 包含Redis信息、数据库大小和命令统计的响应结果
*/
@GetMapping("/cache")
public R cache() {
Properties info = RedisUtils.execute(RedisServerCommands::info);
Properties commandStats = RedisUtils.execute(connection -> connection.serverCommands().info("commandstats"));
Object dbSize = RedisUtils.execute((RedisCallback<Object>) RedisServerCommands::dbSize);
if (commandStats == null) {
return R.failed("获取异常");
}
Map<String, Object> result = new HashMap<>(3);
result.put("info", info);
result.put("dbSize", dbSize);
List<Map<String, String>> pieList = new ArrayList<>();
commandStats.stringPropertyNames().forEach(key -> {
Map<String, String> data = new HashMap<>(2);
String property = commandStats.getProperty(key);
data.put("name", StringUtils.removeStart(key, "cmdstat_"));
data.put("value", StringUtils.substringBetween(property, "calls=", ",usec"));
pieList.add(data);
});
result.put("commandStats", pieList);
return R.ok(result);
}
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pig.admin.controller;
import com.pig4cloud.pig.admin.api.feign.RemoteTokenService;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.log.annotation.SysLog;
import com.pig4cloud.pig.common.security.annotation.HasPermission;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
/**
* 令牌管理控制器:提供令牌的分页查询和删除功能
*
* @author lengleng
* @date 2025/05/30
*/
@RestController
@AllArgsConstructor
@RequestMapping("/sys-token")
@Tag(description = "token", name = "令牌管理模块")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysTokenController {
private final RemoteTokenService remoteTokenService;
/**
* 获取分页token信息
* @param params 请求参数集合
* @return 包含token分页信息的响应结果
*/
@RequestMapping("/page")
public R getTokenPage(@RequestBody Map<String, Object> params) {
return remoteTokenService.getTokenPage(params);
}
/**
* 根据token数组删除token
* @param tokens 需要删除的token数组
* @return 操作结果,成功返回success,失败返回false
*/
@SysLog("删除用户token")
@DeleteMapping("/delete")
@HasPermission("sys_token_del")
public R removeById(@RequestBody String[] tokens) {
for (String token : tokens) {
remoteTokenService.removeTokenById(token);
}
return R.ok();
}
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.controller;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.pig.admin.api.dto.UserDTO;
import com.pig4cloud.pig.admin.api.dto.UserInfo;
import com.pig4cloud.pig.admin.api.entity.SysUser;
import com.pig4cloud.pig.admin.api.vo.UserExcelVO;
import com.pig4cloud.pig.admin.service.SysUserService;
import com.pig4cloud.pig.common.core.constant.CommonConstants;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.log.annotation.SysLog;
import com.pig4cloud.pig.common.security.annotation.HasPermission;
import com.pig4cloud.pig.common.security.annotation.Inner;
import com.pig4cloud.pig.common.security.util.SecurityUtils;
import com.pig4cloud.plugin.excel.annotation.RequestExcel;
import com.pig4cloud.plugin.excel.annotation.ResponseExcel;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.http.HttpHeaders;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 用户管理控制器
*
* @author lengleng
* @date 2025/05/30
*/
@RestController
@AllArgsConstructor
@RequestMapping("/user")
@Tag(description = "user", name = "用户管理模块")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysUserController {
private final SysUserService userService;
/**
* 查询用户信息
* @param userDTO 用户信息查询参数
* @return 包含用户信息的R对象
*/
@Inner
@GetMapping(value = { "/info/query" })
public R info(UserDTO userDTO) {
return userService.getUserInfo(userDTO);
}
/**
* 获取当前登录用户的全部信息
* @return 包含用户信息的响应结果
*/
@GetMapping(value = { "/info" })
public R info() {
String username = SecurityUtils.getUser().getUsername();
UserDTO userDTO = new UserDTO();
userDTO.setUsername(username);
// 获取用户信息,不返回数据库密码字段
R<UserInfo> userInfoR = userService.getUserInfo(userDTO);
if (userInfoR.getData() != null) {
userInfoR.getData().setPassword(null);
}
return userInfoR;
}
/**
* 通过ID查询用户信息
* @param id 用户ID
* @return 包含用户信息的响应对象
*/
@GetMapping("/details/{id}")
public R user(@PathVariable Long id) {
return R.ok(userService.getUserById(id));
}
/**
* 查询用户详细信息
* @param query 用户查询条件对象
* @return 包含查询结果的响应对象,用户不存在时返回null
*/
@Inner(value = false)
@GetMapping("/details")
public R getDetails(@ParameterObject SysUser query) {
SysUser sysUser = userService.getOne(Wrappers.query(query), false);
return R.ok(sysUser == null ? null : CommonConstants.SUCCESS);
}
/**
* 删除用户信息
* @param ids 用户ID数组
* @return 操作结果
*/
@SysLog("删除用户信息")
@DeleteMapping
@HasPermission("sys_user_del")
@Operation(summary = "删除用户", description = "根据ID删除用户")
public R userDel(@RequestBody Long[] ids) {
return R.ok(userService.removeUserByIds(ids));
}
/**
* 添加用户
* @param userDto 用户信息DTO
* @return 操作结果,成功返回success,失败返回false
*/
@SysLog("添加用户")
@PostMapping
@HasPermission("sys_user_add")
public R saveUser(@RequestBody UserDTO userDto) {
return R.ok(userService.saveUser(userDto));
}
/**
* 更新用户信息
* @param userDto 用户信息DTO对象
* @return 包含操作结果的R对象
*/
@SysLog("更新用户信息")
@PutMapping
@HasPermission("sys_user_edit")
public R updateUser(@Valid @RequestBody UserDTO userDto) {
return R.ok(userService.updateUser(userDto));
}
/**
* 分页查询用户
* @param page 参数集
* @param userDTO 查询参数列表
* @return 用户集合
*/
@GetMapping("/page")
public R getUserPage(@ParameterObject Page page, @ParameterObject UserDTO userDTO) {
return R.ok(userService.getUsersWithRolePage(page, userDTO));
}
/**
* 修改个人信息
* @param userDto 用户信息传输对象
* @return 操作结果,成功返回success,失败返回false
*/
@SysLog("修改个人信息")
@PutMapping("/edit")
public R updateUserInfo(@Valid @RequestBody UserDTO userDto) {
return userService.updateUserInfo(userDto);
}
/**
* 导出用户数据到Excel表格
* @param userDTO 用户查询条件
* @return 用户数据列表
*/
@ResponseExcel
@GetMapping("/export")
@HasPermission("sys_user_export")
public List exportUsers(UserDTO userDTO) {
return userService.listUsers(userDTO);
}
/**
* 导入用户信息
* @param excelVOList 用户Excel数据列表
* @param bindingResult 数据校验结果
* @return 导入结果
*/
@PostMapping("/import")
@HasPermission("sys_user_export")
public R importUser(@RequestExcel List<UserExcelVO> excelVOList, BindingResult bindingResult) {
return userService.importUsers(excelVOList, bindingResult);
}
/**
* 锁定指定用户
* @param username 用户名
* @return 操作结果
*/
@PutMapping("/lock/{username}")
public R lockUser(@PathVariable String username) {
return userService.lockUser(username);
}
/**
* 修改当前用户密码
* @param userDto 用户数据传输对象,包含新密码等信息
* @return 操作结果
*/
@PutMapping("/password")
public R password(@RequestBody UserDTO userDto) {
String username = SecurityUtils.getUser().getUsername();
userDto.setUsername(username);
return userService.changePassword(userDto);
}
/**
* 检查密码是否符合要求
* @param password 待检查的密码
* @return 检查结果
*/
@PostMapping("/check")
public R check(String password) {
return userService.checkPassword(password);
}
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.pig4cloud.pig.admin.api.entity.SysDept;
import org.apache.ibatis.annotations.Mapper;
/**
* 部门管理 Mapper 接口
*
* @author lengleng
* @since 2018-01-20
*/
@Mapper
public interface SysDeptMapper extends BaseMapper<SysDept> {
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pig.admin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.pig4cloud.pig.admin.api.entity.SysDictItem;
import org.apache.ibatis.annotations.Mapper;
/**
* 系统字典项数据访问接口
*
* @author lengleng
* @date 2025/05/30
*/
@Mapper
public interface SysDictItemMapper extends BaseMapper<SysDictItem> {
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.pig4cloud.pig.admin.api.entity.SysDict;
import org.apache.ibatis.annotations.Mapper;
/**
* 字典表 Mapper 接口
*
* @author lengleng
* @date 2025/06/27
*/
@Mapper
public interface SysDictMapper extends BaseMapper<SysDict> {
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pig.admin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.pig4cloud.pig.admin.api.entity.SysFile;
import org.apache.ibatis.annotations.Mapper;
/**
* 系统文件映射接口
*
* @author lengleng
* @date 2025/05/30
*/
@Mapper
public interface SysFileMapper extends BaseMapper<SysFile> {
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.pig4cloud.pig.admin.api.entity.SysLog;
import org.apache.ibatis.annotations.Mapper;
/**
* 系统日志表 Mapper 接口
*
* @author lengleng
*/
@Mapper
public interface SysLogMapper extends BaseMapper<SysLog> {
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.pig4cloud.pig.admin.api.entity.SysMenu;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* <p>
* 菜单权限表 Mapper 接口
* </p>
*
* @author lengleng
* @since 2017-10-29
*/
@Mapper
public interface SysMenuMapper extends BaseMapper<SysMenu> {
/**
* 通过角色编号查询菜单
* @param roleId 角色ID
* @return
*/
List<SysMenu> listMenusByRoleId(Long roleId);
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.pig4cloud.pig.admin.api.entity.SysOauthClientDetails;
import org.apache.ibatis.annotations.Mapper;
/**
* 系统OAuth客户端详情 Mapper接口
*
* @author lengleng
* @date 2025/06/27
*/
@Mapper
public interface SysOauthClientDetailsMapper extends BaseMapper<SysOauthClientDetails> {
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pig.admin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.pig4cloud.pig.admin.api.entity.SysPost;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* 岗位信息表 Mapper 接口
*
* @author lengleng
* @date 2025/06/27
*/
@Mapper
public interface SysPostMapper extends BaseMapper<SysPost> {
/**
* 通过用户ID,查询岗位信息
* @param userId 用户id
* @return 岗位信息
*/
List<SysPost> listPostsByUserId(Long userId);
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pig.admin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.pig4cloud.pig.admin.api.entity.SysPublicParam;
import org.apache.ibatis.annotations.Mapper;
/**
* 公共参数配置
*
* @author Lucky
* @date 2019-04-29
*/
@Mapper
public interface SysPublicParamMapper extends BaseMapper<SysPublicParam> {
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.pig4cloud.pig.admin.api.entity.SysRole;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* <p>
* Mapper 接口
* </p>
*
* @author lengleng
* @since 2017-10-29
*/
@Mapper
public interface SysRoleMapper extends BaseMapper<SysRole> {
/**
* 通过用户ID查询角色信息
* @param userId 用户ID
* @return 角色信息列表
*/
List<SysRole> listRolesByUserId(Long userId);
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.pig4cloud.pig.admin.api.entity.SysRoleMenu;
import org.apache.ibatis.annotations.Mapper;
/**
* 角色菜单表 Mapper 接口
*
* @author lengleng
* @since 2017-10-29
*/
@Mapper
public interface SysRoleMenuMapper extends BaseMapper<SysRoleMenu> {
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.pig.admin.api.dto.UserDTO;
import com.pig4cloud.pig.admin.api.entity.SysUser;
import com.pig4cloud.pig.admin.api.vo.UserVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* <p>
* 用户表 Mapper 接口
* </p>
*
* @author lengleng
* @since 2017-10-29
*/
@Mapper
public interface SysUserMapper extends BaseMapper<SysUser> {
/**
* 根据用户DTO获取用户VO
* @param userDTO 用户查询条件DTO
* @return 用户信息VO
*/
UserVO getUser(@Param("query") UserDTO userDTO);
/**
* 分页查询用户信息(含角色)
* @param page 分页参数
* @param userDTO 用户查询条件
* @return 分页用户信息列表
*/
IPage<UserVO> getUsersPage(Page page, @Param("query") UserDTO userDTO);
/**
* 查询用户列表
* @param userDTO 查询条件
* @return 用户VO列表
*/
List<UserVO> listUsers(@Param("query") UserDTO userDTO);
}
/*
* Copyright (c) 2020 pig4cloud Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.pig4cloud.pig.admin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.pig4cloud.pig.admin.api.entity.SysUserPost;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* 用户岗位 Mapper 接口
* </p>
*
* @author fxz
* @since 2022/3/19
*/
@Mapper
public interface SysUserPostMapper extends BaseMapper<SysUserPost> {
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.pig4cloud.pig.admin.api.entity.SysUserRole;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* 用户角色表 Mapper 接口
* </p>
*
* @author lengleng
* @since 2017-10-29
*/
@Mapper
public interface SysUserRoleMapper extends BaseMapper<SysUserRole> {
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.service;
import cn.hutool.core.lang.tree.Tree;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pig.admin.api.entity.SysDept;
import com.pig4cloud.pig.admin.api.vo.DeptExcelVo;
import com.pig4cloud.pig.common.core.util.R;
import org.springframework.validation.BindingResult;
import java.util.List;
/**
* 部门管理服务接口
*
* @author lengleng
* @since 2018-01-20
*/
public interface SysDeptService extends IService<SysDept> {
/**
* 查询部门树菜单
* @param deptName 部门名称
* @return 部门树结构
*/
List<Tree<Long>> getDeptTree(String deptName);
/**
* 根据部门ID删除部门
* @param id 要删除的部门ID
* @return 删除操作是否成功,成功返回true,失败返回false
*/
Boolean removeDeptById(Long id);
/**
* 导出部门Excel数据列表
* @return 部门Excel数据列表
*/
List<DeptExcelVo> exportDepts();
/**
* 导入部门数据
* @param excelVOList 部门Excel数据列表
* @param bindingResult 数据校验结果
* @return 导入结果
*/
R importDept(List<DeptExcelVo> excelVOList, BindingResult bindingResult);
/**
* 获取指定部门的所有后代部门列表
* @param deptId 部门ID
* @return 后代部门列表,如果不存在则返回空列表
*/
List<SysDept> listDescendants(Long deptId);
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pig.admin.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pig.admin.api.entity.SysDictItem;
import com.pig4cloud.pig.common.core.util.R;
/**
* 字典项服务接口
*
* @author lengleng
* @date 2025/05/30
*/
public interface SysDictItemService extends IService<SysDictItem> {
/**
* 删除字典项
* @param id 字典项ID
* @return 操作结果
*/
R removeDictItem(Long id);
/**
* 更新字典项
* @param item 需要更新的字典项
* @return 操作结果
*/
R updateDictItem(SysDictItem item);
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pig.admin.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pig.admin.api.entity.SysDict;
import com.pig4cloud.pig.common.core.util.R;
/**
* 字典表服务接口 提供字典数据的增删改查及缓存同步功能
*
* @author lengleng
* @date 2025/05/30
*/
public interface SysDictService extends IService<SysDict> {
/**
* 根据ID列表删除字典
* @param ids 要删除的字典ID数组
* @return 操作结果
*/
R removeDictByIds(Long[] ids);
/**
* 更新字典
* @param sysDict 要更新的字典对象
* @return 操作结果
*/
R updateDict(SysDict sysDict);
/**
* 同步字典缓存(清空缓存)
* @return 操作结果
*/
R syncDictCache();
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pig.admin.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pig.admin.api.entity.SysFile;
import com.pig4cloud.pig.common.core.util.R;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.multipart.MultipartFile;
/**
* 文件管理服务接口
* <p>
* 提供文件上传、获取、删除等操作
* </p>
*
* @author Luckly
* @date 2019-06-18 17:18:42
*/
public interface SysFileService extends IService<SysFile> {
/**
* 上传文件
* @param file 要上传的文件
* @return 包含文件信息的响应结果,失败时返回错误信息
*/
R uploadFile(MultipartFile file);
/**
* 从指定存储桶中获取文件并写入HTTP响应流
* @param bucket 存储桶名称
* @param fileName 文件名
* @param response HTTP响应对象
*/
void getFile(String bucket, String fileName, HttpServletResponse response);
/**
* 根据ID删除文件
* @param id 文件ID
* @return 删除是否成功,文件不存在时返回false
*/
Boolean removeFile(Long id);
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pig.admin.api.dto.SysLogDTO;
import com.pig4cloud.pig.admin.api.entity.SysLog;
import java.util.List;
/**
* <p>
* 日志表 服务类
* </p>
*
* @author lengleng
* @since 2017-11-20
*/
public interface SysLogService extends IService<SysLog> {
/**
* 分页查询系统日志
* @param page 分页对象
* @param sysLog 系统日志
* @return 系统日志分页数据
*/
Page getLogPage(Page page, SysLogDTO sysLog);
/**
* 保存日志
* @param sysLog 日志实体
* @return Boolean
*/
Boolean saveLog(SysLog sysLog);
/**
* 查询日志列表
* @param sysLog 查询条件
* @return 日志列表
*/
List<SysLog> listLogs(SysLogDTO sysLog);
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.service;
import cn.hutool.core.lang.tree.Tree;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pig.admin.api.entity.SysMenu;
import com.pig4cloud.pig.common.core.util.R;
import java.util.List;
import java.util.Set;
/**
* 菜单权限服务接口
* <p>
* 提供菜单权限相关的服务方法,包括查询、删除、更新和构建菜单树等操作
* </p>
*
* @author lengleng
* @date 2025/06/27
*/
public interface SysMenuService extends IService<SysMenu> {
/**
* 通过角色编号查询URL 权限
* @param roleId 角色ID
* @return 菜单列表
*/
List<SysMenu> findMenuByRoleId(Long roleId);
/**
* 级联删除菜单
* @param id 菜单ID
* @return 成功、失败
*/
R removeMenuById(Long id);
/**
* 更新菜单信息
* @param sysMenu 菜单信息
* @return 成功、失败
*/
Boolean updateMenuById(SysMenu sysMenu);
/**
* 构建树查询
* @param parentId 父级菜单ID
* @param menuName 菜单名称
* @param type 类型
* @return 菜单树
*/
List<Tree<Long>> getMenuTree(Long parentId, String menuName, String type);
/**
* 查询菜单
* @param all 全部菜单
* @param type 类型
* @param parentId 父节点ID
* @return
*/
List<Tree<Long>> filterMenu(Set<SysMenu> all, String type, Long parentId);
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pig.admin.service;
import com.pig4cloud.pig.common.core.util.R;
/**
* 系统手机服务接口:提供手机验证码发送功能
*
* @author lengleng
* @date 2025/05/30
*/
public interface SysMobileService {
/**
* 发送手机验证码
* @param mobile 手机号码
* @return 发送结果,成功返回true,失败返回false
*/
R<Boolean> sendSmsCode(String mobile);
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pig.admin.api.entity.SysOauthClientDetails;
import com.pig4cloud.pig.common.core.util.R;
/**
* OAuth2客户端详情服务接口
*
* @author lengleng
* @since 2018-05-15
*/
public interface SysOauthClientDetailsService extends IService<SysOauthClientDetails> {
/**
* 根据客户端信息更新客户端详情
* @param clientDetails 客户端详情信息
* @return 更新结果,成功返回true
*/
Boolean updateClientById(SysOauthClientDetails clientDetails);
/**
* 保存客户端信息
* @param clientDetails 客户端详细信息
* @return 操作是否成功
*/
Boolean saveClient(SysOauthClientDetails clientDetails);
/**
* 分页查询OAuth客户端详情
* @param page 分页参数
* @param query 查询条件
* @return 分页查询结果
*/
Page getClientPage(Page page, SysOauthClientDetails query);
/**
* 同步客户端缓存
* @return 操作结果
*/
R syncClientCache();
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pig.admin.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pig.admin.api.entity.SysPost;
import com.pig4cloud.pig.admin.api.vo.PostExcelVO;
import com.pig4cloud.pig.common.core.util.R;
import org.springframework.validation.BindingResult;
import java.util.List;
/**
* 岗位信息表
*
* @author fxz
* @date 2022-03-26 12:50:43
*/
public interface SysPostService extends IService<SysPost> {
/**
* 获取岗位列表用于导出Excel
* @return 岗位Excel数据列表
*/
List<PostExcelVO> listPosts();
/**
* 导入岗位信息
* @param excelVOList 岗位Excel数据列表
* @param bindingResult 数据校验结果
* @return 导入结果(R对象)
*/
R importPost(List<PostExcelVO> excelVOList, BindingResult bindingResult);
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pig.admin.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pig.admin.api.entity.SysPublicParam;
import com.pig4cloud.pig.common.core.util.R;
/**
* 系统公共参数配置表 服务类
*
* @author lengleng
* @date 2025/05/30
*/
public interface SysPublicParamService extends IService<SysPublicParam> {
/**
* 根据公共参数key获取对应的value值
* @param publicKey 公共参数key
* @return 公共参数value,未找到时返回null
*/
String getParamValue(String publicKey);
/**
* 更新系统公共参数
* @param sysPublicParam 系统公共参数对象
* @return 操作结果
*/
R updateParam(SysPublicParam sysPublicParam);
/**
* 根据ID删除参数
* @param publicIds 参数ID数组
* @return 删除结果
*/
R removeParamByIds(Long[] publicIds);
/**
* 同步参数缓存
* @return 操作结果
*/
R syncParamCache();
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pig.admin.api.entity.SysRoleMenu;
/**
* 角色菜单表服务接口
*
* @author lengleng
* @since 2017-10-29
*/
public interface SysRoleMenuService extends IService<SysRoleMenu> {
/**
* 更新角色菜单
* @param roleId 角色ID
* @param menuIds 菜单ID字符串,以逗号分隔
* @return 更新是否成功
*/
Boolean saveRoleMenus(Long roleId, String menuIds);
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pig.admin.api.entity.SysRole;
import com.pig4cloud.pig.admin.api.vo.RoleExcelVO;
import com.pig4cloud.pig.admin.api.vo.RoleVO;
import com.pig4cloud.pig.common.core.util.R;
import org.springframework.validation.BindingResult;
import java.util.List;
/**
* 系统角色服务接口
* <p>
* 提供角色相关的业务功能,包括角色查询、删除、更新菜单及导入导出等操作
* </p>
*
* @author lengleng
* @since 2017-10-29
*/
public interface SysRoleService extends IService<SysRole> {
/**
* 通过用户ID查询角色信息
* @param userId 用户ID
* @return 角色信息列表
*/
List<SysRole> listRolesByUserId(Long userId);
/**
* 根据角色ID列表查询角色信息
* @param roleIdList 角色ID列表,不能为空
* @param key 缓存键值
* @return 查询到的角色列表
*/
List<SysRole> listRolesByRoleIds(List<Long> roleIdList, String key);
/**
* 通过角色ID数组删除角色
* @param ids 要删除的角色ID数组
* @return 删除是否成功
*/
Boolean removeRoleByIds(Long[] ids);
/**
* 更新角色菜单列表
* @param roleVo 包含角色和菜单列表信息的VO对象
* @return 更新是否成功
*/
Boolean updateRoleMenus(RoleVO roleVo);
/**
* 导入角色
* @param excelVOList 角色列表
* @param bindingResult 错误信息列表
* @return 导入结果
*/
R importRole(List<RoleExcelVO> excelVOList, BindingResult bindingResult);
/**
* 查询全部角色列表
* @return 角色列表,包含角色Excel视图对象
*/
List<RoleExcelVO> listRoles();
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pig.admin.api.entity.SysUserRole;
/**
* <p>
* 用户角色表 服务类
* </p>
*
* @author lengleng
* @since 2017-10-29
*/
public interface SysUserRoleService extends IService<SysUserRole> {
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pig.admin.api.dto.RegisterUserDTO;
import com.pig4cloud.pig.admin.api.dto.UserDTO;
import com.pig4cloud.pig.admin.api.dto.UserInfo;
import com.pig4cloud.pig.admin.api.entity.SysUser;
import com.pig4cloud.pig.admin.api.vo.UserExcelVO;
import com.pig4cloud.pig.admin.api.vo.UserVO;
import com.pig4cloud.pig.common.core.util.R;
import org.springframework.validation.BindingResult;
import java.util.List;
/**
* 系统用户服务接口
* <p>
* 提供用户信息查询、分页查询、增删改查等操作
*
* @author lengleng
* @date 2025/05/30
*/
public interface SysUserService extends IService<SysUser> {
/**
* 根据用户信息查询用户详情
* @param query 用户查询条件
* @return 用户详细信息
*/
R<UserInfo> getUserInfo(UserDTO query);
/**
* 分页查询用户信息(包含角色信息)
* @param page 分页对象
* @param userDTO 查询参数
* @return 分页结果
*/
IPage getUsersWithRolePage(Page page, UserDTO userDTO);
/**
* 删除用户
* @param ids 用户
* @return boolean
*/
Boolean removeUserByIds(Long[] ids);
/**
* 更新当前用户基本信息
* @param userDto 用户信息
* @return Boolean
*/
R<Boolean> updateUserInfo(UserDTO userDto);
/**
* 更新指定用户信息
* @param userDto 用户信息DTO对象
* @return 更新是否成功
*/
Boolean updateUser(UserDTO userDto);
/**
* 通过ID查询用户信息
* @param id 用户ID
* @return 用户信息
*/
UserVO getUserById(Long id);
/**
* 保存用户信息
* @param userDto DTO 对象
* @return success/fail
*/
Boolean saveUser(UserDTO userDto);
/**
* 查询全部的用户
* @param userDTO 查询条件
* @return list
*/
List<UserExcelVO> listUsers(UserDTO userDTO);
/**
* excel 导入用户
* @param excelVOList excel 列表数据
* @param bindingResult 错误数据
* @return ok fail
*/
R importUsers(List<UserExcelVO> excelVOList, BindingResult bindingResult);
/**
* 注册用户
* @param userDto 用户信息
* @return success/false
*/
R<Boolean> registerUser(RegisterUserDTO userDto);
/**
* 锁定用户
* @param username 用户名
* @return 包含操作结果的R对象,true表示锁定成功
*/
R<Boolean> lockUser(String username);
/**
* 修改用户密码
* @param userDto 包含用户信息的DTO对象
* @return 操作结果
*/
R changePassword(UserDTO userDto);
/**
* 校验密码
* @param password 待校验的密码明文
* @return 校验结果
*/
R checkPassword(String password);
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pig.admin.api.entity.SysDept;
import com.pig4cloud.pig.admin.api.vo.DeptExcelVo;
import com.pig4cloud.pig.admin.mapper.SysDeptMapper;
import com.pig4cloud.pig.admin.service.SysDeptService;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.plugin.excel.vo.ErrorMessage;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import java.util.*;
import java.util.stream.Collectors;
/**
* 部门管理服务实现类
*
* @author lengleng
* @date 2025/05/30
* @since 2018-01-20
*/
@Service
@AllArgsConstructor
public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> implements SysDeptService {
private final SysDeptMapper deptMapper;
/**
* 根据部门ID删除部门(包含级联删除子部门)
* @param id 要删除的部门ID
* @return 删除操作是否成功,始终返回true
* @throws Exception 事务执行过程中可能抛出的异常
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean removeDeptById(Long id) {
// 级联删除部门
List<Long> idList = this.listDescendants(id).stream().map(SysDept::getDeptId).toList();
Optional.ofNullable(idList).filter(CollUtil::isNotEmpty).ifPresent(this::removeByIds);
return Boolean.TRUE;
}
/**
* 查询部门树结构
* @param deptName 部门名称(模糊查询)
* @return 部门树结构列表,模糊查询时返回平铺列表
*/
@Override
public List<Tree<Long>> getDeptTree(String deptName) {
// 查询全部部门
List<SysDept> deptAllList = deptMapper
.selectList(Wrappers.<SysDept>lambdaQuery().like(StrUtil.isNotBlank(deptName), SysDept::getName, deptName));
// 权限内部门
List<TreeNode<Long>> collect = deptAllList.stream()
.filter(dept -> dept.getDeptId().intValue() != dept.getParentId())
.sorted(Comparator.comparingInt(SysDept::getSortOrder))
.map(dept -> {
TreeNode<Long> treeNode = new TreeNode();
treeNode.setId(dept.getDeptId());
treeNode.setParentId(dept.getParentId());
treeNode.setName(dept.getName());
treeNode.setWeight(dept.getSortOrder());
// 有权限不返回标识
Map<String, Object> extra = new HashMap<>(8);
extra.put(SysDept.Fields.createTime, dept.getCreateTime());
treeNode.setExtra(extra);
return treeNode;
})
.toList();
// 模糊查询 不组装树结构 直接返回 表格方便编辑
if (StrUtil.isNotBlank(deptName)) {
return collect.stream().map(node -> {
Tree<Long> tree = new Tree<>();
tree.putAll(node.getExtra());
BeanUtils.copyProperties(node, tree);
return tree;
}).toList();
}
return TreeUtil.build(collect, 0L);
}
/**
* 导出部门列表为Excel视图对象列表
* @return 部门Excel视图对象列表,包含部门名称、父部门名称和排序号
*/
@Override
public List<DeptExcelVo> exportDepts() {
List<SysDept> list = this.list();
List<DeptExcelVo> deptExcelVos = list.stream().map(item -> {
DeptExcelVo deptExcelVo = new DeptExcelVo();
deptExcelVo.setName(item.getName());
Optional<String> first = this.list()
.stream()
.filter(it -> item.getParentId().equals(it.getDeptId()))
.map(SysDept::getName)
.findFirst();
deptExcelVo.setParentName(first.orElse("根部门"));
deptExcelVo.setSortOrder(item.getSortOrder());
return deptExcelVo;
}).toList();
return deptExcelVos;
}
/**
* 导入部门信息
* @param excelVOList 部门Excel数据列表
* @param bindingResult 数据校验结果
* @return 导入结果,包含错误信息或成功信息
*/
@Override
public R importDept(List<DeptExcelVo> excelVOList, BindingResult bindingResult) {
List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
List<SysDept> deptList = this.list();
for (DeptExcelVo item : excelVOList) {
Set<String> errorMsg = new HashSet<>();
boolean exsitUsername = deptList.stream().anyMatch(sysDept -> item.getName().equals(sysDept.getName()));
if (exsitUsername) {
errorMsg.add("部门名称已经存在");
}
SysDept one = this.getOne(Wrappers.<SysDept>lambdaQuery().eq(SysDept::getName, item.getParentName()));
if (item.getParentName().equals("根部门")) {
one = new SysDept();
one.setDeptId(0L);
}
if (one == null) {
errorMsg.add("上级部门不存在");
}
if (CollUtil.isEmpty(errorMsg)) {
SysDept sysDept = new SysDept();
sysDept.setName(item.getName());
sysDept.setParentId(one.getDeptId());
sysDept.setSortOrder(item.getSortOrder());
baseMapper.insert(sysDept);
}
else {
// 数据不合法情况
errorMessageList.add(new ErrorMessage(item.getLineNum(), errorMsg));
}
}
if (CollUtil.isNotEmpty(errorMessageList)) {
return R.failed(errorMessageList);
}
return R.ok(null, "部门导入成功");
}
/**
* 查询部门及其所有子部门
* @param deptId 目标部门ID
* @return 包含目标部门及其所有子部门的列表
*/
@Override
public List<SysDept> listDescendants(Long deptId) {
// 查询全部部门
List<SysDept> allDeptList = baseMapper.selectList(Wrappers.emptyWrapper());
// 递归查询所有子节点
List<SysDept> resDeptList = new ArrayList<>();
recursiveDept(allDeptList, deptId, resDeptList);
// 添加当前节点
resDeptList.addAll(allDeptList.stream().filter(sysDept -> deptId.equals(sysDept.getDeptId())).toList());
return resDeptList;
}
/**
* 递归查询所有子节点
* @param allDeptList 所有部门列表
* @param parentId 父部门ID
* @param resDeptList 结果集合
*/
private void recursiveDept(List<SysDept> allDeptList, Long parentId, List<SysDept> resDeptList) {
// 使用 Stream API 进行筛选和遍历
allDeptList.stream().filter(sysDept -> sysDept.getParentId().equals(parentId)).forEach(sysDept -> {
resDeptList.add(sysDept);
recursiveDept(allDeptList, sysDept.getDeptId(), resDeptList);
});
}
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pig.admin.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pig.admin.api.entity.SysDict;
import com.pig4cloud.pig.admin.api.entity.SysDictItem;
import com.pig4cloud.pig.admin.mapper.SysDictItemMapper;
import com.pig4cloud.pig.admin.service.SysDictItemService;
import com.pig4cloud.pig.admin.service.SysDictService;
import com.pig4cloud.pig.common.core.constant.CacheConstants;
import com.pig4cloud.pig.common.core.constant.enums.DictTypeEnum;
import com.pig4cloud.pig.common.core.exception.ErrorCodes;
import com.pig4cloud.pig.common.core.util.MsgUtils;
import com.pig4cloud.pig.common.core.util.R;
import lombok.AllArgsConstructor;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
/**
* 字典项服务实现类
*
* @author lengleng
* @date 2025/05/30
*/
@Service
@AllArgsConstructor
public class SysDictItemServiceImpl extends ServiceImpl<SysDictItemMapper, SysDictItem> implements SysDictItemService {
private final SysDictService dictService;
/**
* 删除字典项
* @param id 字典项ID
* @return 操作结果
* @see R
*/
@Override
@CacheEvict(value = CacheConstants.DICT_DETAILS, allEntries = true)
public R removeDictItem(Long id) {
// 根据ID查询字典ID
SysDictItem dictItem = this.getById(id);
SysDict dict = dictService.getById(dictItem.getDictId());
// 系统内置
if (DictTypeEnum.SYSTEM.getType().equals(dict.getSystemFlag())) {
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_DICT_DELETE_SYSTEM));
}
return R.ok(this.removeById(id));
}
/**
* 更新字典项
* @param item 需要更新的字典项
* @return 操作结果,包含成功或失败信息
* @see R
*/
@Override
@CacheEvict(value = CacheConstants.DICT_DETAILS, key = "#item.dictType")
public R updateDictItem(SysDictItem item) {
// 查询字典
SysDict dict = dictService.getById(item.getDictId());
// 系统内置
if (DictTypeEnum.SYSTEM.getType().equals(dict.getSystemFlag())) {
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_DICT_UPDATE_SYSTEM));
}
return R.ok(this.updateById(item));
}
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pig.admin.service.impl;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pig.admin.api.entity.SysDict;
import com.pig4cloud.pig.admin.api.entity.SysDictItem;
import com.pig4cloud.pig.admin.mapper.SysDictItemMapper;
import com.pig4cloud.pig.admin.mapper.SysDictMapper;
import com.pig4cloud.pig.admin.service.SysDictService;
import com.pig4cloud.pig.common.core.constant.CacheConstants;
import com.pig4cloud.pig.common.core.constant.enums.DictTypeEnum;
import com.pig4cloud.pig.common.core.exception.ErrorCodes;
import com.pig4cloud.pig.common.core.util.MsgUtils;
import com.pig4cloud.pig.common.core.util.R;
import lombok.AllArgsConstructor;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;
/**
* 系统字典服务实现类
*
* @author lengleng
* @date 2025/05/30
*/
@Service
@AllArgsConstructor
public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> implements SysDictService {
private final SysDictItemMapper dictItemMapper;
/**
* 根据ID删除字典
* @param ids 字典ID数组
* @return 操作结果
*/
@Override
@Transactional(rollbackFor = Exception.class)
@CacheEvict(value = CacheConstants.DICT_DETAILS, allEntries = true)
public R removeDictByIds(Long[] ids) {
List<Long> dictIdList = baseMapper.selectByIds(CollUtil.toList(ids))
.stream()
.filter(sysDict -> !sysDict.getSystemFlag().equals(DictTypeEnum.SYSTEM.getType()))// 系统内置类型不删除
.map(SysDict::getId)
.toList();
baseMapper.deleteByIds(dictIdList);
dictItemMapper.delete(Wrappers.<SysDictItem>lambdaQuery().in(SysDictItem::getDictId, dictIdList));
return R.ok();
}
/**
* 更新字典数据
* @param dict 字典对象
* @return 操作结果
* @see R 返回结果封装类
*/
@Override
@CacheEvict(value = CacheConstants.DICT_DETAILS, key = "#dict.dictType")
public R updateDict(SysDict dict) {
SysDict sysDict = this.getById(dict.getId());
// 系统内置
if (DictTypeEnum.SYSTEM.getType().equals(sysDict.getSystemFlag())) {
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_DICT_UPDATE_SYSTEM));
}
this.updateById(dict);
return R.ok(dict);
}
/**
* 同步字典缓存(清空缓存)
* @return 操作结果
*/
@Override
@CacheEvict(value = CacheConstants.DICT_DETAILS, allEntries = true)
public R syncDictCache() {
return R.ok();
}
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pig.admin.service.impl;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pig.admin.api.entity.SysFile;
import com.pig4cloud.pig.admin.mapper.SysFileMapper;
import com.pig4cloud.pig.admin.service.SysFileService;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.file.core.FileProperties;
import com.pig4cloud.pig.common.file.core.FileTemplate;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* 文件管理
*
* @author Luckly
* @date 2019-06-18 17:18:42
*/
@Slf4j
@Service
@AllArgsConstructor
public class SysFileServiceImpl extends ServiceImpl<SysFileMapper, SysFile> implements SysFileService {
private final FileTemplate fileTemplate;
private final FileProperties properties;
/**
* 上传文件
* @param file 要上传的文件
* @return 包含文件信息的响应结果,失败时返回错误信息
* @throws Exception 文件上传过程中可能出现的异常
*/
@Override
public R uploadFile(MultipartFile file) {
String fileName = IdUtil.simpleUUID() + StrUtil.DOT + FileUtil.extName(file.getOriginalFilename());
Map<String, String> resultMap = new HashMap<>(4);
resultMap.put("bucketName", properties.getBucketName());
resultMap.put("fileName", fileName);
resultMap.put("url", String.format("/admin/sys-file/%s/%s", properties.getBucketName(), fileName));
try (InputStream inputStream = file.getInputStream()) {
fileTemplate.putObject(properties.getBucketName(), fileName, inputStream, file.getContentType());
// 文件管理数据记录,收集管理追踪文件
fileLog(file, fileName);
}
catch (Exception e) {
log.error("上传失败", e);
return R.failed(e.getLocalizedMessage());
}
return R.ok(resultMap);
}
/**
* 从指定存储桶中获取文件并写入HTTP响应流
* @param bucket 存储桶名称
* @param fileName 文件名
* @param response HTTP响应对象
*/
@Override
public void getFile(String bucket, String fileName, HttpServletResponse response) {
try (InputStream inputStream = (InputStream) fileTemplate.getObject(bucket, fileName)) {
response.setContentType("application/octet-stream; charset=UTF-8");
response.addHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + URLUtil.encode(fileName));
IoUtil.copy(inputStream, response.getOutputStream());
}
catch (Exception e) {
log.error("文件读取异常: {}", e.getLocalizedMessage());
}
}
/**
* 根据ID删除文件
* @param id 文件ID
* @return 删除是否成功,文件不存在时返回false
* @throws Exception 删除过程中可能抛出的异常
*/
@Override
@SneakyThrows
@Transactional(rollbackFor = Exception.class)
public Boolean removeFile(Long id) {
SysFile file = this.getById(id);
if (Objects.isNull(file)) {
return Boolean.FALSE;
}
fileTemplate.removeObject(properties.getBucketName(), file.getFileName());
return this.removeById(id);
}
/**
* 记录文件管理数据
* @param file 上传文件
* @param fileName 文件名
*/
private void fileLog(MultipartFile file, String fileName) {
SysFile sysFile = new SysFile();
sysFile.setFileName(fileName);
sysFile.setOriginal(file.getOriginalFilename());
sysFile.setFileSize(file.getSize());
sysFile.setType(FileUtil.extName(file.getOriginalFilename()));
sysFile.setBucketName(properties.getBucketName());
this.save(sysFile);
}
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.service.impl;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
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.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pig.admin.api.dto.SysLogDTO;
import com.pig4cloud.pig.admin.api.entity.SysLog;
import com.pig4cloud.pig.admin.mapper.SysLogMapper;
import com.pig4cloud.pig.admin.service.SysLogService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* 系统日志服务实现类
*
* @author lengleng
* @date 2025/05/30
* @since 2017-11-20
*/
@Service
public class SysLogServiceImpl extends ServiceImpl<SysLogMapper, SysLog> implements SysLogService {
/**
* 分页查询系统日志
* @param page 分页参数
* @param sysLog 日志查询条件
* @return 分页结果
*/
@Override
public Page getLogPage(Page page, SysLogDTO sysLog) {
return baseMapper.selectPage(page, buildQuery(sysLog));
}
/**
* 保存日志
* @param sysLog 日志对象
* @return 保存成功返回true
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean saveLog(SysLog sysLog) {
baseMapper.insert(sysLog);
return Boolean.TRUE;
}
/**
* 查询日志列表
* @param sysLog 查询条件DTO对象
* @return 日志列表
*/
@Override
public List<SysLog> listLogs(SysLogDTO sysLog) {
return baseMapper.selectList(buildQuery(sysLog));
}
/**
* 构建查询条件
* @param sysLog 前端查询条件DTO
* @return 构建好的LambdaQueryWrapper对象
*/
private LambdaQueryWrapper buildQuery(SysLogDTO sysLog) {
LambdaQueryWrapper<SysLog> wrapper = Wrappers.lambdaQuery();
if (StrUtil.isNotBlank(sysLog.getLogType())) {
wrapper.eq(SysLog::getLogType, sysLog.getLogType());
}
if (ArrayUtil.isNotEmpty(sysLog.getCreateTime())) {
wrapper.ge(SysLog::getCreateTime, sysLog.getCreateTime()[0])
.le(SysLog::getCreateTime, sysLog.getCreateTime()[1]);
}
return wrapper;
}
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pig.admin.api.entity.SysMenu;
import com.pig4cloud.pig.admin.api.entity.SysRoleMenu;
import com.pig4cloud.pig.admin.mapper.SysMenuMapper;
import com.pig4cloud.pig.admin.mapper.SysRoleMenuMapper;
import com.pig4cloud.pig.admin.service.SysMenuService;
import com.pig4cloud.pig.common.core.constant.CacheConstants;
import com.pig4cloud.pig.common.core.constant.CommonConstants;
import com.pig4cloud.pig.common.core.constant.enums.MenuTypeEnum;
import com.pig4cloud.pig.common.core.exception.ErrorCodes;
import com.pig4cloud.pig.common.core.util.MsgUtils;
import com.pig4cloud.pig.common.core.util.R;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
* 菜单权限表服务实现类
*
* @author lengleng
* @date 2025/05/30
* @since 2017-10-29
*/
@Service
@AllArgsConstructor
@Slf4j
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {
private final SysRoleMenuMapper sysRoleMenuMapper;
/**
* 根据角色ID查询菜单列表
* @param roleId 角色ID
* @return 菜单列表,如果结果为空则不会被缓存
* @see CacheConstants#MENU_DETAILS
*/
@Override
@Cacheable(value = CacheConstants.MENU_DETAILS, key = "#roleId", unless = "#result.isEmpty()")
public List<SysMenu> findMenuByRoleId(Long roleId) {
return baseMapper.listMenusByRoleId(roleId);
}
/**
* 根据ID删除菜单
* @param id 菜单ID
* @return 删除结果
* @throws Exception 事务回滚时抛出异常
*/
@Override
@Transactional(rollbackFor = Exception.class)
@CacheEvict(value = CacheConstants.MENU_DETAILS, allEntries = true)
public R removeMenuById(Long id) {
// 查询父节点为当前节点的节点
List<SysMenu> menuList = this.list(Wrappers.<SysMenu>query().lambda().eq(SysMenu::getParentId, id));
if (CollUtil.isNotEmpty(menuList)) {
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_MENU_DELETE_EXISTING));
}
sysRoleMenuMapper.delete(Wrappers.<SysRoleMenu>query().lambda().eq(SysRoleMenu::getMenuId, id));
// 删除当前菜单及其子菜单
return R.ok(this.removeById(id));
}
/**
* 根据ID更新菜单信息
* @param sysMenu 菜单实体对象
* @return 更新是否成功
*/
@Override
@CacheEvict(value = CacheConstants.MENU_DETAILS, allEntries = true)
public Boolean updateMenuById(SysMenu sysMenu) {
return this.updateById(sysMenu);
}
/**
* 构建菜单树结构
* @param parentId 父节点ID,为空时使用默认根节点
* @param menuName 菜单名称,支持模糊查询
* @param type 菜单类型
* @return 菜单树结构列表,模糊查询时返回平铺列表
*/
@Override
public List<Tree<Long>> getMenuTree(Long parentId, String menuName, String type) {
Long parent = parentId == null ? CommonConstants.MENU_TREE_ROOT_ID : parentId;
List<TreeNode<Long>> collect = baseMapper
.selectList(Wrappers.<SysMenu>lambdaQuery()
.like(StrUtil.isNotBlank(menuName), SysMenu::getName, menuName)
.eq(StrUtil.isNotBlank(type), SysMenu::getMenuType, type)
.orderByAsc(SysMenu::getSortOrder))
.stream()
.map(getNodeFunction())
.toList();
// 模糊查询 不组装树结构 直接返回 表格方便编辑
if (StrUtil.isNotBlank(menuName)) {
return collect.stream().map(node -> {
Tree<Long> tree = new Tree<>();
tree.putAll(node.getExtra());
BeanUtils.copyProperties(node, tree);
return tree;
}).toList();
}
return TreeUtil.build(collect, parent);
}
/**
* 根据类型和父节点ID过滤菜单并构建树形结构
* @param all 全部菜单集合
* @param type 菜单类型
* @param parentId 父节点ID,为空时使用根节点ID
* @return 构建好的菜单树形结构列表
*/
@Override
public List<Tree<Long>> filterMenu(Set<SysMenu> all, String type, Long parentId) {
List<TreeNode<Long>> collect = all.stream().filter(menuTypePredicate(type)).map(getNodeFunction()).toList();
Long parent = parentId == null ? CommonConstants.MENU_TREE_ROOT_ID : parentId;
return TreeUtil.build(collect, parent);
}
/**
* 获取将SysMenu转换为TreeNode<Long>的函数
* @return 转换函数,将SysMenu对象转换为TreeNode<Long>对象
*/
@NotNull
private Function<SysMenu, TreeNode<Long>> getNodeFunction() {
return menu -> {
TreeNode<Long> node = new TreeNode<>();
node.setId(menu.getMenuId());
node.setName(menu.getName());
node.setParentId(menu.getParentId());
node.setWeight(menu.getSortOrder());
// 扩展属性
Map<String, Object> extra = new HashMap<>();
extra.put(SysMenu.Fields.path, menu.getPath());
extra.put(SysMenu.Fields.menuType, menu.getMenuType());
extra.put(SysMenu.Fields.permission, menu.getPermission());
extra.put(SysMenu.Fields.sortOrder, menu.getSortOrder());
// 适配 vue3
Map<String, Object> meta = new HashMap<>();
meta.put("title", menu.getName());
meta.put("isLink", menu.getPath() != null && menu.getPath().startsWith("http") ? menu.getPath() : "");
meta.put("isHide", !BooleanUtil.toBooleanObject(menu.getVisible()));
meta.put("isKeepAlive", BooleanUtil.toBooleanObject(menu.getKeepAlive()));
meta.put("isAffix", false);
meta.put("isIframe", BooleanUtil.toBooleanObject(menu.getEmbedded()));
meta.put(SysMenu.Fields.icon, menu.getIcon());
// 增加英文
meta.put(SysMenu.Fields.enName, menu.getEnName());
extra.put("meta", meta);
node.setExtra(extra);
return node;
};
}
/**
* menu 类型断言
* @param type 类型
* @return Predicate
*/
private Predicate<SysMenu> menuTypePredicate(String type) {
return vo -> {
if (MenuTypeEnum.TOP_MENU.getDescription().equals(type)) {
return MenuTypeEnum.TOP_MENU.getType().equals(vo.getMenuType());
}
// 其他查询 左侧 + 顶部
return !MenuTypeEnum.BUTTON.getType().equals(vo.getMenuType());
};
}
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pig.admin.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.pig4cloud.pig.admin.api.entity.SysUser;
import com.pig4cloud.pig.admin.mapper.SysUserMapper;
import com.pig4cloud.pig.admin.service.SysMobileService;
import com.pig4cloud.pig.common.core.constant.CacheConstants;
import com.pig4cloud.pig.common.core.constant.SecurityConstants;
import com.pig4cloud.pig.common.core.exception.ErrorCodes;
import com.pig4cloud.pig.common.core.util.MsgUtils;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.core.util.RedisUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.sms4j.api.SmsBlend;
import org.dromara.sms4j.api.entity.SmsResponse;
import org.dromara.sms4j.core.factory.SmsFactory;
import org.springframework.stereotype.Service;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
/**
* 手机登录相关业务实现类
*
* @author lengleng
* @date 2025/05/30
*/
@Slf4j
@Service
@AllArgsConstructor
public class SysMobileServiceImpl implements SysMobileService {
private final SysUserMapper userMapper;
/**
* 发送手机验证码
* @param mobile 手机号码
* @return 返回操作结果,包含验证码发送状态及验证码信息
*/
@Override
public R<Boolean> sendSmsCode(String mobile) {
List<SysUser> userList = userMapper
.selectList(Wrappers.<SysUser>query().lambda().eq(SysUser::getPhone, mobile));
if (CollUtil.isEmpty(userList)) {
log.info("手机号未注册:{}", mobile);
return R.ok(Boolean.FALSE, MsgUtils.getMessage(ErrorCodes.SYS_APP_PHONE_UNREGISTERED, mobile));
}
String cacheKey = CacheConstants.DEFAULT_CODE_KEY + mobile;
String codeObj = RedisUtils.get(cacheKey);
if (codeObj != null) {
log.info("手机号验证码未过期:{},{}", mobile, codeObj);
return R.ok(Boolean.FALSE, MsgUtils.getMessage(ErrorCodes.SYS_APP_SMS_OFTEN));
}
String code = RandomUtil.randomNumbers(Integer.parseInt(SecurityConstants.CODE_SIZE));
log.info("手机号生成验证码成功:{},{}", mobile, code);
RedisUtils.set(cacheKey, code, SecurityConstants.CODE_TIME, TimeUnit.SECONDS);
// 集成短信服务发送验证码
SmsBlend smsBlend = SmsFactory.getSmsBlend();
if (Objects.isNull(smsBlend)) {
return R.ok(Boolean.FALSE, MsgUtils.getMessage(ErrorCodes.SYS_SMS_BLEND_UNREGISTERED));
}
SmsResponse smsResponse = smsBlend.sendMessage(mobile, new LinkedHashMap<>(Map.of("code", code)));
log.debug("调用短信服务发送验证码结果:{}", smsResponse);
return R.ok(Boolean.TRUE);
}
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.service.impl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pig.admin.api.entity.SysOauthClientDetails;
import com.pig4cloud.pig.admin.mapper.SysOauthClientDetailsMapper;
import com.pig4cloud.pig.admin.service.SysOauthClientDetailsService;
import com.pig4cloud.pig.common.core.constant.CacheConstants;
import com.pig4cloud.pig.common.core.util.R;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* OAuth2客户端详情服务实现类
*
* @author lengleng
* @since 2018-05-15
*/
@Service
@RequiredArgsConstructor
public class SysOauthClientDetailsServiceImpl extends ServiceImpl<SysOauthClientDetailsMapper, SysOauthClientDetails>
implements SysOauthClientDetailsService {
/**
* 根据客户端信息更新客户端详情
* @param clientDetails 客户端详情信息
* @return 更新结果,成功返回true
*/
@Override
@CacheEvict(value = CacheConstants.CLIENT_DETAILS_KEY, key = "#clientDetails.clientId")
@Transactional(rollbackFor = Exception.class)
public Boolean updateClientById(SysOauthClientDetails clientDetails) {
this.insertOrUpdate(clientDetails);
return Boolean.TRUE;
}
/**
* 保存客户端信息
* @param clientDetails 客户端详细信息
* @return 操作是否成功
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean saveClient(SysOauthClientDetails clientDetails) {
this.insertOrUpdate(clientDetails);
return Boolean.TRUE;
}
/**
* 插入或更新客户端对象
* @param clientDetails 客户端详情对象
* @return 更新后的客户端详情对象
*/
private SysOauthClientDetails insertOrUpdate(SysOauthClientDetails clientDetails) {
// 更新数据库
saveOrUpdate(clientDetails);
return clientDetails;
}
/**
* 分页查询OAuth客户端详情
* @param page 分页参数
* @param query 查询条件
* @return 分页查询结果
*/
@Override
public Page getClientPage(Page page, SysOauthClientDetails query) {
return baseMapper.selectPage(page, Wrappers.query(query));
}
/**
* 同步客户端缓存
* @return 操作结果
*/
@Override
@CacheEvict(value = CacheConstants.CLIENT_DETAILS_KEY, allEntries = true)
public R syncClientCache() {
return R.ok();
}
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pig.admin.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pig.admin.api.entity.SysPost;
import com.pig4cloud.pig.admin.api.vo.PostExcelVO;
import com.pig4cloud.pig.admin.mapper.SysPostMapper;
import com.pig4cloud.pig.admin.service.SysPostService;
import com.pig4cloud.pig.common.core.exception.ErrorCodes;
import com.pig4cloud.pig.common.core.util.MsgUtils;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.plugin.excel.vo.ErrorMessage;
import org.springframework.stereotype.Service;
import org.springframework.validation.BindingResult;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 岗位信息表服务实现类
*
* @author lengleng
* @date 2025/05/30
*/
@Service
public class SysPostServiceImpl extends ServiceImpl<SysPostMapper, SysPost> implements SysPostService {
/**
* 导入岗位
* @param excelVOList 岗位列表
* @param bindingResult 错误信息列表
* @return ok fail
*/
@Override
public R importPost(List<PostExcelVO> excelVOList, BindingResult bindingResult) {
// 通用校验获取失败的数据
List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
// 个性化校验逻辑
List<SysPost> postList = this.list();
// 执行数据插入操作 组装 PostDto
for (PostExcelVO excel : excelVOList) {
Set<String> errorMsg = new HashSet<>();
// 检验岗位名称或者岗位编码是否存在
boolean existPost = postList.stream()
.anyMatch(post -> excel.getPostName().equals(post.getPostName())
|| excel.getPostCode().equals(post.getPostCode()));
if (existPost) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_POST_NAMEORCODE_EXISTING, excel.getPostName(),
excel.getPostCode()));
}
// 数据合法情况
if (CollUtil.isEmpty(errorMsg)) {
insertExcelPost(excel);
}
else {
// 数据不合法
errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg));
}
}
if (CollUtil.isNotEmpty(errorMessageList)) {
return R.failed(errorMessageList);
}
return R.ok();
}
/**
* 获取岗位列表并转换为Excel导出对象
* @return 岗位Excel导出对象列表
*/
@Override
public List<PostExcelVO> listPosts() {
List<SysPost> postList = this.list(Wrappers.emptyWrapper());
// 转换成execl 对象输出
return postList.stream().map(post -> {
PostExcelVO postExcelVO = new PostExcelVO();
BeanUtil.copyProperties(post, postExcelVO);
return postExcelVO;
}).toList();
}
/**
* 插入Excel中的岗位数据
* @param excel 包含岗位信息的Excel数据对象
*/
private void insertExcelPost(PostExcelVO excel) {
SysPost sysPost = new SysPost();
BeanUtil.copyProperties(excel, sysPost);
this.save(sysPost);
}
}
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pig.admin.service.impl;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pig.admin.api.entity.SysPublicParam;
import com.pig4cloud.pig.admin.mapper.SysPublicParamMapper;
import com.pig4cloud.pig.admin.service.SysPublicParamService;
import com.pig4cloud.pig.common.core.constant.CacheConstants;
import com.pig4cloud.pig.common.core.constant.enums.DictTypeEnum;
import com.pig4cloud.pig.common.core.exception.ErrorCodes;
import com.pig4cloud.pig.common.core.util.MsgUtils;
import com.pig4cloud.pig.common.core.util.R;
import lombok.AllArgsConstructor;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
/**
* 系统公共参数服务实现类
*
* @author lengleng
* @date 2025/05/30
*/
@Service
@AllArgsConstructor
public class SysPublicParamServiceImpl extends ServiceImpl<SysPublicParamMapper, SysPublicParam>
implements SysPublicParamService {
/**
* 根据公共参数key获取对应的value值
* @param publicKey 公共参数key
* @return 公共参数value,未找到时返回null
* @Cacheable 使用缓存,缓存名称为PARAMS_DETAILS,key为publicKey,当结果为null时不缓存
*/
@Override
@Cacheable(value = CacheConstants.PARAMS_DETAILS, key = "#publicKey", unless = "#result == null ")
public String getParamValue(String publicKey) {
SysPublicParam sysPublicParam = this.baseMapper
.selectOne(Wrappers.<SysPublicParam>lambdaQuery().eq(SysPublicParam::getPublicKey, publicKey));
if (sysPublicParam != null) {
return sysPublicParam.getPublicValue();
}
return null;
}
/**
* 更新系统公共参数
* @param sysPublicParam 系统公共参数对象
* @return 操作结果
* @see R
*/
@Override
@CacheEvict(value = CacheConstants.PARAMS_DETAILS, key = "#sysPublicParam.publicKey")
public R updateParam(SysPublicParam sysPublicParam) {
SysPublicParam param = this.getById(sysPublicParam.getPublicId());
// 系统内置
if (DictTypeEnum.SYSTEM.getType().equals(param.getSystemFlag())) {
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_PARAM_DELETE_SYSTEM));
}
return R.ok(this.updateById(sysPublicParam));
}
/**
* 根据ID列表删除参数
* @param publicIds 参数ID数组
* @return 操作结果
* @see CacheConstants#PARAMS_DETAILS 缓存常量
*/
@Override
@CacheEvict(value = CacheConstants.PARAMS_DETAILS, allEntries = true)
public R removeParamByIds(Long[] publicIds) {
List<Long> idList = this.baseMapper.selectByIds(CollUtil.toList(publicIds))
.stream()
.filter(p -> !p.getSystemFlag().equals(DictTypeEnum.SYSTEM.getType()))// 系统内置的跳过不能删除
.map(SysPublicParam::getPublicId)
.toList();
return R.ok(this.removeBatchByIds(idList));
}
/**
* 同步参数缓存
* @return 操作结果
*/
@Override
@CacheEvict(value = CacheConstants.PARAMS_DETAILS, allEntries = true)
public R syncParamCache() {
return R.ok();
}
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.service.impl;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pig.admin.api.entity.SysRoleMenu;
import com.pig4cloud.pig.admin.mapper.SysRoleMenuMapper;
import com.pig4cloud.pig.admin.service.SysRoleMenuService;
import com.pig4cloud.pig.common.core.constant.CacheConstants;
import lombok.AllArgsConstructor;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* 角色菜单表服务实现类
*
* @author lengleng
* @date 2025/05/30
* @since 2017-10-29
*/
@Service
@AllArgsConstructor
public class SysRoleMenuServiceImpl extends ServiceImpl<SysRoleMenuMapper, SysRoleMenu> implements SysRoleMenuService {
private final CacheManager cacheManager;
/**
* @param roleId 角色
* @param menuIds 菜单ID拼成的字符串,每个id之间根据逗号分隔
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
@CacheEvict(value = CacheConstants.MENU_DETAILS, key = "#roleId")
public Boolean saveRoleMenus(Long roleId, String menuIds) {
this.remove(Wrappers.<SysRoleMenu>query().lambda().eq(SysRoleMenu::getRoleId, roleId));
if (StrUtil.isBlank(menuIds)) {
return Boolean.TRUE;
}
List<SysRoleMenu> roleMenuList = Arrays.stream(menuIds.split(StrUtil.COMMA)).map(menuId -> {
SysRoleMenu roleMenu = new SysRoleMenu();
roleMenu.setRoleId(roleId);
roleMenu.setMenuId(Long.valueOf(menuId));
return roleMenu;
}).toList();
// 清空userinfo
cacheManager.getCache(CacheConstants.USER_DETAILS).clear();
this.saveBatch(roleMenuList);
return Boolean.TRUE;
}
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pig.admin.api.entity.SysRole;
import com.pig4cloud.pig.admin.api.entity.SysRoleMenu;
import com.pig4cloud.pig.admin.api.vo.RoleExcelVO;
import com.pig4cloud.pig.admin.api.vo.RoleVO;
import com.pig4cloud.pig.admin.mapper.SysRoleMapper;
import com.pig4cloud.pig.admin.service.SysRoleMenuService;
import com.pig4cloud.pig.admin.service.SysRoleService;
import com.pig4cloud.pig.common.core.constant.CacheConstants;
import com.pig4cloud.pig.common.core.exception.ErrorCodes;
import com.pig4cloud.pig.common.core.util.MsgUtils;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.plugin.excel.vo.ErrorMessage;
import lombok.AllArgsConstructor;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 系统角色服务实现类
*
* @author lengleng
* @since 2017-10-29
*/
@Service
@AllArgsConstructor
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {
private SysRoleMenuService roleMenuService;
/**
* 通过用户ID查询角色信息
* @param userId 用户ID
* @return 角色信息列表
*/
@Override
public List listRolesByUserId(Long userId) {
return baseMapper.listRolesByUserId(userId);
}
/**
* 根据角色ID查询角色列表
* @param roleIdList 角色ID列表
* @param key 缓存key
* @return 角色列表
*/
@Override
@Cacheable(value = CacheConstants.ROLE_DETAILS, key = "#key", unless = "#result.isEmpty()")
public List<SysRole> listRolesByRoleIds(List<Long> roleIdList, String key) {
return baseMapper.selectByIds(roleIdList);
}
/**
* 通过角色ID删除角色并清空角色菜单缓存
* @param ids 角色ID数组
* @return 删除是否成功
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean removeRoleByIds(Long[] ids) {
roleMenuService
.remove(Wrappers.<SysRoleMenu>update().lambda().in(SysRoleMenu::getRoleId, CollUtil.toList(ids)));
return this.removeBatchByIds(CollUtil.toList(ids));
}
/**
* 更新角色菜单列表
* @param roleVo 包含角色ID和菜单ID列表的角色对象
* @return 更新是否成功
*/
@Override
public Boolean updateRoleMenus(RoleVO roleVo) {
return roleMenuService.saveRoleMenus(roleVo.getRoleId(), roleVo.getMenuIds());
}
/**
* 导入角色
* @param excelVOList 角色列表
* @param bindingResult 错误信息列表
* @return ok fail
*/
@Override
public R importRole(List<RoleExcelVO> excelVOList, BindingResult bindingResult) {
// 通用校验获取失败的数据
List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
// 个性化校验逻辑
List<SysRole> roleList = this.list();
// 执行数据插入操作 组装 RoleDto
for (RoleExcelVO excel : excelVOList) {
Set<String> errorMsg = new HashSet<>();
// 检验角色名称或者角色编码是否存在
boolean existRole = roleList.stream()
.anyMatch(sysRole -> excel.getRoleName().equals(sysRole.getRoleName())
|| excel.getRoleCode().equals(sysRole.getRoleCode()));
if (existRole) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_ROLE_NAMEORCODE_EXISTING, excel.getRoleName(),
excel.getRoleCode()));
}
// 数据合法情况
if (CollUtil.isEmpty(errorMsg)) {
insertExcelRole(excel);
}
else {
// 数据不合法情况
errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg));
}
}
if (CollUtil.isNotEmpty(errorMessageList)) {
return R.failed(errorMessageList);
}
return R.ok();
}
/**
* 查询全部角色列表并转换为Excel视图对象
* @return 角色Excel视图对象列表
*/
@Override
public List<RoleExcelVO> listRoles() {
List<SysRole> roleList = this.list(Wrappers.emptyWrapper());
// 转换成execl 对象输出
return roleList.stream().map(role -> {
RoleExcelVO roleExcelVO = new RoleExcelVO();
BeanUtil.copyProperties(role, roleExcelVO);
return roleExcelVO;
}).toList();
}
/**
* 插入Excel中的角色数据
* @param excel 包含角色信息的Excel数据对象
*/
private void insertExcelRole(RoleExcelVO excel) {
SysRole sysRole = new SysRole();
sysRole.setRoleName(excel.getRoleName());
sysRole.setRoleDesc(excel.getRoleDesc());
sysRole.setRoleCode(excel.getRoleCode());
this.save(sysRole);
}
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pig.admin.api.entity.SysUserRole;
import com.pig4cloud.pig.admin.mapper.SysUserRoleMapper;
import com.pig4cloud.pig.admin.service.SysUserRoleService;
import org.springframework.stereotype.Service;
/**
* <p>
* 用户角色表 服务实现类
* </p>
*
* @author lengleng
* @since 2017-10-29
*/
@Service
public class SysUserRoleServiceImpl extends ServiceImpl<SysUserRoleMapper, SysUserRole> implements SysUserRoleService {
}
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pig.admin.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pig.admin.api.dto.RegisterUserDTO;
import com.pig4cloud.pig.admin.api.dto.UserDTO;
import com.pig4cloud.pig.admin.api.dto.UserInfo;
import com.pig4cloud.pig.admin.api.entity.*;
import com.pig4cloud.pig.admin.api.util.ParamResolver;
import com.pig4cloud.pig.admin.api.vo.UserExcelVO;
import com.pig4cloud.pig.admin.api.vo.UserVO;
import com.pig4cloud.pig.admin.mapper.SysUserMapper;
import com.pig4cloud.pig.admin.mapper.SysUserPostMapper;
import com.pig4cloud.pig.admin.mapper.SysUserRoleMapper;
import com.pig4cloud.pig.admin.service.*;
import com.pig4cloud.pig.common.core.constant.CacheConstants;
import com.pig4cloud.pig.common.core.constant.CommonConstants;
import com.pig4cloud.pig.common.core.exception.ErrorCodes;
import com.pig4cloud.pig.common.core.util.MsgUtils;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.security.util.SecurityUtils;
import com.pig4cloud.plugin.excel.vo.ErrorMessage;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
/**
* 系统用户服务实现类
*
* @author lengleng
* @date 2025/05/30
*/
@Slf4j
@Service
@AllArgsConstructor
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {
private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();
private final SysMenuService sysMenuService;
private final SysRoleService sysRoleService;
private final SysPostService sysPostService;
private final SysDeptService sysDeptService;
private final SysUserRoleMapper sysUserRoleMapper;
private final SysUserPostMapper sysUserPostMapper;
private final CacheManager cacheManager;
/**
* 保存用户信息
* @param userDto 用户数据传输对象
* @return 操作是否成功
* @throws Exception 事务回滚时抛出异常
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean saveUser(UserDTO userDto) {
SysUser sysUser = new SysUser();
BeanUtils.copyProperties(userDto, sysUser);
sysUser.setDelFlag(CommonConstants.STATUS_NORMAL);
sysUser.setCreateBy(userDto.getUsername());
sysUser.setPassword(ENCODER.encode(userDto.getPassword()));
baseMapper.insert(sysUser);
// 保存用户岗位信息
Optional.ofNullable(userDto.getPost()).ifPresent(posts -> posts.forEach(postId -> {
SysUserPost userPost = new SysUserPost();
userPost.setUserId(sysUser.getUserId());
userPost.setPostId(postId);
sysUserPostMapper.insert(userPost);
}));
// 如果角色为空,赋默认角色
if (CollUtil.isEmpty(userDto.getRole())) {
// 获取默认角色编码
String defaultRole = ParamResolver.getStr("USER_DEFAULT_ROLE");
// 默认角色
SysRole sysRole = sysRoleService
.getOne(Wrappers.<SysRole>lambdaQuery().eq(SysRole::getRoleCode, defaultRole));
userDto.setRole(Collections.singletonList(sysRole.getRoleId()));
}
// 插入用户角色关系表
userDto.getRole().forEach(roleId -> {
SysUserRole userRole = new SysUserRole();
userRole.setUserId(sysUser.getUserId());
userRole.setRoleId(roleId);
sysUserRoleMapper.insert(userRole);
});
return Boolean.TRUE;
}
/**
* 查询用户全部信息,包括角色和权限
* @param query 用户查询条件
* @return 包含用户角色和权限的用户信息对象
*/
@Override
public R<UserInfo> getUserInfo(UserDTO query) {
UserVO dbUser = baseMapper.getUser(query);
if (dbUser == null) {
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_USER_USERINFO_EMPTY, query.getUsername()));
}
UserInfo userInfo = new UserInfo();
BeanUtils.copyProperties(dbUser, userInfo);
// 设置权限列表(menu.permission)
List<String> permissions = dbUser.getRoleList()
.stream()
.map(SysRole::getRoleId)
.flatMap(roleId -> sysMenuService.findMenuByRoleId(roleId).stream())
.filter(menu -> StrUtil.isNotEmpty(menu.getPermission()))
.map(SysMenu::getPermission)
.toList();
userInfo.setPermissions(permissions);
return R.ok(userInfo);
}
/**
* 分页查询用户信息(包含角色信息)
* @param page 分页对象
* @param userDTO 查询参数
* @return 包含用户和角色信息的分页结果
*/
@Override
public IPage getUsersWithRolePage(Page page, UserDTO userDTO) {
return baseMapper.getUsersPage(page, userDTO);
}
/**
* 通过ID查询用户信息
* @param id 用户ID
* @return 用户信息VO对象
*/
@Override
public UserVO getUserById(Long id) {
UserDTO query = new UserDTO();
query.setUserId(id);
return baseMapper.getUser(query);
}
/**
* 根据用户ID列表删除用户及相关缓存
* @param ids 用户ID数组
* @return 删除成功返回true
* @throws Exception 事务回滚时抛出异常
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean removeUserByIds(Long[] ids) {
List<Long> idList = CollUtil.toList(ids);
// 删除 spring cache
Cache cache = cacheManager.getCache(CacheConstants.USER_DETAILS);
baseMapper.selectByIds(idList).forEach(user -> cache.evictIfPresent(user.getUsername()));
sysUserRoleMapper.delete(Wrappers.<SysUserRole>lambdaQuery().in(SysUserRole::getUserId, idList));
this.removeBatchByIds(idList);
return Boolean.TRUE;
}
/**
* 更新用户信息
* @param userDto 用户数据传输对象
* @return 操作结果,包含更新是否成功
*/
@Override
@CacheEvict(value = CacheConstants.USER_DETAILS, key = "#userDto.username")
public R<Boolean> updateUserInfo(UserDTO userDto) {
SysUser sysUser = new SysUser();
sysUser.setPhone(userDto.getPhone());
sysUser.setUserId(SecurityUtils.getUser().getId());
sysUser.setAvatar(userDto.getAvatar());
sysUser.setNickname(userDto.getNickname());
sysUser.setName(userDto.getName());
sysUser.setEmail(userDto.getEmail());
return R.ok(this.updateById(sysUser));
}
/**
* 更新用户信息
* @param userDto 用户数据传输对象,包含需要更新的用户信息
* @return 更新成功返回true
*/
@Override
@Transactional(rollbackFor = Exception.class)
@CacheEvict(value = CacheConstants.USER_DETAILS, key = "#userDto.username")
public Boolean updateUser(UserDTO userDto) {
// 更新用户表信息
SysUser sysUser = new SysUser();
BeanUtils.copyProperties(userDto, sysUser);
sysUser.setUpdateTime(LocalDateTime.now());
if (StrUtil.isNotBlank(userDto.getPassword())) {
sysUser.setPassword(ENCODER.encode(userDto.getPassword()));
}
this.updateById(sysUser);
// 更新用户角色表
if (Objects.nonNull(userDto.getRole())) {
// 删除用户角色关系
sysUserRoleMapper
.delete(Wrappers.<SysUserRole>lambdaQuery().eq(SysUserRole::getUserId, userDto.getUserId()));
userDto.getRole().forEach(roleId -> {
SysUserRole userRole = new SysUserRole();
userRole.setUserId(sysUser.getUserId());
userRole.setRoleId(roleId);
sysUserRoleMapper.insert(userRole);
});
}
if (Objects.nonNull(userDto.getPost())) {
// 删除用户岗位关系
sysUserPostMapper
.delete(Wrappers.<SysUserPost>lambdaQuery().eq(SysUserPost::getUserId, userDto.getUserId()));
userDto.getPost().forEach(postId -> {
SysUserPost userPost = new SysUserPost();
userPost.setUserId(sysUser.getUserId());
userPost.setPostId(postId);
sysUserPostMapper.insert(userPost);
});
}
return Boolean.TRUE;
}
/**
* 查询用户列表并转换为Excel导出格式
* @param userDTO 用户查询条件
* @return 用户Excel视图对象列表
*/
@Override
public List<UserExcelVO> listUsers(UserDTO userDTO) {
// 根据数据权限查询全部的用户信息
List<UserVO> voList = baseMapper.listUsers(userDTO);
// 转换成execl 对象输出
return voList.stream().map(userVO -> {
UserExcelVO excelVO = new UserExcelVO();
BeanUtils.copyProperties(userVO, excelVO);
excelVO.setRoleNameList(
userVO.getRoleList().stream().map(SysRole::getRoleName).collect(Collectors.joining(StrUtil.COMMA)));
excelVO.setPostNameList(
userVO.getPostList().stream().map(SysPost::getPostName).collect(Collectors.joining(StrUtil.COMMA)));
if (Objects.nonNull(userVO.getDept())) {
excelVO.setDeptName(userVO.getDept().getName());
}
return excelVO;
}).toList();
}
/**
* 导入用户数据
* @param excelVOList Excel数据列表
* @param bindingResult 校验结果
* @return 导入结果,包含成功或失败信息
*/
@Override
public R importUsers(List<UserExcelVO> excelVOList, BindingResult bindingResult) {
// 通用校验获取失败的数据
List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
List<SysDept> deptList = sysDeptService.list();
List<SysRole> roleList = sysRoleService.list();
List<SysPost> postList = sysPostService.list();
// 执行数据插入操作 组装 UserDto
for (UserExcelVO excel : excelVOList) {
// 个性化校验逻辑
List<SysUser> userList = this.list();
Set<String> errorMsg = new HashSet<>();
// 校验用户名是否存在
if (userList.stream().anyMatch(sysUser -> excel.getUsername().equals(sysUser.getUsername()))) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_USER_USERNAME_EXISTING, excel.getUsername()));
}
// 判断输入的部门名称列表是否合法
Optional<SysDept> deptOptional = deptList.stream()
.filter(dept -> excel.getDeptName().equals(dept.getName()))
.findFirst();
if (deptOptional.isEmpty()) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_DEPT_DEPTNAME_INEXISTENCE, excel.getDeptName()));
}
// 判断输入的角色名称列表是否合法
List<String> roleNameList = StrUtil.split(excel.getRoleNameList(), StrUtil.COMMA);
List<SysRole> roleCollList = roleList.stream()
.filter(role -> roleNameList.stream().anyMatch(name -> role.getRoleName().equals(name)))
.toList();
if (roleCollList.size() != roleNameList.size()) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_ROLE_ROLENAME_INEXISTENCE, excel.getRoleNameList()));
}
// 判断输入的部门名称列表是否合法
List<String> postNameList = StrUtil.split(excel.getPostNameList(), StrUtil.COMMA);
List<SysPost> postCollList = postList.stream()
.filter(post -> postNameList.stream().anyMatch(name -> post.getPostName().equals(name)))
.toList();
if (postCollList.size() != postNameList.size()) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_POST_POSTNAME_INEXISTENCE, excel.getPostNameList()));
}
// 数据合法情况
if (CollUtil.isEmpty(errorMsg)) {
insertExcelUser(excel, deptOptional, roleCollList, postCollList);
}
else {
// 数据不合法情况
errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg));
}
}
if (CollUtil.isNotEmpty(errorMessageList)) {
return R.failed(errorMessageList);
}
return R.ok();
}
/**
* 插入Excel导入的用户信息
* @param excel Excel用户数据对象
* @param deptOptional 部门信息Optional对象
* @param roleCollList 角色列表
* @param postCollList 岗位列表
*/
private void insertExcelUser(UserExcelVO excel, Optional<SysDept> deptOptional, List<SysRole> roleCollList,
List<SysPost> postCollList) {
UserDTO userDTO = new UserDTO();
userDTO.setUsername(excel.getUsername());
userDTO.setPhone(excel.getPhone());
userDTO.setNickname(excel.getNickname());
userDTO.setName(excel.getName());
userDTO.setEmail(excel.getEmail());
// 批量导入初始密码为手机号
userDTO.setPassword(userDTO.getPhone());
// 根据部门名称查询部门ID
userDTO.setDeptId(deptOptional.get().getDeptId());
// 插入岗位名称
List<Long> postIdList = postCollList.stream().map(SysPost::getPostId).toList();
userDTO.setPost(postIdList);
// 根据角色名称查询角色ID
List<Long> roleIdList = roleCollList.stream().map(SysRole::getRoleId).toList();
userDTO.setRole(roleIdList);
// 插入用户
this.saveUser(userDTO);
}
/**
* 注册用户并赋予默认角色
* @param userDto 用户注册信息DTO
* @return 注册结果,包含成功或失败状态
*/
@Override
@Transactional(rollbackFor = Exception.class)
public R<Boolean> registerUser(RegisterUserDTO userDto) {
// 判断用户名是否存在
SysUser sysUser = this.getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, userDto.getUsername()));
if (sysUser != null) {
String message = MsgUtils.getMessage(ErrorCodes.SYS_USER_USERNAME_EXISTING, userDto.getUsername());
return R.failed(message);
}
UserDTO user = new UserDTO();
BeanUtils.copyProperties(userDto, user);
return R.ok(saveUser(user));
}
/**
* 锁定用户
* @param username 用户名
* @return 操作结果,包含是否成功的信息
*/
@Override
@CacheEvict(value = CacheConstants.USER_DETAILS, key = "#username")
public R<Boolean> lockUser(String username) {
SysUser sysUser = baseMapper.selectOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, username));
if (Objects.nonNull(sysUser)) {
sysUser.setLockFlag(CommonConstants.STATUS_LOCK);
baseMapper.updateById(sysUser);
}
return R.ok();
}
/**
* 修改用户密码
* @param userDto 用户信息传输对象,包含用户名、原密码和新密码
* @return 操作结果,成功返回R.ok(),失败返回错误信息
* @CacheEvict 清除用户详情缓存
*/
@Override
@CacheEvict(value = CacheConstants.USER_DETAILS, key = "#userDto.username")
public R changePassword(UserDTO userDto) {
SysUser sysUser = baseMapper.selectById(SecurityUtils.getUser().getId());
if (Objects.isNull(sysUser)) {
return R.failed("用户不存在");
}
if (StrUtil.isEmpty(userDto.getPassword())) {
return R.failed("原密码不能为空");
}
if (!ENCODER.matches(userDto.getPassword(), sysUser.getPassword())) {
log.info("原密码错误,修改个人信息失败:{}", userDto.getUsername());
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_USER_UPDATE_PASSWORDERROR));
}
if (StrUtil.isEmpty(userDto.getNewpassword1())) {
return R.failed("新密码不能为空");
}
String password = ENCODER.encode(userDto.getNewpassword1());
this.update(Wrappers.<SysUser>lambdaUpdate()
.set(SysUser::getPassword, password)
.eq(SysUser::getUserId, sysUser.getUserId()));
return R.ok();
}
/**
* 校验用户密码是否正确
* @param password 待校验的密码
* @return 校验结果,成功返回R.ok(),失败返回R.failed()
*/
@Override
public R checkPassword(String password) {
SysUser sysUser = baseMapper.selectById(SecurityUtils.getUser().getId());
if (!ENCODER.matches(password, sysUser.getPassword())) {
log.info("原密码错误");
return R.failed("密码输入错误");
}
else {
return R.ok();
}
}
}
server:
port: 4000
spring:
application:
name: @artifactId@
cloud:
nacos:
username: @nacos.username@
password: @nacos.password@
discovery:
server-addr: ${NACOS_HOST:127.0.0.1}:${NACOS_PORT:8848}
config:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
config:
import:
- nacos:application-@profiles.active@.yml
- nacos:${spring.application.name}-@profiles.active@.yml
<?xml version="1.0" encoding="UTF-8"?>
<!--
小技巧: 在根pom里面设置统一存放路径,统一管理方便维护
<properties>
<log-path>/Users/lengleng</log-path>
</properties>
1. 其他模块加日志输出,直接copy本文件放在resources 目录即可
2. 注意修改 <property name="${log-path}/log.path" value=""/> 的value模块
-->
<configuration debug="false" scan="false">
<property name="log.path" value="logs/${project.artifactId}"/>
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN"
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<property name="FILE_LOG_PATTERN" value=":%d{yyyy-MM-dd HH:mm:ss.SSS} %5p %t %c{1}: %m%n"/>
<!-- 彩色日志依赖的渲染类 -->
<conversionRule conversionWord="clr" class="org.springframework.boot.logging.logback.ColorConverter"/>
<conversionRule conversionWord="wex"
class="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
<conversionRule conversionWord="wEx"
class="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
<!-- Console log output -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- Log file debug output -->
<appender name="debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/debug.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.path}/%d{yyyy-MM, aux}/debug.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>50MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- Log file error output -->
<appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.path}/%d{yyyy-MM}/error.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>50MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
</appender>
<!--nacos 心跳 INFO 屏蔽-->
<logger name="com.alibaba.nacos" level="OFF">
<appender-ref ref="error"/>
</logger>
<!-- Level: FATAL 0 ERROR 3 WARN 4 INFO 6 DEBUG 7 -->
<root level="debug">
<appender-ref ref="console"/>
<appender-ref ref="debug"/>
<appender-ref ref="error"/>
</root>
</configuration>
<?xml version="1.0" encoding="UTF-8"?>
<!--
~
~ Copyright (c) 2018-2025, lengleng All rights reserved.
~
~ Redistribution and use in source and binary forms, with or without
~ modification, are permitted provided that the following conditions are met:
~
~ Redistributions of source code must retain the above copyright notice,
~ this list of conditions and the following disclaimer.
~ Redistributions in binary form must reproduce the above copyright
~ notice, this list of conditions and the following disclaimer in the
~ documentation and/or other materials provided with the distribution.
~ Neither the name of the pig4cloud.com developer nor the names of its
~ contributors may be used to endorse or promote products derived from
~ this software without specific prior written permission.
~ Author: lengleng (wangiegie@gmail.com)
~
-->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pig4cloud.pig.admin.mapper.SysDeptMapper">
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!--
~
~ Copyright (c) 2018-2025, lengleng All rights reserved.
~
~ Redistribution and use in source and binary forms, with or without
~ modification, are permitted provided that the following conditions are met:
~
~ Redistributions of source code must retain the above copyright notice,
~ this list of conditions and the following disclaimer.
~ Redistributions in binary form must reproduce the above copyright
~ notice, this list of conditions and the following disclaimer in the
~ documentation and/or other materials provided with the distribution.
~ Neither the name of the pig4cloud.com developer nor the names of its
~ contributors may be used to endorse or promote products derived from
~ this software without specific prior written permission.
~ Author: lengleng (wangiegie@gmail.com)
~
-->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pig4cloud.pig.admin.mapper.SysMenuMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.pig4cloud.pig.admin.api.entity.SysMenu">
<id column="menu_id" property="menuId"/>
<result column="name" property="name"/>
<result column="en_name" property="enName"/>
<result column="permission" property="permission"/>
<result column="path" property="path"/>
<result column="parent_id" property="parentId"/>
<result column="icon" property="icon"/>
<result column="sort_order" property="sortOrder"/>
<result column="menu_type" property="menuType"/>
<result column="keep_alive" property="keepAlive"/>
<result column="visible" property="visible"/>
<result column="create_time" property="createTime"/>
<result column="update_time" property="updateTime"/>
<result column="del_flag" property="delFlag"/>
<result column="embedded" property="embedded"/>
<result column="visible" property="visible"/>
</resultMap>
<!--通过角色查询菜单信息-->
<select id="listMenusByRoleId" resultMap="BaseResultMap">
SELECT sys_menu.menu_id,
sys_menu.name,
sys_menu.en_name,
sys_menu.permission,
sys_menu.path,
sys_menu.parent_id,
sys_menu.icon,
sys_menu.sort_order,
sys_menu.keep_alive,
sys_menu.menu_type,
sys_menu.create_time,
sys_menu.update_time,
sys_menu.del_flag,
sys_menu.embedded,
sys_menu.visible
FROM sys_menu
LEFT JOIN sys_role_menu ON sys_menu.menu_id = sys_role_menu.menu_id
WHERE sys_menu.del_flag = '0'
AND sys_role_menu.role_id = #{roleId}
ORDER BY sys_menu.sort_order DESC
</select>
<!--通过角色ID 查询权限-->
<select id="listPermissionsByRoleIds" resultType="java.lang.String">
SELECT m.permission
FROM sys_menu m,
sys_role_menu rm
WHERE m.menu_id = rm.menu_id
AND m.del_flag = '0'
AND rm.role_id IN (#{roleIds})
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!--
~
~ Copyright (c) 2018-2025, lengleng All rights reserved.
~
~ Redistribution and use in source and binary forms, with or without
~ modification, are permitted provided that the following conditions are met:
~
~ Redistributions of source code must retain the above copyright notice,
~ this list of conditions and the following disclaimer.
~ Redistributions in binary form must reproduce the above copyright
~ notice, this list of conditions and the following disclaimer in the
~ documentation and/or other materials provided with the distribution.
~ Neither the name of the pig4cloud.com developer nor the names of its
~ contributors may be used to endorse or promote products derived from
~ this software without specific prior written permission.
~ Author: lengleng (wangiegie@gmail.com)
~
-->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pig4cloud.pig.admin.mapper.SysPostMapper">
<resultMap id="sysPostMap" type="com.pig4cloud.pig.admin.api.entity.SysPost">
<id property="postId" column="post_id"/>
<result property="postCode" column="post_code"/>
<result property="postName" column="post_name"/>
<result property="postSort" column="post_sort"/>
<result property="delFlag" column="del_flag"/>
<result property="createTime" column="create_time"/>
<result property="updateTime" column="update_time"/>
<result property="remark" column="remark"/>
</resultMap>
<!-- 通过用户ID,查询岗位信息-->
<select id="listPostsByUserId" resultType="com.pig4cloud.pig.admin.api.entity.SysPost">
SELECT p.post_id,
p.post_name,
p.post_code,
p.post_sort,
p.del_flag,
p.create_time,
p.update_time,
p.remark
FROM sys_post p,
sys_user_post up
WHERE p.post_id = up.post_id
AND p.del_flag = '0'
and up.user_id = #{userId}
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!--
~
~ Copyright (c) 2018-2025, lengleng All rights reserved.
~
~ Redistribution and use in source and binary forms, with or without
~ modification, are permitted provided that the following conditions are met:
~
~ Redistributions of source code must retain the above copyright notice,
~ this list of conditions and the following disclaimer.
~ Redistributions in binary form must reproduce the above copyright
~ notice, this list of conditions and the following disclaimer in the
~ documentation and/or other materials provided with the distribution.
~ Neither the name of the pig4cloud.com developer nor the names of its
~ contributors may be used to endorse or promote products derived from
~ this software without specific prior written permission.
~ Author: lengleng (wangiegie@gmail.com)
~
-->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pig4cloud.pig.admin.mapper.SysRoleMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.pig4cloud.pig.admin.api.entity.SysRole">
<id column="role_id" property="roleId"/>
<result column="role_name" property="roleName"/>
<result column="role_code" property="roleCode"/>
<result column="role_desc" property="roleDesc"/>
<result column="create_time" property="createTime"/>
<result column="update_time" property="updateTime"/>
<result column="del_flag" property="delFlag"/>
</resultMap>
<!-- 通过用户ID,查询角色信息-->
<select id="listRolesByUserId" resultMap="BaseResultMap">
SELECT sys_role.role_id,
sys_role.role_name,
sys_role.role_code,
sys_role.role_desc,
sys_role.create_time,
sys_role.update_time,
sys_role.del_flag
FROM sys_role,
sys_user_role
WHERE sys_role.role_id = sys_user_role.role_id
AND sys_role.del_flag = '0'
and sys_user_role.user_id = #{userId}
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pig4cloud.pig.admin.mapper.SysUserMapper">
<!-- 通用查询映射结果 -->
<resultMap id="baseResultMap" type="com.pig4cloud.pig.admin.api.vo.UserVO">
<id column="user_id" property="userId"/>
<result column="username" property="username"/>
<result column="password" property="password"/>
<result column="salt" property="salt"/>
<result column="phone" property="phone"/>
<result column="avatar" property="avatar"/>
<result column="wx_openid" property="wxOpenid"/>
<result column="qq_openid" property="qqOpenid"/>
<result column="gitee_login" property="giteeOpenId"/>
<result column="osc_id" property="oscOpenId"/>
<result column="create_time" property="createTime"/>
<result column="update_time" property="updateTime"/>
<result column="lock_flag" property="lockFlag"/>
<result column="del_flag" property="delFlag"/>
<result column="nickname" property="nickname"/>
<result column="name" property="name"/>
<result column="email" property="email"/>
<association property="dept" javaType="com.pig4cloud.pig.admin.api.entity.SysDept" column="dept_id"
select="com.pig4cloud.pig.admin.mapper.SysDeptMapper.selectById">
</association>
<collection property="roleList" ofType="com.pig4cloud.pig.admin.api.entity.SysRole"
select="com.pig4cloud.pig.admin.mapper.SysRoleMapper.listRolesByUserId" column="user_id">
</collection>
<collection property="postList" ofType="com.pig4cloud.pig.admin.api.entity.SysPost"
select="com.pig4cloud.pig.admin.mapper.SysPostMapper.listPostsByUserId" column="user_id">
</collection>
</resultMap>
<!-- 用户查询SQL -->
<sql id="userQuerySql">
SELECT * FROM sys_user u
<where>
u.del_flag = '0'
<if test="query.userId != null and query.userId != ''">
AND u.user_id = #{query.userId}
</if>
<if test="query.username != null and query.username != ''">
<bind name="usernameLike" value="'%'+query.username+'%'"/>
AND u.username LIKE #{usernameLike}
</if>
<if test="query.deptId != null and query.deptId != ''">
AND u.dept_id = #{query.deptId}
</if>
<if test="query.phone != null and query.phone != ''">
<bind name="phoneLike" value="'%'+query.phone+'%'"/>
AND u.phone LIKE #{phoneLike}
</if>
</where>
ORDER BY u.create_time DESC
</sql>
<!-- 分页查询 -->
<select id="getUsersPage" resultMap="baseResultMap">
<include refid="userQuerySql"/>
</select>
<!-- 用户列表 -->
<select id="listUsers" resultMap="baseResultMap">
<include refid="userQuerySql"/>
</select>
<!-- 查询用户信息 (单个)-->
<select id="getUser" resultMap="baseResultMap">
SELECT * FROM sys_user u
<where>
u.del_flag = '0'
<if test="query.userId != null and query.userId != ''">
AND u.user_id = #{query.userId}
</if>
<if test="query.username != null and query.username != ''">
AND u.username = #{query.username}
</if>
<if test="query.deptId != null and query.deptId != ''">
AND u.dept_id = #{query.deptId}
</if>
<if test="query.phone != null and query.phone != ''">
AND u.phone = #{query.phone}
</if>
</where>
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2020 pig4cloud Authors. All Rights Reserved.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pig</artifactId>
<version>${revision}</version>
</parent>
<artifactId>pig-upms</artifactId>
<description>pig 通用用户权限管理聚合模块</description>
<packaging>pom</packaging>
<modules>
<module>pig-upms-api</module>
<module>pig-upms-biz</module>
</modules>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2020 pig4cloud Authors. All Rights Reserved.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.pig4cloud</groupId>
<artifactId>pig</artifactId>
<name>${project.artifactId}</name>
<version>${revision}</version>
<packaging>pom</packaging>
<url>https://www.pig4cloud.com</url>
<properties>
<!-- 项目版本号 -->
<revision>3.9.0</revision>
<spring-boot.version>3.5.3</spring-boot.version>
<spring-cloud.version>2025.0.0</spring-cloud.version>
<spring-cloud-alibaba.version>2023.0.3.3</spring-cloud-alibaba.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<spring-boot-admin.version>3.5.0</spring-boot-admin.version>
<screw.version>0.0.3</screw.version>
<captcha.version>2.2.5</captcha.version>
<aws.version>2.29.45</aws.version>
<velocity.version>2.4</velocity.version>
<velocity.tool.version>3.1</velocity.tool.version>
<configuration.version>1.10</configuration.version>
<jasypt.version>3.0.5</jasypt.version>
<jaxb.version>4.0.5</jaxb.version>
<knife4j.version>3.0.5</knife4j.version>
<swagger.fox.version>3.0.0</swagger.fox.version>
<docker.plugin.version>0.45.1</docker.plugin.version>
<docker.host>http://192.168.0.100:2375</docker.host>
<docker.registry>registry.cn-shanghai.aliyuncs.com</docker.registry>
<docker.namespace>pig4cloud</docker.namespace>
<docker.username>username</docker.username>
<docker.password>password</docker.password>
<git.commit.plugin>9.0.1</git.commit.plugin>
<spring.checkstyle.plugin>0.0.43</spring.checkstyle.plugin>
<flatten-maven-plugin.version>1.6.0</flatten-maven-plugin.version>
<maven-compiler-plugin.version>3.14.0</maven-compiler-plugin.version>
</properties>
<!-- 以下依赖 全局所有的模块都会引入 -->
<dependencies>
<!--配置文件处理器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!--配置文件加解密-->
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>${jasypt.version}</version>
</dependency>
<!--监控-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--监控客户端-->
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>${spring-boot-admin.version}</version>
</dependency>
<!--Lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!-- JAVA 17 -->
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>${jaxb.version}</version>
</dependency>
<!--测试依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<modules>
<module>pig-auth</module>
<module>pig-upms</module>
<module>pig-common</module>
<module>pig-ask</module>
</modules>
<dependencyManagement>
<dependencies>
<!--pig 公共版本定义-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common-bom</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- spring boot 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- spring cloud 依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- spring cloud alibaba 依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 排除 spring cloud alibaba 令人头疼的日志封装-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<exclusions>
<exclusion>
<artifactId>logback-adapter</artifactId>
<groupId>com.alibaba.nacos</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<finalName>${project.name}</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<finalName>${project.build.finalName}</finalName>
<layers>
<enabled>true</enabled>
</layers>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>${docker.plugin.version}</version>
<configuration>
<!-- Docker Remote Api-->
<dockerHost>${docker.host}</dockerHost>
<!-- Docker 镜像私服-->
<registry>${docker.registry}</registry>
<!-- 认证信息-->
<authConfig>
<push>
<username>${docker.username}</username>
<password>${docker.password}</password>
</push>
</authConfig>
<images>
<image>
<!-- 镜像名称: 172.17.0.111/library/pig-gateway:2.6.3-->
<name>${docker.registry}/${docker.namespace}/${project.name}:${project.version}</name>
<build>
<dockerFile>${project.basedir}/Dockerfile</dockerFile>
</build>
</image>
</images>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<!-- 统一 revision 版本 -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>flatten-maven-plugin</artifactId>
<version>${flatten-maven-plugin.version}</version>
<configuration>
<flattenMode>resolveCiFriendliesOnly</flattenMode>
<updatePomFile>true</updatePomFile>
</configuration>
<executions>
<execution>
<id>flatten</id>
<phase>process-resources</phase>
<goals>
<goal>flatten</goal>
</goals>
</execution>
<execution>
<id>flatten.clean</id>
<phase>clean</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<target>${maven.compiler.target}</target>
<source>${maven.compiler.source}</source>
<encoding>UTF-8</encoding>
<parameters>true</parameters>
</configuration>
</plugin>
<!--打包jar 与git commit 关联插件-->
<plugin>
<groupId>io.github.git-commit-id</groupId>
<artifactId>git-commit-id-maven-plugin</artifactId>
<version>${git.commit.plugin}</version>
<executions>
<execution>
<id>get-the-git-infos</id>
<phase>initialize</phase>
</execution>
</executions>
<configuration>
<failOnNoGitDirectory>false</failOnNoGitDirectory>
<generateGitPropertiesFile>true</generateGitPropertiesFile>
<!--因为项目定制了jackson的日期时间序列化/反序列化格式,因此这里要进行配置,不然通过management.info.git.mode=full进行完整git信息监控时会存在问题-->
<dateFormat>yyyy-MM-dd HH:mm:ss</dateFormat>
<includeOnlyProperties>
<includeOnlyProperty>^git.build.(time|version)$</includeOnlyProperty>
<includeOnlyProperty>^git.commit.(id|message|time).*$</includeOnlyProperty>
</includeOnlyProperties>
</configuration>
</plugin>
<!--
代码格式插件,默认使用spring 规则,可运行命令进行项目格式化:./mvnw spring-javaformat:apply 或 mvn spring-javaformat:apply,可在IDEA中安装插件以下插件进行自动格式化:
https://repo1.maven.org/maven2/io/spring/javaformat/spring-javaformat-intellij-idea-plugin
-->
<plugin>
<groupId>io.spring.javaformat</groupId>
<artifactId>spring-javaformat-maven-plugin</artifactId>
<version>${spring.checkstyle.plugin}</version>
<executions>
<execution>
<phase>validate</phase>
<inherited>true</inherited>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>cloud</id>
<properties>
<!-- 环境标识,需要与配置文件的名称相对应 -->
<profiles.active>dev</profiles.active>
<nacos.username>nacos</nacos.username>
<nacos.password>nacos</nacos.password>
</properties>
<activation>
<!-- 默认环境 -->
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>boot</id>
<modules>
<module>pig-boot</module>
</modules>
</profile>
</profiles>
</project>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment