feat():月月舒项目框架;

master
jiyufei 3 months ago
commit 5160544751

75
.gitignore vendored

@ -0,0 +1,75 @@
# For Java
*.lck
target/
log/
logback-test.xml
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
# Image snapshot diff
__diff_output__/
/jest-stare
*.iml
.idea/
.ipr
.iws
*~
~*
*.diff
*.patch
*.bak
.DS_Store
Thumbs.db
.project
.*proj
.svn/
*.swp
*.swo
*.log
*.log.*
*.json.gzip
node_modules/
.buildpath
.settings
dist
npm-debug.log
nohup.out
_site
_data
report.html
/lib
/es
elasticsearch-*
config/base.yaml
/.vscode/
/coverage
/.history
*.tmp
!**/nacos/target
**/nacos/data/*
**/nacos/logs/*
**/seata/bin/*

@ -0,0 +1,22 @@
# 基础镜像
FROM eclipse-temurin:8u362-b09-jre
LABEL maintainer=jnpf-team
# 设置时区
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo 'Asia/Shanghai' >/etc/timezone
# 解决连接SQLServer安全错误
COPY security/java.security /opt/java/openjdk/lib/security
# 指定运行时的工作目录
WORKDIR /jnpfsoft/jnpf-server/jnpf-java-boot
# 将构建产物jar包拷贝到运行时目录中
COPY jnpf-admin/target/*.jar ./jnpf-admin.jar
# 指定容器内运行端口
EXPOSE 30000
# 指定容器启动时要运行的命令
ENTRYPOINT ["/bin/sh","-c","java -Dfile.encoding=utf8 -Djava.security.egd=file:/dev/./urandom -jar jnpf-admin.jar"]

@ -0,0 +1,369 @@
> 特别说明源码、JDK、MySQL、Redis等安装或存放路径禁止包含中文、空格、特殊字符等
## 一 技术栈
- 主框架:`Spring Boot` + `Spring Framework`
- 持久层框架:`MyBatis-Plus`
- 数据库连接池:`Alibaba Druid`
- 多数据源:`Dynamic-Datasource`
- 数据库兼容: `MySQL`(默认)、`SQLServer`、`Oracle`、`PostgreSQL`、`达数据库`、`人大金仓数据库`
- 分库分表解决方案:`Apache ShardingSphere`
- 权限认证框架:`Sa-Token`+`JWT`
- 代码生成器:`MyBatis-Plus-Generator`
- 模板引擎:`Velocity`
- 任务调度:`XXL-JOB`
- 分布式锁:`Lock4j`
- JSON序列化: `Jackson`&`Fastjson`
- 缓存数据库:`Redis`
- 校验框架:`Validation`
- 分布式文件存储:兼容`MinIO`及多个云对象存储,如阿里云 OSS、华为云 OBS、七牛云 Kodo、腾讯云 COS等
- 工具类框架:`Hutool`、`Lombok`
- 接口文档:`Knife4j`
- 项目构建:`Maven`
## 二 环境要求
### 2.1 开发环境
| 类目 | 版本说明或建议 |
| --- |---------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 电脑配置 | 建议开发电脑I3及以上CPU内存16G及以上 |
| 操作系统 | Windows 10/11MacOS |
| JDK | 建议使用`1.8.0_281`及以上版本,可使用`Eclipse Temurin JDK 8`、`Alibaba Dragonwell 8`、`BiSheng JDK 8`等 |
| Maven | `3.6.3`及以上版本 |
| 数据缓存 | Redis `3.2.100`(Windows)/`4.0.x`+ (Linux,Mac)  或  TongRDS `2.2.x` |
| 数据库 | 兼容`MySQL 5.7.x/8.0.x`(默认)、`SQLServer 2012+`、`Oracle 11g`、`PostgreSQL 12+`、`达梦数据库(DM8)`、`人大金仓数据库(KingbaseES_V8R6)` |
| 后端开发 | `IDEA2020`及以上版本、`Eclipse` 、 `Spring Tool Suite`等 |
| 前端开发 | `Node.js` v16.15.0(某些情况下可能需要安装 `Python3`)及以上版本;<br/>`Yarn` v1.22.x 版本;<br/>`pnpm` v8.10及以上版本;<br/>浏览器推荐使用`Chrome` 90及以上版本<br/>`Visual Studio Code`(简称VSCode) |
| 移动端开发 | `Node.js` v12/v14/v16(某些情况下可能需要安装 Python3)<br/>HBuilder X(最新版) |
| 文件存储 | 默认使用本地存储,兼容 `MinIO` 及多个云对象存储,如`阿里云 OSS`、`华为云 OBS`、`七牛云 Kodo`、`腾讯云 COS`等 |
### 2.2 运行环境
> 适用于测试或生产环境
| 类目 | 版本说明或建议 |
| --- |-------------------------------------------------------------------------------------------------------------------|
| 服务器配置 | 最低配置要求4c/16G/50G |
| 操作系统 | 推荐使用`Ubuntu 18.0.4`及以上版本,兼容 `统信UOS``OpenEuler``麒麟服务器版`等国产信创环境; |
| JRE | 建议使用`1.8.0_281`及以上版本,如`Eclipse Temurin JRE 8/11/17`、`Alibaba Dragonwell 8/11/17`、`BiSheng JRE 8/11/17` |
| 数据缓存 | Redis `4.0.x+` 或 TongRDS `2.2.x` |
| 数据库 | 兼容`MySQL 5.7.x/8.0.x`(默认)、`SQLServer 2012+`、`Oracle 11g`、`PostgreSQL 12+`、`达梦数据库(DM8)`、`人大金仓数据库(KingbaseES_V8R6)` |
| 中间件(可选) | 东方通 `Tong-web`、金蝶天燕-应用服务器`AAS` v10 |
| 文件存储 | 默认使用本地存储,兼容`MinIO`及多个云对象存储,如阿里云 OSS、华为云 OBS、七牛云 Kodo、腾讯云 COS等 |
| 前端服务器 | Nginx 建议使用`1.18.0`及以上版本  或 TongHttpServer `6.0` |
## 三 IDEA插件
- `Lombok`(必须)
- `Alibaba Java Coding Guidelines`
- `MybatisX`
## 四 Maven私服配置
> Apache Maven 3.6.3及以上版本<br>解决以下依赖无法从公共Maven仓库下载的问题
- com.dm:DmJdbcDriver18:1.8.0
- com.kingbase8:kingbase8-jdbc:2.0
- dingtalk-sdk-java:taobao-sdk-java-source:1.0
- dingtalk-sdk-java:taobao-sdk-java:1.0
打开Maven安装目录中的 `conf/settings.xml` 文件,<br>
`<servers></servers>` 中添加如下内容
```xml
<server>
<id>maven-releases</id>
<username>jnpf-user</username>
<password>HLrQ0MA%S1nE</password>
</server>
```
`<mirrors></mirrors>` 中添加
```xml
<mirror>
<id>maven-releases</id>
<mirrorOf>*</mirrorOf>
<name>maven-releases</name>
<url>https://repository.jnpfsoft.com/repository/maven-public/</url>
</mirror>
```
## 五 配套项目
| 项目 | 分支 | 分支Coding | 说明 |
| --- | --- | --- | --- |
| **后端** | | | |
| jnpf-common | v3.5.x | v3.5.0-stable | java基础依赖项目源码 |
| jnpf-file-core-starter | v3.5.x | v3.4.3-stable | 文件基础依赖项目源码 |
| jnpf-scheduletask | v3.5.x | v3.5.0-stable | 任务调度客户端依赖及服务端项目源码 |
| jnpf-datareport | v3.5.x | v3.4.7-stable | 报表后端项目源码 |
| jnpf-file-preview | v3.4.3 | v3.0.0-stable | 本地文档预览项目源码 |
| **前端** | | | |
| jnpf-web | v3.5.x | v3.5.0-stable | 前端主项目(Vue2)源码 |
| jnpf-web-vue3 | v3.5.x | v3.5.0-stable | 前端主项目(Vue3)源码 |
| jnpf-web-datascreen | v3.5.x | v3.5.0-stable | 大屏前端项目(Vue2)源码 |
| jnpf-web-datascreen-vue3 | v3.5.x | v3.5.0-stable | 大屏前端项目(Vue3)源码 |
| jnpf-web-datareport | v3.4.7 | v3.4.7-stable | 报表前端项目源码 |
| **移动端** | | | |
| jnpf-app | v3.5.x | v3.5.0-stable | 移动端项目(Vue2)源码 |
| **静态资源** | | | |
| jnpf-resources | v3.5.x | v3.5.0-stable | 静态资源 |
| **数据库** | | | |
| jnpf-database | v3.5.x | v3.5.0-stable | 数据库脚本或文件 |
## 六 开发环境
### 6.1 导入数据库脚本
> 以 MySQL数据库为例<br>字符集utf8mb4<br/>排序规则utf8mb4_general_ci
#### 6.1.1 创建平台数据库
在MySQL创建 `jnpf_init` 数据库,并将 `jnpf-database/MySQL/jnpf_init.sql` 以【新建查询】方式导入
#### 6.1.2 创建系统调度数据库
在MySQL创建 `jnpf_xxjob` 数据库,并将 `jnpf-database/MySQL/jnpf_xxjob_init.sql` 以【新建查询】方式导入
### 6.2 导入依赖
#### 6.2.1 基础依赖
详见 `jnpf-common` 项目中的 `README.md` 文档说明
#### 6.2.2 文件基础依赖
详见 `jnpf-file-starter` 项目中的 `README.md` 文档说明
#### 6.2.3 导入系统调度服务端
详见 `jnpf-scheduletask` 项目中的 `README.md` 文档说明
### 6.3 项目配置
打开编辑 `jnpf-admin/src/main/resources/application.yml`
#### 6.3.1 指定环境配置
- `application-dev.yml`  开发环境(默认)
- `application-test.yml`  测试环境
- `application-preview.yml` 预发布环境
- `application-pro.yml` 生产环境
```yaml
# application.yml第5行,可选值dev(默认)|test|pro|preview
active: dev
```
#### 6.3.2 配置域名
打开编辑 `jnpf-admin/src/main/resources/application.yml` ,修改以下配置
```yaml
PreviewType: kkfile #文件预览方式 1.yozo 2.kkfile默认使用kkfile
kkFileUrl: http://127.0.0.1:30090/FileServer/ #kkfile文件预览服务地址
ApiDomain: http://127.0.0.1:30000 #后端域名(文档预览中使用)
FrontDomain: http://127.0.0.1:3000 #前端域名(文档预览中使用)
AppDomain: http://127.0.0.1:8080 #app/h5端域名配置(文档预览中使用)
```
#### 6.3.3 数据源配置
打开编辑 `jnpf-admin/src/main/resources/application-dev.yml`,修改以下配置
> 具体配置说明参考:[https://jnpfsoft.coding.net/p/jnpf-docs/wiki/2165](https://jnpfsoft.coding.net/p/jnpf-docs/wiki/2165)
```yaml
datasource:
db-type: MySQL #数据库类型(可选值 MySQL、SQLServer、Oracle、DM8、KingbaseES、PostgreSQL请严格按可选值填写)
host: 192.168.0.213
port: 3306
username: root
password: a26d27e6a6cd4538
db-name: java_boot_test
db-schema: #金仓达梦选填
prepare-url: #自定义url
```
#### 6.3.4 Redis配置
打开编辑 `jnpf-admin/src/main/resources/application-dev.yml`,修改以下配置
> 支持单机模式和集群模式,配置默认为单机模式
**Redis单机模式**
```yaml
redis:
database: 200 #缓存库编号
host: 192.168.0.213
port: 6379
password: ucfbVgZgyB0dBQdh # 密码为空时,请将本行注释
timeout: 3000 #超时时间(单位:秒)
lettuce: #Lettuce为Redis的Java驱动包
pool:
max-active: 8 # 连接池最大连接数
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
min-idle: 0 # 连接池中的最小空闲连接
max-idle: 8 # 连接池中的最大空闲连接
```
**Redis集群模式**
```yaml
redis:
cluster:
nodes:
- 192.168.0.225:6380
- 192.168.0.225:6381
- 192.168.0.225:6382
- 192.168.0.225:6383
- 192.168.0.225:6384
- 192.168.0.225:6385
password: 123456 # 密码为空时,请将本行注释
timeout: 3000 # 超时时间(单位:秒)
lettuce: #Lettuce为Redis的Java驱动包
pool:
max-active: 8 # 连接池最大连接数
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
min-idle: 0 # 连接池中的最小空闲连接
max-idle: 8 # 连接池中的最大空闲连接
```
#### 6.3.5 静态资源配置
打开编辑 `jnpf-admin/src/main/resources/application-dev.yml` ,修改以下配置
> 默认使用本地存储,兼容`MinIO`及多个云对象存储,如阿里云 OSS、华为云 OBS、七牛云 Kodo、腾讯云 COS等
```yaml
# ===================== 文件存储配置 =====================
file-storage: #文件存储配置,不使用的情况下可以不写
default-platform: local-plus-1 #默认使用的存储平台
thumbnail-suffix: ".min.jpg" #缩略图后缀,例如【.min.jpg】【.png】
local-plus: # 本地存储升级版
- platform: local-plus-1 # 存储平台标识
enable-storage: true #启用存储
enable-access: true #启用访问(线上请使用 Nginx 配置,效率更高)
domain: "" # 访问域名例如“http://127.0.0.1:8030/”,注意后面要和 path-patterns 保持一致,“/”结尾,本地存储建议使用相对路径,方便后期更换域名
base-path: D:/project/jnpf-resources/ # 基础路径
path-patterns: /** # 访问路径
storage-path: # 存储路径
aliyun-oss: # 阿里云 OSS ,不使用的情况下可以不写
- platform: aliyun-oss-1 # 存储平台标识
enable-storage: false # 启用存储
access-key: ??
secret-key: ??
end-point: ??
bucket-name: ??
domain: ?? # 访问域名,注意“/”结尾例如https://abc.oss-cn-shanghai.aliyuncs.com/
base-path: hy/ # 基础路径
qiniu-kodo: # 七牛云 kodo ,不使用的情况下可以不写
- platform: qiniu-kodo-1 # 存储平台标识
enable-storage: false # 启用存储
access-key: ??
secret-key: ??
bucket-name: ??
domain: ?? # 访问域名,注意“/”结尾例如http://abc.hn-bkt.clouddn.com/
base-path: base/ # 基础路径
tencent-cos: # 腾讯云 COS
- platform: tencent-cos-1 # 存储平台标识
enable-storage: false # 启用存储
secret-id: ??
secret-key: ??
region: ?? #存仓库所在地域
bucket-name: ??
domain: ?? # 访问域名,注意“/”结尾例如https://abc.cos.ap-nanjing.myqcloud.com/
base-path: hy/ # 基础路径
minio: # MinIO由于 MinIO SDK 支持 AWS S3其它兼容 AWS S3 协议的存储平台也都可配置在这里
- platform: minio-1 # 存储平台标识
enable-storage: true # 启用存储
access-key: Q9jJs2b6Tv
secret-key: Thj2WkpLu9DhmJyJ
end-point: http://192.168.0.207:9000/
bucket-name: jnpfsoftoss
domain: # 访问域名,注意“/”结尾例如http://minio.abc.com/abc/
base-path: # 基础路径
```
#### 6.3.6 第三方登录配置
打开编辑 `jnpf-admin/src/main/resources/application-dev.yml` ,修改以下配置
> 配置默认关闭
```yaml
socials:
# 第三方登录功能开关(false-关闭true-开启)
socials-enabled: false
config:
- # 微信
provider: wechat_open
client-id: your-client-id
client-secret: your-client-secret
- # qq
provider: qq
client-id: your-client-id
client-secret: your-client-secret
- # 企业微信
provider: wechat_enterprise
client-id: your-client-id
client-secret: your-client-secret
agentId: your-agentId
- # 钉钉
provider: dingtalk
client-id: your-client-id
client-secret: your-client-secret
agentId: your-agentId
- # 飞书
provider: feishu
client-id: your-client-id
client-secret: your-client-secret
- # 小程序
provider: wechat_applets
client-id: your-client-id
client-secret: your-client-secret
```
#### 6.3.7 任务调度配置
打开编辑 `jnpf-admin/src/main/resources/application-dev.yml` ,修改以下配置,调整 xxl.job.admin.addresses 地址
```yaml
xxl:
job:
accessToken: ''
i18n: zh_CN
logretentiondays: 30
triggerpool:
fast:
max: 200
slow:
max: 100
# xxl-job服务端地址
admin:
addresses: http://127.0.0.1:30020/xxl-job-admin/
executor:
address: ''
appname: xxl-job-executor-sample1
ip: ''
logpath: /data/applogs/xxl-job/jobhandler
logretentiondays: 30
port: 9999
# rest调用xxl-job接口地址
admin:
register:
handle-query-address: ${xxl.job.admin.addresses}api/handler/queryList
job-info-address: ${xxl.job.admin.addresses}api/jobinfo
log-query-address: ${xxl.job.admin.addresses}api/log
task-list-address: ${xxl.job.admin.addresses}api/ScheduleTask/List
task-info-address: ${xxl.job.admin.addresses}api/ScheduleTask/getInfo
task-save-address: ${xxl.job.admin.addresses}api/ScheduleTask
task-update-address: ${xxl.job.admin.addresses}api/ScheduleTask
task-remove-address: ${xxl.job.admin.addresses}api/ScheduleTask/remove
task-start-or-remove-address: ${xxl.job.admin.addresses}api/ScheduleTask/updateTask
```
## 七 启动项目
找到`jnpf-admin/src/main/java/JnpfAdminApplication.java`,右击运行即可。
## 八 项目发布
- 在IDEA中双击右侧Maven中 `jnpf-java-boot` > `Lifecycle` > `clean` 清理项目
- 在IDEA中双击右侧Maven中 `jnpf-java-boot` > `Lifecycle` > `package` 打包项目
- 打开 `jnpf-java-boot\jnpf-admin\target`,将 `jnpf-admin-3.5.0-RELEASE.jar` 上传至服务器
## 九 接口文档
- `http://localhost:30000/doc.html`

@ -0,0 +1,174 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>jnpf-java-boot</artifactId>
<groupId>com.jnpf</groupId>
<version>3.5.0-RELEASE</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jnpf-admin</artifactId>
<packaging>jar</packaging>
<!--打包WAR包删除注释-->
<!--<packaging>war</packaging>-->
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-file-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-extend-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-form-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-system-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-scheduletask-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-message-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-permission-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-visualdev-base-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-visualdev-onlinedev-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-visualdev-generater-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-visualdev-portal-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-visualdata-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-exception</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-workflow-engine-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-workflow-form-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-oauth-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-example-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-app-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-visualdev-integrate-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-scm-controller</artifactId>
<version>${project.version}</version>
</dependency>
<!--打包WAR包删除注释-->
<!--<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>-->
</dependencies>
<build>
<plugins>
<!-- ... -->
<!--打包WAR包注释插件-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>jnpf.JnpfAdminApplication</mainClass>
<layout>ZIP</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- ... -->
<!--打包WAR包删除注释-->
<!--<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.2</version>
<configuration>
<warSourceExcludes>src/main/resources/**</warSourceExcludes>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>-->
</plugins>
</build>
</project>

@ -0,0 +1,29 @@
package jnpf;
import cn.xuyanwu.spring.file.storage.EnableFileStorage;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
/**
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2021/3/15 17:12
*/
@SpringBootApplication(scanBasePackages = {"jnpf"},exclude={DataSourceAutoConfiguration.class})
@EnableFileStorage
public class JnpfAdminApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(JnpfAdminApplication.class);
//添加监听器
// springApplication.addListeners(new JnpfListener());
springApplication.run(args);
System.out.println("JnpfAdmin启动完成");
}
}

@ -0,0 +1,86 @@
package jnpf.aop;
import cn.dev33.satoken.context.SaHolder;
import jnpf.base.UserInfo;
import jnpf.config.ConfigValueUtil;
import jnpf.database.util.NotTenantPluginHolder;
import jnpf.util.data.DataSourceContextHolder;
import jnpf.util.StringUtil;
import jnpf.util.UserProvider;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2021/3/15 17:12
*/
@Slf4j
@Aspect
@Component
@Order(1)
public class DataSourceBindAspect {
@Autowired
private ConfigValueUtil configValueUtil;
@Pointcut("((execution(* jnpf.*.controller.*.*(..)) || execution(* jnpf.controller.*.*(..))) " +
"&& !execution(* jnpf.controller.LoginController.login(..)))" +
"|| execution(* jnpf.message.websocket.WebSocket.*(..))")
public void bindDataSource() {
}
/**
* NoDataSourceBind
*
* @param pjp
* @return
* @throws Throwable
*/
@Around("bindDataSource() && !@annotation(jnpf.util.NoDataSourceBind)")
public Object doAroundService(ProceedingJoinPoint pjp) throws Throwable {
if (configValueUtil.isMultiTenancy()) {
if(StringUtil.isEmpty(DataSourceContextHolder.getDatasourceId()) || StringUtil.isEmpty(DataSourceContextHolder.getDatasourceName())){
UserInfo userInfo = UserProvider.getUser();
String url = null;
try{
url = SaHolder.getRequest().getRequestPath();
}catch (Exception ee){ }
log.error("租户" + userInfo.getTenantId() + "数据库不存在, URL: {}, TOKEN: {}", url, userInfo.getToken());
return null;
}
return pjp.proceed();
}
Object obj = pjp.proceed();
return obj;
}
/**
* NoDataSourceBind
*
* @param pjp
* @return
* @throws Throwable
*/
@Around("bindDataSource() && @annotation(jnpf.util.NoDataSourceBind)")
public Object doAroundService2(ProceedingJoinPoint pjp) throws Throwable {
try{
NotTenantPluginHolder.setNotSwitchAlwaysFlag();
//Filter中提前设置租户信息, 不需要切库的方法进行清除切库
DataSourceContextHolder.clearDatasourceType();
return pjp.proceed();
}finally {
NotTenantPluginHolder.clearNotSwitchAlwaysFlag();
}
}
}

@ -0,0 +1,111 @@
package jnpf.aop;
import jnpf.annotation.OrganizeAdminIsTrator;
import jnpf.base.ActionResult;
import jnpf.base.UserInfo;
import jnpf.constant.MsgCode;
import jnpf.constant.PermissionConstant;
import jnpf.permission.entity.OrganizeRelationEntity;
import jnpf.permission.model.authorize.SaveBatchForm;
import jnpf.permission.service.OrganizeRelationService;
import jnpf.util.PermissionAspectUtil;
import jnpf.util.UserProvider;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2021/3/15 17:12
*/
@Slf4j
@Aspect
@Component
public class PermissionAdminAspect implements PermissionAdminBase{
@Autowired
private UserProvider userProvider;
@Autowired
private OrganizeRelationService organizeRelationService;
/**
*
*/
@Pointcut("@annotation(jnpf.annotation.OrganizeAdminIsTrator)")
public void pointcut() {
}
/**
*
*
* @param pjp
* @return
* @throws Throwable
*/
@Around("pointcut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
return PermissionAdminBase.permissionCommon(pjp, userProvider, this);
}
@Override
public Boolean detailPermission(ProceedingJoinPoint pjp, String operatorUserId, String methodName){
switch (methodName) {
case PermissionConstant.METHOD_SAVE:
if(userProvider.get().getIsAdministrator()){
return true;
}
String roleId = (String) pjp.getArgs()[0];
List<String> orgIdList = organizeRelationService.getRelationListByRoleId(roleId).stream().map(OrganizeRelationEntity::getOrganizeId).collect(Collectors.toList());
StringBuilder orgId = new StringBuilder();
orgIdList.stream().forEach(t->{
orgId.append(t + ",");
});
return PermissionAspectUtil.getPermitByOrgId(
// 操作目标对象组织ID集合
orgId.toString(),
operatorUserId,
PermissionConstant.METHOD_UPDATE);
case PermissionConstant.METHOD_SAVE_BATCH:
// 修改为只有超管才能操作
if(userProvider.get().getIsAdministrator()){
return true;
}
// 得到角色id
SaveBatchForm saveBatchForm = (SaveBatchForm) pjp.getArgs()[0];
List<String> list = Arrays.asList(saveBatchForm.getRoleIds());
if (list.size() == 0) {
list = new ArrayList<>();
list.add("");
}
// 得到组织id
List<String> orgIdLists = organizeRelationService.getRelationListByRoleIdList(list).stream().map(OrganizeRelationEntity::getOrganizeId).collect(Collectors.toList());
StringBuilder orgIds = new StringBuilder();
orgIdLists.stream().forEach(t->{
orgIds.append(t + ",");
});
return PermissionAspectUtil.getPermitByOrgId(
// 操作目标对象组织ID集合
orgIds.toString(),
operatorUserId,
PermissionConstant.METHOD_UPDATE);
case PermissionConstant.METHOD_UPDATE:
//判断是否有当前组织的修改权限
String organizeId = String.valueOf(pjp.getArgs()[0]);
return PermissionAspectUtil.containPermission(organizeId, operatorUserId, methodName);
default:
return false;
}
}
}

@ -0,0 +1,40 @@
package jnpf.aop;
import jnpf.base.ActionResult;
import jnpf.base.UserInfo;
import jnpf.constant.MsgCode;
import jnpf.util.UserProvider;
import org.aspectj.lang.ProceedingJoinPoint;
public interface PermissionAdminBase{
/**
*
* @param pjp AOP
* @param operatorUserId
*/
Boolean detailPermission(ProceedingJoinPoint pjp, String operatorUserId, String methodName);
/**
*
*
* @param userProvider
*/
static Object permissionCommon(ProceedingJoinPoint pjp, UserProvider userProvider, PermissionAdminBase permissionAdminBase) throws Throwable {
// 获取用户信息
UserInfo operatorUser = userProvider.get();
// 是否是管理员
if(operatorUser.getIsAdministrator()){
return pjp.proceed();
}else {
// 获取方法名
String methodName = pjp.getSignature().getName();
// 具体方法权限
if(permissionAdminBase.detailPermission(pjp, operatorUser.getUserId(),methodName)){
return pjp.proceed();
}
}
return ActionResult.fail(MsgCode.FA021.get());
}
}

@ -0,0 +1,121 @@
package jnpf.aop;
import jnpf.constant.PermissionConstant;
import jnpf.permission.entity.OrganizeEntity;
import jnpf.permission.model.organize.OrganizeCrForm;
import jnpf.permission.model.organize.OrganizeDepartCrForm;
import jnpf.permission.model.organize.OrganizeDepartUpForm;
import jnpf.permission.model.organize.OrganizeUpForm;
import jnpf.permission.service.OrganizeService;
import jnpf.util.PermissionAspectUtil;
import jnpf.util.UserProvider;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.StringJoiner;
/**
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2021/3/15 17:12
*/
@Slf4j
@Aspect
@Component
public class PermissionOrgAspect implements PermissionAdminBase {
@Autowired
private UserProvider userProvider;
@Autowired
private OrganizeService organizeService;
/**
*
*/
@Pointcut("@annotation(jnpf.annotation.OrganizePermission)")
public void pointcut() {
}
/**
*
*
* @param pjp
* @return
* @throws Throwable
*/
@Around("pointcut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
return PermissionAdminBase.permissionCommon(pjp, userProvider, this);
}
@Override
public Boolean detailPermission(ProceedingJoinPoint pjp, String operatorUserId, String methodName) {
switch (methodName) {
case PermissionConstant.METHOD_CREATE:
return PermissionAspectUtil.getPermitByOrgIds(
// 操作目标对象表单对象
((OrganizeCrForm) pjp.getArgs()[0]).getParentId(),
operatorUserId,
PermissionConstant.METHOD_CREATE);
case PermissionConstant.METHOD_CREATE_DEPARTMENT:
return PermissionAspectUtil.getPermitByOrgIds(
// 操作目标对象表单对象
((OrganizeDepartCrForm) pjp.getArgs()[0]).getParentId(),
operatorUserId,
PermissionConstant.METHOD_CREATE);
case PermissionConstant.METHOD_UPDATE:
// 当前组织id
String orgId = (String) pjp.getArgs()[0];
// 当前组织父级id
OrganizeEntity info = organizeService.getInfo(orgId);
// 修改后的id
OrganizeUpForm organizeUpForm = (OrganizeUpForm) pjp.getArgs()[1];
StringJoiner stringJoiner = new StringJoiner(",");
stringJoiner.add(orgId);
if (!organizeUpForm.getParentId().equals(info.getParentId()) && !"-1".equals(info.getParentId())) {
stringJoiner.add(info.getParentId());
}
if (!organizeUpForm.getParentId().equals(info.getParentId()) && !"-1".equals(organizeUpForm.getParentId())) {
stringJoiner.add(organizeUpForm.getParentId());
}
return PermissionAspectUtil.getPermitByOrgIds(
// 操作目标对象ID
stringJoiner.toString(),
operatorUserId,
PermissionConstant.METHOD_UPDATE);
case PermissionConstant.METHOD_UPDATE_DEPARTMENT:
// 当前组织id
String orgIds = (String) pjp.getArgs()[0];
// 当前组织父级id
OrganizeEntity infos = organizeService.getInfo(orgIds);
// 修改后的id
OrganizeDepartUpForm organizeDepartUpForm = (OrganizeDepartUpForm) pjp.getArgs()[1];
StringJoiner stringJoiners = new StringJoiner(",");
stringJoiners.add(orgIds);
if (!organizeDepartUpForm.getParentId().equals(infos.getParentId())) {
stringJoiners.add(infos.getParentId());
stringJoiners.add(organizeDepartUpForm.getParentId());
}
return PermissionAspectUtil.getPermitByOrgIds(
// 操作目标对象ID
stringJoiners.toString(),
operatorUserId,
PermissionConstant.METHOD_UPDATE);
case PermissionConstant.METHOD_DELETE:
case PermissionConstant.METHOD_DELETE_DEPARTMENT:
return PermissionAspectUtil.getPermitByOrgIds(
// 操作目标对象ID
pjp.getArgs()[0].toString(),
operatorUserId,
PermissionConstant.METHOD_DELETE);
default:
return false;
}
}
}

