Compare commits
1 Commits
dev-cloud-
...
wuwuming
| Author | SHA1 | Date | |
|---|---|---|---|
| e3ac63f9f9 |
36
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
36
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
---
|
||||
name: Bug 报告
|
||||
about: 创建BUG报告以改进项目
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**BUG描述**
|
||||
关于BUG清晰简洁的描述。
|
||||
|
||||
**复现步骤**
|
||||
详细的复现步骤。
|
||||
|
||||
|
||||
**正确的行为**
|
||||
你认为这个修复这个BUG后,正确的行为应该是什么。
|
||||
|
||||
|
||||
**详细截图**
|
||||
如果可以的话,请添加截图以帮助调查BUG.
|
||||
|
||||
**桌面端:**
|
||||
- 操作系统: [例如. iOS]
|
||||
- 浏览器及版本 [例如. chrome 11]
|
||||
- 项目版本 [例如. 1.6.0]
|
||||
|
||||
**手机端:**
|
||||
- 设备: [例如. iPhone6]
|
||||
- 操作系统: [例如. iOS8.1]
|
||||
- 浏览器及版本 [例如.safari 8]
|
||||
- 项目版本 [例如. 1.6.0]
|
||||
|
||||
**Additional context**
|
||||
任何其他你认为有助于排查错误的信息,或者你的猜测。
|
||||
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: 功能建议
|
||||
about: 关于该项目的建议
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**您的功能请求是否与问题相关? 请描述。**
|
||||
清楚简明地描述问题所在。
|
||||
|
||||
**描述您想要的解决方案**
|
||||
对您所设想的问题的清晰简洁的描述。
|
||||
|
||||
**描述您考虑过的替代方案**
|
||||
对您考虑过的任何替代解决方案或功能的清晰简洁的描述。
|
||||
|
||||
**附加上下文**
|
||||
在此处添加有关功能请求的任何其他上下文或屏幕截图。
|
||||
116
.github/workflows/ci-cd.yml
vendored
Normal file
116
.github/workflows/ci-cd.yml
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
|
||||
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven
|
||||
|
||||
# 权限声明,确保 workflow 有权限写 checks 和 security-events
|
||||
permissions:
|
||||
contents: read
|
||||
checks: write
|
||||
security-events: write
|
||||
|
||||
name: Java CI with Maven
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
paths-ignore:
|
||||
- 'README.md'
|
||||
- 'LICENSE'
|
||||
- '.gitignore'
|
||||
- '.gitattributes'
|
||||
- 'picture'
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
strategy:
|
||||
matrix:
|
||||
java-version: ['8', '17', '21']
|
||||
fail-fast: false
|
||||
|
||||
name: Build with Java ${{ matrix.java-version }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up JDK ${{ matrix.java-version }}
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: ${{ matrix.java-version }}
|
||||
distribution: 'temurin'
|
||||
cache: 'maven'
|
||||
|
||||
# 优化Maven本地仓库缓存策略
|
||||
- name: Cache Maven packages
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.m2
|
||||
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}-${{ matrix.java-version }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-m2-
|
||||
|
||||
# 编译和测试:去掉failOnWarning,避免因为警告导致失败
|
||||
- name: Build and Test with Maven
|
||||
run: |
|
||||
mvn -B verify --file pom.xml -Dmaven.test.failure.ignore=false -Dgpg.skip -Dmaven.javadoc.skip=false
|
||||
env:
|
||||
MAVEN_OPTS: -Xmx4g -XX:MaxMetaspaceSize=1g
|
||||
MAVEN_CLI_OPTS: "--batch-mode --errors --fail-at-end --show-version"
|
||||
|
||||
- name: Publish Test Report
|
||||
uses: mikepenz/action-junit-report@v4
|
||||
if: success() || failure()
|
||||
with:
|
||||
report_paths: '**/target/surefire-reports/TEST-*.xml'
|
||||
detailed_summary: true
|
||||
include_passed: true
|
||||
fail_on_failure: true
|
||||
|
||||
- name: Run SonarQube Analysis
|
||||
if: matrix.java-version == '17' && github.event_name != 'pull_request' && github.ref == 'refs/heads/main'
|
||||
continue-on-error: true
|
||||
run: |
|
||||
if [[ ! -z "${{ secrets.SONAR_TOKEN }}" ]]; then
|
||||
mvn sonar:sonar \
|
||||
-Dsonar.projectKey=agileboot \
|
||||
-Dsonar.organization=${{ secrets.SONAR_ORGANIZATION || 'default' }} \
|
||||
-Dsonar.host.url=${{ secrets.SONAR_HOST_URL || 'https://sonarcloud.io' }} \
|
||||
-Dsonar.login=${{ secrets.SONAR_TOKEN }} \
|
||||
-Dsonar.java.source=${{ matrix.java-version }}
|
||||
else
|
||||
echo "Skipping SonarQube analysis - SONAR_TOKEN not configured"
|
||||
fi
|
||||
|
||||
# 上传构建产物,if-no-files-found 改为 warn
|
||||
- name: Upload Build Artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: agileboot-artifacts-java-${{ matrix.java-version }}
|
||||
path: |
|
||||
**/target/*.jar
|
||||
!**/target/original-*.jar
|
||||
retention-days: 5
|
||||
if-no-files-found: warn
|
||||
|
||||
# # 只在 Java 17 版本上更新依赖图(权限和token已修复)
|
||||
# - name: Update dependency graph
|
||||
# uses: advanced-security/maven-dependency-submission-action@v4
|
||||
# if: matrix.java-version == '17' && success()
|
||||
# with:
|
||||
# token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# # 发送构建状态通知
|
||||
# - name: Notify Build Status
|
||||
# if: always()
|
||||
# uses: rtCamp/action-slack-notify@v2.2.1
|
||||
# env:
|
||||
# SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK || '' }}
|
||||
# SLACK_CHANNEL: build-notifications
|
||||
# SLACK_COLOR: ${{ job.status }}
|
||||
# SLACK_TITLE: Build Status for Java ${{ matrix.java-version }}
|
||||
# SLACK_MESSAGE: 'Build ${{ job.status }} on Java ${{ matrix.java-version }}'
|
||||
BIN
.mvn/wrapper/maven-wrapper.jar
vendored
Normal file
BIN
.mvn/wrapper/maven-wrapper.jar
vendored
Normal file
Binary file not shown.
18
.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
18
.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.3/apache-maven-3.9.3-bin.zip
|
||||
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 valarchie
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -12,6 +12,7 @@ import org.springframework.context.annotation.ComponentScan;
|
||||
* http://www.network-science.de/ascii/
|
||||
* http://www.degraeve.com/img2txt.php
|
||||
* http://life.chacuo.net/convertfont2char
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
|
||||
@@ -21,11 +22,11 @@ public class AgileBootAdminApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AgileBootAdminApplication.class, args);
|
||||
String successMsg = " ____ _ _ __ _ _ \n"
|
||||
+ " / ___| | |_ __ _ _ __ | |_ _ _ _ __ ___ _ _ ___ ___ ___ ___ ___ / _| _ _ | || |\n"
|
||||
+ " \\___ \\ | __|/ _` || '__|| __| | | | || '_ \\ / __|| | | | / __|/ __|/ _ \\/ __|/ __|| |_ | | | || || |\n"
|
||||
+ " ___) || |_| (_| || | | |_ | |_| || |_) | \\__ \\| |_| || (__| (__| __/\\__ \\\\__ \\| _|| |_| || ||_|\n"
|
||||
+ " |____/ \\__|\\__,_||_| \\__| \\__,_|| .__/ |___/ \\__,_| \\___|\\___|\\___||___/|___/|_| \\__,_||_|(_)\n"
|
||||
+ " |_| ";
|
||||
+ " / ___| | |_ __ _ _ __ | |_ _ _ _ __ ___ _ _ ___ ___ ___ ___ ___ / _| _ _ | || |\n"
|
||||
+ " \\___ \\ | __|/ _` || '__|| __| | | | || '_ \\ / __|| | | | / __|/ __|/ _ \\/ __|/ __|| |_ | | | || || |\n"
|
||||
+ " ___) || |_| (_| || | | |_ | |_| || |_) | \\__ \\| |_| || (__| (__| __/\\__ \\\\__ \\| _|| |_| || ||_|\n"
|
||||
+ " |____/ \\__|\\__,_||_| \\__| \\__,_|| .__/ |___/ \\__,_| \\___|\\___|\\___||___/|___/|_| \\__,_||_|(_)\n"
|
||||
+ " |_| ";
|
||||
|
||||
System.out.println(successMsg);
|
||||
}
|
||||
|
||||
@@ -14,9 +14,6 @@ import com.agileboot.common.utils.jackson.JacksonUtil;
|
||||
import com.agileboot.domain.common.dto.UploadDTO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
@@ -28,9 +25,14 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 通用请求处理
|
||||
* TODO 需要重构
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@Tag(name = "上传API", description = "上传相关接口")
|
||||
@@ -43,6 +45,7 @@ public class FileController {
|
||||
/**
|
||||
* 通用下载请求
|
||||
* download接口 其实不是很有必要
|
||||
*
|
||||
* @param fileName 文件名称
|
||||
*/
|
||||
@Operation(summary = "下载文件")
|
||||
@@ -52,7 +55,7 @@ public class FileController {
|
||||
if (!FileUploadUtils.isAllowDownload(fileName)) {
|
||||
// 返回类型是ResponseEntity 不能捕获异常, 需要手动将错误填到 ResponseEntity
|
||||
ResponseDTO<Object> fail = ResponseDTO.fail(
|
||||
new ApiException(Business.COMMON_FILE_NOT_ALLOWED_TO_DOWNLOAD, fileName));
|
||||
new ApiException(Business.COMMON_FILE_NOT_ALLOWED_TO_DOWNLOAD, fileName));
|
||||
return new ResponseEntity<>(JacksonUtil.to(fail).getBytes(), null, HttpStatus.OK);
|
||||
}
|
||||
|
||||
@@ -84,14 +87,14 @@ public class FileController {
|
||||
String url = ServletHolderUtil.getContextUrl() + fileName;
|
||||
|
||||
UploadDTO uploadDTO = UploadDTO.builder()
|
||||
// 全路径
|
||||
.url(url)
|
||||
// 相对路径
|
||||
.fileName(fileName)
|
||||
// 新生成的文件名
|
||||
.newFileName(FileNameUtil.getName(fileName))
|
||||
// 原始的文件名
|
||||
.originalFilename(file.getOriginalFilename()).build();
|
||||
// 全路径
|
||||
.url(url)
|
||||
// 相对路径
|
||||
.fileName(fileName)
|
||||
// 新生成的文件名
|
||||
.newFileName(FileNameUtil.getName(fileName))
|
||||
// 原始的文件名
|
||||
.originalFilename(file.getOriginalFilename()).build();
|
||||
|
||||
return ResponseDTO.ok(uploadDTO);
|
||||
}
|
||||
@@ -114,10 +117,10 @@ public class FileController {
|
||||
String fileName = FileUploadUtils.upload(UploadSubDir.UPLOAD_PATH, file);
|
||||
String url = ServletHolderUtil.getContextUrl() + fileName;
|
||||
UploadDTO uploadDTO = UploadDTO.builder()
|
||||
.url(url)
|
||||
.fileName(fileName)
|
||||
.newFileName(FileNameUtil.getName(fileName))
|
||||
.originalFilename(file.getOriginalFilename()).build();
|
||||
.url(url)
|
||||
.fileName(fileName)
|
||||
.newFileName(FileNameUtil.getName(fileName))
|
||||
.originalFilename(file.getOriginalFilename()).build();
|
||||
|
||||
uploads.add(uploadDTO);
|
||||
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
package com.agileboot.admin.controller.common;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.agileboot.admin.customize.service.login.LoginService;
|
||||
import com.agileboot.admin.customize.service.login.command.LoginCommand;
|
||||
import com.agileboot.admin.customize.service.login.dto.CaptchaDTO;
|
||||
import com.agileboot.admin.customize.service.login.dto.ConfigDTO;
|
||||
import com.agileboot.common.config.AgileBootConfig;
|
||||
import com.agileboot.common.core.dto.ResponseDTO;
|
||||
import com.agileboot.common.exception.ApiException;
|
||||
@@ -14,22 +18,19 @@ import com.agileboot.domain.system.user.command.AddUserCommand;
|
||||
import com.agileboot.infrastructure.annotations.ratelimit.RateLimit;
|
||||
import com.agileboot.infrastructure.annotations.ratelimit.RateLimit.CacheType;
|
||||
import com.agileboot.infrastructure.annotations.ratelimit.RateLimit.LimitType;
|
||||
import com.agileboot.infrastructure.user.AuthenticationUtils;
|
||||
import com.agileboot.admin.customize.service.login.dto.CaptchaDTO;
|
||||
import com.agileboot.admin.customize.service.login.dto.ConfigDTO;
|
||||
import com.agileboot.admin.customize.service.login.command.LoginCommand;
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import com.agileboot.infrastructure.annotations.ratelimit.RateLimitKey;
|
||||
import com.agileboot.admin.customize.service.login.LoginService;
|
||||
import com.agileboot.infrastructure.user.AuthenticationUtils;
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import java.util.List;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 首页
|
||||
*
|
||||
@@ -54,10 +55,10 @@ public class LoginController {
|
||||
@Operation(summary = "首页")
|
||||
@GetMapping("/")
|
||||
@RateLimit(key = RateLimitKey.TEST_KEY, time = 10, maxCount = 5, cacheType = CacheType.Map,
|
||||
limitType = LimitType.GLOBAL)
|
||||
limitType = LimitType.GLOBAL)
|
||||
public String index() {
|
||||
return StrUtil.format("欢迎使用{}后台管理框架,当前版本:v{},请通过前端地址访问。",
|
||||
agileBootConfig.getName(), agileBootConfig.getVersion());
|
||||
agileBootConfig.getName(), agileBootConfig.getVersion());
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +78,7 @@ public class LoginController {
|
||||
*/
|
||||
@Operation(summary = "验证码")
|
||||
@RateLimit(key = RateLimitKey.LOGIN_CAPTCHA_KEY, time = 10, maxCount = 10, cacheType = CacheType.REDIS,
|
||||
limitType = LimitType.IP)
|
||||
limitType = LimitType.IP)
|
||||
@GetMapping("/captchaImage")
|
||||
public ResponseDTO<CaptchaDTO> getCaptchaImg() {
|
||||
CaptchaDTO captchaImg = loginService.generateCaptchaImg();
|
||||
@@ -119,6 +120,7 @@ public class LoginController {
|
||||
/**
|
||||
* 获取路由信息
|
||||
* TODO 如果要在前端开启路由缓存的话 需要在ServerConfig.json 中 设置CachingAsyncRoutes=true 避免一直重复请求路由接口
|
||||
*
|
||||
* @return 路由信息
|
||||
*/
|
||||
@Operation(summary = "获取用户对应的菜单路由", description = "用于动态生成路由")
|
||||
|
||||
@@ -1,25 +1,22 @@
|
||||
package com.agileboot.admin.controller.system;
|
||||
|
||||
import com.agileboot.admin.customize.aop.accessLog.AccessLog;
|
||||
import com.agileboot.common.core.base.BaseController;
|
||||
import com.agileboot.common.core.dto.ResponseDTO;
|
||||
import com.agileboot.common.core.page.PageDTO;
|
||||
import com.agileboot.common.enums.common.BusinessTypeEnum;
|
||||
import com.agileboot.domain.common.cache.CacheCenter;
|
||||
import com.agileboot.domain.system.monitor.MonitorApplicationService;
|
||||
import com.agileboot.domain.system.monitor.dto.OnlineUserDTO;
|
||||
import com.agileboot.domain.system.monitor.dto.RedisCacheInfoDTO;
|
||||
import com.agileboot.domain.system.monitor.dto.ServerInfo;
|
||||
import com.agileboot.admin.customize.aop.accessLog.AccessLog;
|
||||
import com.agileboot.common.enums.common.BusinessTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import java.util.List;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
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;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 缓存监控
|
||||
@@ -55,7 +52,7 @@ public class MonitorController extends BaseController {
|
||||
* 获取在线用户列表
|
||||
*
|
||||
* @param ipAddress ip地址
|
||||
* @param username 用户名
|
||||
* @param username 用户名
|
||||
* @return 分页处理后的在线用户信息
|
||||
*/
|
||||
@Operation(summary = "在线用户列表")
|
||||
|
||||
@@ -1,32 +1,28 @@
|
||||
package com.agileboot.admin.controller.system;
|
||||
|
||||
import com.agileboot.admin.customize.aop.accessLog.AccessLog;
|
||||
import com.agileboot.common.core.base.BaseController;
|
||||
import com.agileboot.common.core.dto.ResponseDTO;
|
||||
import com.agileboot.common.core.page.PageDTO;
|
||||
import com.agileboot.common.enums.common.BusinessTypeEnum;
|
||||
import com.agileboot.domain.common.cache.CacheCenter;
|
||||
import com.agileboot.domain.system.config.ConfigApplicationService;
|
||||
import com.agileboot.domain.system.config.command.ConfigUpdateCommand;
|
||||
import com.agileboot.domain.system.config.dto.ConfigDTO;
|
||||
import com.agileboot.domain.system.config.query.ConfigQuery;
|
||||
import com.agileboot.admin.customize.aop.accessLog.AccessLog;
|
||||
import com.agileboot.common.enums.common.BusinessTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Positive;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Positive;
|
||||
|
||||
/**
|
||||
* 参数配置 信息操作处理
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@RestController
|
||||
@@ -65,7 +61,7 @@ public class SysConfigController extends BaseController {
|
||||
* 修改参数配置
|
||||
*/
|
||||
@PreAuthorize("@permission.has('system:config:edit')")
|
||||
@AccessLog(title = "参数管理", businessType = BusinessTypeEnum.MODIFY)
|
||||
@AccessLog(title = "参数管理", businessType = BusinessTypeEnum.UPDATE)
|
||||
@Operation(summary = "配置修改", description = "配置修改")
|
||||
@PutMapping(value = "/config/{configId}")
|
||||
public ResponseDTO<Void> edit(@NotNull @Positive @PathVariable Long configId, @RequestBody ConfigUpdateCommand config) {
|
||||
|
||||
@@ -1,30 +1,24 @@
|
||||
package com.agileboot.admin.controller.system;
|
||||
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import com.agileboot.admin.customize.aop.accessLog.AccessLog;
|
||||
import com.agileboot.common.core.base.BaseController;
|
||||
import com.agileboot.common.core.dto.ResponseDTO;
|
||||
import com.agileboot.common.enums.common.BusinessTypeEnum;
|
||||
import com.agileboot.domain.system.dept.DeptApplicationService;
|
||||
import com.agileboot.domain.system.dept.command.AddDeptCommand;
|
||||
import com.agileboot.domain.system.dept.command.UpdateDeptCommand;
|
||||
import com.agileboot.domain.system.dept.dto.DeptDTO;
|
||||
import com.agileboot.domain.system.dept.query.DeptQuery;
|
||||
import com.agileboot.admin.customize.aop.accessLog.AccessLog;
|
||||
import com.agileboot.common.enums.common.BusinessTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import java.util.List;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 部门信息
|
||||
@@ -77,7 +71,7 @@ public class SysDeptController extends BaseController {
|
||||
*/
|
||||
@Operation(summary = "新增部门")
|
||||
@PreAuthorize("@permission.has('system:dept:add')")
|
||||
@AccessLog(title = "部门管理", businessType = BusinessTypeEnum.ADD)
|
||||
@AccessLog(title = "部门管理", businessType = BusinessTypeEnum.INSERT)
|
||||
@PostMapping("/dept")
|
||||
public ResponseDTO<Void> add(@RequestBody AddDeptCommand addCommand) {
|
||||
deptApplicationService.addDept(addCommand);
|
||||
@@ -89,9 +83,9 @@ public class SysDeptController extends BaseController {
|
||||
*/
|
||||
@Operation(summary = "修改部门")
|
||||
@PreAuthorize("@permission.has('system:dept:edit') AND @dataScope.checkDeptId(#updateCommand.deptId)")
|
||||
@AccessLog(title = "部门管理", businessType = BusinessTypeEnum.MODIFY)
|
||||
@AccessLog(title = "部门管理", businessType = BusinessTypeEnum.UPDATE)
|
||||
@PutMapping("/dept/{deptId}")
|
||||
public ResponseDTO<Void> edit(@PathVariable("deptId")Long deptId, @RequestBody UpdateDeptCommand updateCommand) {
|
||||
public ResponseDTO<Void> edit(@PathVariable("deptId") Long deptId, @RequestBody UpdateDeptCommand updateCommand) {
|
||||
updateCommand.setDeptId(deptId);
|
||||
deptApplicationService.updateDept(updateCommand);
|
||||
return ResponseDTO.ok();
|
||||
|
||||
@@ -1,32 +1,29 @@
|
||||
package com.agileboot.admin.controller.system;
|
||||
|
||||
|
||||
import com.agileboot.admin.customize.aop.accessLog.AccessLog;
|
||||
import com.agileboot.common.core.base.BaseController;
|
||||
import com.agileboot.common.core.dto.ResponseDTO;
|
||||
import com.agileboot.common.core.page.PageDTO;
|
||||
import com.agileboot.common.enums.common.BusinessTypeEnum;
|
||||
import com.agileboot.common.utils.poi.CustomExcelUtil;
|
||||
import com.agileboot.domain.common.command.BulkOperationCommand;
|
||||
import com.agileboot.domain.system.log.LogApplicationService;
|
||||
import com.agileboot.domain.system.log.dto.LoginLogDTO;
|
||||
import com.agileboot.domain.system.log.query.LoginLogQuery;
|
||||
import com.agileboot.domain.system.log.dto.OperationLogDTO;
|
||||
import com.agileboot.domain.system.log.query.LoginLogQuery;
|
||||
import com.agileboot.domain.system.log.query.OperationLogQuery;
|
||||
import com.agileboot.admin.customize.aop.accessLog.AccessLog;
|
||||
import com.agileboot.common.enums.common.BusinessTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import java.util.List;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 系统访问记录
|
||||
@@ -93,8 +90,10 @@ public class SysLogsController extends BaseController {
|
||||
// .contentLength(file.length())
|
||||
// .body(resource);
|
||||
// }
|
||||
|
||||
/**
|
||||
* 可否改成以上的形式 TODO
|
||||
*
|
||||
* @param response
|
||||
* @param query
|
||||
*/
|
||||
|
||||
@@ -1,34 +1,28 @@
|
||||
package com.agileboot.admin.controller.system;
|
||||
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import com.agileboot.admin.customize.aop.accessLog.AccessLog;
|
||||
import com.agileboot.common.core.base.BaseController;
|
||||
import com.agileboot.common.core.dto.ResponseDTO;
|
||||
import com.agileboot.common.enums.common.BusinessTypeEnum;
|
||||
import com.agileboot.domain.system.menu.MenuApplicationService;
|
||||
import com.agileboot.domain.system.menu.command.AddMenuCommand;
|
||||
import com.agileboot.domain.system.menu.command.UpdateMenuCommand;
|
||||
import com.agileboot.domain.system.menu.dto.MenuDTO;
|
||||
import com.agileboot.domain.system.menu.dto.MenuDetailDTO;
|
||||
import com.agileboot.domain.system.menu.query.MenuQuery;
|
||||
import com.agileboot.admin.customize.aop.accessLog.AccessLog;
|
||||
import com.agileboot.infrastructure.user.AuthenticationUtils;
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import com.agileboot.common.enums.common.BusinessTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import java.util.List;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.PositiveOrZero;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.PositiveOrZero;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 菜单信息
|
||||
@@ -85,7 +79,7 @@ public class SysMenuController extends BaseController {
|
||||
*/
|
||||
@Operation(summary = "添加菜单")
|
||||
@PreAuthorize("@permission.has('system:menu:add')")
|
||||
@AccessLog(title = "菜单管理", businessType = BusinessTypeEnum.ADD)
|
||||
@AccessLog(title = "菜单管理", businessType = BusinessTypeEnum.INSERT)
|
||||
@PostMapping
|
||||
public ResponseDTO<Void> add(@RequestBody AddMenuCommand addCommand) {
|
||||
menuApplicationService.addMenu(addCommand);
|
||||
@@ -97,7 +91,7 @@ public class SysMenuController extends BaseController {
|
||||
*/
|
||||
@Operation(summary = "编辑菜单")
|
||||
@PreAuthorize("@permission.has('system:menu:edit')")
|
||||
@AccessLog(title = "菜单管理", businessType = BusinessTypeEnum.MODIFY)
|
||||
@AccessLog(title = "菜单管理", businessType = BusinessTypeEnum.UPDATE)
|
||||
@PutMapping("/{menuId}")
|
||||
public ResponseDTO<Void> edit(@PathVariable("menuId") Long menuId, @RequestBody UpdateMenuCommand updateCommand) {
|
||||
updateCommand.setMenuId(menuId);
|
||||
|
||||
@@ -1,36 +1,29 @@
|
||||
package com.agileboot.admin.controller.system;
|
||||
|
||||
import com.agileboot.admin.customize.aop.accessLog.AccessLog;
|
||||
import com.agileboot.common.core.base.BaseController;
|
||||
import com.agileboot.common.core.dto.ResponseDTO;
|
||||
import com.agileboot.common.core.page.PageDTO;
|
||||
import com.agileboot.common.enums.common.BusinessTypeEnum;
|
||||
import com.agileboot.domain.common.command.BulkOperationCommand;
|
||||
import com.agileboot.domain.system.notice.NoticeApplicationService;
|
||||
import com.agileboot.domain.system.notice.command.NoticeAddCommand;
|
||||
import com.agileboot.domain.system.notice.command.NoticeUpdateCommand;
|
||||
import com.agileboot.domain.system.notice.dto.NoticeDTO;
|
||||
import com.agileboot.domain.system.notice.query.NoticeQuery;
|
||||
import com.agileboot.admin.customize.aop.accessLog.AccessLog;
|
||||
import com.agileboot.infrastructure.annotations.unrepeatable.Unrepeatable;
|
||||
import com.agileboot.infrastructure.annotations.unrepeatable.Unrepeatable.CheckType;
|
||||
import com.agileboot.common.enums.common.BusinessTypeEnum;
|
||||
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import java.util.List;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Positive;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Positive;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 公告 信息操作处理
|
||||
@@ -86,7 +79,7 @@ public class SysNoticeController extends BaseController {
|
||||
@Operation(summary = "添加公告")
|
||||
@Unrepeatable(interval = 60, checkType = CheckType.SYSTEM_USER)
|
||||
@PreAuthorize("@permission.has('system:notice:add')")
|
||||
@AccessLog(title = "通知公告", businessType = BusinessTypeEnum.ADD)
|
||||
@AccessLog(title = "通知公告", businessType = BusinessTypeEnum.INSERT)
|
||||
@PostMapping
|
||||
public ResponseDTO<Void> add(@RequestBody NoticeAddCommand addCommand) {
|
||||
noticeApplicationService.addNotice(addCommand);
|
||||
@@ -98,7 +91,7 @@ public class SysNoticeController extends BaseController {
|
||||
*/
|
||||
@Operation(summary = "修改公告")
|
||||
@PreAuthorize("@permission.has('system:notice:edit')")
|
||||
@AccessLog(title = "通知公告", businessType = BusinessTypeEnum.MODIFY)
|
||||
@AccessLog(title = "通知公告", businessType = BusinessTypeEnum.UPDATE)
|
||||
@PutMapping("/{noticeId}")
|
||||
public ResponseDTO<Void> edit(@PathVariable Long noticeId, @RequestBody NoticeUpdateCommand updateCommand) {
|
||||
updateCommand.setNoticeId(noticeId);
|
||||
|
||||
@@ -14,22 +14,15 @@ import com.agileboot.domain.system.post.dto.PostDTO;
|
||||
import com.agileboot.domain.system.post.query.PostQuery;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import java.util.List;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 岗位信息操作处理
|
||||
@@ -58,8 +51,9 @@ public class SysPostController extends BaseController {
|
||||
|
||||
/**
|
||||
* 导出查询到的所有岗位信息到excel文件
|
||||
*
|
||||
* @param response http响应
|
||||
* @param query 查询参数
|
||||
* @param query 查询参数
|
||||
* @author Kevin Zhang
|
||||
* @date 2023-10-02
|
||||
*/
|
||||
@@ -88,7 +82,7 @@ public class SysPostController extends BaseController {
|
||||
*/
|
||||
@Operation(summary = "添加职位")
|
||||
@PreAuthorize("@permission.has('system:post:add')")
|
||||
@AccessLog(title = "岗位管理", businessType = BusinessTypeEnum.ADD)
|
||||
@AccessLog(title = "岗位管理", businessType = BusinessTypeEnum.INSERT)
|
||||
@PostMapping
|
||||
public ResponseDTO<Void> add(@RequestBody AddPostCommand addCommand) {
|
||||
postApplicationService.addPost(addCommand);
|
||||
@@ -100,7 +94,7 @@ public class SysPostController extends BaseController {
|
||||
*/
|
||||
@Operation(summary = "修改职位")
|
||||
@PreAuthorize("@permission.has('system:post:edit')")
|
||||
@AccessLog(title = "岗位管理", businessType = BusinessTypeEnum.MODIFY)
|
||||
@AccessLog(title = "岗位管理", businessType = BusinessTypeEnum.UPDATE)
|
||||
@PutMapping
|
||||
public ResponseDTO<Void> edit(@RequestBody UpdatePostCommand updateCommand) {
|
||||
postApplicationService.updatePost(updateCommand);
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package com.agileboot.admin.controller.system;
|
||||
|
||||
import com.agileboot.admin.customize.aop.accessLog.AccessLog;
|
||||
import com.agileboot.common.constant.Constants.UploadSubDir;
|
||||
import com.agileboot.common.core.base.BaseController;
|
||||
import com.agileboot.common.core.dto.ResponseDTO;
|
||||
import com.agileboot.common.enums.common.BusinessTypeEnum;
|
||||
import com.agileboot.common.exception.ApiException;
|
||||
import com.agileboot.common.exception.error.ErrorCode;
|
||||
import com.agileboot.common.utils.file.FileUploadUtils;
|
||||
@@ -12,20 +14,12 @@ import com.agileboot.domain.system.user.command.UpdateProfileCommand;
|
||||
import com.agileboot.domain.system.user.command.UpdateUserAvatarCommand;
|
||||
import com.agileboot.domain.system.user.command.UpdateUserPasswordCommand;
|
||||
import com.agileboot.domain.system.user.dto.UserProfileDTO;
|
||||
import com.agileboot.admin.customize.aop.accessLog.AccessLog;
|
||||
import com.agileboot.infrastructure.user.AuthenticationUtils;
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import com.agileboot.common.enums.common.BusinessTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
@@ -56,7 +50,7 @@ public class SysProfileController extends BaseController {
|
||||
* 修改用户
|
||||
*/
|
||||
@Operation(summary = "修改个人信息")
|
||||
@AccessLog(title = "个人信息", businessType = BusinessTypeEnum.MODIFY)
|
||||
@AccessLog(title = "个人信息", businessType = BusinessTypeEnum.UPDATE)
|
||||
@PutMapping
|
||||
public ResponseDTO<Void> updateProfile(@RequestBody UpdateProfileCommand command) {
|
||||
SystemLoginUser loginUser = AuthenticationUtils.getSystemLoginUser();
|
||||
@@ -69,7 +63,7 @@ public class SysProfileController extends BaseController {
|
||||
* 重置密码
|
||||
*/
|
||||
@Operation(summary = "重置个人密码")
|
||||
@AccessLog(title = "个人信息", businessType = BusinessTypeEnum.MODIFY)
|
||||
@AccessLog(title = "个人信息", businessType = BusinessTypeEnum.UPDATE)
|
||||
@PutMapping("/password")
|
||||
public ResponseDTO<Void> updatePassword(@RequestBody UpdateUserPasswordCommand command) {
|
||||
SystemLoginUser loginUser = AuthenticationUtils.getSystemLoginUser();
|
||||
@@ -82,7 +76,7 @@ public class SysProfileController extends BaseController {
|
||||
* 头像上传
|
||||
*/
|
||||
@Operation(summary = "修改个人头像")
|
||||
@AccessLog(title = "用户头像", businessType = BusinessTypeEnum.MODIFY)
|
||||
@AccessLog(title = "用户头像", businessType = BusinessTypeEnum.UPDATE)
|
||||
@PostMapping("/avatar")
|
||||
public ResponseDTO<UploadFileDTO> avatar(@RequestParam("avatarfile") MultipartFile file) {
|
||||
if (file.isEmpty()) {
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package com.agileboot.admin.controller.system;
|
||||
|
||||
import com.agileboot.admin.customize.aop.accessLog.AccessLog;
|
||||
import com.agileboot.common.core.base.BaseController;
|
||||
import com.agileboot.common.core.dto.ResponseDTO;
|
||||
import com.agileboot.common.core.page.PageDTO;
|
||||
import com.agileboot.common.enums.common.BusinessTypeEnum;
|
||||
import com.agileboot.common.utils.poi.CustomExcelUtil;
|
||||
import com.agileboot.domain.system.role.RoleApplicationService;
|
||||
import com.agileboot.domain.system.role.command.AddRoleCommand;
|
||||
@@ -14,24 +16,16 @@ import com.agileboot.domain.system.role.query.AllocatedRoleQuery;
|
||||
import com.agileboot.domain.system.role.query.RoleQuery;
|
||||
import com.agileboot.domain.system.role.query.UnallocatedRoleQuery;
|
||||
import com.agileboot.domain.system.user.dto.UserDTO;
|
||||
import com.agileboot.admin.customize.aop.accessLog.AccessLog;
|
||||
import com.agileboot.common.enums.common.BusinessTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import java.util.List;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 角色信息
|
||||
@@ -80,7 +74,7 @@ public class SysRoleController extends BaseController {
|
||||
*/
|
||||
@Operation(summary = "添加角色")
|
||||
@PreAuthorize("@permission.has('system:role:add')")
|
||||
@AccessLog(title = "角色管理", businessType = BusinessTypeEnum.ADD)
|
||||
@AccessLog(title = "角色管理", businessType = BusinessTypeEnum.INSERT)
|
||||
@PostMapping
|
||||
public ResponseDTO<Void> add(@RequestBody AddRoleCommand addCommand) {
|
||||
roleApplicationService.addRole(addCommand);
|
||||
@@ -104,7 +98,7 @@ public class SysRoleController extends BaseController {
|
||||
*/
|
||||
@Operation(summary = "修改角色")
|
||||
@PreAuthorize("@permission.has('system:role:edit')")
|
||||
@AccessLog(title = "角色管理", businessType = BusinessTypeEnum.MODIFY)
|
||||
@AccessLog(title = "角色管理", businessType = BusinessTypeEnum.UPDATE)
|
||||
@PutMapping
|
||||
public ResponseDTO<Void> edit(@Validated @RequestBody UpdateRoleCommand updateCommand) {
|
||||
roleApplicationService.updateRole(updateCommand);
|
||||
@@ -116,10 +110,10 @@ public class SysRoleController extends BaseController {
|
||||
*/
|
||||
@Operation(summary = "修改角色数据权限")
|
||||
@PreAuthorize("@permission.has('system:role:edit')")
|
||||
@AccessLog(title = "角色管理", businessType = BusinessTypeEnum.MODIFY)
|
||||
@AccessLog(title = "角色管理", businessType = BusinessTypeEnum.UPDATE)
|
||||
@PutMapping("/{roleId}/dataScope")
|
||||
public ResponseDTO<Void> dataScope(@PathVariable("roleId") Long roleId,
|
||||
@RequestBody UpdateDataScopeCommand command) {
|
||||
@RequestBody UpdateDataScopeCommand command) {
|
||||
command.setRoleId(roleId);
|
||||
|
||||
roleApplicationService.updateDataScope(command);
|
||||
@@ -131,10 +125,10 @@ public class SysRoleController extends BaseController {
|
||||
*/
|
||||
@Operation(summary = "修改角色状态")
|
||||
@PreAuthorize("@permission.has('system:role:edit')")
|
||||
@AccessLog(title = "角色管理", businessType = BusinessTypeEnum.MODIFY)
|
||||
@AccessLog(title = "角色管理", businessType = BusinessTypeEnum.UPDATE)
|
||||
@PutMapping("/{roleId}/status")
|
||||
public ResponseDTO<Void> changeStatus(@PathVariable("roleId") Long roleId,
|
||||
@RequestBody UpdateStatusCommand command) {
|
||||
@RequestBody UpdateStatusCommand command) {
|
||||
command.setRoleId(roleId);
|
||||
|
||||
roleApplicationService.updateStatus(command);
|
||||
@@ -149,7 +143,7 @@ public class SysRoleController extends BaseController {
|
||||
@PreAuthorize("@permission.has('system:role:list')")
|
||||
@GetMapping("/{roleId}/allocated/list")
|
||||
public ResponseDTO<PageDTO<UserDTO>> allocatedUserList(@PathVariable("roleId") Long roleId,
|
||||
AllocatedRoleQuery query) {
|
||||
AllocatedRoleQuery query) {
|
||||
query.setRoleId(roleId);
|
||||
PageDTO<UserDTO> page = roleApplicationService.getAllocatedUserList(query);
|
||||
return ResponseDTO.ok(page);
|
||||
@@ -162,7 +156,7 @@ public class SysRoleController extends BaseController {
|
||||
@PreAuthorize("@permission.has('system:role:list')")
|
||||
@GetMapping("/{roleId}/unallocated/list")
|
||||
public ResponseDTO<PageDTO<UserDTO>> unallocatedUserList(@PathVariable("roleId") Long roleId,
|
||||
UnallocatedRoleQuery query) {
|
||||
UnallocatedRoleQuery query) {
|
||||
query.setRoleId(roleId);
|
||||
PageDTO<UserDTO> page = roleApplicationService.getUnallocatedUserList(query);
|
||||
return ResponseDTO.ok(page);
|
||||
@@ -189,7 +183,7 @@ public class SysRoleController extends BaseController {
|
||||
@AccessLog(title = "角色管理", businessType = BusinessTypeEnum.GRANT)
|
||||
@PostMapping("/{roleId}/users/{userIds}/grant/bulk")
|
||||
public ResponseDTO<Void> addRoleForUserByBulk(@PathVariable("roleId") Long roleId,
|
||||
@PathVariable("userIds") List<Long> userIds) {
|
||||
@PathVariable("userIds") List<Long> userIds) {
|
||||
roleApplicationService.addRoleOfUserByBulk(roleId, userIds);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package com.agileboot.admin.controller.system;
|
||||
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import com.agileboot.admin.customize.aop.accessLog.AccessLog;
|
||||
import com.agileboot.common.core.base.BaseController;
|
||||
import com.agileboot.common.core.dto.ResponseDTO;
|
||||
import com.agileboot.common.core.page.PageDTO;
|
||||
import com.agileboot.common.enums.common.BusinessTypeEnum;
|
||||
import com.agileboot.common.utils.poi.CustomExcelUtil;
|
||||
import com.agileboot.domain.common.command.BulkOperationCommand;
|
||||
import com.agileboot.domain.system.user.UserApplicationService;
|
||||
@@ -11,33 +13,26 @@ import com.agileboot.domain.system.user.command.AddUserCommand;
|
||||
import com.agileboot.domain.system.user.command.ChangeStatusCommand;
|
||||
import com.agileboot.domain.system.user.command.ResetPasswordCommand;
|
||||
import com.agileboot.domain.system.user.command.UpdateUserCommand;
|
||||
import com.agileboot.domain.system.user.db.SearchUserDO;
|
||||
import com.agileboot.domain.system.user.dto.UserDTO;
|
||||
import com.agileboot.domain.system.user.dto.UserDetailDTO;
|
||||
import com.agileboot.domain.system.user.query.SearchUserQuery;
|
||||
import com.agileboot.admin.customize.aop.accessLog.AccessLog;
|
||||
import com.agileboot.infrastructure.user.AuthenticationUtils;
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import com.agileboot.common.enums.common.BusinessTypeEnum;
|
||||
import com.agileboot.domain.system.user.db.SearchUserDO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import java.util.List;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户信息
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@Tag(name = "用户API", description = "用户相关的增删查改")
|
||||
@@ -106,7 +101,7 @@ public class SysUserController extends BaseController {
|
||||
*/
|
||||
@Operation(summary = "新增用户")
|
||||
@PreAuthorize("@permission.has('system:user:add') AND @dataScope.checkDeptId(#command.deptId)")
|
||||
@AccessLog(title = "用户管理", businessType = BusinessTypeEnum.ADD)
|
||||
@AccessLog(title = "用户管理", businessType = BusinessTypeEnum.INSERT)
|
||||
@PostMapping
|
||||
public ResponseDTO<Void> add(@Validated @RequestBody AddUserCommand command) {
|
||||
userApplicationService.addUser(command);
|
||||
@@ -118,7 +113,7 @@ public class SysUserController extends BaseController {
|
||||
*/
|
||||
@Operation(summary = "修改用户")
|
||||
@PreAuthorize("@permission.has('system:user:edit') AND @dataScope.checkUserId(#command.userId)")
|
||||
@AccessLog(title = "用户管理", businessType = BusinessTypeEnum.MODIFY)
|
||||
@AccessLog(title = "用户管理", businessType = BusinessTypeEnum.UPDATE)
|
||||
@PutMapping("/{userId}")
|
||||
public ResponseDTO<Void> edit(@Validated @RequestBody UpdateUserCommand command) {
|
||||
userApplicationService.updateUser(command);
|
||||
@@ -144,7 +139,7 @@ public class SysUserController extends BaseController {
|
||||
*/
|
||||
@Operation(summary = "重置用户密码")
|
||||
@PreAuthorize("@permission.has('system:user:resetPwd') AND @dataScope.checkUserId(#userId)")
|
||||
@AccessLog(title = "用户管理", businessType = BusinessTypeEnum.MODIFY)
|
||||
@AccessLog(title = "用户管理", businessType = BusinessTypeEnum.UPDATE)
|
||||
@PutMapping("/{userId}/password")
|
||||
public ResponseDTO<Void> resetPassword(@PathVariable Long userId, @RequestBody ResetPasswordCommand command) {
|
||||
command.setUserId(userId);
|
||||
@@ -157,7 +152,7 @@ public class SysUserController extends BaseController {
|
||||
*/
|
||||
@Operation(summary = "修改用户状态")
|
||||
@PreAuthorize("@permission.has('system:user:edit') AND @dataScope.checkUserId(#command.userId)")
|
||||
@AccessLog(title = "用户管理", businessType = BusinessTypeEnum.MODIFY)
|
||||
@AccessLog(title = "用户管理", businessType = BusinessTypeEnum.UPDATE)
|
||||
@PutMapping("/{userId}/status")
|
||||
public ResponseDTO<Void> changeStatus(@PathVariable Long userId, @RequestBody ChangeStatusCommand command) {
|
||||
command.setUserId(userId);
|
||||
|
||||
@@ -2,11 +2,8 @@ package com.agileboot.admin.customize.aop.accessLog;
|
||||
|
||||
import com.agileboot.common.enums.common.BusinessTypeEnum;
|
||||
import com.agileboot.common.enums.common.OperatorTypeEnum;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 自定义操作日志记录注解
|
||||
|
||||
@@ -33,7 +33,7 @@ public class AccessLogAspect {
|
||||
* 拦截异常操作
|
||||
*
|
||||
* @param joinPoint 切点
|
||||
* @param e 异常
|
||||
* @param e 异常
|
||||
*/
|
||||
@AfterThrowing(value = "@annotation(controllerLog)", throwing = "e")
|
||||
public void doAfterThrowing(JoinPoint joinPoint, AccessLog controllerLog, Exception e) {
|
||||
|
||||
@@ -3,22 +3,23 @@ package com.agileboot.admin.customize.aop.accessLog;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.EnumUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.servlet.ServletUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.agileboot.common.utils.ServletHolderUtil;
|
||||
import com.agileboot.infrastructure.user.AuthenticationUtils;
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import com.agileboot.common.enums.BasicEnumUtil;
|
||||
import com.agileboot.common.enums.common.OperationStatusEnum;
|
||||
import com.agileboot.common.enums.common.RequestMethodEnum;
|
||||
import com.agileboot.common.enums.BasicEnumUtil;
|
||||
import com.agileboot.common.utils.ServletHolderUtil;
|
||||
import com.agileboot.domain.system.log.db.SysOperationLogEntity;
|
||||
import com.agileboot.infrastructure.user.AuthenticationUtils;
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -34,7 +35,7 @@ public class OperationLogModel extends SysOperationLogEntity {
|
||||
|
||||
public void fillOperatorInfo() {
|
||||
// 获取当前的用户
|
||||
String ip = ServletHolderUtil.getClientIp();
|
||||
String ip = ServletUtil.getClientIP(request);
|
||||
setOperatorIp(ip);
|
||||
SystemLoginUser loginUser = AuthenticationUtils.getSystemLoginUser();
|
||||
if (loginUser != null) {
|
||||
@@ -97,7 +98,7 @@ public class OperationLogModel extends SysOperationLogEntity {
|
||||
*/
|
||||
private void recordRequestData(JoinPoint joinPoint) {
|
||||
RequestMethodEnum requestMethodEnum = BasicEnumUtil.fromValue(RequestMethodEnum.class,
|
||||
this.getRequestMethod());
|
||||
this.getRequestMethod());
|
||||
|
||||
if (requestMethodEnum == RequestMethodEnum.GET || requestMethodEnum == RequestMethodEnum.POST) {
|
||||
String params = argsArrayToString(joinPoint.getArgs());
|
||||
@@ -153,7 +154,7 @@ public class OperationLogModel extends SysOperationLogEntity {
|
||||
}
|
||||
}
|
||||
return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse
|
||||
|| o instanceof BindingResult;
|
||||
|| o instanceof BindingResult;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
package com.agileboot.admin.customize.async;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.extra.servlet.ServletUtil;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import com.agileboot.common.enums.common.LoginStatusEnum;
|
||||
import com.agileboot.common.utils.ServletHolderUtil;
|
||||
import com.agileboot.common.utils.ip.IpRegionUtil;
|
||||
import com.agileboot.common.enums.common.LoginStatusEnum;
|
||||
import com.agileboot.domain.system.log.db.SysLoginInfoEntity;
|
||||
import com.agileboot.domain.system.log.db.SysOperationLogEntity;
|
||||
import com.agileboot.domain.system.log.db.SysLoginInfoService;
|
||||
import com.agileboot.domain.system.log.db.SysOperationLogEntity;
|
||||
import com.agileboot.domain.system.log.db.SysOperationLogService;
|
||||
import eu.bitwalker.useragentutils.UserAgent;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -34,16 +35,16 @@ public class AsyncTaskFactory {
|
||||
public static Runnable loginInfoTask(final String username, final LoginStatusEnum loginStatusEnum, final String message) {
|
||||
// 优化一下这个类
|
||||
final UserAgent userAgent = UserAgent.parseUserAgentString(
|
||||
ServletHolderUtil.getRequest().getHeader("User-Agent"));
|
||||
ServletHolderUtil.getRequest().getHeader("User-Agent"));
|
||||
// 获取客户端浏览器
|
||||
final String browser = userAgent.getBrowser() != null ? userAgent.getBrowser().getName() : "";
|
||||
final String ip = ServletHolderUtil.getClientIp();
|
||||
final String ip = ServletUtil.getClientIP(ServletHolderUtil.getRequest());
|
||||
final String address = IpRegionUtil.getBriefLocationByIp(ip);
|
||||
// 获取客户端操作系统
|
||||
final String os = userAgent.getOperatingSystem() != null ? userAgent.getOperatingSystem().getName() : "";
|
||||
|
||||
log.info("ip: {}, address: {}, username: {}, loginStatusEnum: {}, message: {}", ip, address, username,
|
||||
loginStatusEnum, message);
|
||||
loginStatusEnum, message);
|
||||
return () -> {
|
||||
// 封装对象
|
||||
SysLoginInfoEntity loginInfo = new SysLoginInfoEntity();
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
package com.agileboot.admin.customize.config;
|
||||
|
||||
import com.agileboot.admin.customize.service.login.TokenService;
|
||||
import com.agileboot.infrastructure.user.AuthenticationUtils;
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import com.agileboot.admin.customize.service.login.TokenService;
|
||||
import java.io.IOException;
|
||||
import jakarta.servlet.FilterChain;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
@@ -16,9 +11,16 @@ import org.springframework.security.web.authentication.WebAuthenticationDetailsS
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* token过滤器 验证token有效性
|
||||
* 继承OncePerRequestFilter类的话 可以确保只执行filter一次, 避免执行多次
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@Component
|
||||
@@ -30,7 +32,7 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
|
||||
throws ServletException, IOException {
|
||||
throws ServletException, IOException {
|
||||
SystemLoginUser loginUser = tokenService.getLoginUser(request);
|
||||
if (loginUser != null && AuthenticationUtils.getAuthentication() == null) {
|
||||
tokenService.refreshToken(loginUser);
|
||||
@@ -45,7 +47,7 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
|
||||
|
||||
private void putCurrentLoginUserIntoContext(HttpServletRequest request, SystemLoginUser loginUser) {
|
||||
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(loginUser,
|
||||
null, loginUser.getAuthorities());
|
||||
null, loginUser.getAuthorities());
|
||||
authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
|
||||
SecurityContextHolder.getContext().setAuthentication(authToken);
|
||||
}
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
package com.agileboot.admin.customize.config;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.agileboot.admin.customize.async.AsyncTaskFactory;
|
||||
import com.agileboot.admin.customize.service.login.LoginService;
|
||||
import com.agileboot.admin.customize.service.login.TokenService;
|
||||
import com.agileboot.admin.customize.service.login.UserDetailsServiceImpl;
|
||||
import com.agileboot.common.core.dto.ResponseDTO;
|
||||
import com.agileboot.common.enums.common.LoginStatusEnum;
|
||||
import com.agileboot.common.exception.ApiException;
|
||||
import com.agileboot.common.exception.error.ErrorCode.Client;
|
||||
import com.agileboot.common.utils.ServletHolderUtil;
|
||||
import com.agileboot.domain.common.cache.RedisCacheService;
|
||||
import com.agileboot.admin.customize.async.AsyncTaskFactory;
|
||||
import com.agileboot.infrastructure.thread.ThreadPoolManager;
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import com.agileboot.admin.customize.service.login.TokenService;
|
||||
import com.agileboot.common.enums.common.LoginStatusEnum;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -33,12 +34,13 @@ import org.springframework.web.filter.CorsFilter;
|
||||
|
||||
/**
|
||||
* 主要配置登录流程逻辑涉及以下几个类
|
||||
*
|
||||
* @author valarchie
|
||||
* @see UserDetailsServiceImpl#loadUserByUsername 用于登录流程通过用户名加载用户
|
||||
* @see this#unauthorizedHandler() 用于用户未授权或登录失败处理
|
||||
* @see this#logOutSuccessHandler 用于退出登录成功后的逻辑
|
||||
* @see JwtAuthenticationTokenFilter#doFilter token的校验和刷新
|
||||
* @see LoginService#login 登录逻辑
|
||||
* @author valarchie
|
||||
*/
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
@@ -71,7 +73,7 @@ public class SecurityConfig {
|
||||
public AuthenticationEntryPoint unauthorizedHandler() {
|
||||
return (request, response, exception) -> {
|
||||
ResponseDTO<Object> responseDTO = ResponseDTO.fail(
|
||||
new ApiException(Client.COMMON_NO_AUTHORIZATION, request.getRequestURI())
|
||||
new ApiException(Client.COMMON_NO_AUTHORIZATION, request.getRequestURI())
|
||||
);
|
||||
ServletHolderUtil.renderString(response, JSONUtil.toJsonStr(responseDTO));
|
||||
};
|
||||
@@ -79,8 +81,8 @@ public class SecurityConfig {
|
||||
|
||||
|
||||
/**
|
||||
* 退出成功处理类 返回成功
|
||||
* 在SecurityConfig类当中 定义了/logout 路径对应处理逻辑
|
||||
* 退出成功处理类 返回成功
|
||||
* 在SecurityConfig类当中 定义了/logout 路径对应处理逻辑
|
||||
*/
|
||||
@Bean
|
||||
public LogoutSuccessHandler logOutSuccessHandler() {
|
||||
@@ -92,7 +94,7 @@ public class SecurityConfig {
|
||||
redisCache.loginUserCache.delete(loginUser.getCachedKey());
|
||||
// 记录用户退出日志
|
||||
ThreadPoolManager.execute(AsyncTaskFactory.loginInfoTask(
|
||||
userName, LoginStatusEnum.LOGOUT, LoginStatusEnum.LOGOUT.description()));
|
||||
userName, LoginStatusEnum.LOGOUT, LoginStatusEnum.LOGOUT.description()));
|
||||
}
|
||||
ServletHolderUtil.renderString(response, JSONUtil.toJsonStr(ResponseDTO.ok()));
|
||||
};
|
||||
@@ -109,47 +111,48 @@ public class SecurityConfig {
|
||||
|
||||
/**
|
||||
* 鉴权管理类
|
||||
*
|
||||
* @see UserDetailsServiceImpl#loadUserByUsername
|
||||
*/
|
||||
@Bean
|
||||
public AuthenticationManager authManager(HttpSecurity http) throws Exception {
|
||||
return http.getSharedObject(AuthenticationManagerBuilder.class)
|
||||
.userDetailsService(userDetailsService)
|
||||
.passwordEncoder(bCryptPasswordEncoder())
|
||||
.and()
|
||||
.build();
|
||||
.userDetailsService(userDetailsService)
|
||||
.passwordEncoder(bCryptPasswordEncoder())
|
||||
.and()
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
|
||||
httpSecurity
|
||||
// CSRF禁用,因为不使用session
|
||||
.csrf().disable()
|
||||
// 认证失败处理类
|
||||
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler()).and()
|
||||
// 基于token,所以不需要session
|
||||
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
|
||||
// 过滤请求
|
||||
.authorizeRequests()
|
||||
// 对于登录login 注册register 验证码captchaImage 以及公共Api的请求允许匿名访问
|
||||
// 注意: 当携带token请求以下这几个接口时 会返回403的错误
|
||||
.antMatchers("/login", "/register", "/getConfig", "/captchaImage", "/api/**").anonymous()
|
||||
.antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js",
|
||||
"/profile/**").permitAll()
|
||||
// TODO this is danger.
|
||||
.antMatchers("/swagger-ui.html").anonymous()
|
||||
.antMatchers("/swagger-resources/**").anonymous()
|
||||
.antMatchers("/webjars/**").anonymous()
|
||||
.antMatchers("/*/api-docs","/*/api-docs/swagger-config").anonymous()
|
||||
.antMatchers("/**/api-docs.yaml" ).anonymous()
|
||||
.antMatchers("/druid/**").anonymous()
|
||||
// 除上面外的所有请求全部需要鉴权认证
|
||||
.anyRequest().authenticated()
|
||||
.and()
|
||||
// 禁用 X-Frame-Options 响应头。下面是具体解释:
|
||||
// X-Frame-Options 是一个 HTTP 响应头,用于防止网页被嵌入到其他网页的 <frame>、<iframe> 或 <object> 标签中,从而可以减少点击劫持攻击的风险
|
||||
.headers().frameOptions().disable();
|
||||
// CSRF禁用,因为不使用session
|
||||
.csrf().disable()
|
||||
// 认证失败处理类
|
||||
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler()).and()
|
||||
// 基于token,所以不需要session
|
||||
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
|
||||
// 过滤请求
|
||||
.authorizeRequests()
|
||||
// 对于登录login 注册register 验证码captchaImage 以及公共Api的请求允许匿名访问
|
||||
// 注意: 当携带token请求以下这几个接口时 会返回403的错误
|
||||
.antMatchers("/login", "/register", "/getConfig", "/captchaImage", "/api/**").anonymous()
|
||||
.antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js",
|
||||
"/profile/**").permitAll()
|
||||
// TODO this is danger.
|
||||
.antMatchers("/swagger-ui.html").anonymous()
|
||||
.antMatchers("/swagger-resources/**").anonymous()
|
||||
.antMatchers("/webjars/**").anonymous()
|
||||
.antMatchers("/*/api-docs", "/*/api-docs/swagger-config").anonymous()
|
||||
.antMatchers("/**/api-docs.yaml").anonymous()
|
||||
.antMatchers("/druid/**").anonymous()
|
||||
// 除上面外的所有请求全部需要鉴权认证
|
||||
.anyRequest().authenticated()
|
||||
.and()
|
||||
// 禁用 X-Frame-Options 响应头。下面是具体解释:
|
||||
// X-Frame-Options 是一个 HTTP 响应头,用于防止网页被嵌入到其他网页的 <frame>、<iframe> 或 <object> 标签中,从而可以减少点击劫持攻击的风险
|
||||
.headers().frameOptions().disable();
|
||||
httpSecurity.logout().logoutUrl("/logout").logoutSuccessHandler(logOutSuccessHandler());
|
||||
// 添加JWT filter 需要一开始就通过token识别出登录用户 并放到上下文中 所以jwtFilter需要放前面
|
||||
httpSecurity.addFilterBefore(jwtTokenFilter, UsernamePasswordAuthenticationFilter.class);
|
||||
|
||||
@@ -9,9 +9,15 @@ import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import cn.hutool.crypto.asymmetric.KeyType;
|
||||
import com.agileboot.common.utils.ServletHolderUtil;
|
||||
import cn.hutool.extra.servlet.ServletUtil;
|
||||
import com.agileboot.admin.customize.async.AsyncTaskFactory;
|
||||
import com.agileboot.admin.customize.service.login.command.LoginCommand;
|
||||
import com.agileboot.admin.customize.service.login.dto.CaptchaDTO;
|
||||
import com.agileboot.admin.customize.service.login.dto.ConfigDTO;
|
||||
import com.agileboot.common.config.AgileBootConfig;
|
||||
import com.agileboot.common.constant.Constants.Captcha;
|
||||
import com.agileboot.common.enums.common.ConfigKeyEnum;
|
||||
import com.agileboot.common.enums.common.LoginStatusEnum;
|
||||
import com.agileboot.common.exception.ApiException;
|
||||
import com.agileboot.common.exception.error.ErrorCode;
|
||||
import com.agileboot.common.exception.error.ErrorCode.Business;
|
||||
@@ -20,18 +26,10 @@ import com.agileboot.common.utils.i18n.MessageUtils;
|
||||
import com.agileboot.domain.common.cache.GuavaCacheService;
|
||||
import com.agileboot.domain.common.cache.MapCache;
|
||||
import com.agileboot.domain.common.cache.RedisCacheService;
|
||||
import com.agileboot.admin.customize.async.AsyncTaskFactory;
|
||||
import com.agileboot.infrastructure.thread.ThreadPoolManager;
|
||||
import com.agileboot.admin.customize.service.login.dto.CaptchaDTO;
|
||||
import com.agileboot.admin.customize.service.login.dto.ConfigDTO;
|
||||
import com.agileboot.admin.customize.service.login.command.LoginCommand;
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import com.agileboot.common.enums.common.ConfigKeyEnum;
|
||||
import com.agileboot.common.enums.common.LoginStatusEnum;
|
||||
import com.agileboot.domain.system.user.db.SysUserEntity;
|
||||
import com.agileboot.infrastructure.thread.ThreadPoolManager;
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import com.google.code.kaptcha.Producer;
|
||||
import java.awt.image.BufferedImage;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
@@ -43,6 +41,9 @@ import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.FastByteArrayOutputStream;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
/**
|
||||
* 登录校验方法
|
||||
*
|
||||
@@ -84,10 +85,10 @@ public class LoginService {
|
||||
try {
|
||||
// 该方法会去调用UserDetailsServiceImpl#loadUserByUsername 校验用户名和密码 认证鉴权
|
||||
authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(
|
||||
loginCommand.getUsername(), decryptPassword));
|
||||
loginCommand.getUsername(), decryptPassword));
|
||||
} catch (BadCredentialsException e) {
|
||||
ThreadPoolManager.execute(AsyncTaskFactory.loginInfoTask(loginCommand.getUsername(), LoginStatusEnum.LOGIN_FAIL,
|
||||
MessageUtils.message("Business.LOGIN_WRONG_USER_PASSWORD")));
|
||||
MessageUtils.message("Business.LOGIN_WRONG_USER_PASSWORD")));
|
||||
throw new ApiException(e, ErrorCode.Business.LOGIN_WRONG_USER_PASSWORD);
|
||||
} catch (AuthenticationException e) {
|
||||
ThreadPoolManager.execute(AsyncTaskFactory.loginInfoTask(loginCommand.getUsername(), LoginStatusEnum.LOGIN_FAIL, e.getMessage()));
|
||||
@@ -174,8 +175,8 @@ public class LoginService {
|
||||
/**
|
||||
* 校验验证码
|
||||
*
|
||||
* @param username 用户名
|
||||
* @param captchaCode 验证码
|
||||
* @param username 用户名
|
||||
* @param captchaCode 验证码
|
||||
* @param captchaCodeKey 验证码对应的缓存key
|
||||
*/
|
||||
public void validateCaptcha(String username, String captchaCode, String captchaCodeKey) {
|
||||
@@ -183,34 +184,35 @@ public class LoginService {
|
||||
redisCache.captchaCache.delete(captchaCodeKey);
|
||||
if (captcha == null) {
|
||||
ThreadPoolManager.execute(AsyncTaskFactory.loginInfoTask(username, LoginStatusEnum.LOGIN_FAIL,
|
||||
ErrorCode.Business.LOGIN_CAPTCHA_CODE_EXPIRE.message()));
|
||||
ErrorCode.Business.LOGIN_CAPTCHA_CODE_EXPIRE.message()));
|
||||
throw new ApiException(ErrorCode.Business.LOGIN_CAPTCHA_CODE_EXPIRE);
|
||||
}
|
||||
if (!captchaCode.equalsIgnoreCase(captcha)) {
|
||||
ThreadPoolManager.execute(AsyncTaskFactory.loginInfoTask(username, LoginStatusEnum.LOGIN_FAIL,
|
||||
ErrorCode.Business.LOGIN_CAPTCHA_CODE_WRONG.message()));
|
||||
ErrorCode.Business.LOGIN_CAPTCHA_CODE_WRONG.message()));
|
||||
throw new ApiException(ErrorCode.Business.LOGIN_CAPTCHA_CODE_WRONG);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录登录信息
|
||||
*
|
||||
* @param loginUser 登录用户
|
||||
*/
|
||||
public void recordLoginInfo(SystemLoginUser loginUser) {
|
||||
ThreadPoolManager.execute(AsyncTaskFactory.loginInfoTask(loginUser.getUsername(), LoginStatusEnum.LOGIN_SUCCESS,
|
||||
LoginStatusEnum.LOGIN_SUCCESS.description()));
|
||||
LoginStatusEnum.LOGIN_SUCCESS.description()));
|
||||
|
||||
SysUserEntity entity = redisCache.userCache.getObjectById(loginUser.getUserId());
|
||||
|
||||
entity.setLoginIp(ServletHolderUtil.getClientIp());
|
||||
entity.setLoginIp(ServletUtil.getClientIP(ServletHolderUtil.getRequest()));
|
||||
entity.setLoginDate(DateUtil.date());
|
||||
entity.updateById();
|
||||
}
|
||||
|
||||
public String decryptPassword(String originalPassword) {
|
||||
byte[] decryptBytes = SecureUtil.rsa(AgileBootConfig.getRsaPrivateKey(), null)
|
||||
.decrypt(Base64.decode(originalPassword), KeyType.PrivateKey);
|
||||
.decrypt(Base64.decode(originalPassword), KeyType.PrivateKey);
|
||||
|
||||
return StrUtil.str(decryptBytes, CharsetUtil.CHARSET_UTF_8);
|
||||
}
|
||||
|
||||
@@ -8,21 +8,17 @@ import com.agileboot.common.exception.ApiException;
|
||||
import com.agileboot.common.exception.error.ErrorCode;
|
||||
import com.agileboot.domain.common.cache.RedisCacheService;
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.MalformedJwtException;
|
||||
import io.jsonwebtoken.SignatureAlgorithm;
|
||||
import io.jsonwebtoken.SignatureException;
|
||||
import io.jsonwebtoken.UnsupportedJwtException;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import io.jsonwebtoken.*;
|
||||
import lombok.Data;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* token验证处理
|
||||
*
|
||||
@@ -71,7 +67,8 @@ public class TokenService {
|
||||
String uuid = (String) claims.get(Token.LOGIN_USER_KEY);
|
||||
|
||||
return redisCache.loginUserCache.getObjectOnlyInCacheById(uuid);
|
||||
} catch (SignatureException | MalformedJwtException | UnsupportedJwtException | IllegalArgumentException jwtException) {
|
||||
} catch (SignatureException | MalformedJwtException | UnsupportedJwtException |
|
||||
IllegalArgumentException jwtException) {
|
||||
log.error("parse token failed.", jwtException);
|
||||
throw new ApiException(jwtException, ErrorCode.Client.INVALID_TOKEN);
|
||||
} catch (Exception e) {
|
||||
@@ -99,6 +96,7 @@ public class TokenService {
|
||||
|
||||
/**
|
||||
* 当超过20分钟,自动刷新token
|
||||
*
|
||||
* @param loginUser 登录用户
|
||||
*/
|
||||
public void refreshToken(SystemLoginUser loginUser) {
|
||||
@@ -119,8 +117,8 @@ public class TokenService {
|
||||
*/
|
||||
private String generateToken(Map<String, Object> claims) {
|
||||
return Jwts.builder()
|
||||
.setClaims(claims)
|
||||
.signWith(SignatureAlgorithm.HS512, secret).compact();
|
||||
.setClaims(claims)
|
||||
.signWith(SignatureAlgorithm.HS512, secret).compact();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,9 +129,9 @@ public class TokenService {
|
||||
*/
|
||||
private Claims parseToken(String token) {
|
||||
return Jwts.parser()
|
||||
.setSigningKey(secret)
|
||||
.parseClaimsJws(token)
|
||||
.getBody();
|
||||
.setSigningKey(secret)
|
||||
.parseClaimsJws(token)
|
||||
.getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,41 +2,43 @@ package com.agileboot.admin.customize.service.login;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import java.util.Collections;
|
||||
import com.agileboot.common.enums.BasicEnumUtil;
|
||||
import com.agileboot.common.enums.common.UserStatusEnum;
|
||||
import com.agileboot.common.exception.ApiException;
|
||||
import com.agileboot.common.exception.error.ErrorCode;
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import com.agileboot.infrastructure.user.web.RoleInfo;
|
||||
import com.agileboot.infrastructure.user.web.DataScopeEnum;
|
||||
import com.agileboot.common.enums.common.UserStatusEnum;
|
||||
import com.agileboot.common.enums.BasicEnumUtil;
|
||||
import com.agileboot.domain.system.menu.db.SysMenuEntity;
|
||||
import com.agileboot.domain.system.role.db.SysRoleEntity;
|
||||
import com.agileboot.domain.system.user.db.SysUserEntity;
|
||||
import com.agileboot.domain.system.menu.db.SysMenuService;
|
||||
import com.agileboot.domain.system.role.db.SysRoleEntity;
|
||||
import com.agileboot.domain.system.role.db.SysRoleService;
|
||||
import com.agileboot.domain.system.user.db.SysUserEntity;
|
||||
import com.agileboot.domain.system.user.db.SysUserService;
|
||||
import com.agileboot.infrastructure.user.web.DataScopeEnum;
|
||||
import com.agileboot.infrastructure.user.web.RoleInfo;
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.SetUtils;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 自定义加载用户信息通过用户名
|
||||
* 用于SpringSecurity 登录流程
|
||||
* 没有办法把这个类 放进loginService中 会在SecurityConfig中造成循环依赖
|
||||
* @see com.agileboot.infrastructure.config.SecurityConfig#filterChain(HttpSecurity)
|
||||
*
|
||||
* @author valarchie
|
||||
* @see com.agileboot.infrastructure.config.SecurityConfig#filterChain(HttpSecurity)
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
@@ -67,10 +69,10 @@ public class UserDetailsServiceImpl implements UserDetailsService {
|
||||
RoleInfo roleInfo = getRoleInfo(userEntity.getRoleId(), userEntity.getIsAdmin());
|
||||
|
||||
SystemLoginUser loginUser = new SystemLoginUser(userEntity.getUserId(), userEntity.getIsAdmin(), userEntity.getUsername(),
|
||||
userEntity.getPassword(), roleInfo, userEntity.getDeptId());
|
||||
userEntity.getPassword(), roleInfo, userEntity.getDeptId());
|
||||
loginUser.fillLoginInfo();
|
||||
loginUser.setAutoRefreshCacheTime(loginUser.getLoginInfo().getLoginTime()
|
||||
+ TimeUnit.MINUTES.toMillis(tokenService.getAutoRefreshTime()));
|
||||
+ TimeUnit.MINUTES.toMillis(tokenService.getAutoRefreshTime()));
|
||||
return loginUser;
|
||||
}
|
||||
|
||||
@@ -86,8 +88,8 @@ public class UserDetailsServiceImpl implements UserDetailsService {
|
||||
|
||||
Set<Long> allMenuIds = allMenus.stream().map(SysMenuEntity::getMenuId).collect(Collectors.toSet());
|
||||
|
||||
return new RoleInfo(RoleInfo.ADMIN_ROLE_ID, RoleInfo.ADMIN_ROLE_KEY, DataScopeEnum.ALL, Collections.emptySet(),
|
||||
RoleInfo.ADMIN_PERMISSIONS, allMenuIds);
|
||||
return new RoleInfo(RoleInfo.ADMIN_ROLE_ID, RoleInfo.ADMIN_ROLE_KEY, DataScopeEnum.ALL, SetUtils.emptySet(),
|
||||
RoleInfo.ADMIN_PERMISSIONS, allMenuIds);
|
||||
|
||||
}
|
||||
|
||||
@@ -104,10 +106,10 @@ public class UserDetailsServiceImpl implements UserDetailsService {
|
||||
|
||||
DataScopeEnum dataScopeEnum = BasicEnumUtil.fromValue(DataScopeEnum.class, roleEntity.getDataScope());
|
||||
|
||||
Set<Long> deptIdSet = Collections.emptySet();
|
||||
Set<Long> deptIdSet = SetUtils.emptySet();
|
||||
if (StrUtil.isNotEmpty(roleEntity.getDeptIdSet())) {
|
||||
deptIdSet = StrUtil.split(roleEntity.getDeptIdSet(), ",").stream()
|
||||
.map(Convert::toLong).collect(Collectors.toSet());
|
||||
.map(Convert::toLong).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
return new RoleInfo(roleId, roleEntity.getRoleKey(), dataScopeEnum, deptIdSet, permissions, menuIds);
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package com.agileboot.admin.customize.service.login.dto;
|
||||
|
||||
import com.agileboot.common.enums.dictionary.DictionaryData;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author valarchie
|
||||
|
||||
@@ -2,20 +2,17 @@ package com.agileboot.admin.customize.service.permission;
|
||||
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import com.agileboot.admin.customize.service.permission.model.AbstractDataPermissionChecker;
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import com.agileboot.admin.customize.service.permission.model.checker.AllDataPermissionChecker;
|
||||
import com.agileboot.admin.customize.service.permission.model.checker.CustomDataPermissionChecker;
|
||||
import com.agileboot.admin.customize.service.permission.model.checker.DefaultDataPermissionChecker;
|
||||
import com.agileboot.admin.customize.service.permission.model.checker.DeptTreeDataPermissionChecker;
|
||||
import com.agileboot.admin.customize.service.permission.model.checker.OnlySelfDataPermissionChecker;
|
||||
import com.agileboot.admin.customize.service.permission.model.checker.SingleDeptDataPermissionChecker;
|
||||
import com.agileboot.infrastructure.user.web.DataScopeEnum;
|
||||
import com.agileboot.admin.customize.service.permission.model.checker.*;
|
||||
import com.agileboot.domain.system.dept.db.SysDeptService;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import com.agileboot.infrastructure.user.web.DataScopeEnum;
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
/**
|
||||
* 数据权限检测器工厂
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@Component
|
||||
|
||||
@@ -3,16 +3,18 @@ package com.agileboot.admin.customize.service.permission;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.agileboot.admin.customize.service.permission.model.AbstractDataPermissionChecker;
|
||||
import com.agileboot.admin.customize.service.permission.model.DataCondition;
|
||||
import com.agileboot.infrastructure.user.AuthenticationUtils;
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import com.agileboot.domain.system.user.db.SysUserEntity;
|
||||
import com.agileboot.domain.system.user.db.SysUserService;
|
||||
import java.util.List;
|
||||
import com.agileboot.infrastructure.user.AuthenticationUtils;
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 数据权限校验服务
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@Service("dataScope")
|
||||
@@ -38,6 +40,7 @@ public class DataPermissionService {
|
||||
|
||||
/**
|
||||
* 通过userId 校验当前用户 对 目标用户是否有操作权限
|
||||
*
|
||||
* @param userIds 用户id列表
|
||||
* @return 校验结果
|
||||
*/
|
||||
@@ -66,5 +69,4 @@ public class DataPermissionService {
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -3,13 +3,13 @@ package com.agileboot.admin.customize.service.permission;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.agileboot.infrastructure.user.AuthenticationUtils;
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import com.agileboot.infrastructure.user.web.RoleInfo;
|
||||
import java.util.Set;
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@Service("permission")
|
||||
@@ -38,7 +38,7 @@ public class MenuPermissionService {
|
||||
* 判断是否包含权限
|
||||
*
|
||||
* @param permissions 权限列表
|
||||
* @param permission 权限字符串
|
||||
* @param permission 权限字符串
|
||||
* @return 用户是否具备某权限
|
||||
*/
|
||||
private boolean has(Set<String> permissions, String permission) {
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
package com.agileboot.admin.customize.service.permission.model;
|
||||
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import com.agileboot.domain.system.dept.db.SysDeptService;
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 数据权限测试接口
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@Data
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
package com.agileboot.admin.customize.service.permission.model.checker;
|
||||
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import com.agileboot.admin.customize.service.permission.model.AbstractDataPermissionChecker;
|
||||
import com.agileboot.admin.customize.service.permission.model.DataCondition;
|
||||
import com.agileboot.domain.system.dept.db.SysDeptService;
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 数据权限测试接口
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
package com.agileboot.admin.customize.service.permission.model.checker;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import com.agileboot.admin.customize.service.permission.model.AbstractDataPermissionChecker;
|
||||
import com.agileboot.admin.customize.service.permission.model.DataCondition;
|
||||
import com.agileboot.domain.system.dept.db.SysDeptService;
|
||||
import java.util.Set;
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 数据权限测试接口
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
package com.agileboot.admin.customize.service.permission.model.checker;
|
||||
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import com.agileboot.admin.customize.service.permission.model.AbstractDataPermissionChecker;
|
||||
import com.agileboot.admin.customize.service.permission.model.DataCondition;
|
||||
import com.agileboot.domain.system.dept.db.SysDeptService;
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 数据权限测试接口
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
package com.agileboot.admin.customize.service.permission.model.checker;
|
||||
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import com.agileboot.admin.customize.service.permission.model.AbstractDataPermissionChecker;
|
||||
import com.agileboot.admin.customize.service.permission.model.DataCondition;
|
||||
import com.agileboot.domain.system.dept.db.SysDeptService;
|
||||
import java.util.Objects;
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 数据权限测试接口
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
package com.agileboot.admin.customize.service.permission.model.checker;
|
||||
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import com.agileboot.admin.customize.service.permission.model.AbstractDataPermissionChecker;
|
||||
import com.agileboot.admin.customize.service.permission.model.DataCondition;
|
||||
import com.agileboot.domain.system.dept.db.SysDeptService;
|
||||
import java.util.Objects;
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 数据权限测试接口
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
package com.agileboot.admin.customize.service.permission.model.checker;
|
||||
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import com.agileboot.admin.customize.service.permission.model.AbstractDataPermissionChecker;
|
||||
import com.agileboot.admin.customize.service.permission.model.DataCondition;
|
||||
import com.agileboot.domain.system.dept.db.SysDeptService;
|
||||
import java.util.Objects;
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 数据权限测试接口
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
|
||||
@@ -1,104 +1,105 @@
|
||||
# 数据源配置
|
||||
spring:
|
||||
datasource:
|
||||
type: com.alibaba.druid.pool.DruidDataSource
|
||||
driverClassName: com.mysql.cj.jdbc.Driver
|
||||
druid:
|
||||
webStatFilter:
|
||||
enabled: true
|
||||
statViewServlet:
|
||||
enabled: true
|
||||
# 设置白名单,不填则允许所有访问
|
||||
allow:
|
||||
url-pattern: /druid/*
|
||||
# 控制台管理用户名和密码
|
||||
login-username: agileboot
|
||||
login-password: 123456
|
||||
filter:
|
||||
stat:
|
||||
enabled: true
|
||||
# 慢SQL记录
|
||||
log-slow-sql: true
|
||||
slow-sql-millis: 1000
|
||||
merge-sql: true
|
||||
wall:
|
||||
config:
|
||||
multi-statement-allow: true
|
||||
dynamic:
|
||||
primary: master
|
||||
strict: false
|
||||
druid:
|
||||
# 初始连接数
|
||||
initialSize: 5
|
||||
# 最小连接池数量
|
||||
minIdle: 10
|
||||
# 最大连接池数量
|
||||
maxActive: 20
|
||||
# 配置获取连接等待超时的时间
|
||||
maxWait: 60000
|
||||
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
|
||||
timeBetweenEvictionRunsMillis: 60000
|
||||
# 配置一个连接在池中最小生存的时间,单位是毫秒
|
||||
minEvictableIdleTimeMillis: 300000
|
||||
# 配置一个连接在池中最大生存的时间,单位是毫秒
|
||||
maxEvictableIdleTimeMillis: 900000
|
||||
# 配置检测连接是否有效
|
||||
validationQuery: SELECT 1 FROM DUAL
|
||||
testWhileIdle: true
|
||||
testOnBorrow: false
|
||||
testOnReturn: false
|
||||
datasource:
|
||||
# 主库数据源
|
||||
master:
|
||||
url: jdbc:mysql://mysql2.sqlpub.com:3307/agileboot?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&sslMode=REQUIRED
|
||||
username: ENC(s4kjpEsplGGLeV3YRNvJpJhDSOAO0tEf)
|
||||
password: ENC(hg/hxmducWsI8u83/eXgAi8yHBDFbB5z0xzwNtBejPc=)
|
||||
# 从库数据源
|
||||
# slave:
|
||||
# url: jdbc:mysql://localhost:33067/agileboot2?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
||||
# username: root
|
||||
# password: 12345
|
||||
datasource:
|
||||
type: com.alibaba.druid.pool.DruidDataSource
|
||||
driverClassName: com.mysql.cj.jdbc.Driver
|
||||
druid:
|
||||
webStatFilter:
|
||||
enabled: true
|
||||
statViewServlet:
|
||||
enabled: true
|
||||
# 设置白名单,不填则允许所有访问
|
||||
allow:
|
||||
url-pattern: /druid/*
|
||||
# 控制台管理用户名和密码
|
||||
login-username: agileboot
|
||||
login-password: 123456
|
||||
filter:
|
||||
stat:
|
||||
enabled: true
|
||||
# 慢SQL记录
|
||||
log-slow-sql: true
|
||||
slow-sql-millis: 1000
|
||||
merge-sql: true
|
||||
wall:
|
||||
config:
|
||||
multi-statement-allow: true
|
||||
dynamic:
|
||||
primary: master
|
||||
strict: false
|
||||
druid:
|
||||
# 初始连接数
|
||||
initialSize: 5
|
||||
# 最小连接池数量
|
||||
minIdle: 10
|
||||
# 最大连接池数量
|
||||
maxActive: 20
|
||||
# 配置获取连接等待超时的时间
|
||||
maxWait: 60000
|
||||
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
|
||||
timeBetweenEvictionRunsMillis: 60000
|
||||
# 配置一个连接在池中最小生存的时间,单位是毫秒
|
||||
minEvictableIdleTimeMillis: 300000
|
||||
# 配置一个连接在池中最大生存的时间,单位是毫秒
|
||||
maxEvictableIdleTimeMillis: 900000
|
||||
# 配置检测连接是否有效
|
||||
validationQuery: SELECT 1 FROM DUAL
|
||||
testWhileIdle: true
|
||||
testOnBorrow: false
|
||||
testOnReturn: false
|
||||
datasource:
|
||||
# 主库数据源
|
||||
master:
|
||||
url: jdbc:mysql://localhost:3306/agileboot?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
||||
username: root
|
||||
password: 123456
|
||||
# 从库数据源
|
||||
# slave:
|
||||
# url: jdbc:mysql://localhost:33067/agileboot2?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
||||
# username: root
|
||||
# password: 12345
|
||||
|
||||
# redis 配置
|
||||
redis:
|
||||
host: redis
|
||||
port: 6379
|
||||
database: 1
|
||||
password: ENC(s3HU866TUAjzrWStN7kpQQ==)
|
||||
# 连接超时时间
|
||||
timeout: 10s
|
||||
lettuce:
|
||||
pool:
|
||||
# 连接池中的最小空闲连接
|
||||
min-idle: 0
|
||||
# 连接池中的最大空闲连接
|
||||
max-idle: 8
|
||||
# 连接池的最大数据库连接数
|
||||
max-active: 8
|
||||
# #连接池最大阻塞等待时间(使用负值表示没有限制)
|
||||
max-wait: -1ms
|
||||
# redis 配置
|
||||
redis:
|
||||
# 地址
|
||||
host: localhost
|
||||
# 端口,默认为6379
|
||||
port: 63795
|
||||
# 数据库索引
|
||||
database: 0
|
||||
# 密码
|
||||
password:
|
||||
# 连接超时时间
|
||||
timeout: 10s
|
||||
lettuce:
|
||||
pool:
|
||||
# 连接池中的最小空闲连接
|
||||
min-idle: 0
|
||||
# 连接池中的最大空闲连接
|
||||
max-idle: 8
|
||||
# 连接池的最大数据库连接数
|
||||
max-active: 8
|
||||
# #连接池最大阻塞等待时间(使用负值表示没有限制)
|
||||
max-wait: -1ms
|
||||
|
||||
logging:
|
||||
file:
|
||||
path: ./logs/agileboot-dev
|
||||
file:
|
||||
path: F:/logs/agileboot-dev
|
||||
|
||||
|
||||
springdoc:
|
||||
swagger-ui:
|
||||
# ***注意*** 开启Swagger UI界面 **安全考虑的话生产环境需要关掉**
|
||||
# 因为knife4j的一些配置不灵活 所以重新改回springdoc+swagger的组合 真实开发的时候 使用apifox这种工具效率更高
|
||||
enabled: true
|
||||
url: ${agileboot.api-prefix}/v3/api-docs
|
||||
config-url: ${agileboot.api-prefix}/v3/api-docs/swagger-config
|
||||
swagger-ui:
|
||||
# ***注意*** 开启Swagger UI界面 **安全考虑的话生产环境需要关掉**
|
||||
# 因为knife4j的一些配置不灵活 所以重新改回springdoc+swagger的组合 真实开发的时候 使用apifox这种工具效率更高
|
||||
enabled: true
|
||||
url: ${agileboot.api-prefix}/v3/api-docs
|
||||
config-url: ${agileboot.api-prefix}/v3/api-docs/swagger-config
|
||||
|
||||
|
||||
# 项目相关配置
|
||||
agileboot:
|
||||
# 文件基路径 示例( Windows配置D:\agileboot,Linux配置 /home/agileboot)
|
||||
file-base-dir: D:\agileboot
|
||||
# 前端url请求转发前缀
|
||||
api-prefix: /dev-api
|
||||
demo-enabled: false
|
||||
jasypt:
|
||||
encryptor:
|
||||
password: ${JASYPT_ENCRYPTOR_PASSWORD:}
|
||||
# 文件基路径 示例( Windows配置D:\agileboot,Linux配置 /home/agileboot)
|
||||
file-base-dir: D:\agileboot
|
||||
# 前端url请求转发前缀
|
||||
api-prefix: /dev-api
|
||||
demo-enabled: false
|
||||
|
||||
@@ -1,53 +1,52 @@
|
||||
|
||||
# 数据源配置
|
||||
spring:
|
||||
datasource:
|
||||
# 驱动
|
||||
driver-class-name: org.h2.Driver
|
||||
dynamic:
|
||||
primary: master
|
||||
strict: false
|
||||
datasource:
|
||||
master:
|
||||
# h2 内存数据库 内存模式连接配置 库名: agileboot
|
||||
url: jdbc:h2:mem:agileboot;DB_CLOSE_DELAY=-1;MODE=MySQL
|
||||
h2:
|
||||
# 开启console 访问 默认false
|
||||
console:
|
||||
enabled: true
|
||||
settings:
|
||||
# 开启h2 console 跟踪 方便调试 默认 false
|
||||
trace: true
|
||||
# 允许console 远程访问 默认false
|
||||
web-allow-others: true
|
||||
# h2 访问路径上下文
|
||||
path: /h2-console
|
||||
datasource:
|
||||
# 驱动
|
||||
driver-class-name: org.h2.Driver
|
||||
dynamic:
|
||||
primary: master
|
||||
strict: false
|
||||
datasource:
|
||||
master:
|
||||
# h2 内存数据库 内存模式连接配置 库名: agileboot
|
||||
url: jdbc:h2:mem:agileboot;DB_CLOSE_DELAY=-1;MODE=MySQL
|
||||
h2:
|
||||
# 开启console 访问 默认false
|
||||
console:
|
||||
enabled: true
|
||||
settings:
|
||||
# 开启h2 console 跟踪 方便调试 默认 false
|
||||
trace: true
|
||||
# 允许console 远程访问 默认false
|
||||
web-allow-others: true
|
||||
# h2 访问路径上下文
|
||||
path: /h2-console
|
||||
|
||||
sql:
|
||||
init:
|
||||
platform: mysql
|
||||
# 初始化数据
|
||||
schema-locations: classpath:h2sql/agileboot_schema.sql
|
||||
data-locations: classpath:h2sql/agileboot_data.sql
|
||||
sql:
|
||||
init:
|
||||
platform: mysql
|
||||
# 初始化数据
|
||||
schema-locations: classpath:h2sql/agileboot_schema.sql
|
||||
data-locations: classpath:h2sql/agileboot_data.sql
|
||||
|
||||
# redis 配置
|
||||
redis:
|
||||
# 地址
|
||||
host: localhost
|
||||
# 端口,默认为6379
|
||||
port: 36379
|
||||
# 数据库索引
|
||||
database: 0
|
||||
# 连接超时时间
|
||||
timeout: 10s
|
||||
lettuce:
|
||||
pool:
|
||||
# 连接池中的最小空闲连接
|
||||
min-idle: 0
|
||||
# 连接池中的最大空闲连接
|
||||
max-idle: 8
|
||||
# 连接池的最大数据库连接数
|
||||
max-active: 8
|
||||
# #连接池最大阻塞等待时间(使用负值表示没有限制)
|
||||
max-wait: -1ms
|
||||
# redis 配置
|
||||
redis:
|
||||
# 地址
|
||||
host: localhost
|
||||
# 端口,默认为6379
|
||||
port: 36379
|
||||
# 数据库索引
|
||||
database: 0
|
||||
# 连接超时时间
|
||||
timeout: 10s
|
||||
lettuce:
|
||||
pool:
|
||||
# 连接池中的最小空闲连接
|
||||
min-idle: 0
|
||||
# 连接池中的最大空闲连接
|
||||
max-idle: 8
|
||||
# 连接池的最大数据库连接数
|
||||
max-active: 8
|
||||
# #连接池最大阻塞等待时间(使用负值表示没有限制)
|
||||
max-wait: -1ms
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# 开发环境配置
|
||||
server:
|
||||
# 服务器的HTTP端口,默认为8080
|
||||
port: 18080
|
||||
port: 8080
|
||||
servlet:
|
||||
# 应用的访问路径
|
||||
context-path: /
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.agileboot.admin.config;
|
||||
|
||||
|
||||
import com.agileboot.admin.AgileBootAdminApplication;
|
||||
import com.agileboot.common.config.AgileBootConfig;
|
||||
import com.agileboot.common.constant.Constants.UploadSubDir;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.File;
|
||||
|
||||
@SpringBootTest(classes = AgileBootAdminApplication.class)
|
||||
@RunWith(SpringRunner.class)
|
||||
public class AgileBootConfigTest {
|
||||
|
||||
@Resource
|
||||
private AgileBootConfig config;
|
||||
|
||||
@Test
|
||||
public void testConfig() {
|
||||
String fileBaseDir = "D:\\agileboot\\profile";
|
||||
|
||||
Assertions.assertEquals("AgileBoot", config.getName());
|
||||
Assertions.assertEquals("1.8.0", config.getVersion());
|
||||
Assertions.assertEquals("2022", config.getCopyrightYear());
|
||||
Assertions.assertFalse(config.isDemoEnabled());
|
||||
Assertions.assertEquals(fileBaseDir, AgileBootConfig.getFileBaseDir());
|
||||
Assertions.assertFalse(AgileBootConfig.isAddressEnabled());
|
||||
Assertions.assertEquals("math", AgileBootConfig.getCaptchaType());
|
||||
Assertions.assertEquals("math", AgileBootConfig.getCaptchaType());
|
||||
Assertions.assertEquals(fileBaseDir + "\\import",
|
||||
AgileBootConfig.getFileBaseDir() + File.separator + UploadSubDir.IMPORT_PATH);
|
||||
Assertions.assertEquals(fileBaseDir + "\\avatar",
|
||||
AgileBootConfig.getFileBaseDir() + File.separator + UploadSubDir.AVATAR_PATH);
|
||||
Assertions.assertEquals(fileBaseDir + "\\download",
|
||||
AgileBootConfig.getFileBaseDir() + File.separator + UploadSubDir.DOWNLOAD_PATH);
|
||||
Assertions.assertEquals(fileBaseDir + "\\upload",
|
||||
AgileBootConfig.getFileBaseDir() + File.separator + UploadSubDir.UPLOAD_PATH);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.agileboot.admin.customize.service.permission;
|
||||
|
||||
import com.agileboot.admin.customize.service.permission.model.DataCondition;
|
||||
import com.agileboot.admin.customize.service.permission.model.checker.CustomDataPermissionChecker;
|
||||
import com.agileboot.domain.system.dept.db.SysDeptService;
|
||||
import com.agileboot.infrastructure.user.web.RoleInfo;
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import org.apache.commons.collections4.SetUtils;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
class CustomDataPermissionCheckerTest {
|
||||
|
||||
private final SysDeptService deptService = mock(SysDeptService.class);
|
||||
public SystemLoginUser loginUser = mock(SystemLoginUser.class);
|
||||
|
||||
@BeforeEach
|
||||
public void mockBefore() {
|
||||
when(loginUser.getRoleInfo()).thenReturn(RoleInfo.EMPTY_ROLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCheckWhenParameterNull() {
|
||||
CustomDataPermissionChecker customChecker = new CustomDataPermissionChecker(deptService);
|
||||
|
||||
boolean check1 = customChecker.check(null, null);
|
||||
boolean check2 = customChecker.check(loginUser, null);
|
||||
boolean check3 = customChecker.check(null, new DataCondition());
|
||||
|
||||
assertFalse(check1);
|
||||
assertFalse(check2);
|
||||
assertFalse(check3);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCheckWhenTargetDeptIdNull() {
|
||||
CustomDataPermissionChecker customChecker = new CustomDataPermissionChecker(deptService);
|
||||
|
||||
boolean check = customChecker.check(loginUser, new DataCondition(null, 1L));
|
||||
|
||||
assertFalse(check);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testCheckWhenRoleIsNull() {
|
||||
CustomDataPermissionChecker customChecker = new CustomDataPermissionChecker(deptService);
|
||||
|
||||
when(loginUser.getRoleInfo()).thenReturn(null);
|
||||
boolean check = customChecker.check(loginUser, new DataCondition(1L, 1L));
|
||||
|
||||
assertFalse(check);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testCheckWhenNotContainTargetDeptId() {
|
||||
CustomDataPermissionChecker customChecker = new CustomDataPermissionChecker(deptService);
|
||||
|
||||
loginUser.getRoleInfo().setDeptIdSet(SetUtils.hashSet(2L));
|
||||
boolean check = customChecker.check(loginUser, new DataCondition(1L, 1L));
|
||||
|
||||
assertFalse(check);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testCheckWhenContainTargetDeptId() {
|
||||
CustomDataPermissionChecker customChecker = new CustomDataPermissionChecker(deptService);
|
||||
|
||||
loginUser.getRoleInfo().setDeptIdSet(SetUtils.hashSet(1L));
|
||||
boolean check = customChecker.check(loginUser, new DataCondition(1L, 1L));
|
||||
|
||||
assertTrue(check);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package com.agileboot.admin.customize.service.permission;
|
||||
|
||||
import com.agileboot.admin.customize.service.permission.model.DataCondition;
|
||||
import com.agileboot.admin.customize.service.permission.model.checker.DeptTreeDataPermissionChecker;
|
||||
import com.agileboot.domain.system.dept.db.SysDeptService;
|
||||
import com.agileboot.infrastructure.user.web.RoleInfo;
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
class DeptTreeDataPermissionCheckerTest {
|
||||
|
||||
private final SysDeptService deptService = mock(SysDeptService.class);
|
||||
|
||||
public SystemLoginUser loginUser = mock(SystemLoginUser.class);
|
||||
|
||||
@BeforeEach
|
||||
public void mockBefore() {
|
||||
when(loginUser.getRoleInfo()).thenReturn(RoleInfo.EMPTY_ROLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCheckWhenParameterNull() {
|
||||
DeptTreeDataPermissionChecker checker = new DeptTreeDataPermissionChecker(deptService);
|
||||
|
||||
boolean check1 = checker.check(null, null);
|
||||
boolean check2 = checker.check(new SystemLoginUser(), null);
|
||||
boolean check3 = checker.check(null, new DataCondition());
|
||||
boolean check4 = checker.check(loginUser, new DataCondition());
|
||||
|
||||
assertFalse(check1);
|
||||
assertFalse(check2);
|
||||
assertFalse(check3);
|
||||
assertFalse(check4);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testCheckWhenIsChildOfDept() {
|
||||
DeptTreeDataPermissionChecker checker = new DeptTreeDataPermissionChecker(deptService);
|
||||
|
||||
when(deptService.isChildOfTheDept(any(), any())).thenReturn(true);
|
||||
when(loginUser.getDeptId()).thenReturn(1L);
|
||||
|
||||
DataCondition dataCondition = new DataCondition();
|
||||
dataCondition.setTargetDeptId(2L);
|
||||
|
||||
boolean check = checker.check(loginUser, dataCondition);
|
||||
|
||||
assertTrue(check);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testCheckWhenIsSameDept() {
|
||||
DeptTreeDataPermissionChecker checker = new DeptTreeDataPermissionChecker(deptService);
|
||||
|
||||
when(deptService.isChildOfTheDept(any(), any())).thenReturn(false);
|
||||
when(loginUser.getDeptId()).thenReturn(1L);
|
||||
DataCondition dataCondition = new DataCondition();
|
||||
dataCondition.setTargetDeptId(1L);
|
||||
|
||||
boolean check = checker.check(loginUser, dataCondition);
|
||||
|
||||
assertTrue(check);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testCheckWhenFailed() {
|
||||
DeptTreeDataPermissionChecker checker = new DeptTreeDataPermissionChecker(deptService);
|
||||
|
||||
when(deptService.isChildOfTheDept(any(), any())).thenReturn(false);
|
||||
when(loginUser.getDeptId()).thenReturn(1L);
|
||||
DataCondition dataCondition = new DataCondition();
|
||||
dataCondition.setTargetDeptId(2L);
|
||||
|
||||
boolean check = checker.check(loginUser, dataCondition);
|
||||
|
||||
assertFalse(check);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.agileboot.admin.customize.service.permission;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import com.agileboot.admin.customize.service.permission.model.checker.OnlySelfDataPermissionChecker;
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import com.agileboot.admin.customize.service.permission.model.DataCondition;
|
||||
import com.agileboot.domain.system.dept.db.SysDeptService;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class OnlySelfDataPermissionCheckerTest {
|
||||
|
||||
private final SysDeptService deptService = mock(SysDeptService.class);
|
||||
|
||||
@Test
|
||||
void testCheckWhenParameterNull() {
|
||||
OnlySelfDataPermissionChecker checker = new OnlySelfDataPermissionChecker(deptService);
|
||||
|
||||
boolean check1 = checker.check(null, null);
|
||||
boolean check2 = checker.check(new SystemLoginUser(), null);
|
||||
boolean check3 = checker.check(null, new DataCondition());
|
||||
boolean check4 = checker.check(new SystemLoginUser(), new DataCondition());
|
||||
|
||||
assertFalse(check1);
|
||||
assertFalse(check2);
|
||||
assertFalse(check3);
|
||||
assertFalse(check4);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCheckWhenSameUserId() {
|
||||
OnlySelfDataPermissionChecker checker = new OnlySelfDataPermissionChecker(deptService);
|
||||
SystemLoginUser loginUser = new SystemLoginUser();
|
||||
loginUser.setUserId(1L);
|
||||
DataCondition dataCondition = new DataCondition();
|
||||
dataCondition.setTargetUserId(1L);
|
||||
|
||||
boolean check = checker.check(loginUser, dataCondition);
|
||||
|
||||
assertTrue(check);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testCheckWhenDifferentUserId() {
|
||||
OnlySelfDataPermissionChecker checker = new OnlySelfDataPermissionChecker(deptService);
|
||||
SystemLoginUser loginUser = new SystemLoginUser();
|
||||
loginUser.setUserId(1L);
|
||||
DataCondition dataCondition = new DataCondition();
|
||||
dataCondition.setTargetDeptId(2L);
|
||||
|
||||
boolean check = checker.check(loginUser, dataCondition);
|
||||
|
||||
assertFalse(check);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.agileboot.admin.customize.service.permission;
|
||||
|
||||
import com.agileboot.admin.customize.service.permission.model.DataCondition;
|
||||
import com.agileboot.admin.customize.service.permission.model.checker.SingleDeptDataPermissionChecker;
|
||||
import com.agileboot.domain.system.dept.db.SysDeptService;
|
||||
import com.agileboot.infrastructure.user.web.RoleInfo;
|
||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
class SingleDeptDataPermissionCheckerTest {
|
||||
|
||||
private final SysDeptService deptService = mock(SysDeptService.class);
|
||||
|
||||
public SystemLoginUser loginUser = mock(SystemLoginUser.class);
|
||||
|
||||
@BeforeEach
|
||||
public void mockBefore() {
|
||||
when(loginUser.getRoleInfo()).thenReturn(RoleInfo.EMPTY_ROLE);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testCheckWhenParameterNull() {
|
||||
SingleDeptDataPermissionChecker checker = new SingleDeptDataPermissionChecker(deptService);
|
||||
|
||||
boolean check1 = checker.check(null, null);
|
||||
boolean check2 = checker.check(new SystemLoginUser(), null);
|
||||
boolean check3 = checker.check(null, new DataCondition());
|
||||
boolean check4 = checker.check(loginUser, new DataCondition());
|
||||
|
||||
assertFalse(check1);
|
||||
assertFalse(check2);
|
||||
assertFalse(check3);
|
||||
assertFalse(check4);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCheckWhenSameDeptId() {
|
||||
SingleDeptDataPermissionChecker checker = new SingleDeptDataPermissionChecker(deptService);
|
||||
when(loginUser.getDeptId()).thenReturn(1L);
|
||||
DataCondition dataCondition = new DataCondition();
|
||||
dataCondition.setTargetDeptId(1L);
|
||||
|
||||
boolean check = checker.check(loginUser, dataCondition);
|
||||
|
||||
assertTrue(check);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testCheckWhenDifferentDeptId() {
|
||||
SingleDeptDataPermissionChecker checker = new SingleDeptDataPermissionChecker(deptService);
|
||||
when(loginUser.getDeptId()).thenReturn(1L);
|
||||
DataCondition dataCondition = new DataCondition();
|
||||
dataCondition.setTargetUserId(2L);
|
||||
|
||||
boolean check = checker.check(loginUser, dataCondition);
|
||||
|
||||
assertFalse(check);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -4,10 +4,10 @@ import com.agileboot.api.customize.service.JwtTokenService;
|
||||
import com.agileboot.infrastructure.user.app.AppLoginUser;
|
||||
import io.jsonwebtoken.Claims;
|
||||
import java.io.IOException;
|
||||
import jakarta.servlet.FilterChain;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
@@ -13,7 +13,7 @@ import io.jsonwebtoken.SignatureAlgorithm;
|
||||
import io.jsonwebtoken.SignatureException;
|
||||
import io.jsonwebtoken.UnsupportedJwtException;
|
||||
import java.util.Map;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import lombok.Data;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
<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/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.agileboot</groupId>
|
||||
<artifactId>agileboot</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
<artifactId>agileboot-boot-start</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.agileboot</groupId>
|
||||
<artifactId>wol-common-web</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.agileboot</groupId>
|
||||
<artifactId>wol-module-ai</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -1,24 +0,0 @@
|
||||
package com.agileboot;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
/**
|
||||
* @Author cuiJiaWang
|
||||
* @Create 2025-08-12 18:07
|
||||
*/
|
||||
@SpringBootApplication
|
||||
public class AgilebootBootApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AgilebootBootApplication.class, args);
|
||||
String successMsg = " ____ _ _ __ _ _ \n"
|
||||
+ " / ___| | |_ __ _ _ __ | |_ _ _ _ __ ___ _ _ ___ ___ ___ ___ ___ / _| _ _ | || |\n"
|
||||
+ " \\___ \\ | __|/ _` || '__|| __| | | | || '_ \\ / __|| | | | / __|/ __|/ _ \\/ __|/ __|| |_ | | | || || |\n"
|
||||
+ " ___) || |_| (_| || | | |_ | |_| || |_) | \\__ \\| |_| || (__| (__| __/\\__ \\\\__ \\| _|| |_| || ||_|\n"
|
||||
+ " |____/ \\__|\\__,_||_| \\__| \\__,_|| .__/ |___/ \\__,_| \\___|\\___|\\___||___/|___/|_| \\__,_||_|(_)\n"
|
||||
+ " |_| ";
|
||||
|
||||
System.out.println(successMsg);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
server:
|
||||
port: 8080
|
||||
servlet:
|
||||
context-path: /api
|
||||
@@ -1,18 +0,0 @@
|
||||
<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/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.agileboot</groupId>
|
||||
<artifactId>agileboot-cloud</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
<artifactId>agileboot-cloud-start</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.agileboot</groupId>
|
||||
<artifactId>wol-common-web</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -1,11 +0,0 @@
|
||||
package com.agileboot;
|
||||
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
/**
|
||||
* @Author cuiJiaWang
|
||||
* @Create 2025-08-12 17:35
|
||||
*/
|
||||
@SpringBootApplication
|
||||
public class AgilebootCloudApplication {
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
<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/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.agileboot</groupId>
|
||||
<artifactId>agileboot</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
<artifactId>agileboot-cloud</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
<module>agileboot-cloud-start</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
||||
@@ -9,17 +9,6 @@
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<modules>
|
||||
<module>wol-common-box</module>
|
||||
<module>wol-common-core</module>
|
||||
<module>wol-common-doc</module>
|
||||
<module>wol-common-web</module>
|
||||
<module>wol-common-mybatis</module>
|
||||
<module>wol-common-redis</module>
|
||||
<module>wol-common-json</module>
|
||||
</modules>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<artifactId>agileboot-common</artifactId>
|
||||
|
||||
<description>
|
||||
@@ -28,78 +17,178 @@
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- Spring框架基本的核心工具 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context-support</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- SpringWeb模块 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- spring security 安全认证 -->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.springframework.boot</groupId>-->
|
||||
<!-- <artifactId>spring-boot-starter-security</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 自定义验证注解 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--常用工具类 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- JSON工具类 -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- io常用工具类 -->
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 文件上传工具类 -->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>commons-fileupload</groupId>-->
|
||||
<!-- <artifactId>commons-fileupload</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>commons-fileupload</groupId>
|
||||
<artifactId>commons-fileupload</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- excel工具 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- yml解析器 -->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.yaml</groupId>-->
|
||||
<!-- <artifactId>snakeyaml</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Token生成与解析-->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>io.jsonwebtoken</groupId>-->
|
||||
<!-- <artifactId>jjwt</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Jaxb -->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>javax.xml.bind</groupId>-->
|
||||
<!-- <artifactId>jaxb-api</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- redis 缓存操作 -->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.springframework.boot</groupId>-->
|
||||
<!-- <artifactId>spring-boot-starter-data-redis</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- pool 对象池 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-pool2</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 解析客户端操作系统、浏览器等 -->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>eu.bitwalker</groupId>-->
|
||||
<!-- <artifactId>UserAgentUtils</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>eu.bitwalker</groupId>
|
||||
<artifactId>UserAgentUtils</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>it.ozimov</groupId>-->
|
||||
<!-- <artifactId>embedded-redis</artifactId>-->
|
||||
<!-- <!– 不排除掉slf4j的话 会冲突–>-->
|
||||
<!-- <exclusions>-->
|
||||
<!-- <exclusion>-->
|
||||
<!-- <groupId>org.slf4j</groupId>-->
|
||||
<!-- <artifactId>slf4j-simple</artifactId>-->
|
||||
<!-- </exclusion>-->
|
||||
<!-- <!– 排除掉guava依赖,以本项目的guava依赖为准 –>-->
|
||||
<!-- <exclusion>-->
|
||||
<!-- <groupId>com.google.guava</groupId>-->
|
||||
<!-- <artifactId>guava</artifactId>-->
|
||||
<!-- </exclusion>-->
|
||||
<!-- </exclusions>-->
|
||||
<!-- </dependency>-->
|
||||
<!-- servlet包 -->
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-annotations</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.module</groupId>
|
||||
<artifactId>jackson-module-parameter-names</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
<artifactId>jackson-datatype-jdk8</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.lionsoul</groupId>
|
||||
<artifactId>ip2region</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>it.ozimov</groupId>
|
||||
<artifactId>embedded-redis</artifactId>
|
||||
<!-- 不排除掉slf4j的话 会冲突-->
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
</exclusion>
|
||||
<!-- 排除掉guava依赖,以本项目的guava依赖为准 -->
|
||||
<exclusion>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.junit.vintage</groupId>
|
||||
<artifactId>junit-vintage-engine</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- 多数据源 -->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>com.baomidou</groupId>-->
|
||||
<!-- <artifactId>dynamic-datasource-spring-boot-starter</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--ENC加密-->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>com.github.ulisesbocchio</groupId>-->
|
||||
<!-- <artifactId>jasypt-spring-boot-starter</artifactId>-->
|
||||
<!-- <version>2.1.1</version>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>com.github.ulisesbocchio</groupId>
|
||||
<artifactId>jasypt-spring-boot-starter</artifactId>
|
||||
<version>2.1.1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- swagger注解 -->
|
||||
<dependency>
|
||||
<groupId>io.swagger</groupId>
|
||||
<artifactId>swagger-annotations</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.agileboot.common.core.annotation;
|
||||
package com.agileboot.common.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.agileboot.common.core.annotation;
|
||||
package com.agileboot.common.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.agileboot.common.core.config;
|
||||
package com.agileboot.common.config;
|
||||
|
||||
import com.agileboot.common.core.constant.Constants;
|
||||
import com.agileboot.common.constant.Constants;
|
||||
import java.io.File;
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
@@ -0,0 +1,86 @@
|
||||
package com.agileboot.common.constant;
|
||||
|
||||
|
||||
/**
|
||||
* 通用常量信息
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
public class Constants {
|
||||
private Constants() {
|
||||
}
|
||||
|
||||
public static final int KB = 1024;
|
||||
|
||||
public static final int MB = KB * 1024;
|
||||
|
||||
public static final int GB = MB * 1024;
|
||||
|
||||
/**
|
||||
* http请求
|
||||
*/
|
||||
public static final String HTTP = "http://";
|
||||
|
||||
/**
|
||||
* https请求
|
||||
*/
|
||||
public static final String HTTPS = "https://";
|
||||
|
||||
|
||||
public static class Token {
|
||||
|
||||
private Token() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 令牌前缀
|
||||
*/
|
||||
public static final String PREFIX = "Bearer ";
|
||||
|
||||
/**
|
||||
* 令牌前缀
|
||||
*/
|
||||
public static final String LOGIN_USER_KEY = "login_user_key";
|
||||
|
||||
}
|
||||
|
||||
public static class Captcha {
|
||||
|
||||
private Captcha() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 令牌
|
||||
*/
|
||||
public static final String MATH_TYPE = "math";
|
||||
|
||||
/**
|
||||
* 令牌前缀
|
||||
*/
|
||||
public static final String CHAR_TYPE = "char";
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 资源映射路径 前缀
|
||||
*/
|
||||
public static final String RESOURCE_PREFIX = "profile";
|
||||
|
||||
public static class UploadSubDir {
|
||||
|
||||
private UploadSubDir() {
|
||||
}
|
||||
|
||||
public static final String IMPORT_PATH = "import";
|
||||
|
||||
public static final String AVATAR_PATH = "avatar";
|
||||
|
||||
public static final String DOWNLOAD_PATH = "download";
|
||||
|
||||
public static final String UPLOAD_PATH = "upload";
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.agileboot.common.core.core.base;
|
||||
package com.agileboot.common.core.base;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.agileboot.common.core.base;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.extension.activerecord.Model;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import java.util.Date;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* Entity基类
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class BaseEntity<T extends Model<?>> extends Model<T> {
|
||||
|
||||
@ApiModelProperty("创建者ID")
|
||||
@TableField(value = "creator_id", fill = FieldFill.INSERT)
|
||||
private Long creatorId;
|
||||
|
||||
@ApiModelProperty("创建时间")
|
||||
@TableField(value = "create_time", fill = FieldFill.INSERT)
|
||||
private Date createTime;
|
||||
|
||||
@ApiModelProperty("更新者ID")
|
||||
@TableField(value = "updater_id", fill = FieldFill.UPDATE, updateStrategy = FieldStrategy.NOT_NULL)
|
||||
private Long updaterId;
|
||||
|
||||
@ApiModelProperty("更新时间")
|
||||
@TableField(value = "update_time", fill = FieldFill.UPDATE)
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
* deleted字段请在数据库中 设置为tinyInt 并且非null 默认值为0
|
||||
*/
|
||||
@ApiModelProperty("删除标志(0代表存在 1代表删除)")
|
||||
@TableField("deleted")
|
||||
@TableLogic
|
||||
private Boolean deleted;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.agileboot.common.core.dto;
|
||||
|
||||
import com.agileboot.common.exception.ApiException;
|
||||
import com.agileboot.common.exception.error.ErrorCode;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 响应信息主体
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class ResponseDTO<T> {
|
||||
|
||||
private Integer code;
|
||||
|
||||
private String msg;
|
||||
|
||||
@JsonInclude
|
||||
private T data;
|
||||
|
||||
public static <T> ResponseDTO<T> ok() {
|
||||
return build(null, ErrorCode.SUCCESS.code(), ErrorCode.SUCCESS.message());
|
||||
}
|
||||
|
||||
public static <T> ResponseDTO<T> ok(T data) {
|
||||
return build(data, ErrorCode.SUCCESS.code(), ErrorCode.SUCCESS.message());
|
||||
}
|
||||
|
||||
public static <T> ResponseDTO<T> fail() {
|
||||
return build(null, ErrorCode.FAILED.code(), ErrorCode.FAILED.message());
|
||||
}
|
||||
|
||||
public static <T> ResponseDTO<T> fail(T data) {
|
||||
return build(data, ErrorCode.FAILED.code(), ErrorCode.FAILED.message());
|
||||
}
|
||||
|
||||
public static <T> ResponseDTO<T> fail(ApiException exception) {
|
||||
return build(null, exception.getErrorCode().code(), exception.getMessage());
|
||||
}
|
||||
|
||||
public static <T> ResponseDTO<T> fail(ApiException exception, T data) {
|
||||
return build(data, exception.getErrorCode().code(), exception.getMessage());
|
||||
}
|
||||
|
||||
public static <T> ResponseDTO<T> build(T data, Integer code, String msg) {
|
||||
return new ResponseDTO<>(code, msg, data);
|
||||
}
|
||||
|
||||
// 去掉直接填充错误码的方式, 这种方式不能拿到i18n的错误消息 统一通过ApiException来构造错误消息
|
||||
// public static <T> ResponseDTO<T> fail(ErrorCodeInterface code, Object... args) {
|
||||
// return build(null, code, args);
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.agileboot.common.core.page;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import javax.validation.constraints.Max;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* @author valarchie
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public abstract class AbstractPageQuery<T> extends AbstractQuery<T> {
|
||||
|
||||
/**
|
||||
* 最大分页页数
|
||||
*/
|
||||
public static final int MAX_PAGE_NUM = 200;
|
||||
/**
|
||||
* 单页最大大小
|
||||
*/
|
||||
public static final int MAX_PAGE_SIZE = 500;
|
||||
/**
|
||||
* 默认分页页数
|
||||
*/
|
||||
public static final int DEFAULT_PAGE_NUM = 1;
|
||||
/**
|
||||
* 默认分页大小
|
||||
*/
|
||||
public static final int DEFAULT_PAGE_SIZE = 10;
|
||||
|
||||
@Max(MAX_PAGE_NUM)
|
||||
protected Integer pageNum;
|
||||
@Max(MAX_PAGE_SIZE)
|
||||
protected Integer pageSize;
|
||||
|
||||
public Page<T> toPage() {
|
||||
pageNum = ObjectUtil.defaultIfNull(pageNum, DEFAULT_PAGE_NUM);
|
||||
pageSize = ObjectUtil.defaultIfNull(pageSize, DEFAULT_PAGE_SIZE);
|
||||
return new Page<>(pageNum, pageSize);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package com.agileboot.common.core.page;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.agileboot.common.utils.time.DatePickUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat.Shape;
|
||||
import java.util.Date;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 如果是简单的排序 和 时间范围筛选 可以使用内置的这几个字段
|
||||
* @author valarchie
|
||||
*/
|
||||
@Data
|
||||
public abstract class AbstractQuery<T> {
|
||||
|
||||
protected String orderColumn;
|
||||
|
||||
protected String orderDirection;
|
||||
|
||||
protected String timeRangeColumn;
|
||||
|
||||
@JsonFormat(shape = Shape.STRING, pattern = "yyyy-MM-dd")
|
||||
private Date beginTime;
|
||||
|
||||
@JsonFormat(shape = Shape.STRING, pattern = "yyyy-MM-dd")
|
||||
private Date endTime;
|
||||
|
||||
private static final String ASC = "ascending";
|
||||
private static final String DESC = "descending";
|
||||
|
||||
/**
|
||||
* 生成query conditions
|
||||
*
|
||||
* @return 添加条件后的QueryWrapper
|
||||
*/
|
||||
public QueryWrapper<T> toQueryWrapper() {
|
||||
QueryWrapper<T> queryWrapper = addQueryCondition();
|
||||
addSortCondition(queryWrapper);
|
||||
addTimeCondition(queryWrapper);
|
||||
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
public abstract QueryWrapper<T> addQueryCondition();
|
||||
|
||||
public void addSortCondition(QueryWrapper<T> queryWrapper) {
|
||||
if (queryWrapper == null || StrUtil.isEmpty(orderColumn)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Boolean sortDirection = convertSortDirection();
|
||||
if (sortDirection != null) {
|
||||
queryWrapper.orderBy(StrUtil.isNotEmpty(orderColumn), sortDirection,
|
||||
StrUtil.toUnderlineCase(orderColumn));
|
||||
}
|
||||
}
|
||||
|
||||
public void addTimeCondition(QueryWrapper<T> queryWrapper) {
|
||||
if (queryWrapper != null
|
||||
&& StrUtil.isNotEmpty(this.timeRangeColumn)) {
|
||||
queryWrapper
|
||||
.ge(beginTime != null, StrUtil.toUnderlineCase(timeRangeColumn),
|
||||
DatePickUtil.getBeginOfTheDay(beginTime))
|
||||
.le(endTime != null, StrUtil.toUnderlineCase(timeRangeColumn), DatePickUtil.getEndOfTheDay(endTime));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取前端传来的排序方向 转换成MyBatisPlus所需的排序参数 boolean=isAsc
|
||||
* @return 排序顺序, null为无排序
|
||||
*/
|
||||
public Boolean convertSortDirection() {
|
||||
Boolean isAsc = null;
|
||||
if (StrUtil.isEmpty(this.orderDirection)) {
|
||||
return isAsc;
|
||||
}
|
||||
|
||||
if (ASC.equals(this.orderDirection)) {
|
||||
isAsc = true;
|
||||
}
|
||||
if (DESC.equals(this.orderDirection)) {
|
||||
isAsc = false;
|
||||
}
|
||||
|
||||
return isAsc;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.agileboot.common.core.page;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import java.util.List;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 分页模型类
|
||||
* @author valarchie
|
||||
*/
|
||||
@Data
|
||||
public class PageDTO<T> {
|
||||
/**
|
||||
* 总记录数
|
||||
*/
|
||||
private Long total;
|
||||
|
||||
/**
|
||||
* 列表数据
|
||||
*/
|
||||
private List<T> rows;
|
||||
|
||||
public PageDTO(List<T> list) {
|
||||
this.rows = list;
|
||||
this.total = (long) list.size();
|
||||
}
|
||||
|
||||
public PageDTO(Page<T> page) {
|
||||
this.rows = page.getRecords();
|
||||
this.total = page.getTotal();
|
||||
}
|
||||
|
||||
public PageDTO(List<T> list, Long count) {
|
||||
this.rows = list;
|
||||
this.total = count;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.agileboot.common.core.enums;
|
||||
package com.agileboot.common.enums;
|
||||
|
||||
/**
|
||||
* @author valarchie
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.agileboot.common.core.enums;
|
||||
package com.agileboot.common.enums;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import com.agileboot.common.core.exception.ApiException;
|
||||
import com.agileboot.common.core.exception.error.ErrorCode;
|
||||
import com.agileboot.common.core.enums.BasicEnum;
|
||||
import com.agileboot.common.exception.ApiException;
|
||||
import com.agileboot.common.exception.error.ErrorCode;
|
||||
import com.agileboot.common.enums.BasicEnum;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.agileboot.common.core.enums;
|
||||
package com.agileboot.common.enums;
|
||||
|
||||
/**
|
||||
* 字典类型 接口
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.agileboot.common.core.enums.common;
|
||||
package com.agileboot.common.enums.common;
|
||||
|
||||
import com.agileboot.common.core.enums.dictionary.CssTag;
|
||||
import com.agileboot.common.core.enums.dictionary.Dictionary;
|
||||
import com.agileboot.common.core.enums.DictionaryEnum;
|
||||
import com.agileboot.common.enums.dictionary.CssTag;
|
||||
import com.agileboot.common.enums.dictionary.Dictionary;
|
||||
import com.agileboot.common.enums.DictionaryEnum;
|
||||
|
||||
/**
|
||||
* 对应sys_operation_log的business_type
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.agileboot.common.core.enums.common;
|
||||
package com.agileboot.common.enums.common;
|
||||
|
||||
import com.agileboot.common.core.enums.BasicEnum;
|
||||
import com.agileboot.common.enums.BasicEnum;
|
||||
|
||||
/**
|
||||
* 系统配置
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.agileboot.common.core.enums.common;
|
||||
package com.agileboot.common.enums.common;
|
||||
|
||||
import com.agileboot.common.core.enums.dictionary.CssTag;
|
||||
import com.agileboot.common.core.enums.dictionary.Dictionary;
|
||||
import com.agileboot.common.core.enums.DictionaryEnum;
|
||||
import com.agileboot.common.enums.dictionary.CssTag;
|
||||
import com.agileboot.common.enums.dictionary.Dictionary;
|
||||
import com.agileboot.common.enums.DictionaryEnum;
|
||||
|
||||
/**
|
||||
* 对应sys_user的sex字段
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.agileboot.common.core.enums.common;
|
||||
package com.agileboot.common.enums.common;
|
||||
|
||||
import com.agileboot.common.core.enums.dictionary.CssTag;
|
||||
import com.agileboot.common.core.enums.dictionary.Dictionary;
|
||||
import com.agileboot.common.core.enums.DictionaryEnum;
|
||||
import com.agileboot.common.enums.dictionary.CssTag;
|
||||
import com.agileboot.common.enums.dictionary.Dictionary;
|
||||
import com.agileboot.common.enums.DictionaryEnum;
|
||||
|
||||
/**
|
||||
* 用户状态
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.agileboot.common.core.enums.common;
|
||||
package com.agileboot.common.enums.common;
|
||||
|
||||
import com.agileboot.common.core.enums.BasicEnum;
|
||||
import com.agileboot.common.enums.BasicEnum;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.agileboot.common.core.enums.common;
|
||||
package com.agileboot.common.enums.common;
|
||||
|
||||
import com.agileboot.common.core.enums.BasicEnum;
|
||||
import com.agileboot.common.enums.BasicEnum;
|
||||
|
||||
/**
|
||||
* @author valarchie
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.agileboot.common.core.enums.common;
|
||||
package com.agileboot.common.enums.common;
|
||||
|
||||
import com.agileboot.common.core.enums.dictionary.CssTag;
|
||||
import com.agileboot.common.core.enums.dictionary.Dictionary;
|
||||
import com.agileboot.common.core.enums.DictionaryEnum;
|
||||
import com.agileboot.common.enums.dictionary.CssTag;
|
||||
import com.agileboot.common.enums.dictionary.Dictionary;
|
||||
import com.agileboot.common.enums.DictionaryEnum;
|
||||
|
||||
/**
|
||||
* 对应sys_notice的 status字段
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.agileboot.common.core.enums.common;
|
||||
package com.agileboot.common.enums.common;
|
||||
|
||||
import com.agileboot.common.core.enums.dictionary.CssTag;
|
||||
import com.agileboot.common.core.enums.dictionary.Dictionary;
|
||||
import com.agileboot.common.core.enums.DictionaryEnum;
|
||||
import com.agileboot.common.enums.dictionary.CssTag;
|
||||
import com.agileboot.common.enums.dictionary.Dictionary;
|
||||
import com.agileboot.common.enums.DictionaryEnum;
|
||||
|
||||
/**
|
||||
* 对应sys_notice的 notice_type字段
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.agileboot.common.core.enums.common;
|
||||
package com.agileboot.common.enums.common;
|
||||
|
||||
import com.agileboot.common.core.enums.dictionary.CssTag;
|
||||
import com.agileboot.common.core.enums.dictionary.Dictionary;
|
||||
import com.agileboot.common.core.enums.DictionaryEnum;
|
||||
import com.agileboot.common.enums.dictionary.CssTag;
|
||||
import com.agileboot.common.enums.dictionary.Dictionary;
|
||||
import com.agileboot.common.enums.DictionaryEnum;
|
||||
|
||||
/**
|
||||
* 对应sys_operation_log的status字段
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.agileboot.common.core.enums.common;
|
||||
package com.agileboot.common.enums.common;
|
||||
|
||||
import com.agileboot.common.core.enums.dictionary.Dictionary;
|
||||
import com.agileboot.common.core.enums.BasicEnum;
|
||||
import com.agileboot.common.enums.dictionary.Dictionary;
|
||||
import com.agileboot.common.enums.BasicEnum;
|
||||
|
||||
/**
|
||||
* 操作者类型
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.agileboot.common.core.enums.common;
|
||||
package com.agileboot.common.enums.common;
|
||||
|
||||
import com.agileboot.common.core.enums.BasicEnum;
|
||||
import com.agileboot.common.enums.BasicEnum;
|
||||
|
||||
/**
|
||||
* Http Method
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.agileboot.common.core.enums.common;
|
||||
package com.agileboot.common.enums.common;
|
||||
|
||||
import com.agileboot.common.core.enums.dictionary.CssTag;
|
||||
import com.agileboot.common.core.enums.dictionary.Dictionary;
|
||||
import com.agileboot.common.core.enums.DictionaryEnum;
|
||||
import com.agileboot.common.enums.dictionary.CssTag;
|
||||
import com.agileboot.common.enums.dictionary.Dictionary;
|
||||
import com.agileboot.common.enums.DictionaryEnum;
|
||||
|
||||
/**
|
||||
* 除非表有特殊指明的话,一般用这个枚举代表 status字段
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.agileboot.common.core.enums.common;
|
||||
package com.agileboot.common.enums.common;
|
||||
|
||||
import com.agileboot.common.core.enums.dictionary.CssTag;
|
||||
import com.agileboot.common.core.enums.dictionary.Dictionary;
|
||||
import com.agileboot.common.core.enums.DictionaryEnum;
|
||||
import com.agileboot.common.enums.dictionary.CssTag;
|
||||
import com.agileboot.common.enums.dictionary.Dictionary;
|
||||
import com.agileboot.common.enums.DictionaryEnum;
|
||||
|
||||
/**
|
||||
* 对应sys_user的status字段
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.agileboot.common.core.enums.common;
|
||||
package com.agileboot.common.enums.common;
|
||||
|
||||
import com.agileboot.common.core.enums.dictionary.CssTag;
|
||||
import com.agileboot.common.core.enums.dictionary.Dictionary;
|
||||
import com.agileboot.common.core.enums.DictionaryEnum;
|
||||
import com.agileboot.common.enums.dictionary.CssTag;
|
||||
import com.agileboot.common.enums.dictionary.Dictionary;
|
||||
import com.agileboot.common.enums.DictionaryEnum;
|
||||
|
||||
/**
|
||||
* 对应sys_menu表的is_visible字段
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.agileboot.common.core.enums.common;
|
||||
package com.agileboot.common.enums.common;
|
||||
|
||||
import com.agileboot.common.core.enums.DictionaryEnum;
|
||||
import com.agileboot.common.core.enums.dictionary.CssTag;
|
||||
import com.agileboot.common.core.enums.dictionary.Dictionary;
|
||||
import com.agileboot.common.enums.DictionaryEnum;
|
||||
import com.agileboot.common.enums.dictionary.CssTag;
|
||||
import com.agileboot.common.enums.dictionary.Dictionary;
|
||||
|
||||
/**
|
||||
* 系统内代表是与否的枚举
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.agileboot.common.core.enums.dictionary;
|
||||
package com.agileboot.common.enums.dictionary;
|
||||
|
||||
/**
|
||||
* Css 样式
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.agileboot.common.core.enums.dictionary;
|
||||
package com.agileboot.common.enums.dictionary;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.agileboot.common.core.enums.dictionary;
|
||||
package com.agileboot.common.enums.dictionary;
|
||||
|
||||
import com.agileboot.common.core.enums.DictionaryEnum;
|
||||
import com.agileboot.common.enums.DictionaryEnum;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.agileboot.common.core.exception;
|
||||
package com.agileboot.common.exception;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.agileboot.common.core.exception.error.ErrorCodeInterface;
|
||||
import com.agileboot.common.core.utils.i18n.MessageUtils;
|
||||
import com.agileboot.common.exception.error.ErrorCodeInterface;
|
||||
import com.agileboot.common.utils.i18n.MessageUtils;
|
||||
import java.util.HashMap;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.agileboot.common.core.exception.error;
|
||||
package com.agileboot.common.exception.error;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.agileboot.common.core.exception.error;
|
||||
package com.agileboot.common.exception.error;
|
||||
|
||||
/**
|
||||
* @author valarchie
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.agileboot.common.core.utils;
|
||||
package com.agileboot.common.utils;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -6,8 +6,8 @@ import org.springframework.web.context.request.RequestAttributes;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
@@ -73,24 +73,5 @@ public class ServletHolderUtil {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取客户端IP地址(兼容代理头)
|
||||
*/
|
||||
public static String getClientIp() {
|
||||
HttpServletRequest request = getRequest();
|
||||
String xForwardedFor = request.getHeader("X-Forwarded-For");
|
||||
if (StrUtil.isNotEmpty(xForwardedFor)) {
|
||||
// 可能存在多个IP,取第一个
|
||||
int commaIndex = xForwardedFor.indexOf(',');
|
||||
return commaIndex > 0 ? xForwardedFor.substring(0, commaIndex).trim() : xForwardedFor.trim();
|
||||
}
|
||||
String realIp = request.getHeader("X-Real-IP");
|
||||
if (StrUtil.isNotEmpty(realIp)) {
|
||||
return realIp.trim();
|
||||
}
|
||||
return request.getRemoteAddr();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.agileboot.common.core.utils.file;
|
||||
package com.agileboot.common.utils.file;
|
||||
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
@@ -7,12 +7,12 @@ import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import com.agileboot.common.core.config.AgileBootConfig;
|
||||
import com.agileboot.common.core.constant.Constants;
|
||||
import com.agileboot.common.core.exception.ApiException;
|
||||
import com.agileboot.common.core.exception.error.ErrorCode;
|
||||
import com.agileboot.common.core.exception.error.ErrorCode.Business;
|
||||
import com.agileboot.common.core.exception.error.ErrorCode.Internal;
|
||||
import com.agileboot.common.config.AgileBootConfig;
|
||||
import com.agileboot.common.constant.Constants;
|
||||
import com.agileboot.common.exception.ApiException;
|
||||
import com.agileboot.common.exception.error.ErrorCode;
|
||||
import com.agileboot.common.exception.error.ErrorCode.Business;
|
||||
import com.agileboot.common.exception.error.ErrorCode.Internal;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.util.MimeType;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.agileboot.common.core.utils.i18n;
|
||||
package com.agileboot.common.utils.i18n;
|
||||
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import org.springframework.context.MessageSource;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.agileboot.common.core.utils.ip;
|
||||
package com.agileboot.common.utils.ip;
|
||||
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import lombok.AllArgsConstructor;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.agileboot.common.core.utils.ip;
|
||||
package com.agileboot.common.utils.ip;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.agileboot.common.core.utils.ip;
|
||||
package com.agileboot.common.utils.ip;
|
||||
|
||||
import cn.hutool.core.lang.Validator;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.agileboot.common.core.utils.ip;
|
||||
package com.agileboot.common.utils.ip;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -1,10 +1,10 @@
|
||||
package com.agileboot.common.core.utils.ip;
|
||||
package com.agileboot.common.utils.ip;
|
||||
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.agileboot.common.core.config.AgileBootConfig;
|
||||
import com.agileboot.common.core.utils.jackson.JacksonUtil;
|
||||
import com.agileboot.common.config.AgileBootConfig;
|
||||
import com.agileboot.common.utils.jackson.JacksonUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user