@ -0,0 +1,93 @@
package jnpf.aop;
import jnpf.constant.PermissionConstant;
import jnpf.permission.entity.PositionEntity;
import jnpf.permission.model.position.PositionCrForm;
import jnpf.permission.model.position.PositionUpForm;
import jnpf.permission.service.OrganizeService;
import jnpf.permission.service.PositionService;
import jnpf.util.PermissionAspectUtil;
import jnpf.util.UserProvider;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2021/3/15 17:12
*/
@Slf4j
@Aspect
@Component
public class PermissionPositionAspect implements PermissionAdminBase{
@Autowired
private UserProvider userProvider;
@Autowired
private PositionService positionService;
@Autowired
private OrganizeService organizeService;
/**
*
*/
@Pointcut("@annotation(jnpf.annotation.PositionPermission)")
public void pointcut() {
}
/**
*
*
* @param pjp
* @return
* @throws Throwable
*/
@Around("pointcut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
return PermissionAdminBase.permissionCommon(pjp, userProvider, this);
}
@Override
public Boolean detailPermission(ProceedingJoinPoint pjp, String operatorUserId, String methodName) {
switch (methodName){
case PermissionConstant.METHOD_CREATE:
return PermissionAspectUtil.getPermitByOrgId(
// 操作目标对象组织ID集合
((PositionCrForm) pjp.getArgs()[0]).getOrganizeId(),
operatorUserId,
methodName);
case PermissionConstant.METHOD_UPDATE:
// 得到岗位信息后,判断是否有修改前的权限
PositionEntity info = positionService.getInfo(((String) pjp.getArgs()[0]));
if (PermissionAspectUtil.getPermitByOrgId(
// 操作目标对象组织ID集合
info.getOrganizeId(),
operatorUserId,
methodName)) {
return PermissionAspectUtil.getPermitByOrgId(
// 操作目标对象组织ID集合
((PositionUpForm) pjp.getArgs()[1]).getOrganizeId(),
operatorUserId,
methodName);
}
return false;
case PermissionConstant.METHOD_DELETE:
// 获取岗位所关联的组织ID字符串
String positionId = String.valueOf(pjp.getArgs()[0]);
String orgIds = organizeService.getInfo(positionService.getInfo(positionId).getOrganizeId()).getId();
return PermissionAspectUtil.getPermitByOrgId(
// 操作目标对象组织ID集合
orgIds,
operatorUserId,
PermissionConstant.METHOD_DELETE);
default:
return false;
}
}
}

@ -0,0 +1,155 @@
package jnpf.aop;
import jnpf.constant.PermissionConstant;
import jnpf.permission.entity.OrganizeRelationEntity;
import jnpf.permission.entity.RoleEntity;
import jnpf.permission.model.role.RoleCrForm;
import jnpf.permission.model.role.RoleUpForm;
import jnpf.permission.service.OrganizeRelationService;
import jnpf.permission.service.PositionService;
import jnpf.permission.service.RoleService;
import jnpf.util.PermissionAspectUtil;
import jnpf.util.UserProvider;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.StringJoiner;
import java.util.stream.Collectors;
/**
*
*
* @author JNPF YanYu
* @version V3.2.0
* @copyright
* @date 2022/2/10
*/
@Slf4j
@Aspect
@Component
public class PermissionRoleAspect implements PermissionAdminBase {
@Autowired
private UserProvider userProvider;
@Autowired
private RoleService roleService;
@Autowired
private OrganizeRelationService organizeRelationService;
/**
*
*/
@Pointcut("@annotation(jnpf.annotation.RolePermission)")
public void pointcut() {
}
/**
*
*
* @param pjp
* @return
* @throws Throwable
*/
@Around("pointcut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
return PermissionAdminBase.permissionCommon(pjp, userProvider, this);
}
@Override
public Boolean detailPermission(ProceedingJoinPoint pjp, String operatorUserId, String methodName) {
boolean flag = false;
switch (methodName) {
case PermissionConstant.METHOD_CREATE:
RoleCrForm roleCrForm = (RoleCrForm) pjp.getArgs()[0];
if (!checkAdminGlobal(roleCrForm.getGlobalMark(), userProvider)) {
return PermissionAspectUtil.getPermitByOrgId(
// 操作目标对象组织ID集合
getOrganize(roleCrForm.getOrganizeIdsTree()),
operatorUserId,
PermissionConstant.METHOD_CREATE);
}
return true;
case PermissionConstant.METHOD_UPDATE:
RoleUpForm roleUpForm = (RoleUpForm) pjp.getArgs()[0];
// 非管理员情况下
if (!checkAdminGlobal(roleUpForm.getGlobalMark(), userProvider)) {
// 得到以前的组织id
String roleId = (String) pjp.getArgs()[1];
List<String> relationListByRoleId = organizeRelationService.getRelationListByRoleId(roleId).stream().map(OrganizeRelationEntity::getOrganizeId).collect(Collectors.toList());
StringJoiner stringJoiners = new StringJoiner(",");
relationListByRoleId.forEach(t -> {
stringJoiners.add(t);
});
if (PermissionAspectUtil.getPermitByOrgId(
// 操作目标对象组织ID集合
stringJoiners.toString(),
operatorUserId,
PermissionConstant.METHOD_UPDATE)) {
return PermissionAspectUtil.getPermitByOrgId(
// 操作目标对象组织ID集合
getOrganize(roleUpForm.getOrganizeIdsTree()),
operatorUserId,
PermissionConstant.METHOD_UPDATE);
}
return false;
}
return true;
case PermissionConstant.METHOD_DELETE:
String roleId = pjp.getArgs()[0].toString();
RoleEntity roleEntity = roleService.getInfo(roleId);
// 获取角色关联的组织信息
List<OrganizeRelationEntity> relationListByRoleId = organizeRelationService.getRelationListByRoleId(roleId);
StringBuilder orgId = new StringBuilder();
relationListByRoleId.stream().forEach(t->{
orgId.append(t.getOrganizeId() + ",");
});
if (roleEntity != null && !checkAdminGlobal(roleEntity.getGlobalMark(), userProvider)) {
return PermissionAspectUtil.getPermitByOrgId(
// 操作目标对象组织ID集合
orgId.toString(),
operatorUserId,
PermissionConstant.METHOD_DELETE);
}
return true;
default:
break;
}
return true;
}
/**
* id
* @param orgIdsTree
* @return
*/
private String getOrganize(List<List<String>> orgIdsTree) {
StringBuilder orgIds = new StringBuilder();
for (List<String> list : orgIdsTree) {
if (list.size() > 0) {
String orgId = list.get(list.size() - 1);
orgIds.append(orgId + ",");
}
}
return orgIds.toString();
}
/**
*
*
* @param globalMark 1 0:
* @param userProvider
*/
private Boolean checkAdminGlobal(Integer globalMark, UserProvider userProvider) {
if (globalMark != null && globalMark == 1) {
return userProvider.get().getIsAdministrator();
}
return false;
}
}

@ -0,0 +1,151 @@
package jnpf.aop;
import jnpf.constant.PermissionConst;
import jnpf.constant.PermissionConstant;
import jnpf.permission.entity.OrganizeRelationEntity;
import jnpf.permission.entity.UserRelationEntity;
import jnpf.permission.model.user.form.UserCrForm;
import jnpf.permission.model.user.form.UserUpForm;
import jnpf.permission.model.userrelation.UserRelationForm;
import jnpf.permission.service.*;
import jnpf.util.PermissionAspectUtil;
import jnpf.util.UserProvider;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.StringJoiner;
import java.util.stream.Collectors;
/**
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2021/3/15 17:12
*/
@Slf4j
@Aspect
@Component
public class PermissionUserAspect implements PermissionAdminBase{
@Autowired
private UserProvider userProvider;
@Autowired
private OrganizeRelationService organizeRelationService;
@Autowired
private PositionService positionService;
@Autowired
private UserRelationService userRelationService;
/**
*
*/
@Pointcut("@annotation(jnpf.annotation.UserPermission)")
public void pointcut() {
}
/**
*
*
* @param pjp
* @return
* @throws Throwable
*/
@Around("pointcut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
return PermissionAdminBase.permissionCommon(pjp, userProvider, this);
}
@Override
public Boolean detailPermission(ProceedingJoinPoint pjp, String operatorUserId, String methodName) {
switch (methodName){
case PermissionConstant.METHOD_CREATE:
UserCrForm userCrForm = (UserCrForm) pjp.getArgs()[0];
return PermissionAspectUtil.getPermitByOrgId(
// 操作目标对象组织ID集合
userCrForm.getOrganizeId(),
operatorUserId,
PermissionConstant.METHOD_CREATE);
case PermissionConstant.METHOD_UPDATE:
// 得到修改的用户以前的信息
String userId = (String) pjp.getArgs()[0];
List<String> collect = userRelationService.getListByUserId(userId, PermissionConst.ORGANIZE).stream().map(UserRelationEntity::getObjectId).collect(Collectors.toList());
StringJoiner stringJoiner = new StringJoiner(",");
collect.forEach(t -> {
stringJoiner.add(t);
});
if (PermissionAspectUtil.getPermitByOrgId(
// 操作目标对象组织ID集合
stringJoiner.toString(),
operatorUserId,
PermissionConstant.METHOD_UPDATE)) {
return PermissionAspectUtil.getPermitByOrgId(
// 操作目标对象组织ID集合
((UserUpForm) pjp.getArgs()[1]).getOrganizeId(),
operatorUserId,
PermissionConstant.METHOD_UPDATE);
}
return false;
case PermissionConstant.METHOD_MODIFY_PW:
return PermissionAspectUtil.getPermitByUserId(
// 操作目标对象的ID
String.valueOf(pjp.getArgs()[0]),
operatorUserId,
PermissionConstant.METHOD_UPDATE);
case PermissionConstant.METHOD_DELETE:
return PermissionAspectUtil.getPermitByUserId(
// 操作目标对象的ID
pjp.getArgs()[0].toString(),
operatorUserId,
PermissionConstant.METHOD_DELETE);
case PermissionConstant.METHOD_SAVE:
String objId = pjp.getArgs()[0].toString();
UserRelationForm userRelationForm = (UserRelationForm)pjp.getArgs()[1];
List<String> orgIds = new ArrayList<>();
if(userRelationForm.getObjectType().equals(PermissionConst.ROLE)){
// 角色目前修改为只有超管才能够修改
if(userProvider.get().getIsAdministrator()){
return true;
}
orgIds.addAll(organizeRelationService.getRelationListByRoleId(objId).stream().map(OrganizeRelationEntity::getOrganizeId).collect(Collectors.toList()));
return PermissionAspectUtil.getPermitByOrgId(
// 操作目标对象组织ID集合
String.join(",", orgIds),
operatorUserId,
PermissionConstant.METHOD_UPDATE);
}else {
if(userRelationForm.getObjectType().equals(PermissionConst.GROUP)) {
return true;
}
if(userRelationForm.getObjectType().equals(PermissionConst.POSITION)) {
orgIds.add(positionService.getInfo(objId).getOrganizeId());
}
return PermissionAspectUtil.getPermitByOrgId(
String.join(",", orgIds),
operatorUserId,
PermissionConstant.METHOD_UPDATE);
}
case PermissionConstant.METHOD_DELETE_SOCIALS:
if(pjp.getArgs()[0].toString().equals(operatorUserId)){return true;}
return PermissionAspectUtil.getPermitByUserId(
// 操作目标对象的ID
pjp.getArgs()[0].toString(),
operatorUserId,
PermissionConstant.METHOD_UPDATE);
default:
return false;
}
}
}

@ -0,0 +1,202 @@
package jnpf.aop;
import jnpf.base.LogSortEnum;
import jnpf.base.UserInfo;
import jnpf.config.ConfigValueUtil;
import jnpf.entity.LogEntity;
import jnpf.service.LogService;
import jnpf.util.*;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import jnpf.annotation.HandleLog;
import org.springframework.web.multipart.MultipartFile;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.concurrent.Executor;
/**
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2021/3/15 17:12
*/
@Slf4j
@Aspect
@Component
@Order(2)
public class RequestLogAspect {
@Autowired
private ConfigValueUtil configValueUtil;
@Autowired
private LogService logService;
@Autowired
private Executor executor;
@Pointcut("(execution(* jnpf.*.controller.*.*(..)) || execution(* jnpf.message.websocket.WebSocket.*(..)))&&!execution(* jnpf.controller.UtilsController.*(..)) ")
public void requestLog() {
}
@Around("requestLog()")
public Object doAroundService(ProceedingJoinPoint pjp) throws Throwable {
long startTime = System.currentTimeMillis();
Object obj = pjp.proceed();
long costTime = System.currentTimeMillis() - startTime;
UserInfo userInfo = UserProvider.getUser();
if(userInfo.getUserId() != null) {
printLog(userInfo, costTime);
try {
// 判断是否需要操作日志
MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
// 得到请求参数
Object[] args = pjp.getArgs();
// 得到请求方法
Method method = methodSignature.getMethod();
HandleLog methodAnnotation = method.getAnnotation(HandleLog.class);
if (methodAnnotation != null) {
String moduleName = methodAnnotation.moduleName();
String requestMethod = methodAnnotation.requestMethod();
handleLog(userInfo, costTime, obj, moduleName, requestMethod, args);
}
} catch (Exception e) {
log.error("记录操作日志发生错误:" + e.getMessage());
}
}
return obj;
}
/**
*
*
* @param userInfo
* @param costTime
*/
private void printLog(UserInfo userInfo, long costTime) {
LogEntity entity = new LogEntity();
entity.setId(RandomUtil.uuId());
entity.setType(LogSortEnum.Request.getCode());
entity.setUserId(userInfo.getUserId());
entity.setUserName(userInfo.getUserName() + "/" + userInfo.getUserAccount());
//请求耗时
entity.setRequestDuration((int) costTime);
entity.setRequestUrl(ServletUtil.getRequest().getServletPath());
entity.setRequestMethod(ServletUtil.getRequest().getMethod());
entity.setIpAddress(IpUtil.getIpAddr());
entity.setCreatorTime(new Date());
entity.setPlatForm(ServletUtil.getUserAgent());
executor.execute(()->{
logService.save(entity);
});
}
/**
*
*
* @param userInfo
* @param costTime
* @param obj
* @param moduleName
* @param requestMethod
* @param arg
*/
private void handleLog(UserInfo userInfo, long costTime, Object obj, String moduleName, String requestMethod, Object[] arg) {
LogEntity entity = new LogEntity();
entity.setId(RandomUtil.uuId());
entity.setType(LogSortEnum.Operate.getCode());
entity.setUserId(userInfo.getUserId());
entity.setUserName(userInfo.getUserName() + "/" + userInfo.getUserAccount());
//请求耗时
entity.setRequestDuration((int) costTime);
entity.setRequestMethod(requestMethod);
entity.setIpAddress(IpUtil.getIpAddr());
entity.setCreatorTime(new Date());
// 请求设备
entity.setPlatForm(ServletUtil.getUserAgent());
// 操作模块
entity.setModuleName(moduleName);
// 操作记录
try {
// 定义字符串
StringBuilder stringBuilder = new StringBuilder();
for (Object o : arg) {
// 如果是MultipartFile则为导入
if (o instanceof MultipartFile) {
stringBuilder.append("{\"originalFilename\":\"" + ((MultipartFile) o).getOriginalFilename() + "\",");
stringBuilder.append("\"contentType\":\"" + ((MultipartFile) o).getContentType() + "\",");
stringBuilder.append("\"name\":\"" + ((MultipartFile) o).getName() + "\",");
stringBuilder.append("\"resource\":\"" + ((MultipartFile) o).getResource() + "\",");
stringBuilder.append("\"size\":\"" + ((MultipartFile) o).getSize() + "\"}");
}
}
if (stringBuilder.length() > 0) {
entity.setJsons(requestMethod + "应用【" + stringBuilder + "】【" + obj + "】" );
} else {
entity.setJsons(requestMethod + "应用【" + JsonUtil.getObjectToString(arg) + "】【" + obj + "】" );
}
} catch (Exception e) {
entity.setJsons(requestMethod + "应用【" + arg + "】【" + obj + "】" );
}
executor.execute(()->{
logService.save(entity);
});
}
/// 后面可能会用
// /**
// * 判断是否为导入导出
// *
// * @return
// */
// private String getRequestMethod() {
// //得到请求方式
// String methodType = ServletUtil.getRequest().getMethod();
// // 得到当前请求的尾缀
// String endWith = null;
// String servletPath = ServletUtil.getServletPath();
// if (StringUtil.isNotEmpty(servletPath)) {
// String[] path = servletPath.split("/");
// int length = path.length;
// if (length > 5) {
// endWith = path[length - 2] + "/" + path[length - 1];
// }
// }
// // 如果是GET请求且请求后缀是'/Action/Export'则判定为导出
// if (HandleMethodEnum.GET.getRequestType().equals(methodType)) {
// methodType = "Action/Export".equals(endWith) ? "EXPORT" : "GET";
// } else if (HandleMethodEnum.POST.getRequestType().equals(methodType)) {
// methodType = "Action/Import".equals(endWith) ? "IMPORT" : "GET";
// }
// return methodType;
// }
// /**
// * 判断是否为导入导出
// *
// * @return
// */
// private String getRequestModuleName() {
// //得到Url
// String requestURI = ServletUtil.getRequest().getRequestURI();
// // 取模块名
// if (StringUtil.isNotEmpty(requestURI)) {
// String[] split = requestURI.split("/");
// if (split.length > 2) {
// String url = split[1];
// // 得到所在模块
// String moduleName = HandleModuleEnum.getModuleByURL(url);
// return moduleName;
// }
// }
// return "";
// }
///
}

@ -0,0 +1,49 @@
package jnpf.aop;
import jnpf.util.RedisUtil;
import jnpf.util.ServletUtil;
import jnpf.util.UserProvider;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.HashSet;
import java.util.Set;
/**
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2021/3/15 17:12
*/
@Slf4j
@Aspect
@Component
public class VisiualOpaAspect {
@Autowired
UserProvider userProvider;
@Autowired
private RedisUtil redisUtil;
@Pointcut("(execution(* jnpf.onlinedev.controller.VisualdevModelDataController.*(..))) || execution(* jnpf.onlinedev.controller.VisualdevModelAppController.*(..)))" +
"|| execution(* jnpf.generater.controller.VisualdevGenController.*(..)))")
public void visiualOpa() {
}
@After("visiualOpa()")
public void doAroundService(){
String method=ServletUtil.getRequest().getMethod().toLowerCase();
if("put".equals(method)||"delete".equals(method)||"post".equals(method)){
Set<String> allKey=new HashSet<>(16);
allKey.addAll(redisUtil.getAllVisiualKeys());
for(String key:allKey){
redisUtil.remove(key);
}
}
}
}

@ -0,0 +1,73 @@
package jnpf.constant;
/**
*
*
* @author JNPF
* @version V3.1.0
* @copyright https://www.jnpfsoft.com
* @date 2021-11-01
*/
public class PermissionConstant {
/**
*
*/
public static final String METHOD_CREATE = "create";
/**
*
*/
public static final String METHOD_UPDATE = "update";
/**
*
*/
public static final String METHOD_DELETE = "delete";
/**
*
*/
public static final String METHOD_DISABLE = "disable";
/**
*
*/
public static final String METHOD_CREATE_DEPARTMENT = "createDepartment";
/**
*
*/
public static final String METHOD_UPDATE_DEPARTMENT = "updateDepartment";
/**
*
*/
public static final String METHOD_DELETE_DEPARTMENT = "deleteDepartment";
/**
*
*/
public static final String METHOD_SAVE = "save";
public static final String METHOD_SAVE_BATCH = "saveBatch";
/**
*
*/
public static final String METHOD_MODIFY_PW = "modifyPassword";
/**
*
*/
public static final String GET_METHOD_CREATE = "Add";
public static final String GET_METHOD_UPDATE = "Edit";
public static final String GET_METHOD_DELETE = "Delete";
public static final String GET_METHOD_SELECT = "Select";
public static final String GET_METHOD_THIS = "getThisLayer";
public static final String GET_METHOD_SUB = "getSubLayer";
/**
*
*/
public static final String METHOD_DELETE_SOCIALS = "deleteSocials";
}

@ -0,0 +1,115 @@
package jnpf.filter;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.filter.SaServletFilter;
import cn.dev33.satoken.router.SaHttpMethod;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import jnpf.base.ActionResultCode;
import jnpf.config.ConfigValueUtil;
import jnpf.util.GatewayWhite;
import jnpf.util.IpUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import javax.servlet.http.HttpServletRequest;
/**
* token
*
* @author JNPF
* @version V3.1.0
* @copyright https://www.jnpfsoft.com
* @date 2021-03-24
*/
@Slf4j
@Configuration
public class AuthFilter {
private static final String ALL = "*";
private static final String MAX_AGE = "18000L";
@Autowired
private ConfigValueUtil configValueUtil;
@Autowired
private GatewayWhite gatewayWhite;
// 注册 Sa-Token全局过滤器
@Bean
public SaServletFilter getSaReactorFilter(GatewayWhite gatewayWhite) {
return new SaServletFilter()
// 拦截地址
.addInclude("/**")
.setExcludeList(gatewayWhite.excludeUrl)
// 鉴权方法:每次访问进入
.setAuth(obj -> {
if(log.isInfoEnabled()){
log.info("请求路径: {}", SaHolder.getRequest().getRequestPath());
}
//拦截路径
SaRouter.match(gatewayWhite.blockUrl).match(o -> {
//禁止访问URL 排除白名单
String ip = getIpAddr();
for (String o1 : gatewayWhite.whiteIp) {
if(ip.startsWith(o1)){
return false;
}
}
log.info("非白名单IP访问限制接口{}, {}", SaHolder.getRequest().getRequestPath(), ip);
return true;
}).back("接口无法访问");
//测试不验证 鉴权服务重启测试模式不清除Token就够了
//SaRouter.match((r)->"true".equals(configValueUtil.getTestVersion())).stop();
//白名单不拦截
SaRouter.match(gatewayWhite.whiteUrl).stop();
// 登录校验 -- 校验多租户管理模块TOKEN
//SaRouter.match("/api/tenant/**", r -> {
// SaManager.getStpLogic(AuthConsts.ACCOUNT_TYPE_TENANT).checkLogin();
//}).stop();
// 登录校验 -- 拦截所有路由
SaRouter.match("/**", r -> {
StpUtil.checkLogin();
}).stop();
}).setError(e -> {
SaHolder.getResponse().addHeader("Content-Type","application/json; charset=utf-8");
if(e instanceof NotLoginException){
return SaResult.error(ActionResultCode.SessionOverdue.getMessage()).setCode(ActionResultCode.SessionOverdue.getCode());
}
log.error(e.getMessage(), e);
return SaResult.error("系统异常.").setCode(ActionResultCode.Exception.getCode());
})
// 前置函数:在每次认证函数之前执行
.setBeforeAuth(obj -> {
HttpServletRequest request = (HttpServletRequest) SaHolder.getRequest().getSource();
// ---------- 设置跨域响应头 ----------
SaHolder.getResponse()
// 允许指定域访问跨域资源
.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, request.getHeader(HttpHeaders.ORIGIN))
// 允许的header参数
.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, ALL)
// 允许所有请求方式
.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, ALL)
.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true")
.setHeader(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, ALL)
// 有效时间
.setHeader(HttpHeaders.ACCESS_CONTROL_MAX_AGE, MAX_AGE);
// 如果是预检请求,则立即返回到前端
SaRouter.match(SaHttpMethod.OPTIONS)
.back();
});
}
public static String getIpAddr() {
return IpUtil.getIpAddr();
}
}

@ -0,0 +1,181 @@
package jnpf.util;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
* url
* URLURL
*
* @author JNPF
* @version V3.1.0
* @copyright https://www.jnpfsoft.com
* @date 2021-03-24
*/
@Component
@ConfigurationProperties("gateway")
public class GatewayWhite {
/**
*
*/
public List<String> excludeUrl = new ArrayList<>();
/**
* Token, 访
*/
public List<String> whiteUrl = new ArrayList<>();
/**
* 访
*/
public List<String> blockUrl = new ArrayList<>();
/**
* 访IP
* startsWith, 访IP.startsWith(whiteIP)
*/
public List<String> whiteIp = new ArrayList<>();
public GatewayWhite(){
interceptPath();
whitePath();
excludePath();
whiteIp();
}
public List<String> getWhiteUrl() {
return new ArrayList<>(whiteUrl);
}
public List<String> getBlockUrl() {
return new ArrayList<>(blockUrl);
}
public List<String> getExcludeUrl() {
return new ArrayList<>(excludeUrl);
}
public List<String> getWhiteIp() {
return new ArrayList<>(whiteIp);
}
public void setWhiteUrl(List<String> whiteUrl) {
whitePath();
this.whiteUrl.addAll(whiteUrl);
}
public void setBlockUrl(List<String> blockUrl) {
interceptPath();
this.blockUrl.addAll(blockUrl);
}
public void setExcludeUrl(List<String> excludeUrl) {
excludePath();
this.excludeUrl.addAll(excludeUrl);
}
public void setWhiteIp(List<String> whiteIp) {
whiteIp();
this.whiteIp.addAll(whiteIp);
}
private void interceptPath() {
blockUrl.clear();
blockUrl.add("/actuator/**");
blockUrl.add("/api/*/actuator/**");
blockUrl.add("/doc.html");
blockUrl.add("/swagger-resources/**");
blockUrl.add("/swagger-ui/**");
blockUrl.add("/api/*/v?/api-docs/*");
blockUrl.add("/v?/api-docs/*");
}
private void whitePath() {
whiteUrl.clear();
//oauth
whiteUrl.add("/api/oauth/Login/**");
whiteUrl.add("/api/oauth/Logout/**");
// APP
whiteUrl.add("/api/app/Version");
//websocket
whiteUrl.add("/api/message/websocket/*");
//大屏图片
whiteUrl.add("/api/file/VisusalImg/**");
whiteUrl.add("/api/blade-visual/map/data");
whiteUrl.add("/api/blade-visual/category/list");
whiteUrl.add("/api/blade-visual/visual/put-file/**");
//数据地图
whiteUrl.add("/api/system/DataMap/**");
//代码下载接口
whiteUrl.add("/api/visualdev/Generater/DownloadVisCode");
//多租户
whiteUrl.add("/api/tenant/DbName/**");
whiteUrl.add("/api/tenant/login");
whiteUrl.add("/api/tenant/logout");
//extend KK
whiteUrl.add("/api/extend/DocumentPreview/**");
//file模块不拦截
//文件下载接口
whiteUrl.add("/api/file/filedownload/**");
whiteUrl.add("/api/file/VisusalImg/**");
whiteUrl.add("/api/file/AppStartInfo/*");
whiteUrl.add("/api/file/IMVoice/*");
whiteUrl.add("/api/file/{type}/{fileName}");
whiteUrl.add("/api/file/IMImage/*");
whiteUrl.add("/api/file/Image/**");
whiteUrl.add("/api/file/DownloadModel");
whiteUrl.add("/api/file/Download/**");
whiteUrl.add("/api/file/ImageCode/**");
whiteUrl.add("/api/system/DictionaryData/*/Data/Selector");
whiteUrl.add("/api/datareport/pdf/show");
whiteUrl.add("/api/datareport/preview/loadPagePaper");
whiteUrl.add("/api/datareport/pdf");
whiteUrl.add("/api/datareport/word");
whiteUrl.add("/api/datareport/excel/**");
whiteUrl.add("/api/datareport/Data/*/Actions/Export");
//报表模板导入
whiteUrl.add("/api/datareport/import");
whiteUrl.add("/api/system/DataInterface/*/Actions/Response");
whiteUrl.add("/api/system/DataInterface/Actions/GetAuth");
//swagger3
whiteUrl.add("/doc.html");
whiteUrl.add("/webjars/**");
whiteUrl.add("/api/*/v?/api-docs/*");
whiteUrl.add("/v?/api-docs/*");
whiteUrl.add("/swagger-ui/**");
whiteUrl.add("/swagger-resources/**");
whiteUrl.add("/csrf");
whiteUrl.add("/api/oauth/ImageCode/**");
whiteUrl.add("/api/oauth/getConfig/*");
whiteUrl.add("/api/oauth/getLoginConfig");
whiteUrl.add("/api/oauth/getTicketStatus/*");
whiteUrl.add("/api/oauth/getTicket");
whiteUrl.add("/api/message/ShortLink/**");
whiteUrl.add("/api/message/WechatOpen/token/**");
//在线表单外链触发接口
whiteUrl.add("/api/visualdev/ShortLink/**");
}
private void excludePath(){
excludeUrl.clear();
excludeUrl.add("/favicon.ico");
excludeUrl.add("/api/message/websocket/*");
}
private void whiteIp(){
whiteIp.clear();
whiteIp.add("127.0.0.1");
}
}

@ -0,0 +1,165 @@
package jnpf.util;
import jnpf.constant.PermissionConstant;
import jnpf.permission.entity.OrganizeAdministratorEntity;
import jnpf.permission.entity.OrganizeEntity;
import jnpf.permission.service.OrganizeAdministratorService;
import jnpf.permission.service.OrganizeService;
import jnpf.util.context.SpringContext;
/**
*
*
* @author JNPF
* @version V3.1.0
* @copyright https://www.jnpfsoft.com
* @date 2021-11-01
*/
public class PermissionAspectUtil {
private static final OrganizeService organizeService;
private static final OrganizeAdministratorService organizeAdministratorService;
static {
organizeService = SpringContext.getBean(OrganizeService.class);
organizeAdministratorService = SpringContext.getBean(OrganizeAdministratorService.class);
}
/**
*
*
* @param targetUserId ID
* @param operatorUsrId ID
* @param methodName
*/
public static Boolean getPermitByUserId(String targetUserId, String operatorUsrId, String methodName) {
for(OrganizeEntity organizeEntity : organizeService.getAllOrgByUserId(targetUserId)){
if (PermissionAspectUtil.containPermission(organizeEntity.getId(), operatorUsrId, methodName)) {
return true;
}
}
return false;
}
/**
*
*
* @param organizeId ID
* @param operatorUserId ID
* @param methodName
*/
public static boolean containPermission(String organizeId, String operatorUserId, String methodName) {
OrganizeEntity organizeEntity = organizeService.getInfo(organizeId);
if (organizeEntity != null) {
// 当前用户的所有分级权限
OrganizeAdministratorEntity adminEntity = organizeAdministratorService.getOne(operatorUserId, organizeId);
if(permissionFlag(adminEntity, methodName, true)){
return true;
}
// 查看父级的组织权限是否含有子集权限
return parentPermission(organizeEntity.getParentId(), methodName, operatorUserId);
}
return false;
}
/**
* ()
*
* @param organizeIds ID
* @param operatorUsrId ID
* @param methodName
*/
public static Boolean getPermitByOrgIds(String organizeIds, String operatorUsrId, String methodName) {
boolean flag = true;
for (String organizeId : organizeIds.split(",")) {
flag = true;
flag = PermissionAspectUtil.containPermission(organizeId, operatorUsrId, methodName);
if (!flag) {
break;
}
}
return flag;
}
/**
* ()
*
* @param organizeIds ID
* @param operatorUsrId ID
* @param methodName
*/
public static Boolean getPermitByOrgId(String organizeIds, String operatorUsrId, String methodName) {
for (String organizeId : organizeIds.split(",")) {
if (PermissionAspectUtil.containPermission(organizeId,operatorUsrId, methodName)) {
return true;
}
}
return false;
}
/**
* ()
*
* @param organizeParentId
* @param methodName
* @param userId
* @return
*/
private static boolean parentPermission(String organizeParentId, String methodName, String userId) {
// 得到父级组织
OrganizeEntity parentOrganizeEntity = organizeService.getInfo(organizeParentId);
if (parentOrganizeEntity != null) {
// 得到父级的权限
if(permissionFlag(organizeAdministratorService.getOne(userId, parentOrganizeEntity.getId()), methodName, false)){
return true;
}
// 当前正在判断的组织已经是顶级则无需递归
if (!"-1".equals(parentOrganizeEntity.getParentId())) {
return parentPermission(parentOrganizeEntity.getParentId(), methodName, userId);
}
}
return false;
}
/**
*
* @param adminEntity
* @param methodName
* @param thisFlag true: false:
*/
private static boolean permissionFlag(OrganizeAdministratorEntity adminEntity, String methodName, Boolean thisFlag) {
if (adminEntity != null) {
String methodType = "";
// 存在则验证是否有当前组织分级管理
try {
switch (methodName) {
case PermissionConstant.METHOD_CREATE:
// 创建权限
methodType = PermissionConstant.GET_METHOD_CREATE;
break;
case PermissionConstant.METHOD_UPDATE:
// 编辑权限
methodType = PermissionConstant.GET_METHOD_UPDATE;
break;
case PermissionConstant.METHOD_DELETE:
// 删除权限
methodType = PermissionConstant.GET_METHOD_DELETE;
break;
default:
break;
}
// 拼接方法名
String method = (thisFlag ? PermissionConstant.GET_METHOD_THIS : PermissionConstant.GET_METHOD_SUB) + methodType;
String selectMethod = (thisFlag ? PermissionConstant.GET_METHOD_THIS : PermissionConstant.GET_METHOD_SUB) + PermissionConstant.GET_METHOD_SELECT;
if ((int)OrganizeAdministratorEntity.class.getMethod(method).invoke(adminEntity) == 1 && (int)OrganizeAdministratorEntity.class.getMethod(selectMethod).invoke(adminEntity) == 1) {
return true;
}
} catch (Exception e) {
e.printStackTrace();
}
}
return false;
}
}

@ -0,0 +1,34 @@
# General
error.size.toolarge=\u8F93\u5165\u592A\u5927\u3002\u5B9E\u9645\u7684\u8F93\u5165\u4E3A{0}\u5B57\u8282\u3002\u5141\u8BB8\u7684\u6700\u5927\u8F93\u5165\u4E3A{1}\u5B57\u8282\u3002
error.comment.removed=\u51FA\u4E8E\u5B89\u5168\u7684\u539F\u56E0\uFF0C\u6CE8\u91CA\u57DF\u5DF2\u88AB\u8FC7\u6EE4\u3002\u6CE8\u91CA\u57DF\u7684\u503C\u4E3A{0}
# Tag related
error.tag.notfound=\u51FA\u4E8E\u5B89\u5168\u7684\u539F\u56E0\uFF0C\u6807\u8BB0{0}\u5DF2\u88AB\u8FC7\u6EE4\u3002\u6807\u8BB0\u7684\u5185\u5BB9\u4FDD\u5B58\u4E0D\u53D8\u3002
error.tag.removed=\u51FA\u4E8E\u5B89\u5168\u7684\u539F\u56E0\uFF0C\u6807\u8BB0{0}\u4E0D\u88AB\u5141\u8BB8\u3002\u6B64\u6807\u8BB0\u4E0D\u5E94\u8BE5\u5F71\u54CD\u8F93\u5165\u7684\u663E\u793A\u3002
error.tag.filtered=\u51FA\u4E8E\u5B89\u5168\u7684\u539F\u56E0\uFF0C\u6807\u8BB0{0}\u5DF2\u88AB\u8FC7\u6EE4\u3002\u6807\u8BB0\u7684\u5185\u5BB9\u4FDD\u5B58\u4E0D\u53D8\u3002
error.tag.encoded=The {0} tag has been encoded for security reasons. The contents of the tag will remain in place.
error.tag.empty=\u5728{0}\u7684\u6807\u7B7E\u662F\u7A7A\u7684\uFF0C\u56E0\u6B64\u6211\u4EEC\u65E0\u6CD5\u5904\u7406\u5B83\u3002\u8BE5\u90AE\u4EF6\u7684\u5176\u4F59\u90E8\u5206\u662F\u5B8C\u6574\u7684\uFF0C\u5176\u642C\u8FC1\u5E94\u8BE5\u6CA1\u6709\u4EFB\u4F55\u526F\u4F5C\u7528\u3002
error.cdata.found=\u4E00\u4E2ACDATA\u90E8\u5206\u88AB\u53D1\u73B0\uFF0C\u8FD9\u662F\u4E0D\u5141\u8BB8\u7684\u3002\u8BE5\u90AE\u4EF6\u7684\u5176\u4F59\u90E8\u5206\u662F\u5B8C\u6574\u7684\uFF0C\u5176\u642C\u8FC1\u4E0D\u5E94\u8BE5\u6709\u4EFB\u4F55\u526F\u4F5C\u7528\u3002\u5728CDATA\u7684\u5185\u5BB9\u662F \"{0}\"\u3002
error.pi.found=XML\u5904\u7406\u6307\u4EE4\u88AB\u53D1\u73B0\uFF0C\u8FD9\u662F\u4E0D\u5141\u8BB8\u7684\u3002\u6D88\u606F\u7684\u5176\u4F59\u90E8\u5206\u662F\u5B8C\u6574\u7684\uFF0C\u5176\u642C\u8FC1\u5E94\u8BE5\u4E0D\u4F1A\u6709\u4EFB\u4F55\u526F\u4F5C\u7528\u3002\u8BE5\u6307\u4EE4\u7684\u5185\u5BB9\u4E3A \"{0}\"\u3002
# Attribute related
error.attribute.notfound=\u6807\u8BB0{0}\u5305\u542B\u4E00\u4E2A\u6CA1\u6CD5\u5904\u7406\u7684\u5C5E\u6027\u3002\u5C5E\u6027{1}\u5DF2\u88AB\u8FC7\u6EE4\uFF0C\u4F46\u6807\u8BB0\u4FDD\u5B58\u4E0D\u53D8\u3002
error.attribute.invalid=\u6807\u8BB0{0}\u5305\u542B\u4E00\u4E2A\u6CA1\u6CD5\u5904\u7406\u7684\u5C5E\u6027\u3002\u5C5E\u6027{1}\u5305\u542B\u4E00\u4E2A\u503C\"{2}\"\u3002\u51FA\u4E8E\u5B89\u5168\u7684\u539F\u56E0\uFF0C\u8FD9\u4E2A\u503C\u6CA1\u6CD5\u88AB\u63A5\u53D7\u3002\u4E3A\u4E86\u5904\u7406\u8FD9\u4E2A\u8F93\u5165\uFF0C\u8FD9\u4E2A\u5C5E\u6027\u5DF2\u88AB\u4ECE\u8FD9\u4E2A\u6807\u8BB0\u4E2D\u53BB\u6389\uFF0C\u6807\u8BB0\u5176\u4ED6\u90E8\u5206\u4FDD\u6301\u4E0D\u53D8\u3002
error.attribute.invalid.filtered=\u6807\u8BB0{0}\u5305\u542B\u4E00\u4E2A\u6CA1\u6CD5\u5904\u7406\u7684\u5C5E\u3002\u5C5E\u6027{1}\u5305\u542B\u4E00\u4E2A\u503C\"{2}\"\u3002\u51FA\u4E8E\u5B89\u5168\u7684\u539F\u56E0\uFF0C\u8FD9\u4E2A\u503C\u6CA1\u6CD5\u88AB\u63A5\u53D7\u3002\u4E3A\u4E86\u8FDB\u4E00\u6B65\u5904\u7406\u8FD9\u4E2A\u8F93\u5165\uFF0C\u6807\u8BB0{0}\u5DF2\u88AB\u8FC7\u6EE4\u3002
error.attribute.invalid.encoded=The {0} tag contained an attribute that we could not process. The {1} attribute had a value of \"{2}\". This value could not be accepted for security reasons. We have chosen to encode the {0} tag in order to continue processing the input.
error.attribute.invalid.removed=\u6807\u8BB0{0}\u5305\u542B\u4E00\u4E2A\u6CA1\u6CD5\u5904\u7406\u7684\u5C5E\u6027\u3002\u5C5E\u6027{1}\u5305\u542B\u4E00\u4E2A\u503C\"{2}\"\u3002\u51FA\u4E8E\u5B89\u5168\u7684\u539F\u56E0\uFF0C\u8FD9\u4E2A\u503C\u6CA1\u6CD5\u88AB\u63A5\u53D7\u3002\u4E3A\u4E86\u8FDB\u4E00\u6B65\u5904\u7406\u8FD9\u4E2A\u8F93\u5165\uFF0C\u6574\u4E2A\u6807\u8BB0{0}\u5DF2\u88AB\u53BB\u6389\u3002
# CSS related
error.css.tag.malformed=The stylesheet code \"{0}\" could not be parsed.
error.css.import.disabled=\u6837\u5F0F\u8868\u7684\u5BFC\u5165\u8FD8\u6CA1\u6709\u88AB\u6FC0\u6D3B\u3002
error.css.import.exceeded=\u4F4D\u4E8E{0}\u7684\u6837\u5F0F\u8868\u8D85\u8FC7\u5141\u8BB8\u5BFC\u5165\u7684\u6837\u5F0F\u8868\u7684\u603B\u6570\uFF0C\u56E0\u6B64\u8BE5\u6837\u5F0F\u8868\u6CA1\u6709\u88AB\u8BFB\u53D6\u3002\u5141\u8BB8\u5BFC\u5165\u7684\u6837\u5F0F\u8868\u7684\u6700\u5927\u6570\u76EE\u4E3A{1}\u3002
error.css.import.failure=\u8F93\u5165\u4E2D\u542B\u6709\u7684\u8FDC\u7A0B\u6837\u5F0F\u8868\u4F4D\u4E8E{0}\uFF0C\u6B64\u6837\u5F0F\u8868\u6CA1\u6CD5\u88AB\u8BFB\u53D6\u3002\u7F51\u7AD9\u53EF\u80FD\u5173\u95ED\u6216\u8005\u4E3B\u673A\u6CA1\u6CD5\u88AB\u8BBF\u95EE\u3002\u8FD9\u4E0D\u5E94\u8BE5\u5F71\u54CD\u8F93\u5165\u7684\u683C\u5F0F\u3002
error.css.import.toolarge=\u4F4D\u4E8E{0}\u7684\u6837\u5F0F\u8868\u4F7F\u5F97\u603B\u8F93\u5165\u592A\u5927\uFF0C\u56E0\u6B64\u6CA1\u6709\u88AB\u5BFC\u5165\u3002\u5141\u8BB8\u7684\u6700\u5927\u8F93\u5165\u4E3A{1}\u5B57\u8282\u3002
error.css.import.url.invalid=\u51FA\u4E8E\u5B89\u5168\u7684\u539F\u56E0\uFF0C\u7528\u4E8E\u5BFC\u5165\u6837\u5F0F\u8868\u7684url\u6CA1\u6CD5\u88AB\u63A5\u53D7\u3002\u6B64url\u662F{1}\u3002
error.css.stylesheet.relative=\u6837\u5F0F\u8868\u5F15\u7528\u4E86\u4E00\u4E2A\u6CA1\u6CD5\u8BFB\u53D6\u7684\u76F8\u5BF9\u6837\u5F0F\u8868\"{0}\"\u3002
error.css.tag.relative=\u6807\u8BB0{0}\u4E2D\u7684\u4E00\u4E2A\u6837\u5F0F\u5C5E\u6027\u6307\u5B9A\u4E86\u4E00\u4E2A\u6CA1\u6CD5\u8BFB\u53D6\u7684\u76F8\u5BF9\u6837\u5F0F\u8868\u5E94\u7528\"{0}\"\u3002
error.css.stylesheet.rule.notfound=\u6837\u5F0F\u8868\u4F7F\u7528\u4E86\u4E00\u4E2A\u4E0D\u88AB\u652F\u6301\u7684\u89C4\u5219\"{0}\"\u3002\u51FA\u4E8E\u5B89\u5168\u7684\u539F\u56E0\uFF0C\u6B64\u89C4\u5219\u5DF2\u88AB\u53BB\u6389\u3002
error.css.tag.rule.notfound=\u6807\u8BB0{0}\u4E2D\u7684\u4E00\u4E2A\u6837\u5F0F\u5C5E\u6027\u4F7F\u7528\u4E86\u4E00\u4E2A\u4E0D\u88AB\u652F\u6301\u7684\u89C4\u5219\"{0}\"\u3002\u51FA\u4E8E\u5B89\u5168\u7684\u539F\u56E0\uFF0C\u6B64\u89C4\u5219\u5DF2\u88AB\u53BB\u6389\u3002
error.css.stylesheet.selector.notfound=\u6837\u5F0F\u8868\u4F7F\u7528\u4E86\u4E00\u4E2A\u6CA1\u6CD5\u5904\u7406\u7684\u9009\u62E9\u5668\"{0}\"\u3002\u51FA\u4E8E\u5B89\u5168\u7684\u539F\u56E0\uFF0C\u6B64\u9009\u62E9\u5668\u5DF2\u88AB\u53BB\u6389\u3002
error.css.tag.selector.notfound=\u6807\u8BB0{0}\u4E2D\u7684\u4E00\u4E2A\u6837\u5F0F\u5C5E\u6027\u4F7F\u7528\u4E86\u4E00\u4E2A\u6CA1\u6CD5\u5904\u7406\u7684\u9009\u62E9\u5668\"{0}\"\u3002\u51FA\u4E8E\u5B89\u5168\u7684\u539F\u56E0\uFF0C\u6B64\u89C4\u5219\u5DF2\u88AB\u53BB\u6389\u3002
error.css.stylesheet.selector.disallowed=\u6837\u5F0F\u8868\u4F7F\u7528\u4E86\u4E00\u4E2A\u9009\u62E9\u5668\"{0}\"\u3002\u51FA\u4E8E\u5B89\u5168\u7684\u539F\u56E0\uFF0C\u6B64\u9009\u62E9\u5668\u4E0D\u88AB\u5141\u8BB8\u3002
error.css.tag.selector.disallowed=\u6807\u8BB0{0}\u4E2D\u7684\u4E00\u4E2A\u6837\u5F0F\u5C5E\u6027\u4F7F\u7528\u4E86\u4E00\u4E2A\u9009\u62E9\u5668\"{1}\"\u3002\u51FA\u4E8E\u5B89\u5168\u7684\u539F\u56E0\uFF0C\u6B64\u9009\u62E9\u5668\u4E0D\u88AB\u5141\u8BB8\u3002
error.css.stylesheet.property.invalid=\u6837\u5F0F\u8868\u542B\u6709\u4E00\u4E2A\u5C5E\uFF08property)\"{0}\"\u3002\u51FA\u4E8E\u5B89\u5168\u7684\u539F\u56E0\uFF0C\u6B64\u5C5E\u6027\u4E0D\u88AB\u5141\u8BB8\u3002
error.css.tag.property.invalid=\u6807\u8BB0{0}\u4E2D\u542B\u6709\u4E00\u4E2A\u6837\u5F0F\u5C5E\u6027\"{1}\"\u3002\u51FA\u4E8E\u5B89\u5168\u7684\u539F\u56E0\uFF0C\u6B64\u5C5E\u6027\u4E0D\u88AB\u5141\u8BB8\u3002

File diff suppressed because it is too large Load Diff

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!--
W3C rules retrieved from:
http://www.w3.org/TR/html401/struct/global.html
-->
<anti-samy-rules xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="antisamy.xsd">
<directives>
<directive name="omitXmlDeclaration" value="true"/>
<directive name="omitDoctypeDeclaration" value="true"/>
<directive name="maxInputSize" value="0"/>
<directive name="useXHTML" value="true"/>
<directive name="formatOutput" value="false"/>
<!--
remember, this won't work for relative URIs - AntiSamy doesn't
know anything about the URL or your web structure
-->
<directive name="embedStyleSheets" value="false"/>
</directives>
<common-regexps>
</common-regexps>
<!--
Tag.name = a, b, div, body, etc.
Tag.action = filter: remove tags, but keep content, validate: keep content as long as it passes rules, remove: remove tag and contents
Attribute.name = id, class, href, align, width, etc.
Attribute.onInvalid = what to do when the attribute is invalid, e.g., remove the tag (removeTag), remove the attribute (removeAttribute), filter the tag (filterTag)
Attribute.description = What rules in English you want to tell the users they can have for this attribute. Include helpful things so they'll be able to tune their HTML
-->
<!--
Some attributes are common to all (or most) HTML tags. There aren't many that qualify for this. You have to make sure there's no
collisions between any of these attribute names with attribute names of other tags that are for different purposes.
-->
<common-attributes>
</common-attributes>
<!--
This requires normal updates as browsers continue to diverge from the W3C and each other. As long as the browser wars continue
this is going to continue. I'm not sure war is the right word for what's going on. Doesn't somebody have to win a war after
a while? Even wars of attrition, surely?
-->
<global-tag-attributes>
</global-tag-attributes>
<tags-to-encode>
</tags-to-encode>
<tag-rules>
</tag-rules>
<!-- CSS validation processing rules -->
<css-rules>
<!-- end manual properties -->
</css-rules>
<allowed-empty-tags>
</allowed-empty-tags>
</anti-samy-rules>

@ -0,0 +1,233 @@
# 应用服务器
server:
tomcat:
uri-encoding: UTF-8 #tomcat编码
port: 30000 #tomcat端口
spring:
devtools: #spring开发者工具模块
restart:
enabled: true #热部署开关
freemarker:
cache: false #spring内置freemarker缓存
thymeleaf:
cache: false #spring内置thymeleaf缓存
# ===================== 数据源配置 =====================
exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure #排除自动配置手动配置druid
datasource:
db-type: MySQL #数据库类型(可选值 MySQL、SQLServer、Oracle、DM8、KingbaseES、PostgreSQL请严格按可选值填写)
host: 222.71.165.188
port: 3309
username: root
password: linus,.123
db-name: jnpf_zhihui
db-schema: #金仓达梦选填
prepare-url: #自定义url
# ===================== 动态多数据源 =====================
dynamic:
primary: master #设置默认的数据源或者数据源组,默认值即为master
strict: true #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
druid:
# 空闲时执行连接测试
test-while-idle: true
# 连接测试最小间隔
time-between-eviction-runs-millis: 60000
# 获取连接等待3秒 根据网络情况设定
max-wait: 3000
# 初始化4个连接
initial-size: 4
# 最大20个连接
max-active: 20
# 最少保持4个空闲连接
min-idle: 4
# 空闲连接保活, 超过配置的空闲时间会进行连接检查完成保活操作(数据库自身会断开达到空闲时间的连接, 程序使用断开的连接会报错)
keep-alive: true
# 解除注释后Druid连接池打印SQL语句 忽略日志等级配置
#filters: slf4j
slf4j:
statementLogEnabled: true
resultSetLogEnabled: false
connectionLogEnabled: false
dataSourceLogEnabled: false
statementCreateAfterLogEnabled: false
statementCloseAfterLogEnabled: false
statementExecuteAfterLogEnabled: false
#打印SQL替换参数
statementExecutableSqlLogEnable: true
statementPrepareAfterLogEnabled: false
statementPrepareCallAfterLogEnabled: false
statementParameterSetLogEnabled: false
# datasource:
# master:
# url: jdbc:mysql://${spring.datasource.host}:${spring.datasource.port}/${spring.datasource.dbname}?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true&serverTimezone=UTC
# username: ${spring.datasource.username}
# password: ${spring.datasource.password}
# driver-class-name: com.mysql.cj.jdbc.Driver
# ===================== Redis配置 =====================
# redis单机模式
redis:
database: 1 #缓存库编号
# host: 222.71.165.188
host: 127.0.0.1
port: 6379
# password: qweasd,.123 # 密码为空时,请将本行注释
timeout: 3000 #超时时间(单位:秒)
lettuce: #Lettuce为Redis的Java驱动包
pool:
max-active: 8 # 连接池最大连接数
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
min-idle: 0 # 连接池中的最小空闲连接
max-idle: 8 # 连接池中的最大空闲连接
# redis集群模式
# redis:
# cluster:
# nodes:
# - 192.168.0.225:6380
# - 192.168.0.225:6381
# - 192.168.0.225:6382
# - 192.168.0.225:6383
# - 192.168.0.225:6384
# - 192.168.0.225:6385
# password: 123456 # 密码为空时,请将本行注释
# timeout: 3000 # 超时时间(单位:秒)
# lettuce: #Lettuce为Redis的Java驱动包
# pool:
# max-active: 8 # 连接池最大连接数
# max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
# min-idle: 0 # 连接池中的最小空闲连接
# max-idle: 8 # 连接池中的最大空闲连接
# SpringDoc接口文档 访问地址http://127.0.0.1:30000/doc.html
springdoc:
default-flat-param-object: true
api-docs:
enabled: true
#SpringDoc增强
#knife4j:
# basic: #接口文档访问鉴权
# enable: true
# username: jnpf
# password: 123456
config:
# ===================== 是否开启测试环境 =====================
TestVersion: false
# ===================== ApacheShardingSphere 配置开关 =====================
sharding-sphere-enabled: false
# ===================== 文件存储配置 =====================
file-storage: #文件存储配置,不使用的情况下可以不写
default-platform: local-plus-1 #默认使用的存储平台
thumbnail-suffix: ".min.jpg" #缩略图后缀,例如【.min.jpg】【.png】
local-plus: # 本地存储升级版
- platform: local-plus-1 # 存储平台标识
enable-storage: true #启用存储
enable-access: true #启用访问(线上请使用 Nginx 配置,效率更高)
domain: "" # 访问域名例如“http://127.0.0.1:8030/”,注意后面要和 path-patterns 保持一致,“/”结尾,本地存储建议使用相对路径,方便后期更换域名
base-path: D:/project/jnpf-resources/ # 基础路径
path-patterns: /** # 访问路径
storage-path: # 存储路径
aliyun-oss: # 阿里云 OSS ,不使用的情况下可以不写
- platform: aliyun-oss-1 # 存储平台标识
enable-storage: false # 启用存储
access-key: ??
secret-key: ??
end-point: ??
bucket-name: ??
domain: ?? # 访问域名,注意“/”结尾例如https://abc.oss-cn-shanghai.aliyuncs.com/
base-path: hy/ # 基础路径
qiniu-kodo: # 七牛云 kodo ,不使用的情况下可以不写
- platform: qiniu-kodo-1 # 存储平台标识
enable-storage: false # 启用存储
access-key: ??
secret-key: ??
bucket-name: ??
domain: ?? # 访问域名,注意“/”结尾例如http://abc.hn-bkt.clouddn.com/
base-path: base/ # 基础路径
tencent-cos: # 腾讯云 COS
- platform: tencent-cos-1 # 存储平台标识
enable-storage: false # 启用存储
secret-id: ??
secret-key: ??
region: ?? #存仓库所在地域
bucket-name: ??
domain: ?? # 访问域名,注意“/”结尾例如https://abc.cos.ap-nanjing.myqcloud.com/
base-path: hy/ # 基础路径
minio: # MinIO由于 MinIO SDK 支持 AWS S3其它兼容 AWS S3 协议的存储平台也都可配置在这里
- platform: minio-1 # 存储平台标识
enable-storage: true # 启用存储
access-key: Q9jJs2b6Tv
secret-key: Thj2WkpLu9DhmJyJ
end-point: http://192.168.0.207:9000/
bucket-name: jnpfsoftoss
domain: # 访问域名,注意“/”结尾例如http://minio.abc.com/abc/
base-path: # 基础路径
# ===================== 第三方登录配置 =====================
socials:
# 第三方登录功能开关(false-关闭true-开启)
socials-enabled: false
config:
- # 微信
provider: wechat_open
client-id: your-client-id
client-secret: your-client-secret
- # qq
provider: qq
client-id: your-client-id
client-secret: your-client-secret
- # 企业微信
provider: wechat_enterprise
client-id: your-client-id
client-secret: your-client-secret
agentId: your-agentId
- # 钉钉
provider: dingtalk
client-id: your-client-id
client-secret: your-client-secret
agentId: your-agentId
- # 飞书
provider: feishu
client-id: your-client-id
client-secret: your-client-secret
- # 小程序
provider: wechat_applets
client-id: your-client-id
client-secret: your-client-secret
# ===================== 任务调度配置 =====================
xxl:
job:
accessToken: ''
i18n: zh_CN
logretentiondays: 30
triggerpool:
fast:
max: 200
slow:
max: 100
# xxl-job服务端地址
admin:
addresses: http://127.0.0.1:30020/xxl-job-admin/
executor:
address: ''
appname: xxl-job-executor-sample1
ip: ''
logpath: /data/applogs/xxl-job/jobhandler
logretentiondays: 30
port: 9999
# rest调用xxl-job接口地址
admin:
register:
handle-query-address: ${xxl.job.admin.addresses}api/handler/queryList
job-info-address: ${xxl.job.admin.addresses}api/jobinfo
log-query-address: ${xxl.job.admin.addresses}api/log
task-list-address: ${xxl.job.admin.addresses}api/ScheduleTask/List
task-info-address: ${xxl.job.admin.addresses}api/ScheduleTask/getInfo
task-save-address: ${xxl.job.admin.addresses}api/ScheduleTask
task-update-address: ${xxl.job.admin.addresses}api/ScheduleTask
task-remove-address: ${xxl.job.admin.addresses}api/ScheduleTask/remove
task-start-or-remove-address: ${xxl.job.admin.addresses}api/ScheduleTask/updateTask

@ -0,0 +1,194 @@
# 应用服务器
server:
tomcat:
uri-encoding: UTF-8 #tomcat编码
port: 30000 #tomcat端口
spring:
devtools: #spring开发者工具模块
restart:
enabled: true #热部署开关
freemarker:
cache: false #spring内置freemarker缓存
thymeleaf:
cache: false #spring内置thymeleaf缓存
# ===================== 数据源配置 =====================
exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure #排除自动配置手动配置druid
datasource:
db-type: MySQL #数据库类型(可选值 MySQL、SQLServer、Oracle、DM8、KingbaseES、PostgreSQL请严格按可选值填写)
host: 192.168.0.210
port: 3306
username: java_boot_test
password: pBx5HaW6WMGSTdDf
db-name: java_boot_test
db-schema: #金仓达梦选填
prepare-url: #自定义url
# ===================== 动态多数据源 =====================
dynamic:
primary: master #设置默认的数据源或者数据源组,默认值即为master
strict: true #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
druid:
#定时执行数据链接检测语句 防止数据库闲时超时断开链接
test-while-idle: true #空闲时执行
time-between-eviction-runs-millis: 60000 #执行间隔
# datasource:
# master:
# url: jdbc:mysql://${spring.datasource.host}:${spring.datasource.port}/${spring.datasource.dbname}?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true&serverTimezone=UTC
# username: ${spring.datasource.username}
# password: ${spring.datasource.password}
# driver-class-name: com.mysql.cj.jdbc.Driver
# ===================== Redis配置 =====================
# redis单机模式
redis:
database: 1 #缓存库编号
host: 192.168.0.220
port: 6379
password: 123456 # 密码为空时,请将本行注释
timeout: 3000 #超时时间(单位:秒)
lettuce: #Lettuce为Redis的Java驱动包
pool:
max-active: 8 # 连接池最大连接数
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
min-idle: 0 # 连接池中的最小空闲连接
max-idle: 8 # 连接池中的最大空闲连接
# redis集群模式
# redis:
# cluster:
# nodes:
# - 192.168.0.225:6380
# - 192.168.0.225:6381
# - 192.168.0.225:6382
# - 192.168.0.225:6383
# - 192.168.0.225:6384
# - 192.168.0.225:6385
# password: 123456 # 密码为空时,请将本行注释
# timeout: 3000 # 超时时间(单位:秒)
# lettuce: #Lettuce为Redis的Java驱动包
# pool:
# max-active: 8 # 连接池最大连接数
# max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
# min-idle: 0 # 连接池中的最小空闲连接
# max-idle: 8 # 连接池中的最大空闲连接
config:
# ===================== 是否开启测试环境 =====================
TestVersion: false
# ===================== ApacheShardingSphere 配置开关 =====================
sharding-sphere-enabled: false
# ===================== 文件存储配置 =====================
file-storage: #文件存储配置,不使用的情况下可以不写
default-platform: local-plus-1 #默认使用的存储平台
thumbnail-suffix: ".min.jpg" #缩略图后缀,例如【.min.jpg】【.png】
local-plus: # 本地存储升级版
- platform: local-plus-1 # 存储平台标识
enable-storage: true #启用存储
enable-access: true #启用访问(线上请使用 Nginx 配置,效率更高)
domain: "" # 访问域名例如“http://127.0.0.1:8030/”,注意后面要和 path-patterns 保持一致,“/”结尾,本地存储建议使用相对路径,方便后期更换域名
base-path: F:/work/jnpf-resources/ # 基础路径
path-patterns: /** # 访问路径
storage-path: # 存储路径
aliyun-oss: # 阿里云 OSS ,不使用的情况下可以不写
- platform: aliyun-oss-1 # 存储平台标识
enable-storage: false # 启用存储
access-key: ??
secret-key: ??
end-point: ??
bucket-name: ??
domain: ?? # 访问域名,注意“/”结尾例如https://abc.oss-cn-shanghai.aliyuncs.com/
base-path: hy/ # 基础路径
qiniu-kodo: # 七牛云 kodo ,不使用的情况下可以不写
- platform: qiniu-kodo-1 # 存储平台标识
enable-storage: false # 启用存储
access-key: ??
secret-key: ??
bucket-name: ??
domain: ?? # 访问域名,注意“/”结尾例如http://abc.hn-bkt.clouddn.com/
base-path: base/ # 基础路径
tencent-cos: # 腾讯云 COS
- platform: tencent-cos-1 # 存储平台标识
enable-storage: false # 启用存储
secret-id: ??
secret-key: ??
region: ?? #存仓库所在地域
bucket-name: ??
domain: ?? # 访问域名,注意“/”结尾例如https://abc.cos.ap-nanjing.myqcloud.com/
base-path: hy/ # 基础路径
minio: # MinIO由于 MinIO SDK 支持 AWS S3其它兼容 AWS S3 协议的存储平台也都可配置在这里
- platform: minio-1 # 存储平台标识
enable-storage: true # 启用存储
access-key: Q9jJs2b6Tv
secret-key: Thj2WkpLu9DhmJyJ
end-point: http://192.168.0.207:9000/
bucket-name: jnpfsoftoss
domain: # 访问域名,注意“/”结尾例如http://minio.abc.com/abc/
base-path: # 基础路径
# ===================== 第三方登录配置 =====================
socials:
# 第三方登录功能开关(false-关闭true-开启)
socials-enabled: false
config:
- # 微信
provider: wechat_open
client-id: your-client-id
client-secret: your-client-secret
- # qq
provider: qq
client-id: your-client-id
client-secret: your-client-secret
- # 企业微信
provider: wechat_enterprise
client-id: your-client-id
client-secret: your-client-secret
agentId: your-agentId
- # 钉钉
provider: dingtalk
client-id: your-client-id
client-secret: your-client-secret
agentId: your-agentId
- # 飞书
provider: feishu
client-id: your-client-id
client-secret: your-client-secret
- # 小程序
provider: wechat_applets
client-id: your-client-id
client-secret: your-client-secret
# ===================== 任务调度配置 =====================
xxl:
job:
accessToken: ''
i18n: zh_CN
logretentiondays: 30
triggerpool:
fast:
max: 200
slow:
max: 100
# xxl-job服务端地址
admin:
addresses: http://127.0.0.1:30020/xxl-job-admin/
executor:
address: ''
appname: xxl-job-executor-sample1
ip: ''
logpath: /data/applogs/xxl-job/jobhandler
logretentiondays: 30
port: 9999
# rest调用xxl-job接口地址
admin:
register:
handle-query-address: ${xxl.job.admin.addresses}api/handler/queryList
job-info-address: ${xxl.job.admin.addresses}api/jobinfo
log-query-address: ${xxl.job.admin.addresses}api/log
task-list-address: ${xxl.job.admin.addresses}api/ScheduleTask/List
task-info-address: ${xxl.job.admin.addresses}api/ScheduleTask/getInfo
task-save-address: ${xxl.job.admin.addresses}api/ScheduleTask
task-update-address: ${xxl.job.admin.addresses}api/ScheduleTask
task-remove-address: ${xxl.job.admin.addresses}api/ScheduleTask/remove
task-start-or-remove-address: ${xxl.job.admin.addresses}api/ScheduleTask/updateTask

@ -0,0 +1,194 @@
# 应用服务器
server:
tomcat:
uri-encoding: UTF-8 #tomcat编码
port: 30000 #tomcat端口
spring:
devtools: #spring开发者工具模块
restart:
enabled: true #热部署开关
freemarker:
cache: false #spring内置freemarker缓存
thymeleaf:
cache: false #spring内置thymeleaf缓存
# ===================== 数据源配置 =====================
exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure #排除自动配置手动配置druid
datasource:
db-type: MySQL #数据库类型(可选值 MySQL、SQLServer、Oracle、DM8、KingbaseES、PostgreSQL请严格按可选值填写)
host: 192.168.0.210
port: 3306
username: java_boot_test
password: pBx5HaW6WMGSTdDf
db-name: java_boot_test
db-schema: #金仓达梦选填
prepare-url: #自定义url
# ===================== 动态多数据源 =====================
dynamic:
primary: master #设置默认的数据源或者数据源组,默认值即为master
strict: true #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
druid:
#定时执行数据链接检测语句 防止数据库闲时超时断开链接
test-while-idle: true #空闲时执行
time-between-eviction-runs-millis: 60000 #执行间隔
# datasource:
# master:
# url: jdbc:mysql://${spring.datasource.host}:${spring.datasource.port}/${spring.datasource.dbname}?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true&serverTimezone=UTC
# username: ${spring.datasource.username}
# password: ${spring.datasource.password}
# driver-class-name: com.mysql.cj.jdbc.Driver
# ===================== Redis配置 =====================
# redis单机模式
redis:
database: 1 #缓存库编号
host: 192.168.0.220
port: 6379
password: 123456 # 密码为空时,请将本行注释
timeout: 3000 #超时时间(单位:秒)
lettuce: #Lettuce为Redis的Java驱动包
pool:
max-active: 8 # 连接池最大连接数
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
min-idle: 0 # 连接池中的最小空闲连接
max-idle: 8 # 连接池中的最大空闲连接
# redis集群模式
# redis:
# cluster:
# nodes:
# - 192.168.0.225:6380
# - 192.168.0.225:6381
# - 192.168.0.225:6382
# - 192.168.0.225:6383
# - 192.168.0.225:6384
# - 192.168.0.225:6385
# password: 123456 # 密码为空时,请将本行注释
# timeout: 3000 # 超时时间(单位:秒)
# lettuce: #Lettuce为Redis的Java驱动包
# pool:
# max-active: 8 # 连接池最大连接数
# max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
# min-idle: 0 # 连接池中的最小空闲连接
# max-idle: 8 # 连接池中的最大空闲连接
config:
# ===================== 是否开启测试环境 =====================
TestVersion: false
# ===================== ApacheShardingSphere 配置开关 =====================
sharding-sphere-enabled: false
# ===================== 文件存储配置 =====================
file-storage: #文件存储配置,不使用的情况下可以不写
default-platform: local-plus-1 #默认使用的存储平台
thumbnail-suffix: ".min.jpg" #缩略图后缀,例如【.min.jpg】【.png】
local-plus: # 本地存储升级版
- platform: local-plus-1 # 存储平台标识
enable-storage: true #启用存储
enable-access: true #启用访问(线上请使用 Nginx 配置,效率更高)
domain: "" # 访问域名例如“http://127.0.0.1:8030/”,注意后面要和 path-patterns 保持一致,“/”结尾,本地存储建议使用相对路径,方便后期更换域名
base-path: F:/work/jnpf-resources/ # 基础路径
path-patterns: /** # 访问路径
storage-path: # 存储路径
aliyun-oss: # 阿里云 OSS ,不使用的情况下可以不写
- platform: aliyun-oss-1 # 存储平台标识
enable-storage: false # 启用存储
access-key: ??
secret-key: ??
end-point: ??
bucket-name: ??
domain: ?? # 访问域名,注意“/”结尾例如https://abc.oss-cn-shanghai.aliyuncs.com/
base-path: hy/ # 基础路径
qiniu-kodo: # 七牛云 kodo ,不使用的情况下可以不写
- platform: qiniu-kodo-1 # 存储平台标识
enable-storage: false # 启用存储
access-key: ??
secret-key: ??
bucket-name: ??
domain: ?? # 访问域名,注意“/”结尾例如http://abc.hn-bkt.clouddn.com/
base-path: base/ # 基础路径
tencent-cos: # 腾讯云 COS
- platform: tencent-cos-1 # 存储平台标识
enable-storage: false # 启用存储
secret-id: ??
secret-key: ??
region: ?? #存仓库所在地域
bucket-name: ??
domain: ?? # 访问域名,注意“/”结尾例如https://abc.cos.ap-nanjing.myqcloud.com/
base-path: hy/ # 基础路径
minio: # MinIO由于 MinIO SDK 支持 AWS S3其它兼容 AWS S3 协议的存储平台也都可配置在这里
- platform: minio-1 # 存储平台标识
enable-storage: true # 启用存储
access-key: Q9jJs2b6Tv
secret-key: Thj2WkpLu9DhmJyJ
end-point: http://192.168.0.207:9000/
bucket-name: jnpfsoftoss
domain: # 访问域名,注意“/”结尾例如http://minio.abc.com/abc/
base-path: # 基础路径
# ===================== 第三方登录配置 =====================
socials:
# 第三方登录功能开关(false-关闭true-开启)
socials-enabled: false
config:
- # 微信
provider: wechat_open
client-id: your-client-id
client-secret: your-client-secret
- # qq
provider: qq
client-id: your-client-id
client-secret: your-client-secret
- # 企业微信
provider: wechat_enterprise
client-id: your-client-id
client-secret: your-client-secret
agentId: your-agentId
- # 钉钉
provider: dingtalk
client-id: your-client-id
client-secret: your-client-secret
agentId: your-agentId
- # 飞书
provider: feishu
client-id: your-client-id
client-secret: your-client-secret
- # 小程序
provider: wechat_applets
client-id: your-client-id
client-secret: your-client-secret
# ===================== 任务调度配置 =====================
xxl:
job:
accessToken: ''
i18n: zh_CN
logretentiondays: 30
triggerpool:
fast:
max: 200
slow:
max: 100
# xxl-job服务端地址
admin:
addresses: http://127.0.0.1:30020/xxl-job-admin/
executor:
address: ''
appname: xxl-job-executor-sample1
ip: ''
logpath: /data/applogs/xxl-job/jobhandler
logretentiondays: 30
port: 9999
# rest调用xxl-job接口地址
admin:
register:
handle-query-address: ${xxl.job.admin.addresses}api/handler/queryList
job-info-address: ${xxl.job.admin.addresses}api/jobinfo
log-query-address: ${xxl.job.admin.addresses}api/log
task-list-address: ${xxl.job.admin.addresses}api/ScheduleTask/List
task-info-address: ${xxl.job.admin.addresses}api/ScheduleTask/getInfo
task-save-address: ${xxl.job.admin.addresses}api/ScheduleTask
task-update-address: ${xxl.job.admin.addresses}api/ScheduleTask
task-remove-address: ${xxl.job.admin.addresses}api/ScheduleTask/remove
task-start-or-remove-address: ${xxl.job.admin.addresses}api/ScheduleTask/updateTask

@ -0,0 +1,194 @@
# 应用服务器
server:
tomcat:
uri-encoding: UTF-8 #tomcat编码
port: 30000 #tomcat端口
spring:
devtools: #spring开发者工具模块
restart:
enabled: true #热部署开关
freemarker:
cache: false #spring内置freemarker缓存
thymeleaf:
cache: false #spring内置thymeleaf缓存
# ===================== 数据源配置 =====================
exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure #排除自动配置手动配置druid
datasource:
db-type: MySQL #数据库类型(可选值 MySQL、SQLServer、Oracle、DM8、KingbaseES、PostgreSQL请严格按可选值填写)
host: 192.168.0.210
port: 3306
username: java_boot_test
password: pBx5HaW6WMGSTdDf
db-name: java_boot_test
db-schema: #金仓达梦选填
prepare-url: #自定义url
# ===================== 动态多数据源 =====================
dynamic:
primary: master #设置默认的数据源或者数据源组,默认值即为master
strict: true #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
druid:
#定时执行数据链接检测语句 防止数据库闲时超时断开链接
test-while-idle: true #空闲时执行
time-between-eviction-runs-millis: 60000 #执行间隔
# datasource:
# master:
# url: jdbc:mysql://${spring.datasource.host}:${spring.datasource.port}/${spring.datasource.dbname}?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true&serverTimezone=UTC
# username: ${spring.datasource.username}
# password: ${spring.datasource.password}
# driver-class-name: com.mysql.cj.jdbc.Driver
# ===================== Redis配置 =====================
# redis单机模式
redis:
database: 1 #缓存库编号
host: 192.168.0.220
port: 6379
password: 123456 # 密码为空时,请将本行注释
timeout: 3000 #超时时间(单位:秒)
lettuce: #Lettuce为Redis的Java驱动包
pool:
max-active: 8 # 连接池最大连接数
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
min-idle: 0 # 连接池中的最小空闲连接
max-idle: 8 # 连接池中的最大空闲连接
# redis集群模式
# redis:
# cluster:
# nodes:
# - 192.168.0.225:6380
# - 192.168.0.225:6381
# - 192.168.0.225:6382
# - 192.168.0.225:6383
# - 192.168.0.225:6384
# - 192.168.0.225:6385
# password: 123456 # 密码为空时,请将本行注释
# timeout: 3000 # 超时时间(单位:秒)
# lettuce: #Lettuce为Redis的Java驱动包
# pool:
# max-active: 8 # 连接池最大连接数
# max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
# min-idle: 0 # 连接池中的最小空闲连接
# max-idle: 8 # 连接池中的最大空闲连接
config:
# ===================== 是否开启测试环境 =====================
TestVersion: false
# ===================== ApacheShardingSphere 配置开关 =====================
sharding-sphere-enabled: false
# ===================== 文件存储配置 =====================
file-storage: #文件存储配置,不使用的情况下可以不写
default-platform: local-plus-1 #默认使用的存储平台
thumbnail-suffix: ".min.jpg" #缩略图后缀,例如【.min.jpg】【.png】
local-plus: # 本地存储升级版
- platform: local-plus-1 # 存储平台标识
enable-storage: true #启用存储
enable-access: true #启用访问(线上请使用 Nginx 配置,效率更高)
domain: "" # 访问域名例如“http://127.0.0.1:8030/”,注意后面要和 path-patterns 保持一致,“/”结尾,本地存储建议使用相对路径,方便后期更换域名
base-path: F:/work/jnpf-resources/ # 基础路径
path-patterns: /** # 访问路径
storage-path: # 存储路径
aliyun-oss: # 阿里云 OSS ,不使用的情况下可以不写
- platform: aliyun-oss-1 # 存储平台标识
enable-storage: false # 启用存储
access-key: ??
secret-key: ??
end-point: ??
bucket-name: ??
domain: ?? # 访问域名,注意“/”结尾例如https://abc.oss-cn-shanghai.aliyuncs.com/
base-path: hy/ # 基础路径
qiniu-kodo: # 七牛云 kodo ,不使用的情况下可以不写
- platform: qiniu-kodo-1 # 存储平台标识
enable-storage: false # 启用存储
access-key: ??
secret-key: ??
bucket-name: ??
domain: ?? # 访问域名,注意“/”结尾例如http://abc.hn-bkt.clouddn.com/
base-path: base/ # 基础路径
tencent-cos: # 腾讯云 COS
- platform: tencent-cos-1 # 存储平台标识
enable-storage: false # 启用存储
secret-id: ??
secret-key: ??
region: ?? #存仓库所在地域
bucket-name: ??
domain: ?? # 访问域名,注意“/”结尾例如https://abc.cos.ap-nanjing.myqcloud.com/
base-path: hy/ # 基础路径
minio: # MinIO由于 MinIO SDK 支持 AWS S3其它兼容 AWS S3 协议的存储平台也都可配置在这里
- platform: minio-1 # 存储平台标识
enable-storage: true # 启用存储
access-key: Q9jJs2b6Tv
secret-key: Thj2WkpLu9DhmJyJ
end-point: http://192.168.0.207:9000/
bucket-name: jnpfsoftoss
domain: # 访问域名,注意“/”结尾例如http://minio.abc.com/abc/
base-path: # 基础路径
# ===================== 第三方登录配置 =====================
socials:
# 第三方登录功能开关(false-关闭true-开启)
socials-enabled: false
config:
- # 微信
provider: wechat_open
client-id: your-client-id
client-secret: your-client-secret
- # qq
provider: qq
client-id: your-client-id
client-secret: your-client-secret
- # 企业微信
provider: wechat_enterprise
client-id: your-client-id
client-secret: your-client-secret
agentId: your-agentId
- # 钉钉
provider: dingtalk
client-id: your-client-id
client-secret: your-client-secret
agentId: your-agentId
- # 飞书
provider: feishu
client-id: your-client-id
client-secret: your-client-secret
- # 小程序
provider: wechat_applets
client-id: your-client-id
client-secret: your-client-secret
# ===================== 任务调度配置 =====================
xxl:
job:
accessToken: ''
i18n: zh_CN
logretentiondays: 30
triggerpool:
fast:
max: 200
slow:
max: 100
# xxl-job服务端地址
admin:
addresses: http://127.0.0.1:30020/xxl-job-admin/
executor:
address: ''
appname: xxl-job-executor-sample1
ip: ''
logpath: /data/applogs/xxl-job/jobhandler
logretentiondays: 30
port: 9999
# rest调用xxl-job接口地址
admin:
register:
handle-query-address: ${xxl.job.admin.addresses}api/handler/queryList
job-info-address: ${xxl.job.admin.addresses}api/jobinfo
log-query-address: ${xxl.job.admin.addresses}api/log
task-list-address: ${xxl.job.admin.addresses}api/ScheduleTask/List
task-info-address: ${xxl.job.admin.addresses}api/ScheduleTask/getInfo
task-save-address: ${xxl.job.admin.addresses}api/ScheduleTask
task-update-address: ${xxl.job.admin.addresses}api/ScheduleTask
task-remove-address: ${xxl.job.admin.addresses}api/ScheduleTask/remove
task-start-or-remove-address: ${xxl.job.admin.addresses}api/ScheduleTask/updateTask

@ -0,0 +1,128 @@
spring:
application:
name: jnpf-boot
profiles:
# 指定环境配置 dev(开发环境-默认)、test(测试环境)、preview(预生产)、pro(生产环境)
active: dev
servlet:
multipart: #文件传输配置
max-file-size: 100MB #单个数据大小限制
max-request-size: 100MB #请求总数据大小限制
enabled: true #是否启用分段上传支持
mvc:
hiddenmethod: #隐式方法过滤器
filter:
enabled: true #默认开启。开启以支持PUT,DELETE表单提交方法
jackson: #序列化和反序列化json框架
serialization:
write-dates-as-timestamps: true #是否写入日期时间时间戳格式
time-zone: GMT+8 #指定日期格式化时区
main:
allow-bean-definition-overriding: true #允许同名bean后者覆盖,默认true
allow-circular-references: true #允许Bean相互引用,默认false
config:
# ===============静态资源目录映射==================
WebAnnexFilePath: WebAnnexFile
DataBackupFilePath: DataBackupFile
TemporaryFilePath: TemporaryFile
SystemFilePath: SystemFile
TemplateFilePath: TemplateFile
EmailFilePath: EmailFile
DocumentFilePath: DocumentFile
DocumentPreviewPath: DocumentPreview
UserAvatarFilePath: UserAvatar
IMContentFilePath: IMContentFile
MPMaterialFilePath: MPMaterial
TemplateCodePath: TemplateCode
BiVisualPath: BiVisualPath
# ===============功能格式限制==================
MPUploadFileType: bmp,png,jpeg,jpg,gif,mp3,wma,wav,amr,mp4
WeChatUploadFileType: jpg,png,doc,docx,ppt,pptx,xls,xlsx,pdf,txt,rar,zip,csv,amr,mp4
AllowUploadImageType: jpg,gif,png,bmp,jpeg,tiff,psd,swf,svg,pcx,dxf,wmf,emf,lic,eps,tga #允许上传图片类型
AllowUploadFileType: jpg,gif,png,bmp,jpeg,doc,docx,ppt,pptx,xls,xlsx,pdf,txt,rar,zip,csv,mp3 #允许上传文件类型
AllowPreviewFileType: doc,docx,xls,xlsx,ppt,pptx,pdf,jpg,gif,png,bmp,jpeg #允许预览文件类型
PreviewType: kkfile #文件预览方式 1.yozo 2.kkfile默认使用kkfile
kkFileUrl: http://127.0.0.1:30090/FileServer/ #kkfile文件预览服务地址
ApiDomain: http://127.0.0.1:30000 #后端域名(文档预览中使用)
FrontDomain: http://127.0.0.1:3000 #前端域名(文档预览中使用)
AppDomain: http://127.0.0.1:8080 #app/h5端域名配置(文档预览中使用)
CodeAreasName: example #代码生成器模块命名
#===================== unipush =====================
AppPushUrl: https://8e84eea8-6922-4033-8e86-67ad7442e692.bspapp.com/unipush
#===================== 多租户 =====================
MultiTenancy: false #是否开启
MultiTenancyUrl: http://127.0.0.1:30006/api/tenant/DbName/ #多租户项目地址
#COLUMN、SCHEMA模式
MultiTenantType: SCHEMA
#===================== 系统及错误报告反馈相关 =====================
SoftName: jnpf-java-boot #项目名
SoftFullName: JNPF快速开发平台 #项目全名
SoftVersion: v3.5.0 #版本号
RecordLog: true #系统日志启用
ErrorReport: false #软件错误报告
ErrorReportTo: surrpot@yinmaisoft.com #软件错误报告接收者
IgexinEnabled: true #推送启动
#===================== APP =====================
AppVersion: V3.5.0 #APP版本号
IgexinAppid: HLFY9T2d1z7MySY8hwGwh4 #APPID应用的唯一标识
IgexinAppkey: 6Uiduugq648YDChhCjAt59 #APPKEY公匙相当于账号
IgexinMastersecret: pEyQm156SJ9iS7PbyjLCZ6 #Mastersecret私匙相当于密码
AppUpdateContent: ; #APP更新内容
#===================== 永中office在线预览配置 =====================
YozoDomain: //dcsapi.com/ #永中api域名
YozoDomainKey: 57462250284462899305150 #域名key
YozoCloudDomain: //dmc.yozocloud.cn #云预览
YozoAppId: yozoAgR41jgC0062 #appid
YozoAppKey: fc3134a9ba8bc6f4c69d635f9adf #app秘钥
YozoEditDomain: //eic.yozocloud.cn #云编辑
#===================== 系统功能配置 =====================
EnablePreAuth: false #是否开启接口鉴权
EnableLogicDelete: false #是否开启逻辑删除
# 接口放行地址 与GatewayWhite中的默认URL合并
gateway:
# 禁止访问接口
block-url:
## 配置示例
#- /api/message/Notice
#- /api/permission/Users/*
# 不验证Token, 放行接口(默认记录日志)
white-url:
# # 配置示例
#- /api/message/Notice
#- /api/permission/Users/*
# 放行接口(不记录日志)
exclude-url:
# # 配置示例
#- /api/message/Notice
#- /api/permission/Users/*
# 入站IP禁止配置以外的IP访问block-url配置的接口
white-ip:
#- 192.168.0.10
#- 192.168.0.20
# 日志配置
logging:
config: classpath:logback-spring.xml
level:
#自定义第三方包名日志等级
# 解除注释后Druid连接池打印SQL语句
druid.sql.Statement: debug
# druid.sql.DataSource: debug
# druid.sql.Connection: debug
# druid.sql.ResultSet: debug
log:
level:
# 等级 TRACE,DEBUG,INFO,WARN,ERROR(不区分大小写)
root: info
path: log/${spring.application.name}

@ -0,0 +1,339 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--日志格式应用spring boot默认的格式也可以自己更改-->
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<property name="FILE_LOG_PATTERN" value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] [%thread] [%logger{50}] [%M] [%line] - %msg%n" />
<springProperty scope="context" name="SERVICE_NAME" source="spring.application.name" defaultValue="jnpf"/>
<!--定义日志存放的位置,默认存放在项目启动的相对路径的目录-->
<springProperty scope="context" name="LOG_PATH" source="log.path" defaultValue="log/${SERVICE_NAME}"/>
<!-- 全局日志等级 -->
<springProperty scope="context" name="LOG_LEVEL_ROOT" source="log.level.root" defaultValue="INFO"/>
<!-- 服务自定义等级 如需自定义服务日志等级 修改下方的【自定义服务名】与nacos上的log.level.自定义服务名=等级 -->
<springProperty scope="context" name="LOG_LEVEL" source="log.level.jnpf-boot" defaultValue="${LOG_LEVEL_ROOT}"/>
<!-- 日志记录器日期滚动记录level为 ERROR 日志 -->
<appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${LOG_PATH}/log_error.log</file>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 归档的日志文件的路径,%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
<fileNamePattern>${LOG_PATH}/error/%d{yyyy-MM-dd,aux}/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!--日志最大的历史7天-->
<maxHistory>7</maxHistory>
<!-- 除按日志记录之外还配置了日志文件不能超过2M若超过2M日志文件会以索引0开始
命名日志文件例如log-error-2013-12-21.0.log -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!-- 追加方式记录日志 -->
<append>true</append>
<!-- 日志文件的格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 此日志文件只记录error级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>error</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 日志记录器日期滚动记录level为 INFO 日志 -->
<appender name="FILE_INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${LOG_PATH}/log_info.log</file>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 归档的日志文件的路径,%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
<fileNamePattern>${LOG_PATH}/info/%d{yyyy-MM-dd,aux}/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!--日志最大的历史7天-->
<maxHistory>7</maxHistory>
<!-- 除按日志记录之外还配置了日志文件不能超过2M若超过2M日志文件会以索引0开始
命名日志文件例如log-error-2013-12-21.0.log -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!-- 追加方式记录日志 -->
<append>true</append>
<!-- 日志文件的格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 此日志文件只记录info级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>info</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 日志记录器日期滚动记录level为 WARN 日志 -->
<appender name="FILE_WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${LOG_PATH}/log_warn.log</file>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 归档的日志文件的路径,%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
<fileNamePattern>${LOG_PATH}/warn/%d{yyyy-MM-dd,aux}/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!--日志最大的历史7天-->
<maxHistory>7</maxHistory>
<!-- 除按日志记录之外还配置了日志文件不能超过2M若超过2M日志文件会以索引0开始
命名日志文件例如log-error-2013-12-21.0.log -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!-- 追加方式记录日志 -->
<append>true</append>
<!-- 日志文件的格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 此日志文件只记录warn级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>warn</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 日志记录器日期滚动记录level为 DEBUG 日志 -->
<appender name="FILE_DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${LOG_PATH}/log_debug.log</file>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 归档的日志文件的路径,%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
<fileNamePattern>${LOG_PATH}/debug/%d{yyyy-MM-dd,aux}/log-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!--日志最大的历史7天-->
<maxHistory>7</maxHistory>
<!-- 除按日志记录之外还配置了日志文件不能超过2M若超过2M日志文件会以索引0开始
命名日志文件例如log-error-2013-12-21.0.log -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!-- 追加方式记录日志 -->
<append>true</append>
<!-- 日志文件的格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 此日志文件只记录debug级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>debug</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 日志记录器,日期滚动记录,所有日志 -->
<appender name="FILE_ALL" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${LOG_PATH}/log_total.log</file>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 归档的日志文件的路径,%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
<fileNamePattern>${LOG_PATH}/total/%d{yyyy-MM-dd,aux}/log-total-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!--日志最大的历史7天-->
<maxHistory>7</maxHistory>
<!-- 除按日志记录之外还配置了日志文件不能超过2M若超过2M日志文件会以索引0开始
命名日志文件例如log-error-2013-12-21.0.log -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!-- 追加方式记录日志 -->
<append>true</append>
<!-- 日志文件的格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>utf-8</charset>
</encoder>
</appender>
<!-- 日志记录器日期滚动记录level 根据配置动态输出日志 -->
<appender name="FILE_RELEASE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${LOG_PATH}/log_release.log</file>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 归档的日志文件的路径,%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
<fileNamePattern>${LOG_PATH}/release/%d{yyyy-MM-dd,aux}/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!--日志最大的历史7天-->
<maxHistory>7</maxHistory>
<!-- 除按日志记录之外还配置了日志文件不能超过2M若超过2M日志文件会以索引0开始
命名日志文件例如log-error-2013-12-21.0.log -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!-- 追加方式记录日志 -->
<append>true</append>
<!-- 日志文件的格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 此日志文件只记录warn级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>${LOG_LEVEL}</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 异步输出 DEBUG -->
<appender name="ASYNC_FILE_DEBUG" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>256</queueSize>
<appender-ref ref="FILE_DEBUG"/>
</appender>
<!-- 异步输出 INFO -->
<appender name="ASYNC_FILE_INFO" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>256</queueSize>
<appender-ref ref="FILE_INFO"/>
</appender>
<!-- 异步输出 WARN -->
<appender name="ASYNC_FILE_WARN" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>256</queueSize>
<appender-ref ref="FILE_WARN"/>
</appender>
<!-- 异步输出 ERROR -->
<appender name="ASYNC_FILE_ERROR" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>256</queueSize>
<appender-ref ref="FILE_ERROR"/>
</appender>
<!-- 异步输出 ALL -->
<appender name="ASYNC_FILE_ALL" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>256</queueSize>
<appender-ref ref="FILE_ALL"/>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>utf-8</charset>
</encoder>
</appender>
<!-- 异步输出 控制台 -->
<appender name="ASYNC_STDOUT" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>256</queueSize>
<appender-ref ref="STDOUT"/>
</appender>
<!--<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
&lt;!&ndash; 必填目标LogStash的 IP:Port &ndash;&gt;
<destination>192.168.0.50:50000</destination>
&lt;!&ndash; 可选:保持程序存活时间 &ndash;&gt;
<keepAliveDuration>5 minutes</keepAliveDuration>
&lt;!&ndash; 可选:重连延迟时长 &ndash;&gt;
<reconnectionDelay>10 second</reconnectionDelay>
&lt;!&ndash; 可选:等待策略 &ndash;&gt;
<waitStrategyType>sleeping</waitStrategyType>
&lt;!&ndash; ============ encoder必须配置,有多种可选 ============= &ndash;&gt;
&lt;!&ndash; 编码器二LoggingEventCompositeJsonEncoder &ndash;&gt;
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
&lt;!&ndash; 时间戳:时区 &ndash;&gt;
<timestamp>
<timeZone>UTC</timeZone>
</timestamp>
&lt;!&ndash; 模式 &ndash;&gt;
<pattern>
<pattern>
{
"severity": "%level",
"service": "${SERVICE_NAME:-}",
"trace": "%X{X-B3-TraceId:-}",
"span": "%X{X-B3-SpanId:-}",
"exportable": "%X{X-Span-Export:-}",
"pid": "${PID:-}",
"thread": "%thread",
"class": "%logger{40}",
"msg": "%message"
&lt;!&ndash;"idx_pre": "elk-original-third-access",&ndash;&gt;
&lt;!&ndash;"json": "#asJson{%message}" 这个asJson可以把对应的字符串作为json对象取出来这样es可以对json里面的字段索引了&ndash;&gt;
}
</pattern>
</pattern>
</providers>
</encoder>
</appender>-->
<root level="${LOG_LEVEL}">
<appender-ref ref="ASYNC_STDOUT"/>
<appender-ref ref="ASYNC_FILE_ERROR"/>
<appender-ref ref="ASYNC_FILE_INFO"/>
<appender-ref ref="ASYNC_FILE_WARN"/>
<appender-ref ref="ASYNC_FILE_DEBUG"/>
<appender-ref ref="ASYNC_FILE_ALL"/>
<!--<appender-ref ref="LOGSTASH"/>-->
</root>
</configuration>

@ -0,0 +1,9 @@
<?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="jnpf.mapper.BigDataMapper">
<select id="maxCode" resultType="Integer">
SELECT MAX(F_EN_CODE) FROM ext_big_data
</select>
</mapper>

@ -0,0 +1,46 @@
<?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="jnpf.mapper.DocumentMapper">
<resultMap id="DocumentEntity" type="jnpf.entity.DocumentEntity">
<id column="F_Id" property="id"/>
<result column="F_ParentId" property="parentId"/>
<result column="F_FullName" property="fullName"/>
<result column="F_Type" property="type"/>
<result column="F_FileSize" property="fileSize"/>
<result column="F_SortCode" property="sortCode"/>
<result column="F_FilePath" property="filePath"/>
<result column="F_FileExtension" property="fileExtension"/>
<result column="F_ReadcCount" property="readcCount"/>
<result column="F_IsShare" property="isShare"/>
<result column="F_ShareTime" property="shareTime"/>
<result column="F_Description" property="description"/>
<result column="F_EnabledMark" property="enabledMark"/>
<result column="F_CreatorTime" property="creatorTime"/>
<result column="F_CreatorUserId" property="creatorUserId"/>
<result column="F_LastModifyTime" property="lastModifyTime"/>
<result column="F_LastModifyUserId" property="lastModifyUserId"/>
<result column="F_DeleteMark" property="deleteMark"/>
<result column="F_DeleteTime" property="deleteTime"/>
<result column="F_DeleteUserId" property="deleteUserId"/>
</resultMap>
<select id="getShareTomeList" parameterType="String" resultMap="DocumentEntity">
SELECT * FROM ext_document WHERE F_Id IN (
SELECT F_DocumentId FROM ext_documentshare
WHERE F_ShareUserId = #{userId}
) AND F_DeleteMark is NULL and F_EnabledMark = 1
</select>
<select id="getChildList" parameterType="String" resultMap="DocumentEntity">
WITH document AS (
SELECT * FROM ext_document WHERE F_Id = #{folderId} UNION ALL
SELECT ext_document.* FROM (
SELECT * FROM ext_document WHERE F_Id = #{folderId}
) AS document, ext_document WHERE document.F_Id = ext_document.F_ParentId
) SELECT * FROM document
</select>
<update id="trashRecovery" parameterType="String">
UPDATE ext_document SET F_DELETEMARK=1,F_DELETETIME=NULL,F_DELETEUSERID=NULL WHERE F_Id=#{id}
</update>
</mapper>

@ -0,0 +1,15 @@
<?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="jnpf.mapper.FlowFormMapper">
<resultMap id="flowInfo" type="jnpf.model.flow.FlowTempInfoModel">
<id column="F_Id" property="id"/>
<result column="F_EnCode" property="enCode"/>
</resultMap>
<select id="findFLowInfo" parameterType="String" resultMap="flowInfo">
SELECT ft.F_En_Code as F_EnCode,ft.F_Id as F_Id,F_Enabled_Mark as enabledMark FROM flow_template ft where ft.F_Id =#{tempId}
</select>
</mapper>

@ -0,0 +1,45 @@
<?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="jnpf.mapper.AreaMapper">
<select id="queryAreaList" resultType="jnpf.entity.AreaEntity">
SELECT
a.id,
a.code,
a.name,
a.pid,
a.description,
a.type,
a.space_num as spaceNum,
a.space_area as spaceArea,
a.space_type as spaceType,
a.state,
a.unit_price as unitPrice,
a.lease_start_time as leaseStartTime,
a.lease_end_ime as leaseEndIme,
a.sort,
a.remark,
a.f_creator_time as createTime,
a.f_creator_user_id as creatorUserId,
a.f_last_modify_time as laseModifyTime,
a.f_last_modify_user_id as lastModifyUserId,
a.f_delete_time as deleteTime,
a.f_delete_user_id as deleteUserId,
a.f_delete_mark as deleteMark,
a.f_tenant_id as tenantId,
a.company_id as companyId,
a.department_id as departmentId,
a.organize_json_id as organizeJsonId,
a.f_version as version,
a.f_flow_id as flowId,
b.name as parkName
FROM
yq_park_area_space a
LEFT JOIN yq_park_area_space b on a.pid = b.id and b.f_delete_mark is null
${ew.customSqlSegment}
<if test="areaPagination.sidx != null and areaPagination.sidx != ''">
ORDER BY ${areaPagination.sidx} ${areaPagination.sort}
</if>
</select>
</mapper>

@ -0,0 +1,7 @@
<?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="jnpf.mapper.MeasureSiteConfigMapper">
</mapper>

@ -0,0 +1,7 @@
<?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="jnpf.mapper.ParkMapper">
</mapper>

@ -0,0 +1,56 @@
<?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="jnpf.mapper.SpaceMapper">
<select id="querySpaceList" resultType="jnpf.entity.SpaceEntity">
SELECT
a.id,
a.code,
a.name,
a.pid,
a.description,
a.type,
a.space_num as spaceNum,
a.space_area as spaceArea,
a.space_type as spaceType,
a.state,
a.unit_price as unitPrice,
a.lease_start_time as leaseStartTime,
a.lease_end_ime as leaseEndIme,
a.sort,
a.remark,
a.f_creator_time as createTime,
a.f_creator_user_id as creatorUserId,
a.f_last_modify_time as laseModifyTime,
a.f_last_modify_user_id as lastModifyUserId,
a.f_delete_time as deleteTime,
a.f_delete_user_id as deleteUserId,
a.f_delete_mark as deleteMark,
a.f_tenant_id as tenantId,
a.company_id as companyId,
a.department_id as departmentId,
a.organize_json_id as organizeJsonId,
a.f_version as version,
a.f_flow_id as flowId,
b.name as areaName,
case a.state
when '10' then '待租'
when '20' then '已租'
when '30' then '装修'
when '40' then '预约'
end as state1,
case a.space_type
when '10' then '办公室'
when '20' then '加工车间'
end as spaceType1
FROM
yq_park_area_space a
LEFT JOIN yq_park_area_space b on a.pid = b.id and b.f_delete_mark is null
${ew.customSqlSegment}
<if test="spacePagination.sidx != null and spacePagination.sidx != ''">
ORDER BY ${spacePagination.sidx} ${spacePagination.sort}
</if>
</select>
</mapper>

@ -0,0 +1,7 @@
<?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="jnpf.mapper.SpatialMapper">
</mapper>

@ -0,0 +1,157 @@
<?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="jnpf.permission.mapper.AuthorizeMapper">
<resultMap id="ModuleVO" type="jnpf.base.model.module.ModuleModel">
<id column="f_id" property="id"/>
<result column="f_parent_id" property="parentId"/>
<result column="f_full_name" property="fullName"/>
<result column="f_en_code" property="enCode"/>
<result column="f_type" property="type"/>
<result column="f_url_address" property="urlAddress"/>
<result column="f_link_target" property="linkTarget"/>
<result column="f_category" property="category"/>
<result column="f_icon" property="icon"/>
<result column="f_sort_code" property="sortCode"/>
<result column="f_property_json" property="propertyJson"/>
<result column="f_system_id" property="systemId"/>
<result column="f_description" property="description"/>
</resultMap>
<resultMap id="ButtonVO" type="jnpf.base.model.button.ButtonModel">
<id column="f_id" property="id"/>
<result column="f_parent_id" property="parentId"/>
<result column="f_full_name" property="fullName"/>
<result column="f_en_code" property="enCode"/>
<result column="f_icon" property="icon"/>
<result column="f_url_address" property="urlAddress"/>
<result column="f_module_id" property="moduleId"/>
</resultMap>
<resultMap id="ColumnVO" type="jnpf.base.model.column.ColumnModel">
<id column="f_id" property="id"/>
<result column="f_parent_id" property="parentId"/>
<result column="f_full_name" property="fullName"/>
<result column="f_en_code" property="enCode"/>
<result column="f_bind_table" property="bindTable"/>
<result column="f_bind_table_name" property="bindTableName"/>
<result column="f_module_id" property="moduleId"/>
</resultMap>
<resultMap id="ResourceVO" type="jnpf.base.model.resource.ResourceModel">
<id column="f_id" property="id"/>
<result column="f_full_name" property="fullName"/>
<result column="f_en_code" property="enCode"/>
<result column="f_condition_json" property="conditionJson"/>
<result column="f_condition_text" property="conditionText"/>
<result column="f_module_id" property="moduleId"/>
<result column="f_match_logic" property="matchLogic"/>
<result column="f_object_id" property="objectId"/>
</resultMap>
<resultMap id="FormVO" type="jnpf.base.model.form.ModuleFormModel">
<id column="f_id" property="id"/>
<result column="f_parent_id" property="parentId"/>
<result column="f_full_name" property="fullName"/>
<result column="f_en_code" property="enCode"/>
<result column="f_module_id" property="moduleId"/>
</resultMap>
<resultMap id="SystemVO" type="jnpf.base.model.base.SystemBaeModel">
<id column="f_id" property="id"/>
<result column="f_full_name" property="fullName"/>
<result column="f_en_code" property="enCode"/>
<result column="f_icon" property="icon"/>
<result column="f_property_json" property="propertyJson"/>
<result column="f_description" property="description"/>
<result column="f_sort_code" property="sortCode"/>
<result column="f_enabled_mark" property="enabledMark"/>
</resultMap>
<select id="findModule" parameterType="String" resultMap="ModuleVO">
SELECT * FROM base_module WHERE f_id IN (SELECT f_item_id FROM base_authorize WHERE f_object_id IN (${objectId}) AND f_item_type = 'module') and f_enabled_mark = 1
<if test="id != null and id != ''">
and f_system_id != #{id}
</if>
and f_en_code not in (
'workFlow.addFlow','workFlow.flowLaunch','workFlow.entrust','workFlow','workFlow.flowTodo','workFlow.flowDone','workFlow.flowCirculate'
)
Order by f_sort_code DESC,f_parent_id desc
</select>
<select id="findButton" parameterType="String" resultMap="ButtonVO">
SELECT * FROM base_module_button WHERE f_id IN (SELECT f_item_id FROM base_authorize WHERE f_object_id IN (${objectId}) AND f_item_type = 'button') and f_enabled_mark = 1 Order by f_sort_code desc
</select>
<select id="findColumn" parameterType="String" resultMap="ColumnVO">
SELECT * FROM base_module_column WHERE f_id IN (SELECT f_item_id FROM base_authorize WHERE f_object_id IN (${objectId}) AND f_item_type = 'column') and f_enabled_mark = 1 Order by f_sort_code desc
</select>
<select id="findForms" parameterType="String" resultMap="FormVO">
SELECT * FROM base_module_form WHERE f_id IN (SELECT f_item_id FROM base_authorize WHERE f_object_id IN (${objectId}) AND f_item_type = 'form') and f_enabled_mark = 1 Order by f_sort_code desc
</select>
<select id="findSystem" parameterType="String" resultMap="SystemVO">
SELECT * FROM base_system WHERE f_id IN (SELECT f_item_id FROM base_authorize WHERE f_object_id IN (${objectId}) AND f_item_type = 'system') and f_enabled_mark = 1
<if test="enCode != null and enCode != ''">
and f_en_code != #{enCode}
</if>
Order by f_sort_code desc
</select>
<select id="findResource" parameterType="String" resultMap="ResourceVO">
SELECT s.*,a.f_object_id FROM base_module_scheme s LEFT JOIN
base_authorize a on s.f_id = a.f_item_id WHERE s.f_id IN (SELECT f_item_id FROM base_authorize WHERE f_object_id IN (${objectId}) AND f_item_type = 'resource') and s.f_enabled_mark = 1 Order by s.f_sort_code desc
</select>
<select id="findModuleAdmin" parameterType="Integer" resultMap="ModuleVO">
SELECT * FROM base_module WHERE f_enabled_mark = #{mark}
<if test="id != null and id != ''">
and f_system_id != #{id}
</if>
and f_en_code not in (
'workFlow.addFlow','workFlow.flowLaunch','workFlow.entrust','workFlow','workFlow.flowTodo','workFlow.flowDone','workFlow.flowCirculate'
)
Order by f_sort_code Asc
</select>
<select id="findButtonAdmin" parameterType="Integer" resultMap="ButtonVO">
SELECT * FROM base_module_button WHERE f_enabled_mark = #{mark} Order by f_sort_code desc
</select>
<select id="findColumnAdmin" parameterType="Integer" resultMap="ColumnVO">
SELECT * FROM base_module_column WHERE f_enabled_mark = #{mark} Order by f_sort_code desc
</select>
<select id="findFormsAdmin" parameterType="Integer" resultMap="FormVO">
SELECT * FROM base_module_form WHERE f_enabled_mark = #{mark} Order by f_sort_code desc
</select>
<select id="findResourceAdmin" parameterType="Integer" resultMap="ResourceVO">
SELECT * FROM base_module_scheme WHERE f_enabled_mark = #{mark} Order by f_sort_code desc
</select>
<insert id="saveBatch" parameterType="String">
INSERT INTO base_authorize (f_id, f_item_type, f_item_id, f_object_type, f_object_id, f_sort_code, f_creator_time, f_creator_user_id ) VALUES ${values}
</insert>
<insert id="savaBatchList" parameterType="java.util.List">
INSERT ALL
<foreach item="item" index="index" collection="list">
INTO base_authorize (f_id, f_item_type, f_item_id, f_object_type, f_object_id, f_sort_code, f_creator_time,
f_creator_user_id ) VALUES (
#{item.id},
#{item.itemType},
#{item.itemId},
#{item.objectType},
#{item.objectId},
#{item.sortCode,jdbcType=NUMERIC},
#{item.creatorTime, jdbcType=TIMESTAMP},
#{item.creatorUserId})
</foreach>
SELECT 1 FROM DUAL
</insert>
</mapper>

@ -0,0 +1,30 @@
<?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="jnpf.message.mapper.ImContentMapper">
<!-- <update id="SendMessage" parameterType="jnpf.system.entity.IMContentEntity">
<id column="F_Id" property="id"/>
<result column="F_SENDUSERID" property="sendUserId"/>
<result column="F_SENDTIME" property="sendTime"/>
<result column="F_RECEIVEUSERID" property="receiveUserId"/>
<result column="F_RECEIVETIME" property="receiveTime"/>
<result column="f_content" property="content"/>
<result column="f_content_type" property="contentType"/>
<result column="F_STATE" property="state"/>
</update>-->
<select id="getUnreadList" parameterType="String" resultType="jnpf.message.model.ImUnreadNumModel">
SELECT * FROM (
SELECT SUM(CASE WHEN f_enabled_mark = 0 THEN 1 ELSE 0 END) UnreadNum, f_send_user_id SendUserId, f_receive_user_id ReceiveUserId
FROM base_im_content WHERE 1 = 1 AND f_receive_user_id = #{receiveUserId} GROUP BY f_send_user_id, f_receive_user_id
) t WHERE UnreadNum > 0
</select>
<select id="getUnreadLists" parameterType="String" resultType="jnpf.message.model.ImUnreadNumModel">
select f_send_user_id SendUserId, f_content DefaultMessage,f_content_type DefaultMessageType, f_send_time DefaultMessageTime from base_im_content WHERE 1 = 1 AND f_receive_user_id = #{receiveUserId} AND f_enabled_mark = 0 order by f_send_time desc
</select>
<update id="readMessage" parameterType="map">
UPDATE base_im_content SET f_enabled_mark = 1, f_receive_time = #{map.receiveTime} WHERE 1 = 1 AND f_enabled_mark = 0 AND f_send_user_id = #{map.sendUserId} AND f_receive_user_id = #{map.receiveUserId}
</update>
</mapper>

@ -0,0 +1,35 @@
<?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="jnpf.message.mapper.ImReplyMapper">
<resultMap id="imReplyList" type="jnpf.message.model.ImReplyListModel">
<id column="f_receive_user_id" property="id"/>
<result column="f_user_id" property="userId"/>
<result column="F_HEAD_ICON" property="headIcon"/>
<result column="f_receive_time" property="latestDate"/>
<result column="f_content_type" property="messageType"/>
<result column="f_content" property="latestMessage"/>
<result column="f_delete_user_id" property="deleteUserId"/>
<result column="f_delete_mark" property="deleteMark"/>
</resultMap>
<select id="getImReplyList" resultMap="imReplyList" parameterType="jnpf.message.model.ImReplyListVo">
SELECT
ir.f_user_id,
ir.f_receive_user_id,
ir.f_delete_user_id,
bu.F_HEAD_ICON,
ir.f_receive_time,
ic.f_content_type,
ic.f_content,
ic.f_delete_user_id,
ic.f_delete_mark
FROM
base_im_reply ir
LEFT JOIN base_user bu ON ir.f_user_id = bu.F_Id
LEFT JOIN base_im_content ic ON ic.f_send_user_id = bu.F_Id
AND ir.f_user_id = ic.f_send_user_id
AND ir.f_receive_user_id = ic.f_receive_user_id
AND ir.f_receive_time = ic.f_send_time
AND (ir.f_delete_mark != 1 OR ir.f_delete_mark IS NULL)
</select>
</mapper>

@ -0,0 +1,45 @@
<?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="jnpf.message.mapper.MessageMapper">
<resultMap id="Message" type="jnpf.message.entity.MessageReceiveEntity">
<id column="f_id" property="id"/>
<result column="f_title" property="title"/>
<result column="f_type" property="type"/>
<result column="f_creator_time" property="creatorTime"/>
<result column="f_creator_user_id" property="creatorUserId"/>
<result column="f_last_modify_time" property="lastModifyTime"/>
<result column="f_enabled_mark" property="enabledMark"/>
<result column="f_is_read" property="isRead"/>
<result column="f_last_modify_user_id" property="lastModifyUserId"/>
</resultMap>
<select id="getMessageList" parameterType="map" resultMap="Message">
SELECT r.f_id, r.f_title, r.f_type, r.f_is_read, r.f_creator_time, r.f_creator_user_id, r.f_last_modify_time, r.f_last_modify_user_id,
u.f_real_name,u.f_account FROM base_message r
LEFT JOIN base_user u ON u.f_id = r.f_user_id where 1 = 1
<if test="map.userId != null">
AND r.f_user_id= #{map.userId}
</if>
<if test="map.keyword != null">
AND (r.f_title like #{map.keyword} OR u.f_real_name LIKE #{map.keyword} OR u.f_account LIKE #{map.keyword})
</if>
<if test="map.type != null">
AND r.f_type = #{map.type}
</if>
<if test="map.isRead != null">
AND r.f_is_read = #{map.isRead}
</if>
ORDER BY r.f_last_modify_time desc
</select>
<select id="getUnreadCount" resultType="int">
SELECT COUNT(1) FROM base_message
WHERE f_user_id = #{userId} AND f_is_read = 0 AND f_type = #{type}
</select>
<select id="getInfoDefault" parameterType="int" resultMap="Message">
SELECT * FROM base_message WHERE 1 = 1 AND f_type = #{type} ORDER BY f_creator_time DESC
</select>
</mapper>

@ -0,0 +1,88 @@
<?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="jnpf.base.mapper.PortalManageMapper">
<sql id="selectPages">
SELECT
-- 门户管理表
bpm.F_Id id,
bpm.F_Enabled_Mark enabledMark,
bpm.F_Platform platform,
bpm.F_Description description,
bpm.F_Tenant_Id tenantId,
bpm.F_Sort_Code sortCode,
bpm.F_System_Id systemId,
bpm.F_PORTAL_ID portalId,
bpm.F_Creator_Time creatorTime,
bpm.F_Last_Modify_Time lastModifyTime,
-- 门户表
bp.F_Category categoryId,
bp.F_Full_Name portalName,
bd.F_Full_Name categoryName,
-- 用户表
us.F_Real_Name createUserName,
us.F_Account createUserAccount,
us2.F_Real_Name modifyUserName,
us2.F_Account modifyUserAccount
FROM
base_portal_manage bpm
LEFT JOIN
base_portal bp
ON
bpm.F_Portal_Id = bp.F_Id
LEFT JOIN
base_user us
ON
bpm.F_Creator_User_Id = us.F_Id
LEFT JOIN
base_user us2
ON
bpm.F_Last_Modify_User_Id = us2.F_Id
LEFT JOIN
base_dictionary_data bd
ON bp.F_Category = bd.F_Id
WHERE 1 = 1
<if test="pmPage.keyword != null and pmPage.keyword != ''">
AND (bp.F_Full_Name LIKE #{pmPage.keyword} OR bpm.F_Description LIKE #{pmPage.keyword})
</if>
<if test="pmPage.category != null and pmPage.category != ''">
AND
bp.F_Category = #{pmPage.category}
</if>
<if test="pmPage.enabledMark != null and pmPage.enabledMark != ''">
AND
bpm.F_Enabled_Mark = #{pmPage.enabledMark}
AND bp.F_Enabled_Mark = #{pmPage.enabledMark}
</if>
<if test="pmPage.platform != null and pmPage.platform != ''">
AND
bpm.F_Platform LIKE #{pmPage.platform}
</if>
<if test="pmPage.systemId != null and pmPage.systemId != ''">
AND
bpm.F_System_Id = #{pmPage.systemId}
</if>
<if test="pmPage.state != null and pmPage.state != ''">
AND
bp.F_state != #{pmPage.state}
</if>
</sql>
<select id="selectPortalManageDoPage" resultType="jnpf.base.model.portalManage.PortalManagePageDO" parameterType="jnpf.base.model.portalManage.PortalManagePage">
SELECT
*
FROM (<include refid="selectPages"></include>) TempTable
ORDER BY
sortCode ASC,
creatorTime DESC
</select>
<select id="selectPortalManageDoList" resultType="jnpf.base.model.portalManage.PortalManagePageDO" parameterType="jnpf.base.model.portalManage.PortalManagePage">
SELECT
*
FROM (<include refid="selectPages"></include>) TempTable
ORDER BY
sortCode ASC,
creatorTime DESC
</select>
</mapper>

@ -0,0 +1,45 @@
<?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="jnpf.permission.mapper.PositionMapper">
<select id="getListByUserId" parameterType="String" resultType="jnpf.permission.entity.PositionEntity">
SELECT * FROM base_position WHERE F_ID IN(SELECT F_OBJECT_ID FROM base_user_relation WHERE F_USER_ID = #{userId}) ORDER BY F_SORT_CODE
</select>
<select id="query" resultType="java.lang.String">
SELECT F_Id FROM base_position WHERE F_Id IN (
SELECT DISTINCT a.F_Id FROM (
SELECT
bp.F_Id
FROM
base_organize bo
LEFT JOIN
base_organize_relation bor
ON bo.F_Id = bor.F_Organize_Id
LEFT JOIN
base_position bp
ON bp.F_Id = bor.F_Object_Id
WHERE
bor.F_Object_Type = 'Position'
AND bor.F_Object_Type IS NOT NULL
<if test="keyword != null and keyword != ''">
AND (bp.F_Full_Name LIKE #{keyword} OR bp.F_En_Code LIKE #{keyword})
</if>
<if test="orgIdList != null and orgIdList.size() != 0">
AND bo.F_Id IN
<foreach collection="orgIdList"
item="orgIds" index="index" separator="," open="(" close=")">
#{orgIds}
</foreach>
</if>
) a
)
ORDER BY f_sort_code asc, f_creator_time desc
<!-- <if test="keyword != null and keyword != ''">-->
<!-- ,f_last_modify_time desc-->
<!-- </if>-->
</select>
</mapper>

@ -0,0 +1,64 @@
<?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="jnpf.permission.mapper.RoleMapper">
<select id="getListId" resultType="java.lang.String">
SELECT * FROM base_role WHERE F_ID IN(SELECT F_OBJECT_ID FROM base_user_relation WHERE F_USER_ID = #{userId}) ORDER BY F_SORT_CODE
</select>
<select id="query" resultType="java.lang.String">
SELECT
F_Id
FROM
base_role
<if test="globalMark != 1">
WHERE 1 = 1
AND F_Id IN (
SELECT DISTINCT
a.F_Id
FROM
(
SELECT
br.F_Id
FROM
base_organize bo
LEFT JOIN base_organize_relation bor ON bo.F_Id = bor.F_Organize_Id
LEFT JOIN base_role br ON br.F_Id = bor.F_Object_Id
WHERE
bor.F_Object_Type = 'Role'
AND bor.F_Object_Type IS NOT NULL
<!-- <if test="keyword != null and keyword != ''">-->
<!-- AND (br.F_Full_Name LIKE #{keyword} OR br.F_En_Code LIKE #{keyword})-->
<!-- </if>-->
<if test="orgIdList != null and orgIdList.size() != 0">
AND bo.F_Id IN
<foreach collection="orgIdList"
item="orgIds" index="index" separator="," open="(" close=")">
#{orgIds}
</foreach>
</if>
) a
)
</if>
<if test="globalMark == -1 or globalMark == 1">
<if test="globalMark != 1">
OR
</if>
<if test="globalMark == 1">
Where
</if>
F_Id IN
(
SELECT F_Id FROM base_role WHERE F_Global_Mark = 1
)
</if>
<if test="keyword != null and keyword != ''">
AND (F_Full_Name LIKE #{keyword} OR F_En_Code LIKE #{keyword})
</if>
ORDER BY f_sort_code asc, f_creator_time desc
<!-- <if test="keyword != null and keyword != ''">-->
<!-- ,f_last_modify_time desc-->
<!-- </if>-->
</select>
</mapper>

@ -0,0 +1,15 @@
<?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="jnpf.base.mapper.SysconfigMapper">
<delete id="deleteFig">
delete from base_sys_config where F_Category ='SysConfig'
</delete>
<delete id="deleteMpFig">
delete from base_sys_config where F_Category='MPConfig'
</delete>
<delete id="deleteQyhFig">
delete from base_sys_config where F_Category='QYHConfig'
</delete>
</mapper>

@ -0,0 +1,42 @@
<?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="jnpf.permission.mapper.UserMapper">
<select id="getListId" resultType="java.lang.String">
SELECT F_Id from base_user WHERE F_Enabled_Mark = 1
</select>
<select id="query" resultType="java.lang.String">
SELECT F_Id FROM
(SELECT DISTINCT u.F_Id,u.F_Sort_Code,u.F_Creator_Time
FROM
<if test="dbSchema!=null">
#{dbSchema}.base_user_relation ul1,#{dbSchema}.base_user u
</if>
<if test="dbSchema==null">
base_user_relation ul1,base_user u
</if>
WHERE u.F_Id = ul1.F_User_Id
AND u.F_Account != 'admin'
<if test="account != null and account != ''">
and (u.F_Account like #{account} or u.F_Real_Name like #{account} or u.F_Mobile_Phone like
#{account})
</if>
<if test="orgIdList != null and orgIdList.size > 0">
AND ul1.F_Object_Id IN
<trim suffixOverrides=" OR ul1.F_Object_Id IN()">
<foreach collection="orgIdList" item="orgIds" index="index" open="(" close=")">
<if test="index != 0">
<choose>
<when test="index % 1000 == 999">) OR ul1.F_Object_Id IN (</when>
<otherwise>,</otherwise>
</choose>
</if>
#{orgIds}
</foreach>
</trim>
</if>
ORDER BY u.F_Sort_Code ASC,u.F_Creator_Time DESC) uu
</select>
</mapper>

@ -0,0 +1,317 @@
<?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="jnpf.engine.mapper.FlowTaskMapper">
<resultMap id="FlowTask" type="jnpf.engine.model.flowtask.FlowTaskListModel">
<id column="F_Id" property="id"/>
<result column="F_ProcessId" property="processId"/>
<result column="F_EnCode" property="enCode"/>
<result column="F_FullName" property="fullName"/>
<result column="F_FlowUrgent" property="flowUrgent"/>
<result column="F_FlowId" property="flowId"/>
<result column="F_FlowCode" property="flowCode"/>
<result column="F_FlowName" property="flowName"/>
<result column="F_FlowCategory" property="flowCategory"/>
<result column="F_StartTime" property="startTime"/>
<result column="F_EndTime" property="endTime"/>
<result column="F_ThisStep" property="thisStep"/>
<result column="F_ThisStepId" property="thisStepId"/>
<result column="F_Status" property="status"/>
<result column="F_Completion" property="completion"/>
<result column="F_CreatorUserId" property="creatorUserId"/>
<result column="F_CreatorTime" property="creatorTime"/>
<result column="F_HandleId" property="handleId"/>
<result column="F_NodeName" property="nodeName"/>
<result column="F_NodePropertyJson" property="approversProperties"/>
<result column="F_Description" property="description"/>
<result column="F_FlowVersion" property="flowVersion"/>
<result column="F_DelegateUser" property="delegateUser"/>
<result column="F_TemplateId" property="templateId"/>
<result column="F_CirculateId" property="circulateId"/>
<result column="F_Icon" property="icon"/>
</resultMap>
<select id="getTrialList" parameterType="map" resultMap="FlowTask">
SELECT
r.F_Id AS F_Id,
t.F_Process_Id AS F_ProcessId,
t.F_En_Code AS F_EnCode,
t.F_Start_Time AS F_StartTime,
t.F_Full_Name AS F_FullName,
t.F_Flow_Urgent AS F_FlowUrgent,
t.F_Flow_Id AS F_FlowId,
t.F_Flow_Code AS F_FlowCode,
t.F_Flow_Name AS F_FlowName,
t.F_Flow_Category AS F_FlowCategory,
t.F_End_Time AS F_EndTime,
r.F_Node_Name AS F_ThisStep,
r.F_Task_Node_Id AS F_ThisStepId,
r.F_Handle_Status AS F_Status,
t.F_Completion,
e.F_Icon,
t.F_Creator_User_Id AS F_CreatorUserId,
r.F_Handle_Time AS F_CreatorTime,
t.F_Last_Modify_User_Id AS F_LastModifyUserId,
t.F_Last_Modify_Time AS F_LastModifyTime,
r.F_Handle_Id AS F_HandleId,
o.F_Handle_Id AS F_DelegateUser
FROM
flow_task t
LEFT JOIN flow_task_operator_record r ON r.F_Task_Id = t.F_Id
LEFT JOIN flow_task_operator o ON r.F_Task_Operator_Id = o.F_Id
LEFT JOIN flow_template e on t.F_Template_Id = e.F_Id
WHERE
1 = 1
AND ( r.F_Handle_Status = 0 OR r.F_Handle_Status = 1 OR r.F_Handle_Status = 10 )
AND r.F_Task_Operator_Id IS NOT NULL AND r.F_Handle_Id = #{map.handleId}
<if test="map.keyWord != null and map.keyWord!=''">
AND (t.F_En_Code like #{map.keyWord} or t.F_Full_Name like #{map.keyWord})
</if>
<if test="map.startTime != null and map.startTime!='' and map.endTime != null and map.endTime!=''">
<choose>
<when test="map.oracle != null and map.oracle!=''">
AND r.F_Handle_Time Between TO_DATE(#{map.startTime},'yyyy-mm-dd HH24:mi:ss') AND
TO_DATE(#{map.endTime},'yyyy-mm-dd HH24:mi:ss')
</when>
<otherwise>
AND r.F_Handle_Time Between #{map.startTime} and #{map.endTime}
</otherwise>
</choose>
</if>
<if test="map.flowCategory != null and map.flowCategory.size()>0">
AND t.F_Flow_Category in
<foreach collection="map.flowCategory" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</if>
<if test="map.creatorUserId != null and map.creatorUserId!=''">
AND t.F_Creator_User_Id = #{map.creatorUserId}
</if>
<if test="map.templateId != null and map.templateId!=''">
AND t.F_Template_Id = #{map.templateId}
</if>
<if test="map.flowList != null and map.flowList.size()>0">
AND t.F_Flow_Id in
<foreach collection="map.flowList" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</if>
<if test="map.flowUrgent != null and map.flowUrgent!=''">
AND t.F_Flow_Urgent = #{map.flowUrgent}
</if>
Order by r.F_Handle_Time DESC
</select>
<select id="getCirculateList" parameterType="map" resultMap="FlowTask">
SELECT
t.F_Id,
t.F_Process_Id AS F_ProcessId,
t.F_En_Code AS F_EnCode,
t.F_Full_Name AS F_FullName,
t.F_Flow_Urgent AS F_FlowUrgent,
t.F_Flow_Id AS F_FlowId,
t.F_Flow_Code AS F_FlowCode,
t.F_Flow_Name AS F_FlowName,
t.F_Flow_Category AS F_FlowCategory,
t.F_Start_Time AS F_StartTime,
t.F_End_Time AS F_EndTime,
c.F_Node_Name AS F_ThisStep,
c.F_Task_Node_Id AS F_ThisStepId,
c.F_Id AS F_CirculateId,
t.F_Status,
t.F_Completion,
e.F_Icon,
t.F_Creator_User_Id AS F_CreatorUserId,
c.F_Creator_Time AS F_CreatorTime,
t.F_Last_Modify_User_Id AS F_LastModifyUserId,
t.F_Last_Modify_Time AS F_LastModifyTime
FROM
flow_task t
LEFT JOIN flow_task_circulate c ON c.F_Task_Id = t.F_Id
LEFT JOIN flow_template e on t.F_Template_Id = e.F_Id
WHERE
1 =1
<if test="map.objectId != null and map.objectId.size()>0">
and c.F_Object_Id in
<foreach collection="map.objectId" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</if>
<if test="map.keyWord != null and map.keyWord!=''">
AND (t.F_En_Code like #{map.keyWord} or t.F_Full_Name like #{map.keyWord})
</if>
<if test="map.startTime != null and map.startTime!='' and map.endTime != null and map.endTime!=''">
<choose>
<when test="map.oracle != null and map.oracle!=''">
AND c.F_Creator_Time Between TO_DATE(#{map.startTime},'yyyy-mm-dd HH24:mi:ss') AND
TO_DATE(#{map.endTime},'yyyy-mm-dd HH24:mi:ss')
</when>
<otherwise>
AND c.F_Creator_Time Between #{map.startTime} and #{map.endTime}
</otherwise>
</choose>
</if>
<if test="map.templateId != null and map.templateId!=''">
AND t.F_Template_Id = #{map.templateId}
</if>
<if test="map.flowList != null and map.flowList.size()>0">
AND t.F_Flow_Id in
<foreach collection="map.flowList" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</if>
<if test="map.flowCategory != null and map.flowCategory.size()>0">
AND t.F_Flow_Category in
<foreach collection="map.flowCategory" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</if>
<if test="map.creatorUserId != null and map.creatorUserId!=''">
AND t.F_Creator_User_Id = #{map.creatorUserId}
</if>
<if test="map.flowUrgent != null and map.flowUrgent!=''">
AND t.F_Flow_Urgent = #{map.flowUrgent}
</if>
Order by c.F_Creator_Time DESC
</select>
<select id="getWaitList" parameterType="map" resultMap="FlowTask">
SELECT
o.F_Id AS F_Id,
t.F_Process_Id AS F_ProcessId,
t.F_En_Code AS F_EnCode,
t.F_Full_Name AS F_FullName,
t.F_Flow_Urgent AS F_FlowUrgent,
t.F_Flow_Id AS F_FlowId,
t.F_Flow_Code AS F_FlowCode,
t.F_Flow_Name AS F_FlowName,
t.F_Flow_Category AS F_FlowCategory,
t.F_Start_Time AS F_StartTime,
t.F_End_Time AS F_EndTime,
t.F_Current_Node_Name AS F_ThisStep,
n.F_Id AS F_ThisStepId,
t.F_Status,
t.F_Completion,
t.F_Creator_User_Id AS F_CreatorUserId,
o.F_Creator_Time AS F_CreatorTime,
o.F_Handle_Id AS F_HandleId,
t.F_Last_Modify_User_Id AS F_LastModifyUserId,
t.F_Template_Id AS F_TemplateId,
t.F_Last_Modify_Time AS F_LastModifyTime,
n.F_Node_Property_Json AS F_NodePropertyJson,
o.F_Description,
o.F_Node_Name AS F_NodeName,
t.F_Flow_Version AS F_FlowVersion,
e.F_Icon
FROM
flow_task_operator o
LEFT JOIN flow_task t ON o.F_Task_Id = t.F_Id
LEFT JOIN flow_task_node n ON o.F_Task_Node_Id = n.F_Id
LEFT JOIN flow_template e on t.F_Template_Id = e.F_Id
WHERE
1 = 1
AND o.F_Completion = 0
AND t.F_Status = 1
AND o.F_State = '0'
<if test="map.handleId != null and map.handleId.size()>0">
AND o.F_Handle_Id in
<foreach collection="map.handleId" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</if>
<if test="map.keyWord != null and map.keyWord!=''">
AND (t.F_En_Code like #{map.keyWord} or t.F_Full_Name like #{map.keyWord})
</if>
<if test="map.startTime != null and map.startTime!='' and map.endTime != null and map.endTime!=''">
<choose>
<when test="map.oracle != null and map.oracle!=''">
AND o.F_Creator_Time Between TO_DATE(#{map.startTime},'yyyy-mm-dd HH24:mi:ss') AND
TO_DATE(#{map.endTime},'yyyy-mm-dd HH24:mi:ss')
</when>
<otherwise>
AND o.F_Creator_Time Between #{map.startTime} and #{map.endTime}
</otherwise>
</choose>
</if>
<if test="map.flowCategory != null and map.flowCategory.size()>0">
AND t.F_Flow_Category in
<foreach collection="map.flowCategory" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</if>
<if test="map.creatorUserId != null and map.creatorUserId!=''">
AND t.F_Creator_User_Id = #{map.creatorUserId}
</if>
<if test="map.nodeCode != null and map.nodeCode!=''">
AND o.F_Node_Code = #{map.nodeCode}
</if>
<if test="map.templateId != null and map.templateId!=''">
AND t.F_Template_Id = #{map.templateId}
</if>
<if test="map.flowList != null and map.flowList.size()>0">
AND t.F_Flow_Id in
<foreach collection="map.flowList" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</if>
<if test="map.isBatch != null and map.isBatch!=''">
AND t.F_Is_Batch = #{map.isBatch}
</if>
<if test="map.flowUrgent != null and map.flowUrgent!=''">
AND t.F_Flow_Urgent = #{map.flowUrgent}
</if>
Order by O.F_Creator_Time DESC
</select>
<select id="getWorkTrial" parameterType="map" resultMap="FlowTask">
SELECT
r.F_Id AS F_Id,
t.F_Process_Id AS F_ProcessId,
t.F_En_Code AS F_EnCode,
t.F_Start_Time AS F_StartTime,
t.F_Full_Name AS F_FullName,
t.F_Flow_Urgent AS F_FlowUrgent,
t.F_Flow_Id AS F_FlowId,
t.F_Flow_Code AS F_FlowCode,
t.F_Flow_Name AS F_FlowName,
t.F_Flow_Category AS F_FlowCategory,
t.F_End_Time AS F_EndTime,
r.F_Node_Name AS F_ThisStep,
r.F_Task_Node_Id AS F_ThisStepId,
r.F_Handle_Status AS F_Status,
t.F_Completion,
e.F_Icon,
t.F_Creator_User_Id AS F_CreatorUserId,
r.F_Handle_Time AS F_CreatorTime,
t.F_Last_Modify_User_Id AS F_LastModifyUserId,
t.F_Last_Modify_Time AS F_LastModifyTime,
r.F_Handle_Id AS F_HandleId
FROM
flow_task t
LEFT JOIN flow_task_operator_record r ON r.F_Task_Id = t.F_Id
LEFT JOIN flow_template e on t.F_Template_Id = e.F_Id
WHERE r.F_Handle_Id = #{map.handleId}
</select>
</mapper>

@ -0,0 +1,52 @@
databaseName: myshardingsphere
dataSources: # 数据源配置 =============
# <数据源_0>: # 自定义数据源名称
# dataSourceClassName: com.zaxxer.hikari.HikariDataSource # 连接池提供方完整类名Spring默认Hikari
# driverClassName: com.mysql.jdbc.Driver # JDBC驱动
# jdbcUrl: jdbc:mysql://{host}:{port}/{dbName}?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8 # 数据库连接URL
# username: {username} # 用户
# password: {password} # 密码
ds0: # 自定义数据源名称
dataSourceClassName: com.alibaba.druid.pool.DruidDataSource # 连接池提供方完整类名Spring默认Hikari
driverClassName: com.mysql.jdbc.Driver # JDBC驱动
url: jdbc:mysql://127.0.0.1:3306/sharding1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8 # 数据库连接URL
username: root # 用户
password: 123456 # 密码
ds1: # 自定义数据源名称
dataSourceClassName: com.alibaba.druid.pool.DruidDataSource # 连接池提供方完整类名Spring默认Hikari
driverClassName: com.mysql.jdbc.Driver # JDBC驱动
url: jdbc:mysql://127.0.0.1:3306/sharding2?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8 # 数据库连接URL
username: root # 用户
password: 123456 # 密码
rules: # 规则 =============
- !SHARDING # 注意类似“- !SHARDING”标识不能省略
tables:
ext_bigdata: # 自定义逻辑表名
actualDataNodes: ds${0..1}.ext_bigdata_$->{0..1} # 由数据源名 + 表名组成(参考 Inline 语法规则)
databaseStrategy:
standard:
shardingColumn: F_Id # 分表依据字段
shardingAlgorithmName: myDataSourceAlgorithm
tableStrategy: # 表策略 -------
standard:
shardingColumn: F_Id # 分表依据字段
shardingAlgorithmName: myTableAlgorithm
# defaultDatabaseStrategy: # 库策略 -------
# standard:
# shardingColumn: F_Id
# shardingAlgorithmName: myDataSourceAlgorithm
shardingAlgorithms: # 分片算法 -------
myDataSourceAlgorithm: # 自定义算法名
type: INLINE
props:
algorithm-expression: ds${(long)(Long.parseLong(F_Id)/10) % 2}
myTableAlgorithm: # 自定义算法名
type: INLINE
props:
algorithm-expression: ext_bigdata_${(long)(Long.parseLong(F_Id)/10 / 2) % 2}
# keyGenerators:
# dsKey: # 自定义主键策略名
# type: SNOWFLAKE
props:
sql-show: true

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>jnpf-app</artifactId>
<groupId>com.jnpf</groupId>
<version>3.5.0-RELEASE</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jnpf-app-biz</artifactId>
<dependencies>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-app-entity</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-permission-biz</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-system-biz</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-workflow-engine-biz</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

@ -0,0 +1,16 @@
package jnpf.mapper;
import jnpf.base.mapper.SuperMapper;
import jnpf.entity.AppDataEntity;
/**
* app
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2021-07-08
*/
public interface AppDataMapper extends SuperMapper<AppDataEntity> {
}

@ -0,0 +1,88 @@
package jnpf.service;
import jnpf.base.service.SuperService;
import jnpf.engine.model.flowengine.FlowPagination;
import jnpf.entity.AppDataEntity;
import jnpf.model.AppDataListAllVO;
import jnpf.model.AppFlowListAllVO;
import java.util.List;
/**
* app
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2021-08-08
*/
public interface AppDataService extends SuperService<AppDataEntity> {
/**
*
*
* @param type
* @return
*/
List<AppDataEntity> getList(String type);
/**
*
*
* @return
*/
List<AppDataEntity> getList();
/**
*
*
* @param objectId
* @return
*/
AppDataEntity getInfo(String objectId);
/**
*
*
* @param objectId
* @return
*/
boolean isExistByObjectId(String objectId, String systemId);
/**
*
*
* @param entity
*/
void create(AppDataEntity entity);
/**
*
*
* @param entity
*/
void delete(AppDataEntity entity);
/**
*
*
* @param objectId
*/
void delete(String objectId);
/**
*
*
* @param pagination
* @return
*/
List<AppFlowListAllVO> getFlowList(FlowPagination pagination);
/**
*
* @param type
* @return
*/
List<AppDataListAllVO> getDataList(String type);
}

@ -0,0 +1,28 @@
package jnpf.service;
import jnpf.model.AppUserInfoVO;
import jnpf.model.AppUsersVO;
/**
* app
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2021-08-08
*/
public interface AppService {
/**
* app
* @return
*/
AppUsersVO userInfo();
/**
*
* @return
*/
AppUserInfoVO getInfo(String id);
}

@ -0,0 +1,171 @@
package jnpf.service.impl;
import jnpf.base.service.SuperServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import jnpf.base.UserInfo;
import jnpf.base.entity.ModuleEntity;
import jnpf.base.model.module.ModuleModel;
import jnpf.base.service.ModuleService;
import jnpf.engine.entity.FlowTemplateEntity;
import jnpf.engine.model.flowengine.FlowPagination;
import jnpf.engine.service.FlowTemplateJsonService;
import jnpf.engine.service.FlowTemplateService;
import jnpf.entity.AppDataEntity;
import jnpf.mapper.AppDataMapper;
import jnpf.model.*;
import jnpf.permission.model.authorize.AuthorizeVO;
import jnpf.permission.service.AuthorizeService;
import jnpf.service.AppDataService;
import jnpf.util.JsonUtil;
import jnpf.util.RandomUtil;
import jnpf.util.StringUtil;
import jnpf.util.UserProvider;
import jnpf.util.treeutil.SumTree;
import jnpf.util.treeutil.newtreeutil.TreeDotUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
/**
* app
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2021-08-08
*/
@Service
public class AppDataServiceImpl extends SuperServiceImpl<AppDataMapper, AppDataEntity> implements AppDataService {
@Autowired
private UserProvider userProvider;
@Autowired
private ModuleService moduleService;
@Autowired
private AuthorizeService authorizeService;
@Autowired
private FlowTemplateService flowTemplateService;
@Autowired
private FlowTemplateJsonService flowTemplateJsonService;
@Override
public List<AppDataEntity> getList(String type) {
UserInfo userInfo = userProvider.get();
QueryWrapper<AppDataEntity> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(AppDataEntity::getObjectType, type).eq(AppDataEntity::getCreatorUserId, userInfo.getUserId());
List<AppDataEntity> list = this.list(queryWrapper);
list = list.stream().filter(t -> StringUtil.isNotEmpty(t.getSystemId()) && t.getSystemId().equals(userInfo.getAppSystemId())).collect(Collectors.toList());
List<String> idAll = list.stream().map(AppDataEntity::getObjectId).collect(Collectors.toList());
List<FlowTemplateEntity> templateList = flowTemplateService.getTemplateList(idAll);
for (int i = 0; i < list.size(); i++) {
AppDataEntity appDataEntity = list.get(i);
if ("2".equals(type)) {
ModuleEntity info = moduleService.getInfo(appDataEntity.getObjectId());
if (info == null || info.getEnabledMark() == 0) {
list.remove(i);
i--;
}
} else {
FlowTemplateEntity templateEntity = templateList.stream().filter(t -> t.getId().equals(appDataEntity.getObjectId())).findFirst().orElse(null);
if (templateEntity == null) {
list.remove(i);
i--;
}
}
}
return list;
}
@Override
public List<AppDataEntity> getList() {
QueryWrapper<AppDataEntity> queryWrapper = new QueryWrapper<>();
return this.list(queryWrapper);
}
@Override
public AppDataEntity getInfo(String objectId) {
UserInfo userInfo = userProvider.get();
QueryWrapper<AppDataEntity> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(AppDataEntity::getObjectId, objectId).eq(AppDataEntity::getCreatorUserId, userInfo.getUserId());
return this.getOne(queryWrapper);
}
@Override
public boolean isExistByObjectId(String objectId, String systemId) {
UserInfo userInfo = userProvider.get();
QueryWrapper<AppDataEntity> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(AppDataEntity::getObjectId, objectId)
.eq(AppDataEntity::getCreatorUserId, userInfo.getUserId())
.eq(AppDataEntity::getSystemId, systemId);
return this.count(queryWrapper) > 0 ? true : false;
}
@Override
public void create(AppDataEntity entity) {
UserInfo userInfo = userProvider.get();
entity.setId(RandomUtil.uuId());
entity.setCreatorUserId(userInfo.getUserId());
entity.setCreatorTime(new Date());
entity.setEnabledMark(1);
entity.setSystemId(userInfo.getAppSystemId());
this.save(entity);
}
@Override
public void delete(AppDataEntity entity) {
this.removeById(entity.getId());
}
@Override
public void delete(String objectId) {
QueryWrapper<AppDataEntity> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(AppDataEntity::getObjectId, objectId);
this.remove(queryWrapper);
}
@Override
public List<AppFlowListAllVO> getFlowList(FlowPagination pagination) {
List<String> objectId = getList("1").stream().map(AppDataEntity::getObjectId).collect(Collectors.toList());;
List<FlowTemplateEntity> pageList = flowTemplateService.getListAll(pagination,true);
List<AppFlowListAllVO> result = new ArrayList<>();
for (FlowTemplateEntity entity : pageList) {
AppFlowListAllVO vo = JsonUtil.getJsonToBean(entity, AppFlowListAllVO.class);
vo.setIsData(objectId.contains(vo.getId()));
result.add(vo);
}
return pagination.setData(result, pagination.getTotal());
}
@Override
public List<AppDataListAllVO> getDataList(String type) {
List<AppDataEntity> dataList = getList(type);
String appSystemId = userProvider.get().getAppSystemId();
AuthorizeVO authorizeModel = authorizeService.getAuthorize(true, false);
List<ModuleModel> buttonList = authorizeModel.getModuleList();
List<ModuleEntity> menuList = moduleService.getList().stream().filter(t -> "App".equals(t.getCategory()) && t.getEnabledMark() == 1 && t.getSystemId().equals(appSystemId)).collect(Collectors.toList());
List<UserMenuModel> list = new LinkedList<>();
for (ModuleEntity module : menuList) {
boolean count = buttonList.stream().filter(t -> t.getId().equals(module.getId())).count() > 0;
UserMenuModel userMenuModel = JsonUtil.getJsonToBean(module, UserMenuModel.class);
if (count) {
boolean isData = dataList.stream().filter(t -> t.getObjectId().equals(module.getId())).count() > 0;
userMenuModel.setIsData(isData);
list.add(userMenuModel);
}
}
List<SumTree<UserMenuModel>> menuAll = TreeDotUtils.convertListToTreeDot(list);
List<AppDataListAllVO> menuListAll = JsonUtil.getJsonToList(menuAll, AppDataListAllVO.class);
List<AppDataListAllVO> data = new LinkedList<>();
for (AppDataListAllVO appMenu : menuListAll) {
if ("-1".equals(appMenu.getParentId())) {
data.add(appMenu);
}
}
return data;
}
}

@ -0,0 +1,157 @@
package jnpf.service.impl;
import cn.hutool.core.collection.ListUtil;
import jnpf.base.UserInfo;
import jnpf.model.AppPositionVO;
import jnpf.model.AppUserInfoVO;
import jnpf.model.AppUsersVO;
import jnpf.permission.entity.*;
import jnpf.permission.service.*;
import jnpf.service.AppService;
import jnpf.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
/**
* app
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2021-08-08
*/
@Service
public class AppServiceImpl implements AppService {
@Autowired
private UserProvider userProvider;
@Autowired
private UserService userService;
@Autowired
private PositionService positionService;
@Autowired
private OrganizeService organizeService;
@Autowired
private RoleService roleService;
@Autowired
private RedisUtil redisUtil;
@Autowired
private UserRelationService userRelationService;
@Override
public AppUsersVO userInfo() {
UserInfo userInfo = userProvider.get();
UserEntity userEntity = userService.getInfo(userInfo.getUserId());
AppUsersVO usersVO = new AppUsersVO();
usersVO.setBirthday(userEntity.getBirthday() != null ? userEntity.getBirthday().getTime() : null);
usersVO.setEmail(userEntity.getEmail());
usersVO.setGender(userEntity.getGender());
usersVO.setMobilePhone(userEntity.getMobilePhone());
this.data(usersVO, userEntity, userInfo);
this.userInfo(usersVO, userInfo);
//岗位
PositionEntity position = positionService.getInfo(userEntity.getPositionId());
AppPositionVO positionVO = new AppPositionVO();
if(position != null){
positionVO.setId(position.getId());
positionVO.setName(position.getFullName());
usersVO.setPositionIds(ListUtil.toList(positionVO));
}
//直属主管
if(StringUtil.isNotEmpty(userEntity.getManagerId())){
UserEntity menager = userService.getInfo(userEntity.getManagerId());
usersVO.setManager(menager != null ? menager.getRealName() + "/" + menager.getAccount() : "");
}
//角色
List<String> roles = roleService.getAllRoleIdsByUserIdAndOrgId(userInfo.getUserId(), usersVO.getOrganizeId());
List<RoleEntity> roleList = roleService.getListByIds(roles, null, false);
usersVO.setRoleName(String.join("", roleList.stream().map(RoleEntity::getFullName).collect(Collectors.toList())));
usersVO.setRoleId(String.join(".", roleList.stream().map(RoleEntity::getId).collect(Collectors.toList())));
return usersVO;
}
@Override
public AppUserInfoVO getInfo(String id) {
AppUserInfoVO userInfoVO = new AppUserInfoVO();
UserEntity entity = userService.getInfo(id);
if (entity != null) {
userInfoVO = JsonUtil.getJsonToBean(entity, AppUserInfoVO.class);
List<String> positionIds = StringUtil.isNotEmpty(entity.getPositionId()) ? Arrays.asList(entity.getPositionId().split(",")) : new ArrayList<>();
List<String> positionName = positionService.getPositionName(positionIds, false).stream().map(t -> t.getFullName()).collect(Collectors.toList());
userInfoVO.setPositionName(String.join(",", positionName));
OrganizeEntity info = organizeService.getInfo(entity.getOrganizeId());
userInfoVO.setOrganizeName(info != null ? info.getFullName() : "");
userInfoVO.setHeadIcon(UploaderUtil.uploaderImg(userInfoVO.getHeadIcon()));
}
return userInfoVO;
}
/**
*
*
* @param userInfo
* @param userId
* @param isAdmin
*/
private void userInfo(UserInfo userInfo, String userId, boolean isAdmin, UserEntity userEntity) {
List<String> userIdList = new ArrayList(){{add(userId);}};
List<UserRelationEntity> data = userRelationService.getListByUserIdAll(userIdList);
//获取一个字段的值
List<String> positionList = data.stream().filter(m -> "Position".equals(m.getObjectType())).map(t -> t.getObjectId()).collect(Collectors.toList());
Set<String> id = new LinkedHashSet<>();
String[] position = StringUtil.isNotEmpty(userEntity.getPositionId()) ? userEntity.getPositionId().split(",") : new String[]{};
List<String> positions = positionList.stream().filter(t->Arrays.asList(position).contains(t)).collect(Collectors.toList());
id.addAll(positions);
id.addAll(positionList);
userInfo.setPositionIds(id.toArray(new String[id.size()]));
if (!isAdmin) {
data = data.stream().filter(m -> "Role".equals(m.getObjectType())).collect(Collectors.toList());
}
List<String> roleList = data.stream().map(t -> t.getObjectId()).collect(Collectors.toList());
userInfo.setRoleIds(roleList);
}
private void data(AppUsersVO usersVO, UserEntity userEntity, UserInfo userInfo) {
//组织
usersVO.setOrganizeId(userEntity.getOrganizeId());
List<OrganizeEntity> organizeIdList = new ArrayList<>();
organizeService.getOrganizeId(userEntity.getOrganizeId(),organizeIdList);
Collections.reverse(organizeIdList);
usersVO.setOrganizeName(organizeIdList.stream().map(OrganizeEntity::getFullName).collect(Collectors.joining("/")));
OrganizeEntity organizeEntity = organizeIdList.stream().filter(t->t.getId().equals(userEntity.getOrganizeId())).findFirst().orElse(null);
if (organizeEntity != null) {
String[] organizeId = StringUtil.isNotEmpty(organizeEntity.getOrganizeIdTree()) ? organizeEntity.getOrganizeIdTree().split(",") : new String[]{};
if (organizeId.length > 0) {
userInfo.setOrganizeId(organizeId[0]);
userInfo.setDepartmentId(organizeId[organizeId.length - 1]);
}
}
userInfo.setManagerId(userInfo.getManagerId());
boolean b = userInfo.getIsAdministrator();
List<String> subordinateIdsList = userService.getListByManagerId(userInfo.getUserId(),null).stream().map(UserEntity::getId).collect(Collectors.toList());
userInfo.setSubordinateIds(subordinateIdsList);
this.userInfo(userInfo, userInfo.getUserId(), b,userEntity);
userInfo.setSubOrganizeIds(new String[]{});
//redisUtil.insert(userInfo.getId(), userInfo, DateUtil.getTime(userInfo.getOverdueTime()) - DateUtil.getTime(new Date()));
UserProvider.setLoginUser(userInfo);
UserProvider.setLocalLoginUser(userInfo);
}
/**
*
*
* @param appUsersVO
* @param userInfo
* @return
*/
private void userInfo(AppUsersVO appUsersVO, UserInfo userInfo) {
appUsersVO.setUserId(userInfo.getUserId());
appUsersVO.setHeadIcon(UploaderUtil.uploaderImg(userInfo.getUserIcon()));
appUsersVO.setUserName(userInfo.getUserName());
appUsersVO.setUserAccount(userInfo.getUserAccount());
}
}

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>jnpf-app</artifactId>
<groupId>com.jnpf</groupId>
<version>3.5.0-RELEASE</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jnpf-app-controller</artifactId>
<dependencies>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-app-biz</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

@ -0,0 +1,129 @@
package jnpf.controller;
import jnpf.base.controller.SuperController;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.Operation;
import jnpf.base.ActionResult;
import jnpf.base.vo.ListVO;
import jnpf.base.vo.PageListVO;
import jnpf.base.vo.PaginationVO;
import jnpf.constant.MsgCode;
import jnpf.engine.model.flowengine.FlowPagination;
import jnpf.entity.AppDataEntity;
import jnpf.model.AppDataCrForm;
import jnpf.model.AppDataListAllVO;
import jnpf.model.AppDataListVO;
import jnpf.model.AppFlowListAllVO;
import jnpf.service.AppDataService;
import jnpf.util.JsonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
/**
* app
*
* @author JNPF
* @version V3.1.0
* @copyright https://www.jnpfsoft.com
* @date 2021-07-08
*/
@Tag(name = "app常用数据", description = "data")
@RestController
@RequestMapping("/api/app/Data")
public class AppDataController extends SuperController<AppDataService, AppDataEntity> {
@Autowired
private AppDataService appDataService;
/**
*
*
* @param type
* @return
*/
@Operation(summary = "常用数据")
@GetMapping
@Parameters({
@Parameter(name = "type", description = "类型"),
})
public ActionResult<ListVO<AppDataListVO>> list(@RequestParam("type") String type) {
List<AppDataEntity> list = appDataService.getList(type);
List<AppDataListVO> data = JsonUtil.getJsonToList(list, AppDataListVO.class);
ListVO listVO = new ListVO();
listVO.setList(data);
return ActionResult.success(listVO);
}
/**
*
*
* @param appDataCrForm
* @return
*/
@PostMapping
@Operation(summary = "新建")
@Parameters({
@Parameter(name = "appDataCrForm", description = "常用模型",required = true),
})
public ActionResult create(@RequestBody @Valid AppDataCrForm appDataCrForm) {
AppDataEntity entity = JsonUtil.getJsonToBean(appDataCrForm, AppDataEntity.class);
if (appDataService.isExistByObjectId(entity.getObjectId(),appDataCrForm.getSystemId())) {
return ActionResult.fail("常用数据已存在");
}
appDataService.create(entity);
return ActionResult.success(MsgCode.SU001.get());
}
/**
*
*
* @param objectId
* @return
*/
@Operation(summary = "删除")
@DeleteMapping("/{objectId}")
@Parameters({
@Parameter(name = "objectId", description = "主键", required = true),
})
public ActionResult create(@PathVariable("objectId") String objectId) {
AppDataEntity entity = appDataService.getInfo(objectId);
if (entity != null) {
appDataService.delete(entity);
return ActionResult.success(MsgCode.SU003.get());
}
return ActionResult.fail(MsgCode.FA003.get());
}
/**
*
*
* @param pagination
* @return
*/
@Operation(summary = "所有流程")
@GetMapping("/getFlowList")
public ActionResult<PageListVO<AppFlowListAllVO>> getFlowList(FlowPagination pagination) {
List<AppFlowListAllVO> list = appDataService.getFlowList(pagination);
PaginationVO paginationVO = JsonUtil.getJsonToBean(pagination, PaginationVO.class);
return ActionResult.page(list, paginationVO);
}
/**
*
*
* @return
*/
@Operation(summary = "所有应用")
@GetMapping("/getDataList")
public ActionResult<ListVO<AppDataListAllVO>> getAllList() {
List<AppDataListAllVO> result = appDataService.getDataList("2");
ListVO listVO = new ListVO();
listVO.setList(result);
return ActionResult.success(listVO);
}
}

@ -0,0 +1,93 @@
package jnpf.controller;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import jnpf.base.ActionResult;
import jnpf.base.Page;
import jnpf.base.entity.ModuleEntity;
import jnpf.base.entity.SystemEntity;
import jnpf.base.model.module.ModuleModel;
import jnpf.base.service.ModuleService;
import jnpf.base.service.SystemService;
import jnpf.base.vo.ListVO;
import jnpf.constant.PermissionConst;
import jnpf.model.AppMenuListVO;
import jnpf.model.UserMenuModel;
import jnpf.permission.entity.OrganizeAdministratorEntity;
import jnpf.permission.model.authorize.AuthorizeVO;
import jnpf.permission.service.AuthorizeService;
import jnpf.permission.service.OrganizeAdministratorService;
import jnpf.util.JsonUtil;
import jnpf.util.StringUtil;
import jnpf.util.UserProvider;
import jnpf.util.treeutil.ListToTreeUtil;
import jnpf.util.treeutil.SumTree;
import jnpf.util.treeutil.newtreeutil.TreeDotUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.stream.Collectors;
/**
* app
*
* @author JNPF
* @version V3.1.0
* @copyright https://www.jnpfsoft.com
* @date 2021-07-08
*/
@Tag(name = "app应用", description = "Menu")
@RestController
@RequestMapping("/api/app/Menu")
public class AppMenuController {
@Autowired
private ModuleService moduleApi;
@Autowired
private AuthorizeService authorizeService;
@Autowired
private UserProvider userProvider;
@Autowired
private OrganizeAdministratorService organizeAdminTratorApi;
@Autowired
private SystemService systemApi;
/**
*
*
* @param page
* @return
*/
@Operation(summary = "获取菜单列表")
@GetMapping
public ActionResult<ListVO<AppMenuListVO>> list(Page page) {
// 从分级管理获取应用权限后获取菜单
List<OrganizeAdministratorEntity> listByUserId = organizeAdminTratorApi.getOrganizeAdministratorEntity(UserProvider.getLoginUserId(), PermissionConst.SYSTEM, false);
List<SystemEntity> systemEntities = systemApi.getListByIds(listByUserId.stream().map(OrganizeAdministratorEntity::getOrganizeId).collect(Collectors.toList()));
List<ModuleEntity> moduleBySystemIds = moduleApi.getModuleBySystemIds(systemEntities.stream().map(SystemEntity::getId).collect(Collectors.toList()));
List<ModuleModel> jsonToList = JsonUtil.getJsonToList(moduleBySystemIds, ModuleModel.class);
List<OrganizeAdministratorEntity> listByUserId1 = organizeAdminTratorApi.getOrganizeAdministratorEntity(UserProvider.getLoginUserId(), PermissionConst.MODULE, false);
List<ModuleEntity> moduleEntities = moduleApi.getModuleByIds(listByUserId1.stream().map(OrganizeAdministratorEntity::getOrganizeId).collect(Collectors.toList()));
List<ModuleModel> jsonToList1 = JsonUtil.getJsonToList(moduleEntities, ModuleModel.class);
AuthorizeVO authorizeModel = authorizeService.getAuthorize(true, true);
List<ModuleModel> buttonListAll = authorizeModel.getModuleList().stream().filter(t -> "App".equals(t.getCategory())).collect(Collectors.toList());
buttonListAll.addAll(jsonToList);
buttonListAll.addAll(jsonToList1);
// 通过系统id捞取相应的菜单
buttonListAll = buttonListAll.stream().distinct().filter(t -> userProvider.get().getAppSystemId() != null && userProvider.get().getAppSystemId().equals(t.getSystemId()) && "App".equals(t.getCategory())).collect(Collectors.toList());
List<ModuleModel> buttonList = buttonListAll;
if (StringUtil.isNotEmpty(page.getKeyword())) {
buttonList = buttonListAll.stream().filter(t -> t.getFullName().contains(page.getKeyword())).collect(Collectors.toList());
}
List<UserMenuModel> list = JsonUtil.getJsonToList(ListToTreeUtil.treeWhere(buttonList, buttonListAll), UserMenuModel.class);
List<SumTree<UserMenuModel>> menuAll = TreeDotUtils.convertListToTreeDot(list, "-1");
List<AppMenuListVO> data = JsonUtil.getJsonToList(menuAll, AppMenuListVO.class);
ListVO listVO = new ListVO();
listVO.setList(data);
return ActionResult.success(listVO);
}
}

@ -0,0 +1,62 @@
package jnpf.controller;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.Operation;
import jnpf.base.ActionResult;
import jnpf.model.AppUserInfoVO;
import jnpf.model.AppUsersVO;
import jnpf.model.AppUserInfoVO;
import jnpf.service.AppService;
import org.springframework.beans.factory.annotation.Autowired;
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 JNPF
* @version V3.1.0
* @copyright https://www.jnpfsoft.com
* @date 2021-07-08
*/
@Tag(name = "app用户信息", description = "User")
@RestController
@RequestMapping("/api/app/User")
public class AppUserController {
@Autowired
private AppService appService;
/**
*
*
* @return
*/
@Operation(summary = "用户信息")
@GetMapping
public ActionResult<AppUsersVO> getInfo() {
AppUsersVO userAllVO = appService.userInfo();
return ActionResult.success(userAllVO);
}
/**
*
*
* @param id
* @return
*/
@Operation(summary = "通讯录详情")
@GetMapping("/{id}")
@Parameters({
@Parameter(name = "id", description = "主键", required = true),
})
public ActionResult<AppUserInfoVO> userInfo(@PathVariable("id") String id) {
AppUserInfoVO userInfoVO = appService.getInfo(id);
return ActionResult.success(userInfoVO);
}
}

@ -0,0 +1,45 @@
package jnpf.controller;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import jnpf.base.ActionResult;
import jnpf.util.NoDataSourceBind;
import jnpf.base.service.SysconfigService;
import org.apache.commons.collections4.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
/**
* AppVersion
*
* @author JNPF
* @version: V3.1.0
* @copyright
* @date 2022/3/31 11:26
*/
@Tag(name = "获取APP版本号", description = "AppVersion")
@RestController
@RequestMapping("/api/app")
public class AppVersionController {
@Autowired
private SysconfigService sysconfigService;
/**
*
*
* @return
*/
@NoDataSourceBind()
@Operation(summary = "判断是否需要验证码")
@GetMapping("/Version")
public ActionResult getAppVersion() {
String sysVersion = sysconfigService.getSysInfo().getSysVersion();
Map<String, String> map = new HashedMap<>();
map.put("sysVersion", sysVersion);
return ActionResult.success(map);
}
}

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>jnpf-app</artifactId>
<groupId>com.jnpf</groupId>
<version>3.5.0-RELEASE</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jnpf-app-entity</artifactId>
<dependencies>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-common-all</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

@ -0,0 +1,46 @@
package jnpf.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import jnpf.base.entity.SuperExtendEntity;
import lombok.Data;
import java.util.Date;
/**
* app
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2021-08-08
*/
@Data
@TableName("base_app_data")
public class AppDataEntity extends SuperExtendEntity.SuperExtendDEEntity<String> {
/**
*
*/
@TableField("f_object_type")
private String objectType;
/**
*
*/
@TableField("f_object_id")
private String objectId;
/**
*
*/
@TableField("f_object_data")
private String objectData;
/**
* id
*/
@TableField("f_system_id")
private String systemId;
}

@ -0,0 +1,30 @@
package jnpf.model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* app
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2021-07-08
*/
@Data
@Schema(description = "常用模型")
public class AppDataCrForm {
@NotBlank(message = "必填")
@Schema(description = "应用类型")
private String objectType;
@NotBlank(message = "必填")
@Schema(description = "应用主键")
private String objectId;
@Schema(description = "数据")
private String objectData;
@Schema(description = "系统主键")
private String systemId;
}

@ -0,0 +1,40 @@
package jnpf.model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
/**
* app
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2021-07-08
*/
@Data
@Schema(description = "常用模型")
public class AppDataListAllVO {
@Schema(description = "主键")
private String id;
@Schema(description = "是否有下级菜单")
private Boolean hasChildren;
@Schema(description = "菜单名称")
private String fullName;
@Schema(description = " 图标")
private String icon;
@Schema(description = "链接地址")
private String urlAddress;
@Schema(description = "父级id")
private String parentId;
@Schema(description = "菜单类型",example = "1")
private Integer type;
@Schema(description = "扩展字段")
private String propertyJson;
@Schema(description = "是否常用")
private Boolean isData;
@Schema(description = "下级菜单列表")
private List<AppDataListAllVO> children;
}

@ -0,0 +1,24 @@
package jnpf.model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* app
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2021-07-08
*/
@Data
@Schema(description = "常用模型")
public class AppDataListVO {
@Schema(description = "主键")
private String id;
@Schema(description = "应用主键")
private String objectId;
@Schema(description = "数据")
private String objectData;
}

@ -0,0 +1,30 @@
package jnpf.model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* app
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2021-07-08
*/
@Data
@Schema(description = "常用模型")
public class AppFlowListAllVO {
@Schema(description = "主键")
private String id;
@Schema(description = "名称")
private String fullName;
@Schema(description = "图标")
private String icon;
@Schema(description = "图标背景色")
private String iconBackground;
@Schema(description = "编码")
private String enCode;
@Schema(description = "是否常用")
private Boolean isData;
}

@ -0,0 +1,40 @@
package jnpf.model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
/**
* app
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2021-07-08
*/
@Data
@Schema(description = "常用模型")
public class AppMenuListVO {
@Schema(description = "主键")
private String id;
@Schema(description = "是否有下级菜单")
private Boolean hasChildren;
@Schema(description = "父级id")
private String parentId;
@Schema(description = "菜单名称")
private String fullName;
@Schema(description = " 图标")
private String icon;
@Schema(description = "是否常用")
private Boolean isData;
@Schema(description = "链接地址")
private String urlAddress;
@Schema(description = "菜单类型",example = "1")
private Integer type;
@Schema(description = "扩展字段")
private String propertyJson;
@Schema(description = "下级菜单列表")
private List<AppMenuListVO> children;
}

@ -0,0 +1,22 @@
package jnpf.model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* app
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2021-08-08
*/
@Data
@Schema(description = "常用模型")
public class AppPositionVO {
@Schema(description = "岗位id")
private String id;
@Schema(description = "岗位名称")
private String name;
}

@ -0,0 +1,37 @@
package jnpf.model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2021/3/12 15:31
*/
@Data
@Schema(description = "常用模型")
public class AppUserInfoVO {
@Schema(description = "主键")
private String id;
@Schema(description = "户名")
private String realName;
@Schema(description = "部门名称")
private String organizeName;
@Schema(description = "账号")
private String account;
@Schema(description = "岗位名称")
private String positionName;
@Schema(description = "办公电话")
private String telePhone;
@Schema(description = "办公座机")
private String landline;
@Schema(description = "手机号码")
private String mobilePhone;
@Schema(description = "用户头像")
private String headIcon;
@Schema(description = "邮箱")
private String email;
}

@ -0,0 +1,50 @@
package jnpf.model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
/**
*
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2021-07-08
*/
@Data
@Schema(description = "常用模型")
public class AppUsersVO {
@Schema(description = "用户id")
private String userId;
@Schema(description = "用户账号")
private String userAccount;
@Schema(description = "用户姓名")
private String userName;
@Schema(description = "用户头像")
private String headIcon;
@Schema(description = "组织主键")
private String organizeId;
@Schema(description = "组织名称")
private String organizeName;
@Schema(description = "角色主键")
private String roleId;
@Schema(description = "角色名称")
private String roleName;
@Schema(description = "性别")
private Integer gender;
@Schema(description = "岗位")
private List<AppPositionVO> positionIds;
@Schema(description = "生日")
private Long birthday;
@Schema(description = "手机")
private String mobilePhone;
@Schema(description = "邮箱")
private String email;
@Schema(description = "直属主管")
private String manager;
}

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>jnpf-java-boot</artifactId>
<groupId>com.jnpf</groupId>
<version>3.5.0-RELEASE</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jnpf-app</artifactId>
<packaging>pom</packaging>
<modules>
<module>jnpf-app-entity</module>
<module>jnpf-app-biz</module>
<module>jnpf-app-controller</module>
</modules>
</project>

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>jnpf-java-boot</artifactId>
<groupId>com.jnpf</groupId>
<version>3.5.0-RELEASE</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jnpf-example</artifactId>
<packaging>pom</packaging>
<modules>
<module>jnpf-example-entity</module>
<module>jnpf-example-biz</module>
<module>jnpf-example-controller</module>
</modules>
</project>

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>jnpf-java-boot</artifactId>
<groupId>com.jnpf</groupId>
<version>3.5.0-RELEASE</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jnpf-exception</artifactId>
<dependencies>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-common-auth</artifactId>
</dependency>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-common-all</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-oauth-entity</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

@ -0,0 +1,144 @@
package jnpf.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import jnpf.base.controller.SuperController;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import jnpf.base.ActionResult;
import jnpf.base.PaginationTime;
import jnpf.base.vo.PaginationVO;
import jnpf.constant.MsgCode;
import jnpf.entity.LogEntity;
import jnpf.model.*;
import jnpf.service.LogService;
import jnpf.util.JsonUtil;
import jnpf.util.StringUtil;
import org.apache.commons.collections4.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
*
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2019927 9:18
*/
@Tag(name = "系统日志", description = "Log")
@RestController
@RequestMapping("/api/system/Log")
public class LogController extends SuperController<LogService, LogEntity> {
@Autowired
private LogService logService;
/**
*
*
* @param category 12.访3.4.5.
* @return
*/
@Operation(summary = "获取系统日志列表")
@Parameters({
@Parameter(name = "category", description = "分类", required = true)
})
@SaCheckPermission("system.log")
@GetMapping("/{category}")
public ActionResult getInfoList(@PathVariable("category") String category, PaginationLogModel paginationTime) {
if (StringUtil.isEmpty(category) || !StringUtil.isNumeric(category)) {
return ActionResult.fail("获取失败");
}
List<LogEntity> list = logService.getList(Integer.parseInt(category), paginationTime);
PaginationVO paginationVO = JsonUtil.getJsonToBean(paginationTime, PaginationVO.class);
int i = Integer.parseInt(category);
switch (i) {
case 1:
List<LoginLogVO> loginLogVOList = JsonUtil.getJsonToList(list, LoginLogVO.class);
return ActionResult.page(loginLogVOList, paginationVO);
case 3:
List<HandleLogVO> handleLogVOList = JsonUtil.getJsonToList(list, HandleLogVO.class);
for (int j = 0; j < handleLogVOList.size(); j++) {
handleLogVOList.get(j).setJson(list.get(j).getJsons());
}
return ActionResult.page(handleLogVOList, paginationVO);
case 4:
List<ErrorLogVO> errorLogVOList = JsonUtil.getJsonToList(list, ErrorLogVO.class);
for (int j = 0; j < errorLogVOList.size(); j++) {
errorLogVOList.get(j).setJson(list.get(j).getJsons());
}
return ActionResult.page(errorLogVOList, paginationVO);
case 5:
List<RequestLogVO> requestLogVOList = JsonUtil.getJsonToList(list, RequestLogVO.class);
return ActionResult.page(requestLogVOList, paginationVO);
default:
return ActionResult.fail("获取失败");
}
}
/**
*
*
* @param logDelForm
* @return
*/
@Operation(summary = "批量删除系统日志")
@Parameters({
@Parameter(name = "logDelForm", description = "批量删除日志模型", required = true)
})
@SaCheckPermission("system.log")
@DeleteMapping
public ActionResult delete(@RequestBody LogDelForm logDelForm) {
boolean flag = logService.delete(logDelForm.getIds());
if (flag == false) {
return ActionResult.fail(MsgCode.FA003.get());
}
return ActionResult.success(MsgCode.SU003.get());
}
/**
*
*
* @param type
* @return
*/
@Operation(summary = "一键清空操作日志")
@Parameters({
@Parameter(name = "type", description = "分类", required = true)
})
@SaCheckPermission("system.log")
@DeleteMapping("/{type}")
public ActionResult deleteHandelLog(@PathVariable("type") String type) {
logService.deleteHandleLog(type);
return ActionResult.success(MsgCode.SU005.get());
}
/**
*
*
* @return
*/
@Operation(summary = "获取菜单名")
@SaCheckPermission("system.log")
@GetMapping("/ModuleName")
public ActionResult<List<Map<String, String>>> moduleName() {
List<Map<String, String>> list = new ArrayList<> (16);
Set<String> set = logService.queryList();
for (String moduleName : set) {
Map<String, String> map = new HashedMap<>(1);
map.put("moduleName", moduleName);
list.add(map);
}
return ActionResult.success(list);
}
}

@ -0,0 +1,107 @@
package jnpf.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import jnpf.base.entity.SuperExtendEntity;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
*
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2019927 9:18
*/
@Data
@TableName("base_sys_log")
public class LogEntity extends SuperExtendEntity.SuperExtendDescriptionEntity<String> implements Serializable {
/**
*
*/
@TableField("F_USER_ID")
private String userId;
/**
*
*/
@TableField("F_USER_NAME")
private String userName;
/**
*
*/
@TableField("F_TYPE")
private Integer type;
/**
*
*/
@TableField("F_LEVEL")
private Integer levels;
/**
* IP
*/
@TableField("F_IP_ADDRESS")
private String ipAddress;
/**
* IP
*/
@TableField("F_IP_ADDRESS_NAME")
private String ipAddressName;
/**
*
*/
@TableField("F_REQUEST_URL")
private String requestUrl;
/**
*
*/
@TableField("F_REQUEST_METHOD")
private String requestMethod;
/**
*
*/
@TableField("F_REQUEST_DURATION")
private Integer requestDuration;
/**
*
*/
@TableField("F_JSON")
private String jsons;
/**
*
*/
@TableField("F_PLAT_FORM")
private String platForm;
/**
*
*/
@TableField("F_MODULE_ID")
private String moduleId;
/**
*
*/
@TableField("F_MODULE_NAME")
private String moduleName;
/**
* Id
*/
@TableField("F_OBJECT_ID")
private String objectId;
}

@ -0,0 +1,76 @@
package jnpf.enums;
/**
*
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2019926 9:18
*/
public enum LogLevelEnum {
/**
*
*/
Error(0,"错误"),
/**
*
*/
Success(1,"成功"),
/**
*
*/
Warning(2,"警告");
private int code;
private String message;
LogLevelEnum(int code, String message){
this.code = code;
this.message = message;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
/**
* code
* @return
*/
public static String getMessageByCode(Integer code) {
for (LogLevelEnum status : LogLevelEnum.values()) {
if (status.getCode().equals(code)) {
return status.message;
}
}
return null;
}
/**
* code
* @return
*/
public static LogLevelEnum getByCode(Integer code) {
for (LogLevelEnum status : LogLevelEnum.values()) {
if (status.getCode().equals(code)) {
return status;
}
}
return null;
}
}

@ -0,0 +1,84 @@
package jnpf.enums;
/**
*
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2019926 9:18
*/
public enum LogSortEnum {
/**
*
*/
Login(1, "登录"),
/**
* 访
*/
Visit(2, "访问"),
/**
*
*/
Operate(3, "操作"),
/**
*
*/
Exception(4, "异常"),
/**
*
*/
Request(5, "请求");
private int code;
private String message;
LogSortEnum(int code, String message) {
this.code = code;
this.message = message;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
/**
* code
*
* @return
*/
public static String getMessageByCode(Integer code) {
for (LogSortEnum status : LogSortEnum.values()) {
if (status.getCode().equals(code)) {
return status.message;
}
}
return null;
}
/**
* code
*
* @return
*/
public static LogSortEnum getByCode(Integer code) {
for (LogSortEnum status : LogSortEnum.values()) {
if (status.getCode().equals(code)) {
return status;
}
}
return null;
}
}

@ -0,0 +1,281 @@
package jnpf.exception;
import cn.dev33.satoken.exception.SameTokenInvalidException;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.exception.NotRoleException;
import com.alibaba.fastjson.JSON;
import jnpf.base.ActionResult;
import jnpf.base.ActionResultCode;
import jnpf.base.LogSortEnum;
import jnpf.base.UserInfo;
import jnpf.config.ConfigValueUtil;
import jnpf.database.util.NotTenantPluginHolder;
import jnpf.entity.LogEntity;
import jnpf.service.LogService;
import jnpf.util.*;
import jnpf.util.data.DataSourceContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2021/3/16 10:10
*/
@Slf4j
@Controller
@ControllerAdvice
public class ResultException extends BasicErrorController {
@Autowired
private UserProvider userProvider;
@Autowired
private LogService logService;
@Autowired
private ConfigValueUtil configValueUtil;
public ResultException(){
super(new DefaultErrorAttributes(), new ErrorProperties());
}
@ResponseBody
@ExceptionHandler(value = LoginException.class)
public ActionResult loginException(LoginException e) {
ActionResult result = ActionResult.fail(ActionResultCode.Fail.getCode(), e.getMessage());
return result;
}
@ResponseBody
@ExceptionHandler(value = ImportException.class)
public ActionResult loginException(ImportException e) {
ActionResult result = ActionResult.fail(ActionResultCode.Fail.getCode(), e.getMessage());
return result;
}
// @ResponseBody
// @ExceptionHandler(value = FileNotException.class)
// public ActionResult loginException(FileNotException e) {
// ActionResult result = ActionResult.fail(ActionResultCode.Fail.getCode(), "文件不存在");
// return result;
// }
/**
*
*
* @param e
* @return
*/
@ResponseBody
@ExceptionHandler(value = DataException.class)
public ActionResult dataException(DataException e) {
ActionResult result = ActionResult.fail(ActionResultCode.Fail.getCode(), e.getMessage());
return result;
}
///
// @ResponseBody
// @ExceptionHandler(value = SQLSyntaxErrorException.class)
// public ActionResult sqlException(SQLSyntaxErrorException e) {
// ActionResult result;
// log.error(e.getMessage());
// e.printStackTrace();
// if (e.getMessage().contains("Unknown database")) {
// printLog(e, "请求失败");
// result = ActionResult.fail(ActionResultCode.Fail.getCode(), "请求失败");
// } else {
// printLog(e, "数据库异常");
// result = ActionResult.fail(ActionResultCode.Fail.getCode(), "数据库异常");
// }
// return result;
// }
//
// @ResponseBody
// @ExceptionHandler(value = SQLServerException.class)
// public ActionResult sqlServerException(SQLServerException e) {
// ActionResult result;
// printLog(e, "系统异常");
// if (e.getMessage().contains("将截断字符串")) {
// printLog(e, "某个字段字符长度超过限制,请检查。");
// result = ActionResult.fail(ActionResultCode.Fail.getCode(), "某个字段字符长度超过限制,请检查。");
// } else {
// log.error(e.getMessage());
// printLog(e, "数据库异常,请检查。");
// result = ActionResult.fail(ActionResultCode.Fail.getCode(), "数据库异常,请检查。");
// }
// return result;
// }
@ResponseBody
@ExceptionHandler(value = MethodArgumentNotValidException.class)
public ActionResult methodArgumentNotValidException(MethodArgumentNotValidException e) {
Map<String, String> map = new HashMap<>(16);
List<ObjectError> allErrors = e.getBindingResult().getAllErrors();
for (int i = 0; i < allErrors.size(); i++) {
String s = allErrors.get(i).getCodes()[0];
//用分割的方法得到字段名
String[] parts = s.split("\\.");
String part1 = parts[parts.length - 1];
map.put(part1, allErrors.get(i).getDefaultMessage());
}
String json = JSON.toJSONString(map);
ActionResult result = ActionResult.fail(ActionResultCode.ValidateError.getCode(), json);
printLog(e, "字段验证异常");
return result;
}
@ResponseBody
@ExceptionHandler(value = WorkFlowException.class)
public ActionResult workFlowException(WorkFlowException e) {
if (e.getCode() == 200) {
List<Map<String, Object>> list = JsonUtil.getJsonToListMap(e.getMessage());
return ActionResult.success(list);
} else {
return ActionResult.fail(e.getMessage());
}
}
@ResponseBody
@ExceptionHandler(value = WxErrorException.class)
public ActionResult wxErrorException(WxErrorException e) {
return ActionResult.fail(e.getError().getErrorCode(), "操作过于频繁");
}
@ResponseBody
@ExceptionHandler(value = ServletException.class)
public void exception(ServletException e) throws Exception {
log.error("系统异常:" + e.getMessage(), e);
printLog(e, "系统异常");
throw new Exception();
}
@ResponseBody
@ExceptionHandler(value = Exception.class)
public ActionResult exception(Exception e) {
log.error("系统异常:" + e.getMessage(), e);
printLog(e, "系统异常");
return ActionResult.fail(ActionResultCode.Fail.getCode(), "系统异常");
}
/**
*
*/
@ResponseBody
@ExceptionHandler(NotPermissionException.class)
public ActionResult<Void> handleNotPermissionException(NotPermissionException e) {
return ActionResult.fail(ActionResultCode.Fail.getCode(), "没有访问权限,请联系管理员授权");
}
/**
*
*/
@ResponseBody
@ExceptionHandler(NotRoleException.class)
public ActionResult<Void> handleNotRoleException(NotRoleException e) {
return ActionResult.fail(ActionResultCode.ValidateError.getCode(), "没有访问权限,请联系管理员授权");
}
/**
*
*/
@ResponseBody
@ExceptionHandler(NotLoginException.class)
public ActionResult<Void> handleNotLoginException(NotLoginException e) {
return ActionResult.fail(ActionResultCode.SessionOverdue.getCode(), "认证失败,无法访问系统资源");
}
/**
*
*/
@ResponseBody
@ExceptionHandler(SameTokenInvalidException.class)
public ActionResult<Void> handleIdTokenInvalidException(SameTokenInvalidException e) {
return ActionResult.fail(ActionResultCode.SessionOverdue.getCode(), "无效内部认证,无法访问系统资源");
}
private void printLog(Exception e, String module) {
try {
UserInfo userInfo = userProvider.get();
if (userInfo.getId() == null) {
e.printStackTrace();
return;
}
//接口错误将不会进入数据库切源拦截器需要手动设置
if (configValueUtil.isMultiTenancy() && DataSourceContextHolder.getDatasourceId() == null) {
DataSourceContextHolder.setDatasource(userInfo.getTenantId(), userInfo.getTenantDbConnectionString(), userInfo.isAssignDataSource());
}
LogEntity entity = new LogEntity();
entity.setId(RandomUtil.uuId());
entity.setType(LogSortEnum.Operate.getCode());
entity.setUserId(userInfo.getUserId());
entity.setUserName(userInfo.getUserName() + "/" + userInfo.getUserAccount());
if (!ServletUtil.getIsMobileDevice()) {
String modelName = module;
entity.setModuleName(modelName);
}
StringBuilder sb = new StringBuilder();
sb.append(e.toString() + "\n");
StackTraceElement[] stackArray = e.getStackTrace();
for (int i = 0; i < stackArray.length; i++) {
StackTraceElement element = stackArray[i];
sb.append(element.toString() + "\n");
}
entity.setJsons(sb.toString());
entity.setRequestUrl(ServletUtil.getRequest().getServletPath());
entity.setRequestMethod(ServletUtil.getRequest().getMethod());
entity.setType(4);
entity.setUserId(userInfo.getUserId());
entity.setIpAddress(IpUtil.getIpAddr());
entity.setCreatorTime(new Date());
entity.setPlatForm(ServletUtil.getUserAgent());
if (configValueUtil.isMultiTenancy() && StringUtil.isEmpty(DataSourceContextHolder.getDatasourceId())) {
log.error("请求异常, 无登陆租户:" + ReflectionUtil.toString(entity), e);
} else {
logService.save(entity);
}
}catch (Exception g){
log.error(g.getMessage());
}finally {
UserProvider.clearLocalUser();
TenantProvider.clearBaseSystemIfo();
DataSourceContextHolder.clearDatasourceType();
NotTenantPluginHolder.clearNotSwitchFlag();
}
}
/**
* JSON
*/
@Override
@RequestMapping
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
HttpStatus status = getStatus(request);
if (status == HttpStatus.NOT_FOUND) {
return new ResponseEntity<>(status);
}
return super.error(request);
}
}

@ -0,0 +1,18 @@
package jnpf.mapper;
import jnpf.base.mapper.SuperMapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import jnpf.entity.LogEntity;
/**
*
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2019927 9:18
*/
public interface LogMapper extends SuperMapper<LogEntity> {
}

@ -0,0 +1,27 @@
package jnpf.model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2021/3/16 10:10
*/
@Data
public class ErrorLogVO {
@Schema(description = "创建用户")
private String userName;
@Schema(description = "创建时间",example = "1")
private Long creatorTime;
@Schema(description = "IP")
private String ipaddress;
@Schema(description = "id")
private String id;
@Schema(description = "异常功能")
private String moduleName;
@Schema(description = "异常描述")
private String json;
}

@ -0,0 +1,63 @@
package jnpf.model;
import lombok.Data;
import java.io.Serializable;
/**
*
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2021/3/16 10:10
*/
@Data
public class HandleLogVO implements Serializable {
/**
* id
*/
public String id;
/**
*
*/
public Long creatorTime;
/**
*
*/
public String userName;
/**
* IP
*/
public String ipaddress;
/**
*
*/
public String platForm;
/**
*
*/
public String moduleName;
/**
*
*/
public String requestMethod;
/**
*
*/
public int requestDuration;
/**
*
*/
public String json;
}

@ -0,0 +1,18 @@
package jnpf.model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2021/3/16 10:10
*/
@Data
public class LogDelForm {
@Schema(description = "id集合")
private String[] ids;
}

@ -0,0 +1,27 @@
package jnpf.model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2021/3/16 10:10
*/
@Data
public class LoginLogVO {
@Schema(description = "id")
private String id;
@Schema(description = "创建时间",example = "1")
private Long creatorTime;
@Schema(description = "登陆用户")
private String userName;
@Schema(description = "登陆IP")
private String ipaddress;
@Schema(description = "登陆平台")
private String platForm;
@Schema(description = "登陆日志摘要")
private String abstracts;
}

@ -0,0 +1,34 @@
package jnpf.model;
import jnpf.base.PaginationTime;
import lombok.Data;
/**
*
*
* @author JNPF
* @version: V3.1.0
* @copyright
* @date 2022/3/18 9:50
*/
@Data
public class PaginationLogModel extends PaginationTime {
/**
*
*/
private String userName;
/**
* ip
*/
private String ipaddress;
/**
*
*/
private String moduleName;
/**
*
*/
private String requestMethod;
}

@ -0,0 +1,31 @@
package jnpf.model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2021/3/16 10:10
*/
@Data
public class RequestLogVO {
@Schema(description = "id")
private String id;
@Schema(description = "请求时间",example = "1")
private Long creatorTime;
@Schema(description = "请求用户名")
private String userName;
@Schema(description = "请求IP")
private String ipaddress;
@Schema(description = "请求设备")
private String platForm;
@Schema(description = "请求地址")
private String requestURL;
@Schema(description = "请求类型")
private String requestMethod;
@Schema(description = "请求耗时",example = "1")
private Long requestDuration;
}

@ -0,0 +1,83 @@
package jnpf.service;
import jnpf.base.service.SuperService;
import com.baomidou.mybatisplus.extension.service.IService;
import jnpf.base.PaginationTime;
import jnpf.entity.LogEntity;
import jnpf.model.PaginationLogModel;
import jnpf.model.UserLogForm;
import java.util.List;
import java.util.Set;
/**
*
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2019927 9:18
*/
public interface LogService extends SuperService<LogEntity> {
/**
*
*
* @param userLogForm
* @return
*/
List<LogEntity> getList(UserLogForm userLogForm);
/**
*
*
* @param category
* @param paginationTime
* @return
*/
List<LogEntity> getList(int category, PaginationLogModel paginationTime);
/**
*
*
* @param id
* @return
*/
LogEntity getInfo(String id);
/**
*
* @param ids
* @return
*/
boolean delete(String[] ids);
/**
*
*
* @param userId Id
* @param userName
* @param abstracts
*/
void writeLogAsync(String userId, String userName, String abstracts);
/**
*
*
* @param logEntity
*/
void writeLogAsync(LogEntity logEntity);
/**
*
*/
void deleteHandleLog(String type);
/**
*
*
* @return
*/
Set<String> queryList();
}

@ -0,0 +1,182 @@
package jnpf.service.impl;
import jnpf.base.service.SuperServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jnpf.base.PaginationTime;
import jnpf.base.UserInfo;
import jnpf.entity.LogEntity;
import jnpf.enums.LogSortEnum;
import jnpf.mapper.LogMapper;
import jnpf.model.PaginationLogModel;
import jnpf.model.UserLogForm;
import jnpf.service.LogService;
import jnpf.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import java.util.*;
import java.util.stream.Collectors;
/**
*
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2019927 9:18
*/
@Service
public class LogServiceImpl extends SuperServiceImpl<LogMapper, LogEntity> implements LogService {
@Autowired
private UserProvider userProvider;
@Override
public List<LogEntity> getList(int category, PaginationLogModel paginationTime) {
UserInfo userInfo = userProvider.get();
QueryWrapper<LogEntity> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(LogEntity::getType, category);
//日期范围近7天、近1月、近3月、自定义
String startTime = paginationTime.getStartTime() != null ? paginationTime.getStartTime() : null;
String endTime = paginationTime.getEndTime() != null ? paginationTime.getEndTime() : null;
if (!StringUtil.isEmpty(startTime) && !StringUtil.isEmpty(endTime)) {
Date startTimes = DateUtil.stringToDate(DateUtil.daFormatYmd(Long.parseLong(startTime)) + " 00:00:00");
Date endTimes = DateUtil.stringToDate(DateUtil.daFormatYmd(Long.parseLong(endTime)) + " 23:59:59");
queryWrapper.lambda().ge(LogEntity::getCreatorTime, startTimes).le(LogEntity::getCreatorTime, endTimes);
}
//关键字用户、IP地址、功能名称
String keyWord = paginationTime.getKeyword() != null ? paginationTime.getKeyword() : null;
if (!StringUtil.isEmpty(keyWord)) {
queryWrapper.lambda().and(
t -> t.like(LogEntity::getUserName, keyWord)
.or().like(LogEntity::getIpAddress, keyWord)
.or().like(LogEntity::getModuleName, keyWord)
);
}
//用户Id
String userId = userInfo.getUserId() != null ? userInfo.getUserId() : null;
String userAccount = userInfo.getUserAccount() != null ? userInfo.getUserAccount() : null;
if (!StringUtil.isEmpty(userId) && !StringUtil.isEmpty(userAccount)) {
if (!userInfo.getIsAdministrator()){
queryWrapper.lambda().and(
t -> t.eq(LogEntity::getUserId, userId)
.or().eq(LogEntity::getUserId, userAccount)
);
}
}
// 操作ip
if (StringUtil.isNotEmpty(paginationTime.getIpaddress())) {
queryWrapper.lambda().like(LogEntity::getIpAddress, paginationTime.getIpaddress());
}
// 操作模块
if (StringUtil.isNotEmpty(paginationTime.getModuleName())) {
queryWrapper.lambda().like(LogEntity::getModuleName, paginationTime.getModuleName());
}
// 操作类型
if (StringUtil.isNotEmpty(paginationTime.getRequestMethod())) {
queryWrapper.lambda().eq(LogEntity::getRequestMethod, paginationTime.getRequestMethod());
}
//排序
queryWrapper.lambda().orderByDesc(LogEntity::getCreatorTime);
Page<LogEntity> page = new Page<>(paginationTime.getCurrentPage(), paginationTime.getPageSize());
IPage<LogEntity> userPage = this.page(page, queryWrapper);
return paginationTime.setData(userPage.getRecords(), page.getTotal());
}
@Override
public List<LogEntity> getList(UserLogForm userLogForm) {
UserInfo userInfo = userProvider.get();
QueryWrapper<LogEntity> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(LogEntity::getType, userLogForm.getCategory());
//日期范围近7天、近1月、近3月、自定义
if (!StringUtil.isEmpty(userLogForm.getStartTime()) && !StringUtil.isEmpty(userLogForm.getEndTime())) {
Date startTimes = DateUtil.stringToDate(DateUtil.daFormatYmd(Long.parseLong(userLogForm.getStartTime())) + " 00:00:00");
Date endTimes = DateUtil.stringToDate(DateUtil.daFormatYmd(Long.parseLong(userLogForm.getEndTime())) + " 23:59:59");
queryWrapper.lambda().ge(LogEntity::getCreatorTime, startTimes).le(LogEntity::getCreatorTime, endTimes);
}
//关键字用户、IP地址、功能名称
String keyWord = userLogForm.getKeyword();
if (!StringUtil.isEmpty(keyWord)) {
queryWrapper.lambda().and(
t -> t.like(LogEntity::getUserName, keyWord)
.or().like(LogEntity::getIpAddress, keyWord)
.or().like(LogEntity::getModuleName, keyWord)
);
}
//用户Id
String userId = userInfo.getUserId() != null ? userInfo.getUserId() : null;
String userAccount = userInfo.getUserAccount() != null ? userInfo.getUserAccount() : null;
if (!StringUtil.isEmpty(userId) && !StringUtil.isEmpty(userAccount)) {
queryWrapper.lambda().and(
t -> t.eq(LogEntity::getUserId, userId)
.or().eq(LogEntity::getUserId, userAccount)
);
}
//排序
if (StringUtil.isEmpty(userLogForm.getSidx())) {
queryWrapper.lambda().orderByDesc(LogEntity::getCreatorTime);
} else {
queryWrapper = "asc".equals(userLogForm.getSort().toLowerCase()) ? queryWrapper.orderByAsc(userLogForm.getSidx()) : queryWrapper.orderByDesc(userLogForm.getSidx());
}
Page<LogEntity> page = new Page<>(userLogForm.getCurrentPage(), userLogForm.getPageSize());
IPage<LogEntity> userPage = this.page(page, queryWrapper);
return userLogForm.setData(userPage.getRecords(), page.getTotal());
}
@Override
public LogEntity getInfo(String id) {
QueryWrapper<LogEntity> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(LogEntity::getId, id);
return this.getOne(queryWrapper);
}
@Override
@DSTransactional
public boolean delete(String[] ids) {
if (ids.length > 0) {
QueryWrapper<LogEntity> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().in(LogEntity::getId, ids);
return this.remove(queryWrapper);
}
return false;
}
@Override
public void writeLogAsync(String userId, String userName, String abstracts) {
LogEntity entity = new LogEntity();
entity.setId(RandomUtil.uuId());
entity.setUserId(userId);
entity.setUserName(userName);
entity.setDescription(abstracts);
entity.setRequestUrl(ServletUtil.getServletPath());
entity.setRequestMethod(ServletUtil.getRequest().getMethod());
entity.setIpAddress(IpUtil.getIpAddr());
entity.setPlatForm(ServletUtil.getUserAgent());
entity.setType(LogSortEnum.Login.getCode());
this.save(entity);
}
@Override
public void writeLogAsync(LogEntity entity) {
entity.setId(RandomUtil.uuId());
this.save(entity);
}
@Override
public void deleteHandleLog(String type) {
QueryWrapper<LogEntity> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(LogEntity::getType, Integer.valueOf(type));
this.remove(queryWrapper);
}
@Override
public Set<String> queryList() {
QueryWrapper<LogEntity> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(LogEntity::getType, 3);
return this.list(queryWrapper).size() > 0 ? this.list(queryWrapper).stream().map(t -> t.getModuleName()).collect(Collectors.toSet()) : new HashSet<>(16);
}
}

@ -0,0 +1,78 @@
package jnpf.util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import jnpf.constant.MsgCode;
import jnpf.exception.DataException;
/**
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2021/3/16 10:10
*/
public class JsonUtilEx {
/**
* javaJSON,
* @param object java
* @return JSON
*/
public static String getObjectToStringDateFormat(Object object,String dateFormat) {
return JSON.toJSONStringWithDateFormat(object, dateFormat,SerializerFeature.WriteMapNullValue);
}
// /**
// * 功能描述把JSON数据转换成指定的java对象列表
// * @param jsonData JSON数据
// * @param clazz 指定的java对象
// * @return List<T>
// */
// public static <T> List<T> getJsonToListStringDateFormat(String jsonData, Class<T> clazz,String dateFormat) {
// JSONArray jsonArray=JSONUtil.getJsonToJsonArray(jsonData);
// JSONArray newJsonArray=JSONUtil.getJsonToJsonArray(jsonData);
// for (int i = 0; i < jsonArray.size(); i++) {
// JSONObject jsonObject = jsonArray.getJSONObject(i);
// newJsonArray.add(JSON.toJSONStringWithDateFormat(jsonObject, dateFormat,SerializerFeature.WriteMapNullValue));
// }
// jsonData=JSONUtil.getObjectToString(newJsonArray);
// return JSON.parseArray(jsonData, clazz);
// }
//
// public static void main(String[] args) {
// Date date=new Date();
// String obk="[" +
// "{\"date\":\""+date+"\"},{\"date\":\"1603165505\"}" +
// "]";
// List<String> list1= getJsonToList(obk,String.class);
// List<String> list11= getJsonToListStringDateFormat(obk,String.class,"yyyy-MM-dd");
// System.out.println("aaa");
// }
/**
* javaJSON
* @param object java
* @return JSON
*/
public static String getObjectToString(Object object) {
return JSON.toJSONString(object, SerializerFeature.WriteMapNullValue);
}
/**
* JSONjava
* @param dto dto
* @param clazz java
* @return java
*/
public static <T> T getJsonToBeanEx(Object dto, Class<T> clazz) throws DataException {
if(dto==null){
throw new DataException(MsgCode.FA001.get());
}
return JSON.parseObject(getObjectToString(dto), clazz);
}
}

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>jnpf-extend</artifactId>
<groupId>com.jnpf</groupId>
<version>3.5.0-RELEASE</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jnpf-extend-biz</artifactId>
<dependencies>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-extend-entity</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-system-biz</artifactId>
<version>${project.version}</version>
</dependency>
<!-- PDF -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
</dependency>
</dependencies>
</project>

@ -0,0 +1,19 @@
package jnpf.mapper;
import jnpf.base.mapper.SuperMapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import jnpf.entity.BigDataEntity;
/**
*
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2019926 9:18
*/
public interface BigDataMapper extends SuperMapper<BigDataEntity> {
Integer maxCode();
}

@ -0,0 +1,17 @@
package jnpf.mapper;
import jnpf.base.mapper.SuperMapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import jnpf.entity.CustomerEntity;
/**
*
*
* V3.1.0
* https://www.jnpfsoft.com
* JNPF
* 2021-07-10 14:09:05
*/
public interface CustomerMapper extends SuperMapper<CustomerEntity> {
}

@ -0,0 +1,41 @@
package jnpf.mapper;
import jnpf.base.mapper.SuperMapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import jnpf.entity.DocumentEntity;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
*
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2019926 9:18
*/
public interface DocumentMapper extends SuperMapper<DocumentEntity> {
/**
*
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2021/3/15 10:26
*/
List<DocumentEntity> getShareTomeList(@Param("userId") String userId);
/**
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2021/3/15 10:26
*/
List<DocumentEntity> getChildList(@Param("folderId") String folderId);
int trashRecovery(@Param("id") String id);
}

@ -0,0 +1,18 @@
package jnpf.mapper;
import jnpf.base.mapper.SuperMapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import jnpf.entity.DocumentShareEntity;
/**
*
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2019926 9:18
*/
public interface DocumentShareMapper extends SuperMapper<DocumentShareEntity> {
}

@ -0,0 +1,18 @@
package jnpf.mapper;
import jnpf.base.mapper.SuperMapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import jnpf.base.entity.EmailConfigEntity;
/**
*
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2019926 9:18
*/
public interface EmailConfigMapper extends SuperMapper<EmailConfigEntity> {
}

@ -0,0 +1,17 @@
package jnpf.mapper;
import jnpf.base.mapper.SuperMapper;
import jnpf.entity.EmailReceiveEntity;
/**
*
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2019926 9:18
*/
public interface EmailReceiveMapper extends SuperMapper<EmailReceiveEntity> {
}

@ -0,0 +1,18 @@
package jnpf.mapper;
import jnpf.base.mapper.SuperMapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import jnpf.entity.EmailSendEntity;
/**
*
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2019926 9:18
*/
public interface EmailSendMapper extends SuperMapper<EmailSendEntity> {
}

@ -0,0 +1,18 @@
package jnpf.mapper;
import jnpf.base.mapper.SuperMapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import jnpf.entity.EmployeeEntity;
/**
*
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2019926 9:18
*/
public interface EmployeeMapper extends SuperMapper<EmployeeEntity> {
}

@ -0,0 +1,17 @@
package jnpf.mapper;
import jnpf.base.mapper.SuperMapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import jnpf.entity.OrderEntryEntity;
/**
*
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2019926 9:18
*/
public interface OrderEntryMapper extends SuperMapper<OrderEntryEntity> {
}

@ -0,0 +1,17 @@
package jnpf.mapper;
import jnpf.base.mapper.SuperMapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import jnpf.entity.OrderEntity;
/**
*
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2019926 9:18
*/
public interface OrderMapper extends SuperMapper<OrderEntity> {
}

@ -0,0 +1,17 @@
package jnpf.mapper;
import jnpf.base.mapper.SuperMapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import jnpf.entity.OrderReceivableEntity;
/**
*
*
* @author JNPF
* @version V3.1.0
* @copyright
* @date 2019926 9:18
*/
public interface OrderReceivableMapper extends SuperMapper<OrderReceivableEntity> {
}

@ -0,0 +1,18 @@
package jnpf.mapper;
import jnpf.base.mapper.SuperMapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import jnpf.entity.ProductEntryEntity;
/**
*
* base_productentry
* V3.1.0
* https://www.jnpfsoft.com
* JNPF
* 2021-07-10 10:40:59
*/
public interface ProductEntryMapper extends SuperMapper<ProductEntryEntity> {
}

@ -0,0 +1,17 @@
package jnpf.mapper;
import jnpf.base.mapper.SuperMapper;
import jnpf.entity.ProductGoodsEntity;
/**
*
*
* V3.1.0
* https://www.jnpfsoft.com
* JNPF
* 2021-07-10 15:57:50
*/
public interface ProductGoodsMapper extends SuperMapper<ProductGoodsEntity> {
}

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

Loading…
Cancel
Save