Compare commits
4 Commits
main
..
98eae63435
| Author | SHA1 | Date | |
|---|---|---|---|
| 98eae63435 | |||
| d26a012edb | |||
| ebccb7283f | |||
| 2a702fa6a9 |
@@ -0,0 +1,12 @@
|
|||||||
|
MYSQL_ROOT_PASSWORD=root123
|
||||||
|
MYSQL_DATABASE=todo_agileboot_pure
|
||||||
|
MYSQL_APP_USERNAME=todo_app
|
||||||
|
MYSQL_APP_PASSWORD=todo_app123
|
||||||
|
MYSQL_PORT=3306
|
||||||
|
|
||||||
|
REDIS_PASSWORD=redis123
|
||||||
|
REDIS_PORT=6379
|
||||||
|
|
||||||
|
APP_PORT=8080
|
||||||
|
WEB_PORT=8081
|
||||||
|
JAVA_OPTS=-Xms256m -Xmx512m
|
||||||
+2
-1
@@ -1,5 +1,6 @@
|
|||||||
# Common
|
# Common
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
/.env
|
||||||
.idea/
|
.idea/
|
||||||
*.iws
|
*.iws
|
||||||
*.iml
|
*.iml
|
||||||
@@ -68,4 +69,4 @@
|
|||||||
!/backend/*/build/*.xml
|
!/backend/*/build/*.xml
|
||||||
|
|
||||||
# Backend local configuration
|
# Backend local configuration
|
||||||
/backend/agileboot-admin/src/main/resources/application-prod.yml
|
/backend/.env
|
||||||
|
|||||||
@@ -1,127 +1,232 @@
|
|||||||
# Simple Template
|
# Simple Todo
|
||||||
|
|
||||||
## Quick Start
|
`simple-todo` 是一个前后端分离的待办/后台管理模板项目。后端基于 AgileBoot 的 Spring Boot 分层架构改造,前端包含 Web 管理端和 Taro 多端应用,根目录提供 Docker Compose 用于本地依赖启动和生产部署。
|
||||||
|
|
||||||
This project contains:
|
## 项目架构
|
||||||
|
|
||||||
- `backend`: Spring Boot admin API.
|
### 原仓库地址
|
||||||
- `frontend/web`: Vite + Vue 3 admin frontend.
|
|
||||||
- `frontend/app`: Taro + Vue 3 app frontend.
|
|
||||||
|
|
||||||
The local development flow starts MySQL and Redis with Docker, then runs the
|
当前项目是在以下开源项目基础上改造:
|
||||||
backend and web frontend locally.
|
|
||||||
|
|
||||||
### Requirements
|
- 后端原仓库:<https://github.com/valarchie/AgileBoot-Back-End>
|
||||||
|
- Web 前端原仓库:<https://github.com/valarchie/agileboot-front-end-pure>
|
||||||
|
- Web UI 上游项目:<https://github.com/pure-admin/vue-pure-admin>
|
||||||
|
|
||||||
|
### 目录结构
|
||||||
|
|
||||||
|
```text
|
||||||
|
simple-todo
|
||||||
|
├── backend # Spring Boot 后端
|
||||||
|
│ ├── agileboot-admin # 后台管理接口启动模块
|
||||||
|
│ ├── agileboot-api # 开放接口模块
|
||||||
|
│ ├── agileboot-common # 通用工具与基础能力
|
||||||
|
│ ├── agileboot-domain # 业务领域模块
|
||||||
|
│ ├── agileboot-infrastructure # 基础设施、配置、集成能力
|
||||||
|
│ └── sql # 初始化 SQL
|
||||||
|
├── frontend
|
||||||
|
│ ├── web # Vite + Vue 3 Web 管理端
|
||||||
|
│ └── app # Taro + Vue 3 多端应用
|
||||||
|
├── docs # 项目开发约定
|
||||||
|
├── docker-compose.yml # MySQL、Redis、后端、Web 编排
|
||||||
|
└── .env.example # Docker Compose 环境变量示例
|
||||||
|
```
|
||||||
|
|
||||||
|
## 基础环境
|
||||||
|
|
||||||
- JDK 8+
|
- JDK 8+
|
||||||
- Docker Desktop or Docker Engine with Compose
|
- Maven 3.8+,也可以直接使用 `backend/mvnw` 或 `backend/mvnw.cmd`
|
||||||
- Node.js
|
- Node.js 22+,推荐配合 Corepack 使用 pnpm
|
||||||
- pnpm
|
- pnpm,Dockerfile 中使用 `pnpm@11.1.3`
|
||||||
|
- Docker Desktop 或 Docker Engine + Docker Compose
|
||||||
|
|
||||||
### Start Infrastructure
|
## 开发启动步骤
|
||||||
|
|
||||||
The development backend is configured to use the same defaults as
|
### 1. 准备环境变量
|
||||||
`backend/docker-compose.yml`:
|
|
||||||
|
|
||||||
- MySQL: `localhost:3306`, user `root`, password `root123`
|
Docker Compose 在项目根目录执行时会自动读取 `.env`。可以从示例文件复制:
|
||||||
- Redis: `localhost:6379`, password `redis123`
|
|
||||||
- Database name: `agileboot_pure`
|
|
||||||
|
|
||||||
You can start MySQL and Redis manually:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd backend
|
cp .env.example .env
|
||||||
docker compose up -d
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The compose configuration mounts `backend/sql/agileboot.sql` into the MySQL
|
Windows PowerShell:
|
||||||
container as `/docker-entrypoint-initdb.d/01-agileboot.sql`.
|
|
||||||
The official MySQL image only runs files in `/docker-entrypoint-initdb.d` when
|
|
||||||
the database directory is empty, during the first initialization of the
|
|
||||||
`mysql_data` volume.
|
|
||||||
|
|
||||||
If MySQL has already been started before, the `mysql_data` volume already
|
```powershell
|
||||||
contains data and `docker compose up -d` will not import the SQL again. To
|
Copy-Item .env.example .env
|
||||||
reinitialize the local database, remove the volumes first:
|
```
|
||||||
|
|
||||||
|
`.env.example` 默认把 MySQL 和 Redis 映射到宿主机 `3306`、`6379`,与后端 `application-dev.yml` 的本地开发配置保持一致。
|
||||||
|
|
||||||
|
### 2. 启动 MySQL 和 Redis
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose up -d mysql redis
|
||||||
|
```
|
||||||
|
|
||||||
|
首次启动 MySQL 容器时,Compose 会把 `backend/sql/agileboot.sql` 挂载到 `/docker-entrypoint-initdb.d/01-agileboot.sql`,由 MySQL 镜像自动初始化数据库。
|
||||||
|
|
||||||
|
如果数据库卷已经存在,初始化 SQL 不会重复执行。需要重建本地数据时可以执行:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd backend
|
|
||||||
docker compose down -v
|
docker compose down -v
|
||||||
docker compose up -d
|
docker compose up -d mysql redis
|
||||||
```
|
```
|
||||||
|
|
||||||
Warning: `docker compose down -v` deletes the local MySQL and Redis volumes,
|
`docker compose down -v` 会删除本地 MySQL 和 Redis 数据卷,请确认不需要保留本地数据后再执行。
|
||||||
including existing database data and Redis data.
|
|
||||||
|
|
||||||
If you do not want to delete the volumes, import the SQL manually:
|
### 3. 启动后端
|
||||||
|
|
||||||
```bash
|
Windows PowerShell:
|
||||||
|
|
||||||
|
```powershell
|
||||||
cd backend
|
cd backend
|
||||||
docker exec -i mysql-server mysql -uroot -proot123 agileboot_pure < sql/agileboot.sql
|
.\mvnw.cmd -pl agileboot-admin spring-boot:run
|
||||||
```
|
```
|
||||||
|
|
||||||
### Install Frontend Dependencies
|
macOS / Linux:
|
||||||
|
|
||||||
```bash
|
|
||||||
cd frontend
|
|
||||||
pnpm install
|
|
||||||
```
|
|
||||||
|
|
||||||
### Start Backend and Web Frontend
|
|
||||||
|
|
||||||
Start the backend:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd backend
|
cd backend
|
||||||
./mvnw -pl agileboot-admin spring-boot:run
|
./mvnw -pl agileboot-admin spring-boot:run
|
||||||
```
|
```
|
||||||
|
|
||||||
Start the web frontend:
|
后端默认地址:
|
||||||
|
|
||||||
```bash
|
```text
|
||||||
cd frontend
|
http://localhost:8080
|
||||||
pnpm dev:web
|
|
||||||
```
|
```
|
||||||
|
|
||||||
- Backend: `http://localhost:8080`
|
接口文档地址:
|
||||||
- Frontend: Vite output, usually `http://localhost:80/`
|
|
||||||
|
|
||||||
The frontend development proxy maps `/dev-api` to `http://localhost:8080`.
|
```text
|
||||||
|
http://localhost:8080/swagger-ui/index.html
|
||||||
Optional app commands:
|
http://localhost:8080/v3/api-docs
|
||||||
|
|
||||||
```bash
|
|
||||||
cd frontend
|
|
||||||
pnpm dev:app:weapp
|
|
||||||
pnpm dev:app:h5
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Git Hooks
|
### 4. 启动 Web 管理端
|
||||||
|
|
||||||
This repository uses `.githooks` as the single Git hooks entrypoint.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git config core.hooksPath .githooks
|
|
||||||
```
|
|
||||||
|
|
||||||
The frontend workspace uses pnpm:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd frontend
|
cd frontend
|
||||||
pnpm install
|
pnpm install
|
||||||
pnpm dev:web
|
pnpm dev:web
|
||||||
pnpm build:web
|
|
||||||
pnpm dev:app:weapp
|
|
||||||
pnpm build:app:weapp
|
|
||||||
pnpm lint
|
|
||||||
pnpm typecheck
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Frontend
|
`frontend/web/.env.development` 默认配置:
|
||||||
|
|
||||||
`frontend` is a pnpm workspace:
|
```env
|
||||||
|
VITE_PORT=80
|
||||||
|
VITE_APP_BASE_API=/dev-api
|
||||||
|
```
|
||||||
|
|
||||||
- `web`: Vite + Vue 3 admin frontend.
|
Web 开发服务默认地址:
|
||||||
- `app`: Taro + Vue 3 app frontend.
|
|
||||||
|
|
||||||
Shared engineering configuration lives in `frontend` root. Subprojects should extend the shared TypeScript, ESLint, Stylelint, Prettier, commitlint, and lint-staged configuration instead of duplicating it.
|
```text
|
||||||
|
http://localhost:80
|
||||||
|
```
|
||||||
|
|
||||||
|
如果 80 端口被占用,可以修改 `frontend/web/.env.development` 中的 `VITE_PORT`。
|
||||||
|
|
||||||
|
### 5. 启动 App 端,可选
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd frontend
|
||||||
|
pnpm dev:app:weapp
|
||||||
|
```
|
||||||
|
|
||||||
|
H5 模式:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd frontend
|
||||||
|
pnpm dev:app:h5
|
||||||
|
```
|
||||||
|
|
||||||
|
## 部署步骤
|
||||||
|
|
||||||
|
生产部署推荐使用根目录的 Docker Compose。它会启动 MySQL、Redis、后端服务和 Web Nginx 服务。
|
||||||
|
|
||||||
|
### 1. 准备生产环境变量
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp .env.example .env
|
||||||
|
```
|
||||||
|
|
||||||
|
按实际环境修改 `.env`,至少建议调整:
|
||||||
|
|
||||||
|
```env
|
||||||
|
MYSQL_ROOT_PASSWORD=请替换为强密码
|
||||||
|
MYSQL_DATABASE=todo_agileboot_pure
|
||||||
|
MYSQL_APP_USERNAME=todo_app
|
||||||
|
MYSQL_APP_PASSWORD=请替换为强密码
|
||||||
|
MYSQL_PORT=13306
|
||||||
|
|
||||||
|
REDIS_PASSWORD=请替换为强密码
|
||||||
|
REDIS_PORT=16379
|
||||||
|
|
||||||
|
APP_PORT=8080
|
||||||
|
WEB_PORT=8081
|
||||||
|
JAVA_OPTS=-Xms256m -Xmx512m
|
||||||
|
```
|
||||||
|
|
||||||
|
生产环境建议把 `MYSQL_PORT`、`REDIS_PORT` 改成非默认宿主机端口,例如上面的 `13306`、`16379`。这两个变量只影响宿主机暴露端口,不影响容器内部端口;后端容器仍通过 Compose 内部网络访问 MySQL `3306` 和 Redis `6379`。
|
||||||
|
|
||||||
|
如果数据库和 Redis 只给后端容器使用,建议进一步通过服务器防火墙限制这些端口的外部访问,或按实际部署需要移除 `docker-compose.yml` 中 MySQL/Redis 的 `ports` 暴露配置。
|
||||||
|
|
||||||
|
不要提交真实生产 `.env` 文件。
|
||||||
|
|
||||||
|
### 2. 构建并启动完整服务
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose --profile prod up -d --build
|
||||||
|
```
|
||||||
|
|
||||||
|
Compose 会执行以下构建:
|
||||||
|
|
||||||
|
- `backend/Dockerfile`:使用 Maven 构建 `agileboot-admin`,运行 Spring Boot Jar。
|
||||||
|
- `frontend/web/Dockerfile`:构建 Web 静态文件,并用 Nginx 提供访问。
|
||||||
|
|
||||||
|
Web 容器中的 Nginx 会把 `/prod-api/` 代理到 Compose 内部的后端服务 `app:8080`。
|
||||||
|
|
||||||
|
### 3. 访问服务
|
||||||
|
|
||||||
|
默认访问地址:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Web:http://localhost:8081
|
||||||
|
后端:http://localhost:8080
|
||||||
|
```
|
||||||
|
|
||||||
|
如果修改了 `.env` 中的 `WEB_PORT` 或 `APP_PORT`,以实际端口为准。
|
||||||
|
|
||||||
|
### 4. 常用运维命令
|
||||||
|
|
||||||
|
查看服务状态:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose --profile prod ps
|
||||||
|
```
|
||||||
|
|
||||||
|
查看后端日志:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose --profile prod logs -f app
|
||||||
|
```
|
||||||
|
|
||||||
|
查看 Web 日志:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose --profile prod logs -f web
|
||||||
|
```
|
||||||
|
|
||||||
|
停止服务:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose --profile prod down
|
||||||
|
```
|
||||||
|
|
||||||
|
停止并删除数据卷:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose --profile prod down -v
|
||||||
|
```
|
||||||
|
|
||||||
|
`down -v` 会删除数据库和 Redis 数据,生产环境谨慎使用。
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
.idea
|
||||||
|
*.iml
|
||||||
|
*.log
|
||||||
|
**/target
|
||||||
|
build
|
||||||
|
dist
|
||||||
|
.gradle
|
||||||
|
.mvn/wrapper/maven-wrapper.jar
|
||||||
|
.env
|
||||||
|
docker-compose.yml
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
FROM maven:3.8.8-eclipse-temurin-8 AS build-stage
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
RUN mvn -pl agileboot-admin -am package -Dmaven.test.skip=true -B
|
||||||
|
|
||||||
|
FROM eclipse-temurin:8-jre
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
ENV TZ=Asia/Shanghai
|
||||||
|
|
||||||
|
COPY --from=build-stage /app/agileboot-admin/target/*.jar /app/app.jar
|
||||||
|
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar /app/app.jar"]
|
||||||
+84
@@ -0,0 +1,84 @@
|
|||||||
|
package com.agileboot.admin.controller.app;
|
||||||
|
|
||||||
|
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.core.dto.ResponseDTO;
|
||||||
|
import com.agileboot.domain.common.dto.CurrentLoginUserDTO;
|
||||||
|
import com.agileboot.domain.common.dto.TokenDTO;
|
||||||
|
import com.agileboot.domain.system.user.UserApplicationService;
|
||||||
|
import com.agileboot.domain.system.user.command.RegisterUserCommand;
|
||||||
|
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 lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author codex
|
||||||
|
*/
|
||||||
|
@Tag(name = "小程序登录API", description = "小程序登录注册相关接口")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/app")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class AppAuthController {
|
||||||
|
|
||||||
|
private final LoginService loginService;
|
||||||
|
private final UserApplicationService userApplicationService;
|
||||||
|
|
||||||
|
@Operation(summary = "小程序配置")
|
||||||
|
@GetMapping("/getConfig")
|
||||||
|
public ResponseDTO<ConfigDTO> getConfig() {
|
||||||
|
return ResponseDTO.ok(loginService.getConfig());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "小程序验证码")
|
||||||
|
@GetMapping("/captchaImage")
|
||||||
|
public ResponseDTO<CaptchaDTO> getCaptchaImg() {
|
||||||
|
return ResponseDTO.ok(loginService.generateCaptchaImg());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "小程序登录")
|
||||||
|
@PostMapping("/login")
|
||||||
|
public ResponseDTO<TokenDTO> login(@RequestBody LoginCommand command) {
|
||||||
|
String token = loginService.login(command);
|
||||||
|
return ResponseDTO.ok(buildTokenDTO(token));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "小程序注册")
|
||||||
|
@PostMapping("/register")
|
||||||
|
public ResponseDTO<TokenDTO> register(@Validated @RequestBody RegisterUserCommand command) {
|
||||||
|
decryptRegisterPassword(command);
|
||||||
|
loginService.validateCaptchaIfEnabled(command.getUsername(), command.getCaptchaCode(),
|
||||||
|
command.getCaptchaCodeKey());
|
||||||
|
userApplicationService.registerUser(command);
|
||||||
|
loginService.recordRegisterInfo(command.getUsername());
|
||||||
|
return ResponseDTO.ok(buildTokenDTO(loginService.createTokenForRegisteredUser(command.getUsername())));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "小程序当前登录用户")
|
||||||
|
@GetMapping("/getLoginUserInfo")
|
||||||
|
public ResponseDTO<CurrentLoginUserDTO> getLoginUserInfo() {
|
||||||
|
SystemLoginUser loginUser = AuthenticationUtils.getSystemLoginUser();
|
||||||
|
return ResponseDTO.ok(userApplicationService.getLoginUserInfo(loginUser));
|
||||||
|
}
|
||||||
|
|
||||||
|
private TokenDTO buildTokenDTO(String token) {
|
||||||
|
SystemLoginUser loginUser = AuthenticationUtils.getSystemLoginUser();
|
||||||
|
CurrentLoginUserDTO currentUser = userApplicationService.getLoginUserInfo(loginUser);
|
||||||
|
return new TokenDTO(token, currentUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void decryptRegisterPassword(RegisterUserCommand command) {
|
||||||
|
command.setPassword(loginService.decryptPassword(command.getPassword()));
|
||||||
|
command.setConfirmPassword(loginService.decryptPassword(command.getConfirmPassword()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+90
@@ -0,0 +1,90 @@
|
|||||||
|
package com.agileboot.admin.controller.app;
|
||||||
|
|
||||||
|
import com.agileboot.common.core.dto.ResponseDTO;
|
||||||
|
import com.agileboot.common.core.page.PageDTO;
|
||||||
|
import com.agileboot.domain.collaboration.record.CollaborationRecordApplicationService;
|
||||||
|
import com.agileboot.domain.collaboration.record.command.AddCollaborationRecordCommand;
|
||||||
|
import com.agileboot.domain.collaboration.record.command.UpdateCollaborationRecordCommand;
|
||||||
|
import com.agileboot.domain.collaboration.record.dto.CollaborationMonthlyStatisticsDTO;
|
||||||
|
import com.agileboot.domain.collaboration.record.dto.CollaborationOptionDTO;
|
||||||
|
import com.agileboot.domain.collaboration.record.dto.CollaborationRecordDTO;
|
||||||
|
import com.agileboot.domain.collaboration.record.dto.CollaborationRecordDetailDTO;
|
||||||
|
import com.agileboot.domain.collaboration.record.query.CollaborationRecordQuery;
|
||||||
|
import com.agileboot.domain.common.command.BulkOperationCommand;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.validation.Valid;
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import javax.validation.constraints.Positive;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author codex
|
||||||
|
*/
|
||||||
|
@Tag(name = "小程序合作记录API", description = "小程序合作记录相关接口")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/app/collaboration/record")
|
||||||
|
@Validated
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class AppCollaborationRecordController {
|
||||||
|
|
||||||
|
private final CollaborationRecordApplicationService recordApplicationService;
|
||||||
|
|
||||||
|
@Operation(summary = "小程序合作记录列表")
|
||||||
|
@GetMapping("/list")
|
||||||
|
public ResponseDTO<PageDTO<CollaborationRecordDTO>> list(CollaborationRecordQuery query) {
|
||||||
|
return ResponseDTO.ok(recordApplicationService.getRecordList(query));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "小程序合作记录详情")
|
||||||
|
@GetMapping("/{recordId}")
|
||||||
|
public ResponseDTO<CollaborationRecordDetailDTO> getInfo(@PathVariable @Positive Long recordId) {
|
||||||
|
return ResponseDTO.ok(recordApplicationService.getRecordInfo(recordId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "小程序合作记录选项")
|
||||||
|
@GetMapping("/options")
|
||||||
|
public ResponseDTO<List<CollaborationOptionDTO>> options() {
|
||||||
|
return ResponseDTO.ok(recordApplicationService.getOptions());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "小程序合作记录月度统计")
|
||||||
|
@GetMapping("/monthly-statistics")
|
||||||
|
public ResponseDTO<List<CollaborationMonthlyStatisticsDTO>> monthlyStatistics(@RequestParam Integer year) {
|
||||||
|
return ResponseDTO.ok(recordApplicationService.getMonthlyStatistics(year));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "小程序新增合作记录")
|
||||||
|
@PostMapping
|
||||||
|
public ResponseDTO<Void> add(@Valid @RequestBody AddCollaborationRecordCommand command) {
|
||||||
|
recordApplicationService.addRecord(command);
|
||||||
|
return ResponseDTO.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "小程序修改合作记录")
|
||||||
|
@PutMapping
|
||||||
|
public ResponseDTO<Void> edit(@Valid @RequestBody UpdateCollaborationRecordCommand command) {
|
||||||
|
recordApplicationService.updateRecord(command);
|
||||||
|
return ResponseDTO.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "小程序删除合作记录")
|
||||||
|
@DeleteMapping
|
||||||
|
public ResponseDTO<Void> remove(@RequestParam @NotNull @NotEmpty List<Long> ids) {
|
||||||
|
recordApplicationService.deleteRecord(new BulkOperationCommand<>(ids));
|
||||||
|
return ResponseDTO.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+56
@@ -0,0 +1,56 @@
|
|||||||
|
package com.agileboot.admin.controller.app;
|
||||||
|
|
||||||
|
import com.agileboot.common.core.dto.ResponseDTO;
|
||||||
|
import com.agileboot.domain.system.user.UserApplicationService;
|
||||||
|
import com.agileboot.domain.system.user.command.UpdateProfileCommand;
|
||||||
|
import com.agileboot.domain.system.user.command.UpdateUserPasswordCommand;
|
||||||
|
import com.agileboot.domain.system.user.dto.UserProfileDTO;
|
||||||
|
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 lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author codex
|
||||||
|
*/
|
||||||
|
@Tag(name = "小程序个人信息API", description = "小程序个人信息相关接口")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/app/user/profile")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class AppProfileController {
|
||||||
|
|
||||||
|
private final UserApplicationService userApplicationService;
|
||||||
|
|
||||||
|
@Operation(summary = "小程序获取个人信息")
|
||||||
|
@GetMapping
|
||||||
|
public ResponseDTO<UserProfileDTO> profile() {
|
||||||
|
SystemLoginUser user = AuthenticationUtils.getSystemLoginUser();
|
||||||
|
return ResponseDTO.ok(userApplicationService.getUserProfile(user.getUserId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "小程序修改个人信息")
|
||||||
|
@PutMapping
|
||||||
|
public ResponseDTO<Void> updateProfile(@RequestBody UpdateProfileCommand command) {
|
||||||
|
SystemLoginUser loginUser = AuthenticationUtils.getSystemLoginUser();
|
||||||
|
command.setUserId(loginUser.getUserId());
|
||||||
|
userApplicationService.updateUserProfile(command);
|
||||||
|
return ResponseDTO.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "小程序修改个人密码")
|
||||||
|
@PutMapping("/password")
|
||||||
|
public ResponseDTO<Void> updatePassword(@Validated @RequestBody UpdateUserPasswordCommand command) {
|
||||||
|
SystemLoginUser loginUser = AuthenticationUtils.getSystemLoginUser();
|
||||||
|
command.setUserId(loginUser.getUserId());
|
||||||
|
userApplicationService.updatePasswordBySelf(loginUser, command);
|
||||||
|
return ResponseDTO.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+3
-2
@@ -70,8 +70,9 @@ public class CollaborationRecordController extends BaseController {
|
|||||||
@Operation(summary = "合作记录月度统计")
|
@Operation(summary = "合作记录月度统计")
|
||||||
@PreAuthorize("@permission.has('collaboration:record:statistics')")
|
@PreAuthorize("@permission.has('collaboration:record:statistics')")
|
||||||
@GetMapping("/monthly-statistics")
|
@GetMapping("/monthly-statistics")
|
||||||
public ResponseDTO<List<CollaborationMonthlyStatisticsDTO>> monthlyStatistics(@RequestParam Integer year) {
|
public ResponseDTO<List<CollaborationMonthlyStatisticsDTO>> monthlyStatistics(
|
||||||
return ResponseDTO.ok(recordApplicationService.getMonthlyStatistics(year));
|
@RequestParam Integer year, @RequestParam(required = false) Long creatorId) {
|
||||||
|
return ResponseDTO.ok(recordApplicationService.getMonthlyStatistics(year, creatorId));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "新增合作记录")
|
@Operation(summary = "新增合作记录")
|
||||||
|
|||||||
+3
-2
@@ -24,6 +24,7 @@ import org.springframework.http.MediaType;
|
|||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
@@ -73,7 +74,7 @@ public class FileController {
|
|||||||
*/
|
*/
|
||||||
@Operation(summary = "单个上传文件")
|
@Operation(summary = "单个上传文件")
|
||||||
@PostMapping("/upload")
|
@PostMapping("/upload")
|
||||||
public ResponseDTO<UploadDTO> uploadFile(MultipartFile file) {
|
public ResponseDTO<UploadDTO> uploadFile(@RequestParam("file") MultipartFile file) {
|
||||||
if (file == null) {
|
if (file == null) {
|
||||||
throw new ApiException(ErrorCode.Business.UPLOAD_FILE_IS_EMPTY);
|
throw new ApiException(ErrorCode.Business.UPLOAD_FILE_IS_EMPTY);
|
||||||
}
|
}
|
||||||
@@ -101,7 +102,7 @@ public class FileController {
|
|||||||
*/
|
*/
|
||||||
@Operation(summary = "多个上传文件")
|
@Operation(summary = "多个上传文件")
|
||||||
@PostMapping("/uploads")
|
@PostMapping("/uploads")
|
||||||
public ResponseDTO<List<UploadDTO>> uploadFiles(List<MultipartFile> files) {
|
public ResponseDTO<List<UploadDTO>> uploadFiles(@RequestParam("files") List<MultipartFile> files) {
|
||||||
if (CollUtil.isEmpty(files)) {
|
if (CollUtil.isEmpty(files)) {
|
||||||
throw new ApiException(ErrorCode.Business.UPLOAD_FILE_IS_EMPTY);
|
throw new ApiException(ErrorCode.Business.UPLOAD_FILE_IS_EMPTY);
|
||||||
}
|
}
|
||||||
|
|||||||
+19
-6
@@ -3,14 +3,12 @@ package com.agileboot.admin.controller.common;
|
|||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.agileboot.common.config.AgileBootConfig;
|
import com.agileboot.common.config.AgileBootConfig;
|
||||||
import com.agileboot.common.core.dto.ResponseDTO;
|
import com.agileboot.common.core.dto.ResponseDTO;
|
||||||
import com.agileboot.common.exception.ApiException;
|
|
||||||
import com.agileboot.common.exception.error.ErrorCode.Business;
|
|
||||||
import com.agileboot.domain.common.dto.CurrentLoginUserDTO;
|
import com.agileboot.domain.common.dto.CurrentLoginUserDTO;
|
||||||
import com.agileboot.domain.common.dto.TokenDTO;
|
import com.agileboot.domain.common.dto.TokenDTO;
|
||||||
import com.agileboot.domain.system.menu.MenuApplicationService;
|
import com.agileboot.domain.system.menu.MenuApplicationService;
|
||||||
import com.agileboot.domain.system.menu.dto.RouterDTO;
|
import com.agileboot.domain.system.menu.dto.RouterDTO;
|
||||||
import com.agileboot.domain.system.user.UserApplicationService;
|
import com.agileboot.domain.system.user.UserApplicationService;
|
||||||
import com.agileboot.domain.system.user.command.AddUserCommand;
|
import com.agileboot.domain.system.user.command.RegisterUserCommand;
|
||||||
import com.agileboot.infrastructure.annotations.ratelimit.RateLimit;
|
import com.agileboot.infrastructure.annotations.ratelimit.RateLimit;
|
||||||
import com.agileboot.infrastructure.annotations.ratelimit.RateLimit.CacheType;
|
import com.agileboot.infrastructure.annotations.ratelimit.RateLimit.CacheType;
|
||||||
import com.agileboot.infrastructure.annotations.ratelimit.RateLimit.LimitType;
|
import com.agileboot.infrastructure.annotations.ratelimit.RateLimit.LimitType;
|
||||||
@@ -25,6 +23,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
@@ -130,10 +129,24 @@ public class LoginController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Operation(summary = "注册接口", description = "暂未实现")
|
@Operation(summary = "注册接口")
|
||||||
@PostMapping("/register")
|
@PostMapping("/register")
|
||||||
public ResponseDTO<Void> register(@RequestBody AddUserCommand command) {
|
public ResponseDTO<TokenDTO> register(@Validated @RequestBody RegisterUserCommand command) {
|
||||||
return ResponseDTO.fail(new ApiException(Business.COMMON_UNSUPPORTED_OPERATION));
|
decryptRegisterPassword(command);
|
||||||
|
loginService.validateCaptchaIfEnabled(command.getUsername(), command.getCaptchaCode(), command.getCaptchaCodeKey());
|
||||||
|
userApplicationService.registerUser(command);
|
||||||
|
loginService.recordRegisterInfo(command.getUsername());
|
||||||
|
|
||||||
|
String token = loginService.createTokenForRegisteredUser(command.getUsername());
|
||||||
|
SystemLoginUser loginUser = AuthenticationUtils.getSystemLoginUser();
|
||||||
|
CurrentLoginUserDTO currentUserDTO = userApplicationService.getLoginUserInfo(loginUser);
|
||||||
|
|
||||||
|
return ResponseDTO.ok(new TokenDTO(token, currentUserDTO));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void decryptRegisterPassword(RegisterUserCommand command) {
|
||||||
|
command.setPassword(loginService.decryptPassword(command.getPassword()));
|
||||||
|
command.setConfirmPassword(loginService.decryptPassword(command.getConfirmPassword()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
-111
@@ -1,111 +0,0 @@
|
|||||||
package com.agileboot.admin.controller.system;
|
|
||||||
|
|
||||||
import cn.hutool.core.lang.tree.Tree;
|
|
||||||
import com.agileboot.common.core.base.BaseController;
|
|
||||||
import com.agileboot.common.core.dto.ResponseDTO;
|
|
||||||
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 javax.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;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 部门信息
|
|
||||||
*
|
|
||||||
* @author valarchie
|
|
||||||
*/
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/system")
|
|
||||||
@Validated
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
@Tag(name = "部门API", description = "部门相关的增删查改")
|
|
||||||
public class SysDeptController extends BaseController {
|
|
||||||
|
|
||||||
private final DeptApplicationService deptApplicationService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取部门列表
|
|
||||||
*/
|
|
||||||
@Operation(summary = "部门列表")
|
|
||||||
@PreAuthorize("@permission.has('system:dept:list')")
|
|
||||||
@GetMapping("/depts")
|
|
||||||
public ResponseDTO<List<DeptDTO>> list(DeptQuery query) {
|
|
||||||
List<DeptDTO> deptList = deptApplicationService.getDeptList(query);
|
|
||||||
return ResponseDTO.ok(deptList);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据部门编号获取详细信息
|
|
||||||
*/
|
|
||||||
@Operation(summary = "部门详情")
|
|
||||||
@PreAuthorize("@permission.has('system:dept:query')")
|
|
||||||
@GetMapping(value = "/dept/{deptId}")
|
|
||||||
public ResponseDTO<DeptDTO> getInfo(@PathVariable Long deptId) {
|
|
||||||
DeptDTO dept = deptApplicationService.getDeptInfo(deptId);
|
|
||||||
return ResponseDTO.ok(dept);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取部门下拉树列表
|
|
||||||
*/
|
|
||||||
@Operation(summary = "获取部门树级结构")
|
|
||||||
@GetMapping("/depts/dropdown")
|
|
||||||
public ResponseDTO<List<Tree<Long>>> dropdownList() {
|
|
||||||
List<Tree<Long>> deptTree = deptApplicationService.getDeptTree();
|
|
||||||
return ResponseDTO.ok(deptTree);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增部门
|
|
||||||
*/
|
|
||||||
@Operation(summary = "新增部门")
|
|
||||||
@PreAuthorize("@permission.has('system:dept:add')")
|
|
||||||
@AccessLog(title = "部门管理", businessType = BusinessTypeEnum.ADD)
|
|
||||||
@PostMapping("/dept")
|
|
||||||
public ResponseDTO<Void> add(@RequestBody AddDeptCommand addCommand) {
|
|
||||||
deptApplicationService.addDept(addCommand);
|
|
||||||
return ResponseDTO.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改部门
|
|
||||||
*/
|
|
||||||
@Operation(summary = "修改部门")
|
|
||||||
@PreAuthorize("@permission.has('system:dept:edit') AND @dataScope.checkDeptId(#updateCommand.deptId)")
|
|
||||||
@AccessLog(title = "部门管理", businessType = BusinessTypeEnum.MODIFY)
|
|
||||||
@PutMapping("/dept/{deptId}")
|
|
||||||
public ResponseDTO<Void> edit(@PathVariable("deptId")Long deptId, @RequestBody UpdateDeptCommand updateCommand) {
|
|
||||||
updateCommand.setDeptId(deptId);
|
|
||||||
deptApplicationService.updateDept(updateCommand);
|
|
||||||
return ResponseDTO.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除部门
|
|
||||||
*/
|
|
||||||
@Operation(summary = "删除部门")
|
|
||||||
@PreAuthorize("@permission.has('system:dept:remove') AND @dataScope.checkDeptId(#deptId)")
|
|
||||||
@AccessLog(title = "部门管理", businessType = BusinessTypeEnum.DELETE)
|
|
||||||
@DeleteMapping("/dept/{deptId}")
|
|
||||||
public ResponseDTO<Void> remove(@PathVariable @NotNull Long deptId) {
|
|
||||||
deptApplicationService.removeDept(deptId);
|
|
||||||
return ResponseDTO.ok();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-122
@@ -1,122 +0,0 @@
|
|||||||
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.post.PostApplicationService;
|
|
||||||
import com.agileboot.domain.system.post.command.AddPostCommand;
|
|
||||||
import com.agileboot.domain.system.post.command.UpdatePostCommand;
|
|
||||||
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 javax.servlet.http.HttpServletResponse;
|
|
||||||
import javax.validation.constraints.NotEmpty;
|
|
||||||
import javax.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;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 岗位信息操作处理
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
*/
|
|
||||||
@Tag(name = "职位API", description = "职位相关的增删查改")
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/system/post")
|
|
||||||
@Validated
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class SysPostController extends BaseController {
|
|
||||||
|
|
||||||
private final PostApplicationService postApplicationService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取岗位列表
|
|
||||||
*/
|
|
||||||
@Operation(summary = "职位列表")
|
|
||||||
@PreAuthorize("@permission.has('system:post:list')")
|
|
||||||
@GetMapping("/list")
|
|
||||||
public ResponseDTO<PageDTO<PostDTO>> list(PostQuery query) {
|
|
||||||
PageDTO<PostDTO> pageDTO = postApplicationService.getPostList(query);
|
|
||||||
return ResponseDTO.ok(pageDTO);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 导出查询到的所有岗位信息到excel文件
|
|
||||||
* @param response http响应
|
|
||||||
* @param query 查询参数
|
|
||||||
* @author Kevin Zhang
|
|
||||||
* @date 2023-10-02
|
|
||||||
*/
|
|
||||||
@Operation(summary = "职位列表导出")
|
|
||||||
@AccessLog(title = "岗位管理", businessType = BusinessTypeEnum.EXPORT)
|
|
||||||
@PreAuthorize("@permission.has('system:post:export')")
|
|
||||||
@GetMapping("/excel")
|
|
||||||
public void export(HttpServletResponse response, PostQuery query) {
|
|
||||||
List<PostDTO> all = postApplicationService.getPostListAll(query);
|
|
||||||
CustomExcelUtil.writeToResponse(all, PostDTO.class, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据岗位编号获取详细信息
|
|
||||||
*/
|
|
||||||
@Operation(summary = "职位详情")
|
|
||||||
@PreAuthorize("@permission.has('system:post:query')")
|
|
||||||
@GetMapping(value = "/{postId}")
|
|
||||||
public ResponseDTO<PostDTO> getInfo(@PathVariable Long postId) {
|
|
||||||
PostDTO post = postApplicationService.getPostInfo(postId);
|
|
||||||
return ResponseDTO.ok(post);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增岗位
|
|
||||||
*/
|
|
||||||
@Operation(summary = "添加职位")
|
|
||||||
@PreAuthorize("@permission.has('system:post:add')")
|
|
||||||
@AccessLog(title = "岗位管理", businessType = BusinessTypeEnum.ADD)
|
|
||||||
@PostMapping
|
|
||||||
public ResponseDTO<Void> add(@RequestBody AddPostCommand addCommand) {
|
|
||||||
postApplicationService.addPost(addCommand);
|
|
||||||
return ResponseDTO.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改岗位
|
|
||||||
*/
|
|
||||||
@Operation(summary = "修改职位")
|
|
||||||
@PreAuthorize("@permission.has('system:post:edit')")
|
|
||||||
@AccessLog(title = "岗位管理", businessType = BusinessTypeEnum.MODIFY)
|
|
||||||
@PutMapping
|
|
||||||
public ResponseDTO<Void> edit(@RequestBody UpdatePostCommand updateCommand) {
|
|
||||||
postApplicationService.updatePost(updateCommand);
|
|
||||||
return ResponseDTO.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除岗位
|
|
||||||
*/
|
|
||||||
@Operation(summary = "删除职位")
|
|
||||||
@PreAuthorize("@permission.has('system:post:remove')")
|
|
||||||
@AccessLog(title = "岗位管理", businessType = BusinessTypeEnum.DELETE)
|
|
||||||
@DeleteMapping
|
|
||||||
public ResponseDTO<Void> remove(@RequestParam @NotNull @NotEmpty List<Long> ids) {
|
|
||||||
postApplicationService.deletePost(new BulkOperationCommand<>(ids));
|
|
||||||
return ResponseDTO.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
+2
-1
@@ -19,6 +19,7 @@ import com.agileboot.common.enums.common.BusinessTypeEnum;
|
|||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.PutMapping;
|
import org.springframework.web.bind.annotation.PutMapping;
|
||||||
@@ -71,7 +72,7 @@ public class SysProfileController extends BaseController {
|
|||||||
@Operation(summary = "重置个人密码")
|
@Operation(summary = "重置个人密码")
|
||||||
@AccessLog(title = "个人信息", businessType = BusinessTypeEnum.MODIFY)
|
@AccessLog(title = "个人信息", businessType = BusinessTypeEnum.MODIFY)
|
||||||
@PutMapping("/password")
|
@PutMapping("/password")
|
||||||
public ResponseDTO<Void> updatePassword(@RequestBody UpdateUserPasswordCommand command) {
|
public ResponseDTO<Void> updatePassword(@Validated @RequestBody UpdateUserPasswordCommand command) {
|
||||||
SystemLoginUser loginUser = AuthenticationUtils.getSystemLoginUser();
|
SystemLoginUser loginUser = AuthenticationUtils.getSystemLoginUser();
|
||||||
command.setUserId(loginUser.getUserId());
|
command.setUserId(loginUser.getUserId());
|
||||||
userApplicationService.updatePasswordBySelf(loginUser, command);
|
userApplicationService.updatePasswordBySelf(loginUser, command);
|
||||||
|
|||||||
-16
@@ -6,7 +6,6 @@ import com.agileboot.common.core.page.PageDTO;
|
|||||||
import com.agileboot.common.utils.poi.CustomExcelUtil;
|
import com.agileboot.common.utils.poi.CustomExcelUtil;
|
||||||
import com.agileboot.domain.system.role.RoleApplicationService;
|
import com.agileboot.domain.system.role.RoleApplicationService;
|
||||||
import com.agileboot.domain.system.role.command.AddRoleCommand;
|
import com.agileboot.domain.system.role.command.AddRoleCommand;
|
||||||
import com.agileboot.domain.system.role.command.UpdateDataScopeCommand;
|
|
||||||
import com.agileboot.domain.system.role.command.UpdateRoleCommand;
|
import com.agileboot.domain.system.role.command.UpdateRoleCommand;
|
||||||
import com.agileboot.domain.system.role.command.UpdateStatusCommand;
|
import com.agileboot.domain.system.role.command.UpdateStatusCommand;
|
||||||
import com.agileboot.domain.system.role.dto.RoleDTO;
|
import com.agileboot.domain.system.role.dto.RoleDTO;
|
||||||
@@ -111,21 +110,6 @@ public class SysRoleController extends BaseController {
|
|||||||
return ResponseDTO.ok();
|
return ResponseDTO.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改保存数据权限
|
|
||||||
*/
|
|
||||||
@Operation(summary = "修改角色数据权限")
|
|
||||||
@PreAuthorize("@permission.has('system:role:edit')")
|
|
||||||
@AccessLog(title = "角色管理", businessType = BusinessTypeEnum.MODIFY)
|
|
||||||
@PutMapping("/{roleId}/dataScope")
|
|
||||||
public ResponseDTO<Void> dataScope(@PathVariable("roleId") Long roleId,
|
|
||||||
@RequestBody UpdateDataScopeCommand command) {
|
|
||||||
command.setRoleId(roleId);
|
|
||||||
|
|
||||||
roleApplicationService.updateDataScope(command);
|
|
||||||
return ResponseDTO.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 角色状态修改
|
* 角色状态修改
|
||||||
*/
|
*/
|
||||||
|
|||||||
+2
-2
@@ -52,7 +52,7 @@ public class SysUserController extends BaseController {
|
|||||||
* 获取用户列表
|
* 获取用户列表
|
||||||
*/
|
*/
|
||||||
@Operation(summary = "用户列表")
|
@Operation(summary = "用户列表")
|
||||||
@PreAuthorize("@permission.has('system:user:list') AND @dataScope.checkDeptId(#query.deptId)")
|
@PreAuthorize("@permission.has('system:user:list')")
|
||||||
@GetMapping
|
@GetMapping
|
||||||
public ResponseDTO<PageDTO<UserDTO>> userList(SearchUserQuery<SearchUserDO> query) {
|
public ResponseDTO<PageDTO<UserDTO>> userList(SearchUserQuery<SearchUserDO> query) {
|
||||||
PageDTO<UserDTO> page = userApplicationService.getUserList(query);
|
PageDTO<UserDTO> page = userApplicationService.getUserList(query);
|
||||||
@@ -105,7 +105,7 @@ public class SysUserController extends BaseController {
|
|||||||
* 新增用户
|
* 新增用户
|
||||||
*/
|
*/
|
||||||
@Operation(summary = "新增用户")
|
@Operation(summary = "新增用户")
|
||||||
@PreAuthorize("@permission.has('system:user:add') AND @dataScope.checkDeptId(#command.deptId)")
|
@PreAuthorize("@permission.has('system:user:add')")
|
||||||
@AccessLog(title = "用户管理", businessType = BusinessTypeEnum.ADD)
|
@AccessLog(title = "用户管理", businessType = BusinessTypeEnum.ADD)
|
||||||
@PostMapping
|
@PostMapping
|
||||||
public ResponseDTO<Void> add(@Validated @RequestBody AddUserCommand command) {
|
public ResponseDTO<Void> add(@Validated @RequestBody AddUserCommand command) {
|
||||||
|
|||||||
+1
@@ -135,6 +135,7 @@ public class SecurityConfig {
|
|||||||
// 对于登录login 注册register 验证码captchaImage 以及公共Api的请求允许匿名访问
|
// 对于登录login 注册register 验证码captchaImage 以及公共Api的请求允许匿名访问
|
||||||
// 注意: 当携带token请求以下这几个接口时 会返回403的错误
|
// 注意: 当携带token请求以下这几个接口时 会返回403的错误
|
||||||
.antMatchers("/login", "/register", "/getConfig", "/captchaImage", "/api/**").anonymous()
|
.antMatchers("/login", "/register", "/getConfig", "/captchaImage", "/api/**").anonymous()
|
||||||
|
.antMatchers("/app/login", "/app/register", "/app/getConfig", "/app/captchaImage").anonymous()
|
||||||
.antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js",
|
.antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js",
|
||||||
"/profile/**").permitAll()
|
"/profile/**").permitAll()
|
||||||
// TODO this is danger.
|
// TODO this is danger.
|
||||||
|
|||||||
+34
@@ -40,6 +40,7 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticatio
|
|||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.AuthenticationException;
|
import org.springframework.security.core.AuthenticationException;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.FastByteArrayOutputStream;
|
import org.springframework.util.FastByteArrayOutputStream;
|
||||||
|
|
||||||
@@ -61,6 +62,8 @@ public class LoginService {
|
|||||||
|
|
||||||
private final AuthenticationManager authenticationManager;
|
private final AuthenticationManager authenticationManager;
|
||||||
|
|
||||||
|
private final UserDetailsService userDetailsService;
|
||||||
|
|
||||||
@Resource(name = "captchaProducer")
|
@Resource(name = "captchaProducer")
|
||||||
private Producer captchaProducer;
|
private Producer captchaProducer;
|
||||||
|
|
||||||
@@ -115,6 +118,7 @@ public class LoginService {
|
|||||||
|
|
||||||
boolean isCaptchaOn = isCaptchaOn();
|
boolean isCaptchaOn = isCaptchaOn();
|
||||||
configDTO.setIsCaptchaOn(isCaptchaOn);
|
configDTO.setIsCaptchaOn(isCaptchaOn);
|
||||||
|
configDTO.setIsRegisterUserOn(isRegisterUserOn());
|
||||||
configDTO.setDictionary(MapCache.dictionaryCache());
|
configDTO.setDictionary(MapCache.dictionaryCache());
|
||||||
return configDTO;
|
return configDTO;
|
||||||
}
|
}
|
||||||
@@ -179,6 +183,9 @@ public class LoginService {
|
|||||||
* @param captchaCodeKey 验证码对应的缓存key
|
* @param captchaCodeKey 验证码对应的缓存key
|
||||||
*/
|
*/
|
||||||
public void validateCaptcha(String username, String captchaCode, String captchaCodeKey) {
|
public void validateCaptcha(String username, String captchaCode, String captchaCodeKey) {
|
||||||
|
if (StrUtil.isBlank(captchaCode) || StrUtil.isBlank(captchaCodeKey)) {
|
||||||
|
throw new ApiException(ErrorCode.Business.LOGIN_CAPTCHA_CODE_NULL);
|
||||||
|
}
|
||||||
String captcha = redisCache.captchaCache.getObjectById(captchaCodeKey);
|
String captcha = redisCache.captchaCache.getObjectById(captchaCodeKey);
|
||||||
redisCache.captchaCache.delete(captchaCodeKey);
|
redisCache.captchaCache.delete(captchaCodeKey);
|
||||||
if (captcha == null) {
|
if (captcha == null) {
|
||||||
@@ -193,6 +200,26 @@ public class LoginService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void validateCaptchaIfEnabled(String username, String captchaCode, String captchaCodeKey) {
|
||||||
|
if (isCaptchaOn()) {
|
||||||
|
validateCaptcha(username, captchaCode, captchaCodeKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String createTokenForRegisteredUser(String username) {
|
||||||
|
SystemLoginUser loginUser = (SystemLoginUser) userDetailsService.loadUserByUsername(username);
|
||||||
|
Authentication authentication = new UsernamePasswordAuthenticationToken(loginUser, null,
|
||||||
|
loginUser.getAuthorities());
|
||||||
|
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||||
|
updateLoginInfo(loginUser);
|
||||||
|
return tokenService.createTokenAndPutUserInCache(loginUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void recordRegisterInfo(String username) {
|
||||||
|
ThreadPoolManager.execute(AsyncTaskFactory.loginInfoTask(username, LoginStatusEnum.REGISTER,
|
||||||
|
LoginStatusEnum.REGISTER.description()));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 记录登录信息
|
* 记录登录信息
|
||||||
* @param loginUser 登录用户
|
* @param loginUser 登录用户
|
||||||
@@ -200,7 +227,10 @@ public class LoginService {
|
|||||||
public void recordLoginInfo(SystemLoginUser loginUser) {
|
public void recordLoginInfo(SystemLoginUser loginUser) {
|
||||||
ThreadPoolManager.execute(AsyncTaskFactory.loginInfoTask(loginUser.getUsername(), LoginStatusEnum.LOGIN_SUCCESS,
|
ThreadPoolManager.execute(AsyncTaskFactory.loginInfoTask(loginUser.getUsername(), LoginStatusEnum.LOGIN_SUCCESS,
|
||||||
LoginStatusEnum.LOGIN_SUCCESS.description()));
|
LoginStatusEnum.LOGIN_SUCCESS.description()));
|
||||||
|
updateLoginInfo(loginUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateLoginInfo(SystemLoginUser loginUser) {
|
||||||
SysUserEntity entity = redisCache.userCache.getObjectById(loginUser.getUserId());
|
SysUserEntity entity = redisCache.userCache.getObjectById(loginUser.getUserId());
|
||||||
|
|
||||||
entity.setLoginIp(ServletUtil.getClientIP(ServletHolderUtil.getRequest()));
|
entity.setLoginIp(ServletUtil.getClientIP(ServletHolderUtil.getRequest()));
|
||||||
@@ -219,4 +249,8 @@ public class LoginService {
|
|||||||
return Convert.toBool(guavaCache.configCache.get(ConfigKeyEnum.CAPTCHA.getValue()));
|
return Convert.toBool(guavaCache.configCache.get(ConfigKeyEnum.CAPTCHA.getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isRegisterUserOn() {
|
||||||
|
return Convert.toBool(guavaCache.configCache.get(ConfigKeyEnum.REGISTER.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-12
@@ -1,7 +1,5 @@
|
|||||||
package com.agileboot.admin.customize.service.login;
|
package com.agileboot.admin.customize.service.login;
|
||||||
|
|
||||||
import cn.hutool.core.convert.Convert;
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import com.agileboot.common.exception.ApiException;
|
import com.agileboot.common.exception.ApiException;
|
||||||
import com.agileboot.common.exception.error.ErrorCode;
|
import com.agileboot.common.exception.error.ErrorCode;
|
||||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||||
@@ -24,7 +22,6 @@ import java.util.concurrent.TimeUnit;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.collections4.SetUtils;
|
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
@@ -67,7 +64,7 @@ public class UserDetailsServiceImpl implements UserDetailsService {
|
|||||||
RoleInfo roleInfo = getRoleInfo(userEntity.getRoleId(), userEntity.getIsAdmin());
|
RoleInfo roleInfo = getRoleInfo(userEntity.getRoleId(), userEntity.getIsAdmin());
|
||||||
|
|
||||||
SystemLoginUser loginUser = new SystemLoginUser(userEntity.getUserId(), userEntity.getIsAdmin(), userEntity.getUsername(),
|
SystemLoginUser loginUser = new SystemLoginUser(userEntity.getUserId(), userEntity.getIsAdmin(), userEntity.getUsername(),
|
||||||
userEntity.getPassword(), roleInfo, userEntity.getDeptId());
|
userEntity.getPassword(), roleInfo);
|
||||||
loginUser.fillLoginInfo();
|
loginUser.fillLoginInfo();
|
||||||
loginUser.setAutoRefreshCacheTime(loginUser.getLoginInfo().getLoginTime()
|
loginUser.setAutoRefreshCacheTime(loginUser.getLoginInfo().getLoginTime()
|
||||||
+ TimeUnit.MINUTES.toMillis(tokenService.getAutoRefreshTime()));
|
+ TimeUnit.MINUTES.toMillis(tokenService.getAutoRefreshTime()));
|
||||||
@@ -86,7 +83,7 @@ public class UserDetailsServiceImpl implements UserDetailsService {
|
|||||||
|
|
||||||
Set<Long> allMenuIds = allMenus.stream().map(SysMenuEntity::getMenuId).collect(Collectors.toSet());
|
Set<Long> allMenuIds = allMenus.stream().map(SysMenuEntity::getMenuId).collect(Collectors.toSet());
|
||||||
|
|
||||||
return new RoleInfo(RoleInfo.ADMIN_ROLE_ID, RoleInfo.ADMIN_ROLE_KEY, DataScopeEnum.ALL, SetUtils.emptySet(),
|
return new RoleInfo(RoleInfo.ADMIN_ROLE_ID, RoleInfo.ADMIN_ROLE_KEY, DataScopeEnum.ALL,
|
||||||
RoleInfo.ADMIN_PERMISSIONS, allMenuIds);
|
RoleInfo.ADMIN_PERMISSIONS, allMenuIds);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -104,13 +101,7 @@ public class UserDetailsServiceImpl implements UserDetailsService {
|
|||||||
|
|
||||||
DataScopeEnum dataScopeEnum = BasicEnumUtil.fromValue(DataScopeEnum.class, roleEntity.getDataScope());
|
DataScopeEnum dataScopeEnum = BasicEnumUtil.fromValue(DataScopeEnum.class, roleEntity.getDataScope());
|
||||||
|
|
||||||
Set<Long> deptIdSet = SetUtils.emptySet();
|
return new RoleInfo(roleId, roleEntity.getRoleKey(), dataScopeEnum, permissions, menuIds);
|
||||||
if (StrUtil.isNotEmpty(roleEntity.getDeptIdSet())) {
|
|
||||||
deptIdSet = StrUtil.split(roleEntity.getDeptIdSet(), ",").stream()
|
|
||||||
.map(Convert::toLong).collect(Collectors.toSet());
|
|
||||||
}
|
|
||||||
|
|
||||||
return new RoleInfo(roleId, roleEntity.getRoleKey(), dataScopeEnum, deptIdSet, permissions, menuIds);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+2
@@ -13,6 +13,8 @@ public class ConfigDTO {
|
|||||||
|
|
||||||
private Boolean isCaptchaOn;
|
private Boolean isCaptchaOn;
|
||||||
|
|
||||||
|
private Boolean isRegisterUserOn;
|
||||||
|
|
||||||
private Map<String, List<DictionaryData>> dictionary;
|
private Map<String, List<DictionaryData>> dictionary;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-21
@@ -1,16 +1,11 @@
|
|||||||
package com.agileboot.admin.customize.service.permission;
|
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.admin.customize.service.permission.model.AbstractDataPermissionChecker;
|
||||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
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.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.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.OnlySelfDataPermissionChecker;
|
||||||
import com.agileboot.admin.customize.service.permission.model.checker.SingleDeptDataPermissionChecker;
|
|
||||||
import com.agileboot.infrastructure.user.web.DataScopeEnum;
|
import com.agileboot.infrastructure.user.web.DataScopeEnum;
|
||||||
import com.agileboot.domain.system.dept.db.SysDeptService;
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@@ -21,41 +16,31 @@ import org.springframework.stereotype.Component;
|
|||||||
@Component
|
@Component
|
||||||
public class DataPermissionCheckerFactory {
|
public class DataPermissionCheckerFactory {
|
||||||
private static AbstractDataPermissionChecker allChecker;
|
private static AbstractDataPermissionChecker allChecker;
|
||||||
private static AbstractDataPermissionChecker customChecker;
|
|
||||||
private static AbstractDataPermissionChecker singleDeptChecker;
|
|
||||||
private static AbstractDataPermissionChecker deptTreeChecker;
|
|
||||||
private static AbstractDataPermissionChecker onlySelfChecker;
|
private static AbstractDataPermissionChecker onlySelfChecker;
|
||||||
private static AbstractDataPermissionChecker defaultSelfChecker;
|
private static AbstractDataPermissionChecker defaultSelfChecker;
|
||||||
|
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void initAllChecker() {
|
public void initAllChecker() {
|
||||||
SysDeptService deptService = SpringUtil.getBean(SysDeptService.class);
|
|
||||||
|
|
||||||
allChecker = new AllDataPermissionChecker();
|
allChecker = new AllDataPermissionChecker();
|
||||||
customChecker = new CustomDataPermissionChecker(deptService);
|
onlySelfChecker = new OnlySelfDataPermissionChecker();
|
||||||
singleDeptChecker = new SingleDeptDataPermissionChecker(deptService);
|
|
||||||
deptTreeChecker = new DeptTreeDataPermissionChecker(deptService);
|
|
||||||
onlySelfChecker = new OnlySelfDataPermissionChecker(deptService);
|
|
||||||
defaultSelfChecker = new DefaultDataPermissionChecker();
|
defaultSelfChecker = new DefaultDataPermissionChecker();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static AbstractDataPermissionChecker getChecker(SystemLoginUser loginUser) {
|
public static AbstractDataPermissionChecker getChecker(SystemLoginUser loginUser) {
|
||||||
if (loginUser == null) {
|
if (loginUser == null) {
|
||||||
return deptTreeChecker;
|
return defaultSelfChecker;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loginUser.getRoleInfo() == null || loginUser.getRoleInfo().getDataScope() == null) {
|
||||||
|
return defaultSelfChecker;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataScopeEnum dataScope = loginUser.getRoleInfo().getDataScope();
|
DataScopeEnum dataScope = loginUser.getRoleInfo().getDataScope();
|
||||||
switch (dataScope) {
|
switch (dataScope) {
|
||||||
case ALL:
|
case ALL:
|
||||||
return allChecker;
|
return allChecker;
|
||||||
case CUSTOM_DEFINE:
|
|
||||||
return customChecker;
|
|
||||||
case SINGLE_DEPT:
|
|
||||||
return singleDeptChecker;
|
|
||||||
case DEPT_TREE:
|
|
||||||
return deptTreeChecker;
|
|
||||||
case ONLY_SELF:
|
case ONLY_SELF:
|
||||||
return onlySelfChecker;
|
return onlySelfChecker;
|
||||||
default:
|
default:
|
||||||
|
|||||||
+3
-9
@@ -33,7 +33,7 @@ public class DataPermissionService {
|
|||||||
if (targetUser == null) {
|
if (targetUser == null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return checkDataScope(loginUser, targetUser.getDeptId(), userId);
|
return checkDataScope(loginUser, userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -53,14 +53,8 @@ public class DataPermissionService {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean checkDeptId(Long deptId) {
|
public boolean checkDataScope(SystemLoginUser loginUser, Long targetUserId) {
|
||||||
SystemLoginUser loginUser = AuthenticationUtils.getSystemLoginUser();
|
DataCondition dataCondition = DataCondition.builder().targetUserId(targetUserId).build();
|
||||||
return checkDataScope(loginUser, deptId, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public boolean checkDataScope(SystemLoginUser loginUser, Long targetDeptId, Long targetUserId) {
|
|
||||||
DataCondition dataCondition = DataCondition.builder().targetDeptId(targetDeptId).targetUserId(targetUserId).build();
|
|
||||||
AbstractDataPermissionChecker checker = DataPermissionCheckerFactory.getChecker(loginUser);
|
AbstractDataPermissionChecker checker = DataPermissionCheckerFactory.getChecker(loginUser);
|
||||||
return checker.check(loginUser, dataCondition);
|
return checker.check(loginUser, dataCondition);
|
||||||
}
|
}
|
||||||
|
|||||||
-3
@@ -1,7 +1,6 @@
|
|||||||
package com.agileboot.admin.customize.service.permission.model;
|
package com.agileboot.admin.customize.service.permission.model;
|
||||||
|
|
||||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||||
import com.agileboot.domain.system.dept.db.SysDeptService;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -11,8 +10,6 @@ import lombok.Data;
|
|||||||
@Data
|
@Data
|
||||||
public abstract class AbstractDataPermissionChecker {
|
public abstract class AbstractDataPermissionChecker {
|
||||||
|
|
||||||
private SysDeptService deptService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检测当前用户对于 给定条件的数据 是否有权限
|
* 检测当前用户对于 给定条件的数据 是否有权限
|
||||||
*
|
*
|
||||||
|
|||||||
-1
@@ -15,7 +15,6 @@ import lombok.NoArgsConstructor;
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class DataCondition {
|
public class DataCondition {
|
||||||
|
|
||||||
private Long targetDeptId;
|
|
||||||
private Long targetUserId;
|
private Long targetUserId;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
-4
@@ -3,7 +3,6 @@ package com.agileboot.admin.customize.service.permission.model.checker;
|
|||||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||||
import com.agileboot.admin.customize.service.permission.model.AbstractDataPermissionChecker;
|
import com.agileboot.admin.customize.service.permission.model.AbstractDataPermissionChecker;
|
||||||
import com.agileboot.admin.customize.service.permission.model.DataCondition;
|
import com.agileboot.admin.customize.service.permission.model.DataCondition;
|
||||||
import com.agileboot.domain.system.dept.db.SysDeptService;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
@@ -15,9 +14,6 @@ import lombok.EqualsAndHashCode;
|
|||||||
@Data
|
@Data
|
||||||
public class AllDataPermissionChecker extends AbstractDataPermissionChecker {
|
public class AllDataPermissionChecker extends AbstractDataPermissionChecker {
|
||||||
|
|
||||||
private SysDeptService deptService;
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean check(SystemLoginUser loginUser, DataCondition condition) {
|
public boolean check(SystemLoginUser loginUser, DataCondition condition) {
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
-42
@@ -1,42 +0,0 @@
|
|||||||
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 lombok.AllArgsConstructor;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 数据权限测试接口
|
|
||||||
* @author valarchie
|
|
||||||
*/
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@Data
|
|
||||||
@AllArgsConstructor
|
|
||||||
@NoArgsConstructor
|
|
||||||
public class CustomDataPermissionChecker extends AbstractDataPermissionChecker {
|
|
||||||
|
|
||||||
private SysDeptService deptService;
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean check(SystemLoginUser loginUser, DataCondition condition) {
|
|
||||||
if (condition == null || loginUser == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (loginUser.getRoleInfo() == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Set<Long> deptIdSet = loginUser.getRoleInfo().getDeptIdSet();
|
|
||||||
Long targetDeptId = condition.getTargetDeptId();
|
|
||||||
|
|
||||||
return condition.getTargetDeptId() != null && CollUtil.safeContains(deptIdSet, targetDeptId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-3
@@ -3,7 +3,6 @@ package com.agileboot.admin.customize.service.permission.model.checker;
|
|||||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||||
import com.agileboot.admin.customize.service.permission.model.AbstractDataPermissionChecker;
|
import com.agileboot.admin.customize.service.permission.model.AbstractDataPermissionChecker;
|
||||||
import com.agileboot.admin.customize.service.permission.model.DataCondition;
|
import com.agileboot.admin.customize.service.permission.model.DataCondition;
|
||||||
import com.agileboot.domain.system.dept.db.SysDeptService;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
@@ -15,8 +14,6 @@ import lombok.EqualsAndHashCode;
|
|||||||
@Data
|
@Data
|
||||||
public class DefaultDataPermissionChecker extends AbstractDataPermissionChecker {
|
public class DefaultDataPermissionChecker extends AbstractDataPermissionChecker {
|
||||||
|
|
||||||
private SysDeptService deptService;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean check(SystemLoginUser loginUser, DataCondition condition) {
|
public boolean check(SystemLoginUser loginUser, DataCondition condition) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
-44
@@ -1,44 +0,0 @@
|
|||||||
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 lombok.AllArgsConstructor;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 数据权限测试接口
|
|
||||||
* @author valarchie
|
|
||||||
*/
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@Data
|
|
||||||
@AllArgsConstructor
|
|
||||||
@NoArgsConstructor
|
|
||||||
public class DeptTreeDataPermissionChecker extends AbstractDataPermissionChecker {
|
|
||||||
|
|
||||||
private SysDeptService deptService;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean check(SystemLoginUser loginUser, DataCondition condition) {
|
|
||||||
if (condition == null || loginUser == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (loginUser.getDeptId() == null || condition.getTargetDeptId() == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Long currentDeptId = loginUser.getDeptId();
|
|
||||||
Long targetDeptId = condition.getTargetDeptId();
|
|
||||||
|
|
||||||
boolean isContainsTargetDept = deptService.isChildOfTheDept(loginUser.getDeptId(), targetDeptId);
|
|
||||||
boolean isSameDept = Objects.equals(currentDeptId, targetDeptId);
|
|
||||||
|
|
||||||
return isContainsTargetDept || isSameDept;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-5
@@ -3,9 +3,7 @@ package com.agileboot.admin.customize.service.permission.model.checker;
|
|||||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||||
import com.agileboot.admin.customize.service.permission.model.AbstractDataPermissionChecker;
|
import com.agileboot.admin.customize.service.permission.model.AbstractDataPermissionChecker;
|
||||||
import com.agileboot.admin.customize.service.permission.model.DataCondition;
|
import com.agileboot.admin.customize.service.permission.model.DataCondition;
|
||||||
import com.agileboot.domain.system.dept.db.SysDeptService;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
@@ -16,12 +14,9 @@ import lombok.NoArgsConstructor;
|
|||||||
*/
|
*/
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
public class OnlySelfDataPermissionChecker extends AbstractDataPermissionChecker {
|
public class OnlySelfDataPermissionChecker extends AbstractDataPermissionChecker {
|
||||||
|
|
||||||
private SysDeptService deptService;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean check(SystemLoginUser loginUser, DataCondition condition) {
|
public boolean check(SystemLoginUser loginUser, DataCondition condition) {
|
||||||
if (condition == null || loginUser == null) {
|
if (condition == null || loginUser == null) {
|
||||||
|
|||||||
-42
@@ -1,42 +0,0 @@
|
|||||||
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 lombok.AllArgsConstructor;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 数据权限测试接口
|
|
||||||
* @author valarchie
|
|
||||||
*/
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@Data
|
|
||||||
@AllArgsConstructor
|
|
||||||
@NoArgsConstructor
|
|
||||||
public class SingleDeptDataPermissionChecker extends AbstractDataPermissionChecker {
|
|
||||||
|
|
||||||
private SysDeptService deptService;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean check(SystemLoginUser loginUser, DataCondition condition) {
|
|
||||||
if (condition == null || loginUser == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (loginUser.getDeptId() == null || condition.getTargetDeptId() == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Long currentDeptId = loginUser.getDeptId();
|
|
||||||
Long targetDeptId = condition.getTargetDeptId();
|
|
||||||
|
|
||||||
return Objects.equals(currentDeptId, targetDeptId);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -50,7 +50,7 @@ spring:
|
|||||||
datasource:
|
datasource:
|
||||||
# 主库数据源
|
# 主库数据源
|
||||||
master:
|
master:
|
||||||
url: jdbc:mysql://localhost:33061/todo_agileboot_pure?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
url: jdbc:mysql://localhost:3306/todo_agileboot_pure?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
||||||
username: root
|
username: root
|
||||||
password: root123
|
password: root123
|
||||||
# 从库数据源
|
# 从库数据源
|
||||||
@@ -64,7 +64,7 @@ spring:
|
|||||||
# 地址
|
# 地址
|
||||||
host: localhost
|
host: localhost
|
||||||
# 端口,默认为6379
|
# 端口,默认为6379
|
||||||
port: 63791
|
port: 6379
|
||||||
# 数据库索引
|
# 数据库索引
|
||||||
database: 0
|
database: 0
|
||||||
# 密码
|
# 密码
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
# 数据源配置
|
||||||
|
spring:
|
||||||
|
datasource:
|
||||||
|
type: com.alibaba.druid.pool.DruidDataSource
|
||||||
|
driverClassName: com.mysql.cj.jdbc.Driver
|
||||||
|
druid:
|
||||||
|
webStatFilter:
|
||||||
|
enabled: true
|
||||||
|
statViewServlet:
|
||||||
|
enabled: false
|
||||||
|
filter:
|
||||||
|
stat:
|
||||||
|
enabled: true
|
||||||
|
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://${MYSQL_HOST:mysql}:${MYSQL_PORT:3306}/${MYSQL_DATABASE:todo_agileboot_pure}?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8
|
||||||
|
username: ${MYSQL_USERNAME:todo_app}
|
||||||
|
password: ${MYSQL_PASSWORD:todo_app123}
|
||||||
|
|
||||||
|
redis:
|
||||||
|
host: ${REDIS_HOST:redis}
|
||||||
|
port: ${REDIS_PORT:6379}
|
||||||
|
database: 0
|
||||||
|
password: ${REDIS_PASSWORD:redis123}
|
||||||
|
timeout: 10s
|
||||||
|
lettuce:
|
||||||
|
pool:
|
||||||
|
min-idle: 0
|
||||||
|
max-idle: 8
|
||||||
|
max-active: 8
|
||||||
|
max-wait: -1ms
|
||||||
|
|
||||||
|
logging:
|
||||||
|
file:
|
||||||
|
path: /home/agileboot/logs/agileboot-prod
|
||||||
|
|
||||||
|
springdoc:
|
||||||
|
swagger-ui:
|
||||||
|
enabled: false
|
||||||
|
|
||||||
|
agileboot:
|
||||||
|
file-base-dir: /home/agileboot
|
||||||
|
api-prefix: /dev-api
|
||||||
|
demo-enabled: false
|
||||||
-83
@@ -1,83 +0,0 @@
|
|||||||
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 static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import com.agileboot.admin.customize.service.permission.model.checker.CustomDataPermissionChecker;
|
|
||||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
|
||||||
import com.agileboot.infrastructure.user.web.RoleInfo;
|
|
||||||
import com.agileboot.admin.customize.service.permission.model.DataCondition;
|
|
||||||
import com.agileboot.domain.system.dept.db.SysDeptService;
|
|
||||||
import org.apache.commons.collections4.SetUtils;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
-92
@@ -1,92 +0,0 @@
|
|||||||
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.ArgumentMatchers.any;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import com.agileboot.admin.customize.service.permission.model.checker.DeptTreeDataPermissionChecker;
|
|
||||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
|
||||||
import com.agileboot.infrastructure.user.web.RoleInfo;
|
|
||||||
import com.agileboot.admin.customize.service.permission.model.DataCondition;
|
|
||||||
import com.agileboot.domain.system.dept.db.SysDeptService;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
+4
-8
@@ -2,21 +2,17 @@ package com.agileboot.admin.customize.service.permission;
|
|||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
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.admin.customize.service.permission.model.checker.OnlySelfDataPermissionChecker;
|
||||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||||
import com.agileboot.admin.customize.service.permission.model.DataCondition;
|
import com.agileboot.admin.customize.service.permission.model.DataCondition;
|
||||||
import com.agileboot.domain.system.dept.db.SysDeptService;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
class OnlySelfDataPermissionCheckerTest {
|
class OnlySelfDataPermissionCheckerTest {
|
||||||
|
|
||||||
private final SysDeptService deptService = mock(SysDeptService.class);
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCheckWhenParameterNull() {
|
void testCheckWhenParameterNull() {
|
||||||
OnlySelfDataPermissionChecker checker = new OnlySelfDataPermissionChecker(deptService);
|
OnlySelfDataPermissionChecker checker = new OnlySelfDataPermissionChecker();
|
||||||
|
|
||||||
boolean check1 = checker.check(null, null);
|
boolean check1 = checker.check(null, null);
|
||||||
boolean check2 = checker.check(new SystemLoginUser(), null);
|
boolean check2 = checker.check(new SystemLoginUser(), null);
|
||||||
@@ -31,7 +27,7 @@ class OnlySelfDataPermissionCheckerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCheckWhenSameUserId() {
|
void testCheckWhenSameUserId() {
|
||||||
OnlySelfDataPermissionChecker checker = new OnlySelfDataPermissionChecker(deptService);
|
OnlySelfDataPermissionChecker checker = new OnlySelfDataPermissionChecker();
|
||||||
SystemLoginUser loginUser = new SystemLoginUser();
|
SystemLoginUser loginUser = new SystemLoginUser();
|
||||||
loginUser.setUserId(1L);
|
loginUser.setUserId(1L);
|
||||||
DataCondition dataCondition = new DataCondition();
|
DataCondition dataCondition = new DataCondition();
|
||||||
@@ -45,11 +41,11 @@ class OnlySelfDataPermissionCheckerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCheckWhenDifferentUserId() {
|
void testCheckWhenDifferentUserId() {
|
||||||
OnlySelfDataPermissionChecker checker = new OnlySelfDataPermissionChecker(deptService);
|
OnlySelfDataPermissionChecker checker = new OnlySelfDataPermissionChecker();
|
||||||
SystemLoginUser loginUser = new SystemLoginUser();
|
SystemLoginUser loginUser = new SystemLoginUser();
|
||||||
loginUser.setUserId(1L);
|
loginUser.setUserId(1L);
|
||||||
DataCondition dataCondition = new DataCondition();
|
DataCondition dataCondition = new DataCondition();
|
||||||
dataCondition.setTargetDeptId(2L);
|
dataCondition.setTargetUserId(2L);
|
||||||
|
|
||||||
boolean check = checker.check(loginUser, dataCondition);
|
boolean check = checker.check(loginUser, dataCondition);
|
||||||
|
|
||||||
|
|||||||
-72
@@ -1,72 +0,0 @@
|
|||||||
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 static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import com.agileboot.admin.customize.service.permission.model.checker.SingleDeptDataPermissionChecker;
|
|
||||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
|
||||||
import com.agileboot.infrastructure.user.web.RoleInfo;
|
|
||||||
import com.agileboot.admin.customize.service.permission.model.DataCondition;
|
|
||||||
import com.agileboot.domain.system.dept.db.SysDeptService;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
+2
-8
@@ -3,18 +3,13 @@ package com.agileboot.common.enums.common;
|
|||||||
import com.agileboot.common.enums.BasicEnum;
|
import com.agileboot.common.enums.BasicEnum;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 系统配置
|
* 系统配置,对应 sys_config 表的 config_key 字段。
|
||||||
|
*
|
||||||
* @author valarchie
|
* @author valarchie
|
||||||
* 对应 sys_config表的config_key字段
|
|
||||||
*/
|
*/
|
||||||
public enum ConfigKeyEnum implements BasicEnum<String> {
|
public enum ConfigKeyEnum implements BasicEnum<String> {
|
||||||
|
|
||||||
/**
|
|
||||||
* 菜单类型
|
|
||||||
*/
|
|
||||||
SKIN_THEME("sys.index.skinName", "系统皮肤主题"),
|
|
||||||
INIT_PASSWORD("sys.user.initPassword", "初始密码"),
|
INIT_PASSWORD("sys.user.initPassword", "初始密码"),
|
||||||
SIDE_BAR_THEME("sys.index.sideTheme", "侧边栏开关"),
|
|
||||||
CAPTCHA("sys.account.captchaOnOff", "验证码开关"),
|
CAPTCHA("sys.account.captchaOnOff", "验证码开关"),
|
||||||
REGISTER("sys.account.registerUser", "注册开放功能");
|
REGISTER("sys.account.registerUser", "注册开放功能");
|
||||||
|
|
||||||
@@ -36,5 +31,4 @@ public enum ConfigKeyEnum implements BasicEnum<String> {
|
|||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-26
@@ -118,28 +118,6 @@ public enum ErrorCode implements ErrorCodeInterface {
|
|||||||
|
|
||||||
CONFIG_VALUE_IS_NOT_IN_OPTIONS(10602, "参数键值不存在列表中", "Business.CONFIG_VALUE_IS_NOT_IN_OPTIONS"),
|
CONFIG_VALUE_IS_NOT_IN_OPTIONS(10602, "参数键值不存在列表中", "Business.CONFIG_VALUE_IS_NOT_IN_OPTIONS"),
|
||||||
|
|
||||||
// ------------------------------- POST --------------------------------------------
|
|
||||||
|
|
||||||
POST_NAME_IS_NOT_UNIQUE(10701, "岗位名称:{}, 已存在", "Business.POST_NAME_IS_NOT_UNIQUE"),
|
|
||||||
|
|
||||||
POST_CODE_IS_NOT_UNIQUE(10702, "岗位编号:{}, 已存在", "Business.POST_CODE_IS_NOT_UNIQUE"),
|
|
||||||
|
|
||||||
POST_ALREADY_ASSIGNED_TO_USER_CAN_NOT_BE_DELETED(10703, "职位已分配给用户,请先取消分配再删除", "Business.POST_ALREADY_ASSIGNED_TO_USER_CAN_NOT_BE_DELETED"),
|
|
||||||
|
|
||||||
// ------------------------------- DEPT ---------------------------------------------
|
|
||||||
|
|
||||||
DEPT_NAME_IS_NOT_UNIQUE(10801, "部门名称:{}, 已存在", "Business.DEPT_NAME_IS_NOT_UNIQUE"),
|
|
||||||
|
|
||||||
DEPT_PARENT_ID_IS_NOT_ALLOWED_SELF(10802, "父级部门不能选择自己", "Business.DEPT_PARENT_ID_IS_NOT_ALLOWED_SELF"),
|
|
||||||
|
|
||||||
DEPT_STATUS_ID_IS_NOT_ALLOWED_CHANGE(10803, "子部门还有正在启用的部门,暂时不能停用该部门", "Business.DEPT_STATUS_ID_IS_NOT_ALLOWED_CHANGE"),
|
|
||||||
|
|
||||||
DEPT_EXIST_CHILD_DEPT_NOT_ALLOW_DELETE(10804, "该部门存在下级部门不允许删除", "Business.DEPT_EXIST_CHILD_DEPT_NOT_ALLOW_DELETE"),
|
|
||||||
|
|
||||||
DEPT_EXIST_LINK_USER_NOT_ALLOW_DELETE(10805, "该部门存在关联的用户不允许删除", "Business.DEPT_EXIST_LINK_USER_NOT_ALLOW_DELETE"),
|
|
||||||
|
|
||||||
DEPT_PARENT_DEPT_NO_EXIST_OR_DISABLED(10806, "该父级部门不存在或已停用", "Business.DEPT_PARENT_DEPT_NO_EXIST_OR_DISABLED"),
|
|
||||||
|
|
||||||
// ------------------------------- MENU -------------------------------------------------
|
// ------------------------------- MENU -------------------------------------------------
|
||||||
|
|
||||||
MENU_NAME_IS_NOT_UNIQUE(10901, "新增菜单:{} 失败,菜单名称已存在", "Business.MENU_NAME_IS_NOT_UNIQUE"),
|
MENU_NAME_IS_NOT_UNIQUE(10901, "新增菜单:{} 失败,菜单名称已存在", "Business.MENU_NAME_IS_NOT_UNIQUE"),
|
||||||
@@ -164,8 +142,6 @@ public enum ErrorCode implements ErrorCodeInterface {
|
|||||||
|
|
||||||
ROLE_KEY_IS_NOT_UNIQUE(11002, "角色标识:{}, 已存在", "Business.ROLE_KEY_IS_NOT_UNIQUE"),
|
ROLE_KEY_IS_NOT_UNIQUE(11002, "角色标识:{}, 已存在", "Business.ROLE_KEY_IS_NOT_UNIQUE"),
|
||||||
|
|
||||||
ROLE_DATA_SCOPE_DUPLICATED_DEPT(11003, "重复的部门id", "Business.ROLE_DATA_SCOPE_DUPLICATED_DEPT"),
|
|
||||||
|
|
||||||
ROLE_ALREADY_ASSIGN_TO_USER(11004, "角色已分配给用户,请先取消分配,再删除角色", "Business.ROLE_ALREADY_ASSIGN_TO_USER"),
|
ROLE_ALREADY_ASSIGN_TO_USER(11004, "角色已分配给用户,请先取消分配,再删除角色", "Business.ROLE_ALREADY_ASSIGN_TO_USER"),
|
||||||
|
|
||||||
ROLE_IS_NOT_AVAILABLE(11005, "角色:{} 已禁用,无法分配给用户", "Business.ROLE_IS_NOT_AVAILABLE"),
|
ROLE_IS_NOT_AVAILABLE(11005, "角色:{} 已禁用,无法分配给用户", "Business.ROLE_IS_NOT_AVAILABLE"),
|
||||||
@@ -180,8 +156,6 @@ public enum ErrorCode implements ErrorCodeInterface {
|
|||||||
|
|
||||||
USER_FAIL_TO_GET_USER_ID(11004, "获取用户ID失败", "Business.USER_FAIL_TO_GET_USER_ID"),
|
USER_FAIL_TO_GET_USER_ID(11004, "获取用户ID失败", "Business.USER_FAIL_TO_GET_USER_ID"),
|
||||||
|
|
||||||
USER_FAIL_TO_GET_DEPT_ID(10504, "获取用户部门ID失败", "Business.USER_FAIL_TO_GET_DEPT_ID"),
|
|
||||||
|
|
||||||
USER_FAIL_TO_GET_ACCOUNT(10505, "获取用户账户失败", "Business.USER_FAIL_TO_GET_ACCOUNT"),
|
USER_FAIL_TO_GET_ACCOUNT(10505, "获取用户账户失败", "Business.USER_FAIL_TO_GET_ACCOUNT"),
|
||||||
|
|
||||||
USER_FAIL_TO_GET_USER_INFO(10506, "获取用户信息失败", "Business.USER_FAIL_TO_GET_USER_INFO"),
|
USER_FAIL_TO_GET_USER_INFO(10506, "获取用户信息失败", "Business.USER_FAIL_TO_GET_USER_INFO"),
|
||||||
@@ -204,6 +178,12 @@ public enum ErrorCode implements ErrorCodeInterface {
|
|||||||
|
|
||||||
USER_ADMIN_CAN_NOT_BE_MODIFY(10515, "管理员不允许做任何修改", "Business.USER_ADMIN_CAN_NOT_BE_MODIFY"),
|
USER_ADMIN_CAN_NOT_BE_MODIFY(10515, "管理员不允许做任何修改", "Business.USER_ADMIN_CAN_NOT_BE_MODIFY"),
|
||||||
|
|
||||||
|
USER_REGISTER_IS_CLOSED(10516, "当前系统未开启用户注册功能", "Business.USER_REGISTER_IS_CLOSED"),
|
||||||
|
|
||||||
|
USER_REGISTER_PASSWORD_NOT_MATCH(10517, "两次输入的密码不一致", "Business.USER_REGISTER_PASSWORD_NOT_MATCH"),
|
||||||
|
|
||||||
|
USER_PASSWORD_IS_EMPTY(10518, "密码不能为空", "Business.USER_PASSWORD_IS_EMPTY"),
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+203
-17
@@ -1,6 +1,9 @@
|
|||||||
package com.agileboot.domain.collaboration.record;
|
package com.agileboot.domain.collaboration.record;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.agileboot.common.core.page.PageDTO;
|
import com.agileboot.common.core.page.PageDTO;
|
||||||
|
import com.agileboot.common.exception.ApiException;
|
||||||
|
import com.agileboot.common.exception.error.ErrorCode;
|
||||||
import com.agileboot.domain.collaboration.record.command.AddCollaborationRecordCommand;
|
import com.agileboot.domain.collaboration.record.command.AddCollaborationRecordCommand;
|
||||||
import com.agileboot.domain.collaboration.record.command.CollaborationExpenditureCommand;
|
import com.agileboot.domain.collaboration.record.command.CollaborationExpenditureCommand;
|
||||||
import com.agileboot.domain.collaboration.record.command.CollaborationFileCommand;
|
import com.agileboot.domain.collaboration.record.command.CollaborationFileCommand;
|
||||||
@@ -31,7 +34,11 @@ import com.agileboot.domain.collaboration.record.enumtype.SettlementStatusEnum;
|
|||||||
import com.agileboot.domain.collaboration.record.model.CollaborationRecordModel;
|
import com.agileboot.domain.collaboration.record.model.CollaborationRecordModel;
|
||||||
import com.agileboot.domain.collaboration.record.model.CollaborationRecordModelFactory;
|
import com.agileboot.domain.collaboration.record.model.CollaborationRecordModelFactory;
|
||||||
import com.agileboot.domain.collaboration.record.query.CollaborationRecordQuery;
|
import com.agileboot.domain.collaboration.record.query.CollaborationRecordQuery;
|
||||||
|
import com.agileboot.domain.common.cache.CacheCenter;
|
||||||
import com.agileboot.domain.common.command.BulkOperationCommand;
|
import com.agileboot.domain.common.command.BulkOperationCommand;
|
||||||
|
import com.agileboot.domain.system.user.db.SysUserEntity;
|
||||||
|
import com.agileboot.infrastructure.user.AuthenticationUtils;
|
||||||
|
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
@@ -42,6 +49,7 @@ import java.util.Collections;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -57,6 +65,8 @@ public class CollaborationRecordApplicationService {
|
|||||||
private static final String PURCHASE_FEE = "拍单费用";
|
private static final String PURCHASE_FEE = "拍单费用";
|
||||||
private static final String DELIVERY_FEE = "快递费用";
|
private static final String DELIVERY_FEE = "快递费用";
|
||||||
private static final String REMUNERATION_FEE = "稿费";
|
private static final String REMUNERATION_FEE = "稿费";
|
||||||
|
private static final String TASK_STATUS_COMPLETED = "COMPLETED";
|
||||||
|
private static final String TASK_STATUS_INCOMPLETE = "INCOMPLETE";
|
||||||
|
|
||||||
private final CollaborationRecordModelFactory recordModelFactory;
|
private final CollaborationRecordModelFactory recordModelFactory;
|
||||||
private final CollaborationRecordService recordService;
|
private final CollaborationRecordService recordService;
|
||||||
@@ -66,7 +76,10 @@ public class CollaborationRecordApplicationService {
|
|||||||
private final CollaborationFileService fileService;
|
private final CollaborationFileService fileService;
|
||||||
|
|
||||||
public PageDTO<CollaborationRecordDTO> getRecordList(CollaborationRecordQuery query) {
|
public PageDTO<CollaborationRecordDTO> getRecordList(CollaborationRecordQuery query) {
|
||||||
Page<CollaborationRecordEntity> page = recordService.page(query.toPage(), query.toQueryWrapper());
|
if (hasComputedFilters(query)) {
|
||||||
|
return getComputedFilteredRecordList(query);
|
||||||
|
}
|
||||||
|
Page<CollaborationRecordEntity> page = recordService.page(query.toPage(), getScopedRecordWrapper(query));
|
||||||
List<CollaborationRecordDTO> records = page.getRecords().stream()
|
List<CollaborationRecordDTO> records = page.getRecords().stream()
|
||||||
.map(this::buildRecordDTO)
|
.map(this::buildRecordDTO)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
@@ -74,7 +87,7 @@ public class CollaborationRecordApplicationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public CollaborationRecordDetailDTO getRecordInfo(Long recordId) {
|
public CollaborationRecordDetailDTO getRecordInfo(Long recordId) {
|
||||||
CollaborationRecordModel model = recordModelFactory.loadById(recordId);
|
CollaborationRecordModel model = loadRecordInScope(recordId);
|
||||||
CollaborationRecordDetailDTO dto = new CollaborationRecordDetailDTO(model);
|
CollaborationRecordDetailDTO dto = new CollaborationRecordDetailDTO(model);
|
||||||
fillDetailChildren(dto, recordId);
|
fillDetailChildren(dto, recordId);
|
||||||
fillRecordStats(dto, recordId);
|
fillRecordStats(dto, recordId);
|
||||||
@@ -85,14 +98,16 @@ public class CollaborationRecordApplicationService {
|
|||||||
public void addRecord(AddCollaborationRecordCommand command) {
|
public void addRecord(AddCollaborationRecordCommand command) {
|
||||||
CollaborationRecordModel model = recordModelFactory.create();
|
CollaborationRecordModel model = recordModelFactory.create();
|
||||||
model.loadFromAddCommand(command);
|
model.loadFromAddCommand(command);
|
||||||
|
model.setCompleteDate(getRecordCompleteDate(command.getTasks(), CollaborationTaskCommand::getReleaseDate));
|
||||||
model.saveRecord();
|
model.saveRecord();
|
||||||
saveChildren(model.getRecordId(), command);
|
saveChildren(model.getRecordId(), command);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void updateRecord(UpdateCollaborationRecordCommand command) {
|
public void updateRecord(UpdateCollaborationRecordCommand command) {
|
||||||
CollaborationRecordModel model = recordModelFactory.loadById(command.getRecordId());
|
CollaborationRecordModel model = loadRecordInScope(command.getRecordId());
|
||||||
model.loadFromUpdateCommand(command);
|
model.loadFromUpdateCommand(command);
|
||||||
|
model.setCompleteDate(getRecordCompleteDate(command.getTasks(), CollaborationTaskCommand::getReleaseDate));
|
||||||
model.updateRecord();
|
model.updateRecord();
|
||||||
replaceChildren(command.getRecordId(), command);
|
replaceChildren(command.getRecordId(), command);
|
||||||
}
|
}
|
||||||
@@ -103,6 +118,7 @@ public class CollaborationRecordApplicationService {
|
|||||||
if (ids == null || ids.isEmpty()) {
|
if (ids == null || ids.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
checkAllRecordsInScope(ids);
|
||||||
taskService.removeByRecordIds(ids);
|
taskService.removeByRecordIds(ids);
|
||||||
expenditureService.removeByRecordIds(ids);
|
expenditureService.removeByRecordIds(ids);
|
||||||
settlementService.removeByRecordIds(ids);
|
settlementService.removeByRecordIds(ids);
|
||||||
@@ -116,20 +132,145 @@ public class CollaborationRecordApplicationService {
|
|||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<CollaborationMonthlyStatisticsDTO> getMonthlyStatistics(Integer year) {
|
public List<CollaborationMonthlyStatisticsDTO> getMonthlyStatistics(Integer year, Long creatorId) {
|
||||||
List<CollaborationMonthlyStatisticsDTO> statistics = new ArrayList<>();
|
List<CollaborationMonthlyStatisticsDTO> statistics = new ArrayList<>();
|
||||||
for (int month = 1; month <= 12; month++) {
|
for (int month = 1; month <= 12; month++) {
|
||||||
statistics.add(buildMonthlyStatistics(year, month));
|
statistics.add(buildMonthlyStatistics(year, month, creatorId));
|
||||||
}
|
}
|
||||||
return statistics;
|
return statistics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<CollaborationMonthlyStatisticsDTO> getMonthlyStatistics(Integer year) {
|
||||||
|
return getMonthlyStatistics(year, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private QueryWrapper<CollaborationRecordEntity> getScopedRecordWrapper(CollaborationRecordQuery query) {
|
||||||
|
applyQueryCreatorScope(query);
|
||||||
|
QueryWrapper<CollaborationRecordEntity> wrapper = query.toQueryWrapper();
|
||||||
|
return wrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
private PageDTO<CollaborationRecordDTO> getComputedFilteredRecordList(CollaborationRecordQuery query) {
|
||||||
|
List<CollaborationRecordDTO> records = recordService.list(getScopedRecordWrapper(query)).stream()
|
||||||
|
.map(this::buildRecordDTO)
|
||||||
|
.filter(record -> matchesComputedFilters(record, query))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
return new PageDTO<>(pageRecords(records, query), (long) records.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<CollaborationRecordDTO> pageRecords(List<CollaborationRecordDTO> records, CollaborationRecordQuery query) {
|
||||||
|
Page<CollaborationRecordEntity> page = query.toPage();
|
||||||
|
int start = (int) Math.min((page.getCurrent() - 1) * page.getSize(), records.size());
|
||||||
|
int end = (int) Math.min(start + page.getSize(), records.size());
|
||||||
|
return records.subList(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasComputedFilters(CollaborationRecordQuery query) {
|
||||||
|
return StrUtil.isNotEmpty(query.getSettlementStatus()) || StrUtil.isNotEmpty(query.getTaskStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean matchesComputedFilters(CollaborationRecordDTO record, CollaborationRecordQuery query) {
|
||||||
|
return matchesSettlementStatus(record, query.getSettlementStatus())
|
||||||
|
&& matchesTaskStatus(record, query.getTaskStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean matchesSettlementStatus(CollaborationRecordDTO record, String status) {
|
||||||
|
if (StrUtil.isEmpty(status)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return status.equals(getRecordSettlementStatus(record));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getRecordSettlementStatus(CollaborationRecordDTO record) {
|
||||||
|
return SettlementStatusEnum.aggregate(Arrays.asList(
|
||||||
|
getSettlementStatusValue(record.getPurchaseSettlementStatus()),
|
||||||
|
getSettlementStatusValue(record.getDeliverySettlementStatus()),
|
||||||
|
getSettlementStatusValue(record.getRemunerationSettlementStatus())
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getSettlementStatusValue(SettlementStatusDTO status) {
|
||||||
|
return status == null ? SettlementStatusEnum.NONE.getValue() : status.getStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean matchesTaskStatus(CollaborationRecordDTO record, String status) {
|
||||||
|
if (StrUtil.isEmpty(status)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
boolean isCompleted = isRecordCompleted(record);
|
||||||
|
if (TASK_STATUS_COMPLETED.equals(status)) {
|
||||||
|
return isCompleted;
|
||||||
|
}
|
||||||
|
return TASK_STATUS_INCOMPLETE.equals(status) && !isCompleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isRecordCompleted(CollaborationRecordDTO record) {
|
||||||
|
Integer tasksNum = record.getTasksNum();
|
||||||
|
Integer completedTasksNum = record.getCompletedTasksNum();
|
||||||
|
return tasksNum != null && tasksNum > 0 && tasksNum.equals(completedTasksNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CollaborationRecordModel loadRecordInScope(Long recordId) {
|
||||||
|
CollaborationRecordEntity entity = recordService.getOne(buildScopedRecordIdWrapper(recordId));
|
||||||
|
if (entity == null) {
|
||||||
|
throw new ApiException(ErrorCode.Business.COMMON_OBJECT_NOT_FOUND, recordId, "合作记录");
|
||||||
|
}
|
||||||
|
return new CollaborationRecordModel(entity, recordService);
|
||||||
|
}
|
||||||
|
|
||||||
|
private QueryWrapper<CollaborationRecordEntity> buildScopedRecordIdWrapper(Long recordId) {
|
||||||
|
QueryWrapper<CollaborationRecordEntity> wrapper = new QueryWrapper<CollaborationRecordEntity>()
|
||||||
|
.eq("record_id", recordId);
|
||||||
|
applyCurrentCreatorScope(wrapper);
|
||||||
|
return wrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkAllRecordsInScope(Set<Long> ids) {
|
||||||
|
QueryWrapper<CollaborationRecordEntity> wrapper = new QueryWrapper<CollaborationRecordEntity>()
|
||||||
|
.in("record_id", ids);
|
||||||
|
applyCurrentCreatorScope(wrapper);
|
||||||
|
if (recordService.count(wrapper) != ids.size()) {
|
||||||
|
throw new ApiException(ErrorCode.Business.PERMISSION_NOT_ALLOWED_TO_OPERATE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyCurrentCreatorScope(QueryWrapper<CollaborationRecordEntity> wrapper) {
|
||||||
|
Long creatorId = getCurrentCreatorScope();
|
||||||
|
if (creatorId != null) {
|
||||||
|
wrapper.eq("creator_id", creatorId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyQueryCreatorScope(CollaborationRecordQuery query) {
|
||||||
|
Long creatorId = getCurrentCreatorScope();
|
||||||
|
if (creatorId != null) {
|
||||||
|
query.setCreatorId(creatorId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Long getCurrentCreatorScope() {
|
||||||
|
SystemLoginUser loginUser = AuthenticationUtils.getSystemLoginUser();
|
||||||
|
return loginUser.isAdmin() ? null : loginUser.getUserId();
|
||||||
|
}
|
||||||
|
|
||||||
private CollaborationRecordDTO buildRecordDTO(CollaborationRecordEntity entity) {
|
private CollaborationRecordDTO buildRecordDTO(CollaborationRecordEntity entity) {
|
||||||
CollaborationRecordDTO dto = new CollaborationRecordDTO(entity);
|
CollaborationRecordDTO dto = new CollaborationRecordDTO(entity);
|
||||||
|
dto.setCreatorName(getCreatorName(entity.getCreatorId()));
|
||||||
fillRecordStats(dto, entity.getRecordId());
|
fillRecordStats(dto, entity.getRecordId());
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getCreatorName(Long creatorId) {
|
||||||
|
if (creatorId == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
SysUserEntity user = CacheCenter.userCache.getObjectById(creatorId);
|
||||||
|
if (user == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return StrUtil.blankToDefault(user.getNickname(), user.getUsername());
|
||||||
|
}
|
||||||
|
|
||||||
private void fillDetailChildren(CollaborationRecordDetailDTO dto, Long recordId) {
|
private void fillDetailChildren(CollaborationRecordDetailDTO dto, Long recordId) {
|
||||||
dto.setTasks(taskService.listByRecordId(recordId).stream()
|
dto.setTasks(taskService.listByRecordId(recordId).stream()
|
||||||
.map(CollaborationTaskDTO::new)
|
.map(CollaborationTaskDTO::new)
|
||||||
@@ -151,11 +292,25 @@ public class CollaborationRecordApplicationService {
|
|||||||
List<CollaborationSettlementEntity> settlements = settlementService.listByRecordId(recordId);
|
List<CollaborationSettlementEntity> settlements = settlementService.listByRecordId(recordId);
|
||||||
dto.setTasksNum(tasks.size());
|
dto.setTasksNum(tasks.size());
|
||||||
dto.setCompletedTasksNum((int) tasks.stream().filter(item -> item.getReleaseDate() != null).count());
|
dto.setCompletedTasksNum((int) tasks.stream().filter(item -> item.getReleaseDate() != null).count());
|
||||||
|
dto.setCompleteDate(getRecordCompleteDate(tasks, CollaborationTaskEntity::getReleaseDate));
|
||||||
dto.setPurchaseSettlementStatus(getStatus(dto.getPurchasePrice(), settlements, PURCHASE_FEE));
|
dto.setPurchaseSettlementStatus(getStatus(dto.getPurchasePrice(), settlements, PURCHASE_FEE));
|
||||||
dto.setDeliverySettlementStatus(getStatus(sumExpenditure(expenditures, DELIVERY_FEE), settlements, DELIVERY_FEE));
|
dto.setDeliverySettlementStatus(getStatus(sumExpenditure(expenditures, DELIVERY_FEE), settlements, DELIVERY_FEE));
|
||||||
dto.setRemunerationSettlementStatus(getStatus(dto.getRemuneration(), settlements, REMUNERATION_FEE));
|
dto.setRemunerationSettlementStatus(getStatus(dto.getRemuneration(), settlements, REMUNERATION_FEE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private <T> Date getRecordCompleteDate(List<T> tasks, Function<T, Date> getReleaseDate) {
|
||||||
|
if (tasks == null || tasks.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (tasks.stream().anyMatch(item -> getReleaseDate.apply(item) == null)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return tasks.stream()
|
||||||
|
.map(getReleaseDate)
|
||||||
|
.max(Date::compareTo)
|
||||||
|
.orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
private SettlementStatusDTO getStatus(
|
private SettlementStatusDTO getStatus(
|
||||||
BigDecimal expectedAmount, List<CollaborationSettlementEntity> settlements, String purpose) {
|
BigDecimal expectedAmount, List<CollaborationSettlementEntity> settlements, String purpose) {
|
||||||
List<CollaborationSettlementEntity> matched = filterSettlements(settlements, purpose);
|
List<CollaborationSettlementEntity> matched = filterSettlements(settlements, purpose);
|
||||||
@@ -324,43 +479,74 @@ public class CollaborationRecordApplicationService {
|
|||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
private CollaborationMonthlyStatisticsDTO buildMonthlyStatistics(Integer year, Integer month) {
|
private CollaborationMonthlyStatisticsDTO buildMonthlyStatistics(Integer year, Integer month, Long creatorId) {
|
||||||
Date[] range = getMonthRange(year, month);
|
Date[] range = getMonthRange(year, month);
|
||||||
BigDecimal purchasePrice = sumPurchasePrice(range);
|
BigDecimal purchasePrice = sumPurchasePrice(range, creatorId);
|
||||||
BigDecimal expenditureAmount = sumExpenditure(range);
|
BigDecimal expenditureAmount = sumExpenditure(range, creatorId);
|
||||||
BigDecimal settledRemuneration = sumSettlement(range, REMUNERATION_FEE);
|
BigDecimal settledRemuneration = sumSettlement(range, REMUNERATION_FEE, creatorId);
|
||||||
BigDecimal settledTotal = sumSettlement(range, null);
|
BigDecimal settledTotal = sumSettlement(range, null, creatorId);
|
||||||
return new CollaborationMonthlyStatisticsDTO(month, purchasePrice, expenditureAmount,
|
return new CollaborationMonthlyStatisticsDTO(month, purchasePrice, expenditureAmount,
|
||||||
settledRemuneration, settledTotal);
|
settledRemuneration, settledTotal);
|
||||||
}
|
}
|
||||||
|
|
||||||
private BigDecimal sumPurchasePrice(Date[] range) {
|
private BigDecimal sumPurchasePrice(Date[] range, Long creatorId) {
|
||||||
List<CollaborationRecordEntity> records = recordService.list(new QueryWrapper<CollaborationRecordEntity>()
|
QueryWrapper<CollaborationRecordEntity> wrapper = new QueryWrapper<CollaborationRecordEntity>()
|
||||||
.ge("purchase_date", range[0])
|
.ge("purchase_date", range[0])
|
||||||
.le("purchase_date", range[1]));
|
.le("purchase_date", range[1]);
|
||||||
|
applyCreatorScope(wrapper, creatorId);
|
||||||
|
List<CollaborationRecordEntity> records = recordService.list(wrapper);
|
||||||
return records.stream()
|
return records.stream()
|
||||||
.map(CollaborationRecordEntity::getPurchasePrice)
|
.map(CollaborationRecordEntity::getPurchasePrice)
|
||||||
.map(this::defaultAmount)
|
.map(this::defaultAmount)
|
||||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||||
}
|
}
|
||||||
|
|
||||||
private BigDecimal sumExpenditure(Date[] range) {
|
private BigDecimal sumExpenditure(Date[] range, Long creatorId) {
|
||||||
List<CollaborationExpenditureEntity> expenditures = expenditureService.list(
|
QueryWrapper<CollaborationExpenditureEntity> wrapper = new QueryWrapper<CollaborationExpenditureEntity>()
|
||||||
new QueryWrapper<CollaborationExpenditureEntity>().ge("spend_date", range[0]).le("spend_date", range[1]));
|
.ge("spend_date", range[0])
|
||||||
|
.le("spend_date", range[1]);
|
||||||
|
applyChildRecordScope(wrapper, creatorId);
|
||||||
|
List<CollaborationExpenditureEntity> expenditures = expenditureService.list(wrapper);
|
||||||
return expenditures.stream()
|
return expenditures.stream()
|
||||||
.map(CollaborationExpenditureEntity::getAmount)
|
.map(CollaborationExpenditureEntity::getAmount)
|
||||||
.map(this::defaultAmount)
|
.map(this::defaultAmount)
|
||||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||||
}
|
}
|
||||||
|
|
||||||
private BigDecimal sumSettlement(Date[] range, String purpose) {
|
private BigDecimal sumSettlement(Date[] range, String purpose, Long creatorId) {
|
||||||
QueryWrapper<CollaborationSettlementEntity> wrapper = new QueryWrapper<CollaborationSettlementEntity>()
|
QueryWrapper<CollaborationSettlementEntity> wrapper = new QueryWrapper<CollaborationSettlementEntity>()
|
||||||
.ge("settle_date", range[0])
|
.ge("settle_date", range[0])
|
||||||
.le("settle_date", range[1])
|
.le("settle_date", range[1])
|
||||||
.eq(purpose != null, "purpose", purpose);
|
.eq(purpose != null, "purpose", purpose);
|
||||||
|
applyChildRecordScope(wrapper, creatorId);
|
||||||
return sumSettlement(settlementService.list(wrapper));
|
return sumSettlement(settlementService.list(wrapper));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void applyChildRecordScope(QueryWrapper<?> wrapper, Long requestedCreatorId) {
|
||||||
|
Long creatorId = getEffectiveCreatorScope(requestedCreatorId);
|
||||||
|
if (creatorId == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wrapper.inSql("record_id", buildCreatorRecordSubQuery(creatorId));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyCreatorScope(QueryWrapper<CollaborationRecordEntity> wrapper, Long requestedCreatorId) {
|
||||||
|
Long creatorId = getEffectiveCreatorScope(requestedCreatorId);
|
||||||
|
if (creatorId == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wrapper.eq("creator_id", creatorId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Long getEffectiveCreatorScope(Long requestedCreatorId) {
|
||||||
|
Long currentCreatorScope = getCurrentCreatorScope();
|
||||||
|
return currentCreatorScope == null ? requestedCreatorId : currentCreatorScope;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildCreatorRecordSubQuery(Long creatorId) {
|
||||||
|
return "select record_id from collaboration_record where deleted = 0 and creator_id = " + creatorId;
|
||||||
|
}
|
||||||
|
|
||||||
private BigDecimal sumExpenditure(List<CollaborationExpenditureEntity> expenditures, String purpose) {
|
private BigDecimal sumExpenditure(List<CollaborationExpenditureEntity> expenditures, String purpose) {
|
||||||
return expenditures.stream()
|
return expenditures.stream()
|
||||||
.filter(item -> purpose.equals(item.getPurpose()))
|
.filter(item -> purpose.equals(item.getPurpose()))
|
||||||
|
|||||||
+4
@@ -56,6 +56,10 @@ public class CollaborationRecordDTO {
|
|||||||
|
|
||||||
private String remark;
|
private String remark;
|
||||||
|
|
||||||
|
private Long creatorId;
|
||||||
|
|
||||||
|
private String creatorName;
|
||||||
|
|
||||||
private Integer tasksNum;
|
private Integer tasksNum;
|
||||||
|
|
||||||
private Integer completedTasksNum;
|
private Integer completedTasksNum;
|
||||||
|
|||||||
+30
@@ -1,5 +1,8 @@
|
|||||||
package com.agileboot.domain.collaboration.record.enumtype;
|
package com.agileboot.domain.collaboration.record.enumtype;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -24,4 +27,31 @@ public enum SettlementStatusEnum {
|
|||||||
this.label = label;
|
this.label = label;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String aggregate(Collection<String> statuses) {
|
||||||
|
if (statuses == null || statuses.isEmpty()) {
|
||||||
|
return NONE.value;
|
||||||
|
}
|
||||||
|
List<String> effectiveStatuses = statuses.stream()
|
||||||
|
.filter(SettlementStatusEnum::isEffectiveStatus)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
if (effectiveStatuses.isEmpty()) {
|
||||||
|
return NONE.value;
|
||||||
|
}
|
||||||
|
if (isSameStatus(effectiveStatuses, SETTLED)) {
|
||||||
|
return SETTLED.value;
|
||||||
|
}
|
||||||
|
if (isSameStatus(effectiveStatuses, UNSETTLED)) {
|
||||||
|
return UNSETTLED.value;
|
||||||
|
}
|
||||||
|
return PARTIAL.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isEffectiveStatus(String status) {
|
||||||
|
return status != null && !NONE.value.equals(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isSameStatus(List<String> statuses, SettlementStatusEnum expected) {
|
||||||
|
return statuses.stream().allMatch(status -> expected.value.equals(status));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -33,7 +33,7 @@ public class CollaborationRecordModel extends CollaborationRecordEntity {
|
|||||||
if (command == null) {
|
if (command == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
BeanUtil.copyProperties(command, this, "recordId");
|
BeanUtil.copyProperties(command, this, "recordId", "completeDate");
|
||||||
loadDefaultValues();
|
loadDefaultValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
@@ -23,6 +23,12 @@ public class CollaborationRecordQuery extends AbstractPageQuery<CollaborationRec
|
|||||||
|
|
||||||
private String cooperationPlatform;
|
private String cooperationPlatform;
|
||||||
|
|
||||||
|
private String settlementStatus;
|
||||||
|
|
||||||
|
private String taskStatus;
|
||||||
|
|
||||||
|
private Long creatorId;
|
||||||
|
|
||||||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||||
private Date purchaseBeginTime;
|
private Date purchaseBeginTime;
|
||||||
|
|
||||||
@@ -35,6 +41,7 @@ public class CollaborationRecordQuery extends AbstractPageQuery<CollaborationRec
|
|||||||
.like(StrUtil.isNotEmpty(brand), "brand", brand)
|
.like(StrUtil.isNotEmpty(brand), "brand", brand)
|
||||||
.like(StrUtil.isNotEmpty(goods), "goods", goods)
|
.like(StrUtil.isNotEmpty(goods), "goods", goods)
|
||||||
.eq(StrUtil.isNotEmpty(cooperationPlatform), "cooperation_platform", cooperationPlatform)
|
.eq(StrUtil.isNotEmpty(cooperationPlatform), "cooperation_platform", cooperationPlatform)
|
||||||
|
.eq(creatorId != null, "creator_id", creatorId)
|
||||||
.ge(purchaseBeginTime != null, "purchase_date", DatePickUtil.getBeginOfTheDay(purchaseBeginTime))
|
.ge(purchaseBeginTime != null, "purchase_date", DatePickUtil.getBeginOfTheDay(purchaseBeginTime))
|
||||||
.le(purchaseEndTime != null, "purchase_date", DatePickUtil.getEndOfTheDay(purchaseEndTime));
|
.le(purchaseEndTime != null, "purchase_date", DatePickUtil.getEndOfTheDay(purchaseEndTime));
|
||||||
|
|
||||||
|
|||||||
-8
@@ -4,8 +4,6 @@ import cn.hutool.extra.spring.SpringUtil;
|
|||||||
import com.agileboot.infrastructure.cache.guava.AbstractGuavaCacheTemplate;
|
import com.agileboot.infrastructure.cache.guava.AbstractGuavaCacheTemplate;
|
||||||
import com.agileboot.infrastructure.cache.redis.RedisCacheTemplate;
|
import com.agileboot.infrastructure.cache.redis.RedisCacheTemplate;
|
||||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||||
import com.agileboot.domain.system.dept.db.SysDeptEntity;
|
|
||||||
import com.agileboot.domain.system.post.db.SysPostEntity;
|
|
||||||
import com.agileboot.domain.system.role.db.SysRoleEntity;
|
import com.agileboot.domain.system.role.db.SysRoleEntity;
|
||||||
import com.agileboot.domain.system.user.db.SysUserEntity;
|
import com.agileboot.domain.system.user.db.SysUserEntity;
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
@@ -22,8 +20,6 @@ public class CacheCenter {
|
|||||||
|
|
||||||
public static AbstractGuavaCacheTemplate<String> configCache;
|
public static AbstractGuavaCacheTemplate<String> configCache;
|
||||||
|
|
||||||
public static AbstractGuavaCacheTemplate<SysDeptEntity> deptCache;
|
|
||||||
|
|
||||||
public static RedisCacheTemplate<String> captchaCache;
|
public static RedisCacheTemplate<String> captchaCache;
|
||||||
|
|
||||||
public static RedisCacheTemplate<SystemLoginUser> loginUserCache;
|
public static RedisCacheTemplate<SystemLoginUser> loginUserCache;
|
||||||
@@ -32,21 +28,17 @@ public class CacheCenter {
|
|||||||
|
|
||||||
public static RedisCacheTemplate<SysRoleEntity> roleCache;
|
public static RedisCacheTemplate<SysRoleEntity> roleCache;
|
||||||
|
|
||||||
public static RedisCacheTemplate<SysPostEntity> postCache;
|
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() {
|
public void init() {
|
||||||
GuavaCacheService guavaCache = SpringUtil.getBean(GuavaCacheService.class);
|
GuavaCacheService guavaCache = SpringUtil.getBean(GuavaCacheService.class);
|
||||||
RedisCacheService redisCache = SpringUtil.getBean(RedisCacheService.class);
|
RedisCacheService redisCache = SpringUtil.getBean(RedisCacheService.class);
|
||||||
|
|
||||||
configCache = guavaCache.configCache;
|
configCache = guavaCache.configCache;
|
||||||
deptCache = guavaCache.deptCache;
|
|
||||||
|
|
||||||
captchaCache = redisCache.captchaCache;
|
captchaCache = redisCache.captchaCache;
|
||||||
loginUserCache = redisCache.loginUserCache;
|
loginUserCache = redisCache.loginUserCache;
|
||||||
userCache = redisCache.userCache;
|
userCache = redisCache.userCache;
|
||||||
roleCache = redisCache.roleCache;
|
roleCache = redisCache.roleCache;
|
||||||
postCache = redisCache.postCache;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
-12
@@ -2,9 +2,7 @@ package com.agileboot.domain.common.cache;
|
|||||||
|
|
||||||
|
|
||||||
import com.agileboot.infrastructure.cache.guava.AbstractGuavaCacheTemplate;
|
import com.agileboot.infrastructure.cache.guava.AbstractGuavaCacheTemplate;
|
||||||
import com.agileboot.domain.system.dept.db.SysDeptEntity;
|
|
||||||
import com.agileboot.domain.system.config.db.SysConfigService;
|
import com.agileboot.domain.system.config.db.SysConfigService;
|
||||||
import com.agileboot.domain.system.dept.db.SysDeptService;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -19,8 +17,6 @@ public class GuavaCacheService {
|
|||||||
|
|
||||||
private final SysConfigService configService;
|
private final SysConfigService configService;
|
||||||
|
|
||||||
private final SysDeptService deptService;
|
|
||||||
|
|
||||||
public final AbstractGuavaCacheTemplate<String> configCache = new AbstractGuavaCacheTemplate<String>() {
|
public final AbstractGuavaCacheTemplate<String> configCache = new AbstractGuavaCacheTemplate<String>() {
|
||||||
@Override
|
@Override
|
||||||
public String getObjectFromDb(Object id) {
|
public String getObjectFromDb(Object id) {
|
||||||
@@ -28,12 +24,4 @@ public class GuavaCacheService {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public final AbstractGuavaCacheTemplate<SysDeptEntity> deptCache = new AbstractGuavaCacheTemplate<SysDeptEntity>() {
|
|
||||||
@Override
|
|
||||||
public SysDeptEntity getObjectFromDb(Object id) {
|
|
||||||
return deptService.getById(id.toString());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
-14
@@ -5,10 +5,8 @@ import com.agileboot.infrastructure.cache.RedisUtil;
|
|||||||
import com.agileboot.infrastructure.cache.redis.CacheKeyEnum;
|
import com.agileboot.infrastructure.cache.redis.CacheKeyEnum;
|
||||||
import com.agileboot.infrastructure.cache.redis.RedisCacheTemplate;
|
import com.agileboot.infrastructure.cache.redis.RedisCacheTemplate;
|
||||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||||
import com.agileboot.domain.system.post.db.SysPostEntity;
|
|
||||||
import com.agileboot.domain.system.role.db.SysRoleEntity;
|
import com.agileboot.domain.system.role.db.SysRoleEntity;
|
||||||
import com.agileboot.domain.system.user.db.SysUserEntity;
|
import com.agileboot.domain.system.user.db.SysUserEntity;
|
||||||
import com.agileboot.domain.system.post.db.SysPostService;
|
|
||||||
import com.agileboot.domain.system.role.db.SysRoleService;
|
import com.agileboot.domain.system.role.db.SysRoleService;
|
||||||
import com.agileboot.domain.system.user.db.SysUserService;
|
import com.agileboot.domain.system.user.db.SysUserService;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
@@ -30,8 +28,6 @@ public class RedisCacheService {
|
|||||||
public RedisCacheTemplate<SysUserEntity> userCache;
|
public RedisCacheTemplate<SysUserEntity> userCache;
|
||||||
public RedisCacheTemplate<SysRoleEntity> roleCache;
|
public RedisCacheTemplate<SysRoleEntity> roleCache;
|
||||||
|
|
||||||
public RedisCacheTemplate<SysPostEntity> postCache;
|
|
||||||
|
|
||||||
// public RedisCacheTemplate<RoleInfo> roleModelInfoCache;
|
// public RedisCacheTemplate<RoleInfo> roleModelInfoCache;
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
@@ -66,16 +62,6 @@ public class RedisCacheService {
|
|||||||
//
|
//
|
||||||
// };
|
// };
|
||||||
|
|
||||||
postCache = new RedisCacheTemplate<SysPostEntity>(redisUtil, CacheKeyEnum.POST_ENTITY_KEY) {
|
|
||||||
@Override
|
|
||||||
public SysPostEntity getObjectFromDb(Object id) {
|
|
||||||
SysPostService postService = SpringUtil.getBean(SysPostService.class);
|
|
||||||
return postService.getById((Serializable) id);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
-1
@@ -14,6 +14,5 @@ public class TreeSelectedDTO {
|
|||||||
|
|
||||||
private List<Long> checkedKeys;
|
private List<Long> checkedKeys;
|
||||||
private List<Tree<Long>> menus;
|
private List<Tree<Long>> menus;
|
||||||
private List<Tree<Long>> depts;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
-88
@@ -1,88 +0,0 @@
|
|||||||
package com.agileboot.domain.system.dept;
|
|
||||||
|
|
||||||
import cn.hutool.core.lang.tree.Tree;
|
|
||||||
import cn.hutool.core.lang.tree.TreeUtil;
|
|
||||||
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.model.DeptModel;
|
|
||||||
import com.agileboot.domain.system.dept.model.DeptModelFactory;
|
|
||||||
import com.agileboot.domain.system.dept.query.DeptQuery;
|
|
||||||
import com.agileboot.domain.system.dept.db.SysDeptEntity;
|
|
||||||
import com.agileboot.domain.system.dept.db.SysDeptService;
|
|
||||||
import com.agileboot.domain.system.role.db.SysRoleService;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 部门服务
|
|
||||||
* @author valarchie
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class DeptApplicationService {
|
|
||||||
|
|
||||||
private final SysDeptService deptService;
|
|
||||||
|
|
||||||
private final SysRoleService roleService;
|
|
||||||
|
|
||||||
private final DeptModelFactory deptModelFactory;
|
|
||||||
|
|
||||||
|
|
||||||
public List<DeptDTO> getDeptList(DeptQuery query) {
|
|
||||||
List<SysDeptEntity> list = deptService.list(query.toQueryWrapper());
|
|
||||||
return list.stream().map(DeptDTO::new).collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
public DeptDTO getDeptInfo(Long id) {
|
|
||||||
SysDeptEntity byId = deptService.getById(id);
|
|
||||||
return new DeptDTO(byId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Tree<Long>> getDeptTree() {
|
|
||||||
List<SysDeptEntity> list = deptService.list();
|
|
||||||
|
|
||||||
return TreeUtil.build(list, 0L, (dept, tree) -> {
|
|
||||||
tree.setId(dept.getDeptId());
|
|
||||||
tree.setParentId(dept.getParentId());
|
|
||||||
tree.putExtra("label", dept.getDeptName());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void addDept(AddDeptCommand addCommand) {
|
|
||||||
DeptModel deptModel = deptModelFactory.create();
|
|
||||||
deptModel.loadAddCommand(addCommand);
|
|
||||||
|
|
||||||
deptModel.checkDeptNameUnique();
|
|
||||||
deptModel.generateAncestors();
|
|
||||||
|
|
||||||
deptModel.insert();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateDept(UpdateDeptCommand updateCommand) {
|
|
||||||
DeptModel deptModel = deptModelFactory.loadById(updateCommand.getDeptId());
|
|
||||||
deptModel.loadUpdateCommand(updateCommand);
|
|
||||||
|
|
||||||
deptModel.checkDeptNameUnique();
|
|
||||||
deptModel.checkParentIdConflict();
|
|
||||||
deptModel.checkStatusAllowChange();
|
|
||||||
deptModel.generateAncestors();
|
|
||||||
|
|
||||||
deptModel.updateById();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeDept(Long deptId) {
|
|
||||||
DeptModel deptModel = deptModelFactory.loadById(deptId);
|
|
||||||
|
|
||||||
deptModel.checkHasChildDept();
|
|
||||||
deptModel.checkDeptAssignedToUsers();
|
|
||||||
|
|
||||||
deptModel.deleteById();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
-58
@@ -1,58 +0,0 @@
|
|||||||
package com.agileboot.domain.system.dept.command;
|
|
||||||
|
|
||||||
import javax.validation.constraints.Email;
|
|
||||||
import javax.validation.constraints.NotBlank;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import javax.validation.constraints.PositiveOrZero;
|
|
||||||
import javax.validation.constraints.Size;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author valarchie
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class AddDeptCommand {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 父部门ID
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
@PositiveOrZero
|
|
||||||
private Long parentId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 部门名称
|
|
||||||
*/
|
|
||||||
@NotBlank(message = "部门名称不能为空")
|
|
||||||
@Size(max = 30, message = "部门名称长度不能超过30个字符")
|
|
||||||
private String deptName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 显示顺序
|
|
||||||
*/
|
|
||||||
@NotNull(message = "显示顺序不能为空")
|
|
||||||
private Integer orderNum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 负责人
|
|
||||||
*/
|
|
||||||
private String leaderName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 联系电话
|
|
||||||
*/
|
|
||||||
@Size(max = 11, message = "联系电话长度不能超过11个字符")
|
|
||||||
private String phone;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 邮箱
|
|
||||||
*/
|
|
||||||
@Email(message = "邮箱格式不正确")
|
|
||||||
@Size(max = 50, message = "邮箱长度不能超过50个字符")
|
|
||||||
private String email;
|
|
||||||
|
|
||||||
|
|
||||||
private Integer status;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
-19
@@ -1,19 +0,0 @@
|
|||||||
package com.agileboot.domain.system.dept.command;
|
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import javax.validation.constraints.PositiveOrZero;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author valarchie
|
|
||||||
*/
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@Data
|
|
||||||
public class UpdateDeptCommand extends AddDeptCommand {
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@PositiveOrZero
|
|
||||||
private Long deptId;
|
|
||||||
|
|
||||||
}
|
|
||||||
-75
@@ -1,75 +0,0 @@
|
|||||||
package com.agileboot.domain.system.dept.db;
|
|
||||||
|
|
||||||
import com.agileboot.common.core.base.BaseEntity;
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import java.io.Serializable;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 部门表
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author valarchie
|
|
||||||
* @since 2022-10-02
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@TableName("sys_dept")
|
|
||||||
@ApiModel(value = "SysDeptEntity对象", description = "部门表")
|
|
||||||
public class SysDeptEntity extends BaseEntity<SysDeptEntity> {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
@ApiModelProperty("部门id")
|
|
||||||
@TableId(value = "dept_id", type = IdType.AUTO)
|
|
||||||
private Long deptId;
|
|
||||||
|
|
||||||
@ApiModelProperty("父部门id")
|
|
||||||
@TableField("parent_id")
|
|
||||||
private Long parentId;
|
|
||||||
|
|
||||||
@ApiModelProperty("祖级列表")
|
|
||||||
@TableField("ancestors")
|
|
||||||
private String ancestors;
|
|
||||||
|
|
||||||
@ApiModelProperty("部门名称")
|
|
||||||
@TableField("dept_name")
|
|
||||||
private String deptName;
|
|
||||||
|
|
||||||
@ApiModelProperty("显示顺序")
|
|
||||||
@TableField("order_num")
|
|
||||||
private Integer orderNum;
|
|
||||||
|
|
||||||
@TableField("leader_id")
|
|
||||||
private Long leaderId;
|
|
||||||
|
|
||||||
@ApiModelProperty("负责人")
|
|
||||||
@TableField("leader_name")
|
|
||||||
private String leaderName;
|
|
||||||
|
|
||||||
@ApiModelProperty("联系电话")
|
|
||||||
@TableField("phone")
|
|
||||||
private String phone;
|
|
||||||
|
|
||||||
@ApiModelProperty("邮箱")
|
|
||||||
@TableField("email")
|
|
||||||
private String email;
|
|
||||||
|
|
||||||
@ApiModelProperty("部门状态(0正常 1停用)")
|
|
||||||
@TableField("`status`")
|
|
||||||
private Integer status;
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Serializable pkVal() {
|
|
||||||
return this.deptId;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-15
@@ -1,15 +0,0 @@
|
|||||||
package com.agileboot.domain.system.dept.db;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 部门表 Mapper 接口
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author valarchie
|
|
||||||
* @since 2022-06-16
|
|
||||||
*/
|
|
||||||
public interface SysDeptMapper extends BaseMapper<SysDeptEntity> {
|
|
||||||
|
|
||||||
}
|
|
||||||
-50
@@ -1,50 +0,0 @@
|
|||||||
package com.agileboot.domain.system.dept.db;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 部门表 服务类
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author valarchie
|
|
||||||
* @since 2022-06-16
|
|
||||||
*/
|
|
||||||
public interface SysDeptService extends IService<SysDeptEntity> {
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 检测部门名称是否一致
|
|
||||||
*
|
|
||||||
* @param deptName 部门名称
|
|
||||||
* @param deptId 部门id
|
|
||||||
* @param parentId 父级部门id
|
|
||||||
* @return 校验结果
|
|
||||||
*/
|
|
||||||
boolean isDeptNameDuplicated(String deptName, Long deptId, Long parentId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 检测部门底下是否还有正在使用中的子部门
|
|
||||||
* @param deptId 部门id
|
|
||||||
* @param enabled 部门是否开启
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
boolean hasChildrenDept(Long deptId, Boolean enabled);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否是目标部门的子部门
|
|
||||||
* @param parentId 目标部门id
|
|
||||||
* @param childId 子部门id
|
|
||||||
* @return 校验结果
|
|
||||||
*/
|
|
||||||
boolean isChildOfTheDept(Long parentId, Long childId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 检测该部门是否已有用户使用
|
|
||||||
* @param deptId 部门id
|
|
||||||
* @return 校验结果
|
|
||||||
*/
|
|
||||||
boolean isDeptAssignedToUsers(Long deptId);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
-62
@@ -1,62 +0,0 @@
|
|||||||
package com.agileboot.domain.system.dept.db;
|
|
||||||
|
|
||||||
import com.agileboot.domain.system.user.db.SysUserEntity;
|
|
||||||
import com.agileboot.domain.system.user.db.SysUserMapper;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 部门表 服务实现类
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author valarchie
|
|
||||||
* @since 2022-06-16
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDeptEntity> implements SysDeptService {
|
|
||||||
|
|
||||||
private final SysUserMapper userMapper;
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isDeptNameDuplicated(String deptName, Long deptId, Long parentId) {
|
|
||||||
QueryWrapper<SysDeptEntity> queryWrapper = new QueryWrapper<>();
|
|
||||||
queryWrapper.eq("dept_name", deptName)
|
|
||||||
.ne(deptId != null, "dept_id", deptId)
|
|
||||||
.eq(parentId != null, "parent_id", parentId);
|
|
||||||
|
|
||||||
return this.baseMapper.exists(queryWrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasChildrenDept(Long deptId, Boolean enabled) {
|
|
||||||
QueryWrapper<SysDeptEntity> queryWrapper = new QueryWrapper<>();
|
|
||||||
queryWrapper.eq(enabled != null, "status", 1)
|
|
||||||
.and(o -> o.eq("parent_id", deptId).or()
|
|
||||||
.apply("FIND_IN_SET (" + deptId + " , ancestors)")
|
|
||||||
);
|
|
||||||
return this.baseMapper.exists(queryWrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isChildOfTheDept(Long parentId, Long childId) {
|
|
||||||
QueryWrapper<SysDeptEntity> queryWrapper = new QueryWrapper<>();
|
|
||||||
queryWrapper.apply("dept_id = '" + childId + "' and FIND_IN_SET ( " + parentId + " , ancestors)");
|
|
||||||
return this.baseMapper.exists(queryWrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isDeptAssignedToUsers(Long deptId) {
|
|
||||||
QueryWrapper<SysUserEntity> queryWrapper = new QueryWrapper<>();
|
|
||||||
queryWrapper.eq("dept_id", deptId);
|
|
||||||
return userMapper.exists(queryWrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-51
@@ -1,51 +0,0 @@
|
|||||||
package com.agileboot.domain.system.dept.dto;
|
|
||||||
|
|
||||||
import com.agileboot.common.enums.common.StatusEnum;
|
|
||||||
import com.agileboot.common.enums.BasicEnumUtil;
|
|
||||||
import com.agileboot.domain.system.dept.db.SysDeptEntity;
|
|
||||||
import java.util.Date;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author valarchie
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class DeptDTO {
|
|
||||||
|
|
||||||
public DeptDTO(SysDeptEntity entity) {
|
|
||||||
if (entity != null) {
|
|
||||||
this.id = entity.getDeptId();
|
|
||||||
this.parentId = entity.getParentId();
|
|
||||||
this.deptName = entity.getDeptName();
|
|
||||||
this.orderNum = entity.getOrderNum();
|
|
||||||
this.leaderName = entity.getLeaderName();
|
|
||||||
this.email = entity.getEmail();
|
|
||||||
this.phone = entity.getPhone();
|
|
||||||
this.status = entity.getStatus();
|
|
||||||
this.createTime = entity.getCreateTime();
|
|
||||||
this.statusStr = BasicEnumUtil.getDescriptionByValue(StatusEnum.class, entity.getStatus());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
private Long parentId;
|
|
||||||
|
|
||||||
private String deptName;
|
|
||||||
|
|
||||||
private Integer orderNum;
|
|
||||||
|
|
||||||
private String leaderName;
|
|
||||||
|
|
||||||
private String phone;
|
|
||||||
|
|
||||||
private String email;
|
|
||||||
|
|
||||||
private Integer status;
|
|
||||||
|
|
||||||
private String statusStr;
|
|
||||||
|
|
||||||
private Date createTime;
|
|
||||||
|
|
||||||
}
|
|
||||||
-106
@@ -1,106 +0,0 @@
|
|||||||
package com.agileboot.domain.system.dept.model;
|
|
||||||
|
|
||||||
import cn.hutool.core.bean.BeanUtil;
|
|
||||||
import cn.hutool.core.convert.Convert;
|
|
||||||
import com.agileboot.common.exception.ApiException;
|
|
||||||
import com.agileboot.common.exception.error.ErrorCode;
|
|
||||||
import com.agileboot.domain.system.dept.command.AddDeptCommand;
|
|
||||||
import com.agileboot.domain.system.dept.command.UpdateDeptCommand;
|
|
||||||
import com.agileboot.common.enums.common.StatusEnum;
|
|
||||||
import com.agileboot.common.enums.BasicEnumUtil;
|
|
||||||
import com.agileboot.domain.system.dept.db.SysDeptEntity;
|
|
||||||
import com.agileboot.domain.system.dept.db.SysDeptService;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author valarchie
|
|
||||||
*/
|
|
||||||
public class DeptModel extends SysDeptEntity {
|
|
||||||
|
|
||||||
private final SysDeptService deptService;
|
|
||||||
|
|
||||||
public DeptModel(SysDeptService deptService) {
|
|
||||||
this.deptService = deptService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DeptModel(SysDeptEntity entity, SysDeptService deptService) {
|
|
||||||
if (entity != null) {
|
|
||||||
// 如果大数据量的话 可以用MapStruct优化
|
|
||||||
BeanUtil.copyProperties(entity, this);
|
|
||||||
}
|
|
||||||
this.deptService = deptService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void loadAddCommand(AddDeptCommand addCommand) {
|
|
||||||
this.setParentId(addCommand.getParentId());
|
|
||||||
this.setDeptName(addCommand.getDeptName());
|
|
||||||
this.setOrderNum(addCommand.getOrderNum());
|
|
||||||
this.setLeaderName(addCommand.getLeaderName());
|
|
||||||
this.setPhone(addCommand.getPhone());
|
|
||||||
this.setEmail(addCommand.getEmail());
|
|
||||||
this.setStatus(addCommand.getStatus());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void loadUpdateCommand(UpdateDeptCommand updateCommand) {
|
|
||||||
loadAddCommand(updateCommand);
|
|
||||||
setStatus(Convert.toInt(updateCommand.getStatus(), 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void checkDeptNameUnique() {
|
|
||||||
if (deptService.isDeptNameDuplicated(getDeptName(), getDeptId(), getParentId())) {
|
|
||||||
throw new ApiException(ErrorCode.Business.DEPT_NAME_IS_NOT_UNIQUE, getDeptName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void checkParentIdConflict() {
|
|
||||||
if (Objects.equals(getParentId(), getDeptId())) {
|
|
||||||
throw new ApiException(ErrorCode.Business.DEPT_PARENT_ID_IS_NOT_ALLOWED_SELF);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void checkHasChildDept() {
|
|
||||||
if (deptService.hasChildrenDept(getDeptId(), null)) {
|
|
||||||
throw new ApiException(ErrorCode.Business.DEPT_EXIST_CHILD_DEPT_NOT_ALLOW_DELETE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void checkDeptAssignedToUsers() {
|
|
||||||
if (deptService.isDeptAssignedToUsers(getDeptId())) {
|
|
||||||
throw new ApiException(ErrorCode.Business.DEPT_EXIST_LINK_USER_NOT_ALLOW_DELETE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void generateAncestors() {
|
|
||||||
|
|
||||||
// 处理 getParentId 可能为 null 的情况
|
|
||||||
if (getParentId() == null || getParentId() == 0) {
|
|
||||||
setAncestors(String.valueOf(getParentId() == null ? 0 : getParentId()));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SysDeptEntity parentDept = deptService.getById(getParentId());
|
|
||||||
|
|
||||||
// 检查 parentDept 是否为 null 或者状态为禁用
|
|
||||||
if (parentDept == null || StatusEnum.DISABLE.equals(
|
|
||||||
BasicEnumUtil.fromValue(StatusEnum.class, parentDept.getStatus()))) {
|
|
||||||
throw new ApiException(ErrorCode.Business.DEPT_PARENT_DEPT_NO_EXIST_OR_DISABLED);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理 parentDept.getAncestors() 可能为 null 的情况
|
|
||||||
String ancestors = parentDept.getAncestors() == null ? "" : parentDept.getAncestors();
|
|
||||||
setAncestors(ancestors + "," + getParentId());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* DDD 有些阻抗 如果为了追求性能的话 还是得通过 数据库的方式来判断
|
|
||||||
*/
|
|
||||||
public void checkStatusAllowChange() {
|
|
||||||
if (StatusEnum.DISABLE.getValue().equals(getStatus()) &&
|
|
||||||
deptService.hasChildrenDept(getDeptId(), true)) {
|
|
||||||
throw new ApiException(ErrorCode.Business.DEPT_STATUS_ID_IS_NOT_ALLOWED_CHANGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-45
@@ -1,45 +0,0 @@
|
|||||||
package com.agileboot.domain.system.dept.model;
|
|
||||||
|
|
||||||
import com.agileboot.common.exception.ApiException;
|
|
||||||
import com.agileboot.common.exception.error.ErrorCode;
|
|
||||||
import com.agileboot.domain.system.dept.command.AddDeptCommand;
|
|
||||||
import com.agileboot.domain.system.dept.db.SysDeptEntity;
|
|
||||||
import com.agileboot.domain.system.dept.db.SysDeptService;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 部门模型工厂
|
|
||||||
* @author valarchie
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class DeptModelFactory {
|
|
||||||
|
|
||||||
private final SysDeptService deptService;
|
|
||||||
|
|
||||||
public DeptModel loadById(Long deptId) {
|
|
||||||
SysDeptEntity byId = deptService.getById(deptId);
|
|
||||||
if (byId == null) {
|
|
||||||
throw new ApiException(ErrorCode.Business.COMMON_OBJECT_NOT_FOUND, deptId, "部门");
|
|
||||||
}
|
|
||||||
return new DeptModel(byId, deptService);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DeptModel create() {
|
|
||||||
return new DeptModel(deptService);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DeptModel loadFromAddCommand(AddDeptCommand addCommand, DeptModel model) {
|
|
||||||
model.setParentId(addCommand.getParentId());
|
|
||||||
model.setDeptName(addCommand.getDeptName());
|
|
||||||
model.setOrderNum(addCommand.getOrderNum());
|
|
||||||
model.setLeaderName(addCommand.getLeaderName());
|
|
||||||
model.setPhone(addCommand.getPhone());
|
|
||||||
model.setEmail(addCommand.getEmail());
|
|
||||||
return model;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
-36
@@ -1,36 +0,0 @@
|
|||||||
package com.agileboot.domain.system.dept.query;
|
|
||||||
|
|
||||||
import com.agileboot.common.core.page.AbstractQuery;
|
|
||||||
import com.agileboot.domain.system.dept.db.SysDeptEntity;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author valarchie
|
|
||||||
*/
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@Data
|
|
||||||
@NoArgsConstructor
|
|
||||||
public class DeptQuery extends AbstractQuery<SysDeptEntity> {
|
|
||||||
|
|
||||||
private Long deptId;
|
|
||||||
|
|
||||||
private Long parentId;
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public QueryWrapper<SysDeptEntity> addQueryCondition() {
|
|
||||||
// TODO parentId 这个似乎没使用
|
|
||||||
return new QueryWrapper<SysDeptEntity>()
|
|
||||||
// .eq(status != null, "status", status)
|
|
||||||
.eq(parentId != null, "parent_id", parentId);
|
|
||||||
// .like(StrUtil.isNotEmpty(deptName), "dept_name", deptName);
|
|
||||||
// .and(deptId != null && isExcludeCurrentDept, o ->
|
|
||||||
// o.ne("dept_id", deptId)
|
|
||||||
// .or()
|
|
||||||
// .apply("FIND_IN_SET (dept_id , ancestors)")
|
|
||||||
// );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-8
@@ -73,14 +73,6 @@ public class SysOperationLogEntity extends Model<SysOperationLogEntity> {
|
|||||||
@TableField("operator_location")
|
@TableField("operator_location")
|
||||||
private String operatorLocation;
|
private String operatorLocation;
|
||||||
|
|
||||||
@ApiModelProperty("部门ID")
|
|
||||||
@TableField("dept_id")
|
|
||||||
private Long deptId;
|
|
||||||
|
|
||||||
@ApiModelProperty("部门名称")
|
|
||||||
@TableField("dept_name")
|
|
||||||
private String deptName;
|
|
||||||
|
|
||||||
@ApiModelProperty("请求参数")
|
@ApiModelProperty("请求参数")
|
||||||
@TableField("operation_param")
|
@TableField("operation_param")
|
||||||
private String operationParam;
|
private String operationParam;
|
||||||
|
|||||||
-6
@@ -69,12 +69,6 @@ public class OperationLogDTO {
|
|||||||
@ExcelColumn(name = "ip地点")
|
@ExcelColumn(name = "ip地点")
|
||||||
private String operatorLocation;
|
private String operatorLocation;
|
||||||
|
|
||||||
@ExcelColumn(name = "部门ID")
|
|
||||||
private Long deptId;
|
|
||||||
|
|
||||||
@ExcelColumn(name = "部门")
|
|
||||||
private String deptName;
|
|
||||||
|
|
||||||
@ExcelColumn(name = "操作参数")
|
@ExcelColumn(name = "操作参数")
|
||||||
private String operationParam;
|
private String operationParam;
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -105,7 +105,7 @@ public class MenuApplicationService {
|
|||||||
//默认为id可以不设置
|
//默认为id可以不设置
|
||||||
config.setIdKey("menuId");
|
config.setIdKey("menuId");
|
||||||
return TreeUtil.build(menus, 0L, config, (menu, tree) -> {
|
return TreeUtil.build(menus, 0L, config, (menu, tree) -> {
|
||||||
// 也可以使用 tree.setId(dept.getId());等一些默认值
|
// 也可以使用 tree.setId(menu.getId());等一些默认值
|
||||||
tree.setId(menu.getMenuId());
|
tree.setId(menu.getMenuId());
|
||||||
tree.setParentId(menu.getParentId());
|
tree.setParentId(menu.getParentId());
|
||||||
tree.putExtra("label", menu.getMenuName());
|
tree.putExtra("label", menu.getMenuName());
|
||||||
@@ -132,7 +132,7 @@ public class MenuApplicationService {
|
|||||||
config.setIdKey("menuId");
|
config.setIdKey("menuId");
|
||||||
|
|
||||||
return TreeUtil.build(noButtonMenus, 0L, config, (menu, tree) -> {
|
return TreeUtil.build(noButtonMenus, 0L, config, (menu, tree) -> {
|
||||||
// 也可以使用 tree.setId(dept.getId());等一些默认值
|
// 也可以使用 tree.setId(menu.getId());等一些默认值
|
||||||
tree.setId(menu.getMenuId());
|
tree.setId(menu.getMenuId());
|
||||||
tree.setParentId(menu.getParentId());
|
tree.setParentId(menu.getParentId());
|
||||||
// TODO 可以取meta中的rank来排序
|
// TODO 可以取meta中的rank来排序
|
||||||
|
|||||||
-13
@@ -1,8 +1,6 @@
|
|||||||
package com.agileboot.domain.system.monitor.dto;
|
package com.agileboot.domain.system.monitor.dto;
|
||||||
|
|
||||||
import com.agileboot.domain.common.cache.CacheCenter;
|
|
||||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||||
import com.agileboot.domain.system.dept.db.SysDeptEntity;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -18,11 +16,6 @@ public class OnlineUserDTO {
|
|||||||
*/
|
*/
|
||||||
private String tokenId;
|
private String tokenId;
|
||||||
|
|
||||||
/**
|
|
||||||
* 部门名称
|
|
||||||
*/
|
|
||||||
private String deptName;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户名称
|
* 用户名称
|
||||||
*/
|
*/
|
||||||
@@ -66,12 +59,6 @@ public class OnlineUserDTO {
|
|||||||
this.browser = user.getLoginInfo().getBrowser();
|
this.browser = user.getLoginInfo().getBrowser();
|
||||||
this.operationSystem = user.getLoginInfo().getOperationSystem();
|
this.operationSystem = user.getLoginInfo().getOperationSystem();
|
||||||
this.loginTime = user.getLoginInfo().getLoginTime();
|
this.loginTime = user.getLoginInfo().getLoginTime();
|
||||||
|
|
||||||
SysDeptEntity deptEntity = CacheCenter.deptCache.get(user.getDeptId() + "");
|
|
||||||
|
|
||||||
if (deptEntity != null) {
|
|
||||||
this.deptName = deptEntity.getDeptName();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
-85
@@ -1,85 +0,0 @@
|
|||||||
package com.agileboot.domain.system.post;
|
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import com.agileboot.common.core.page.PageDTO;
|
|
||||||
import com.agileboot.domain.common.command.BulkOperationCommand;
|
|
||||||
import com.agileboot.domain.system.post.command.AddPostCommand;
|
|
||||||
import com.agileboot.domain.system.post.command.UpdatePostCommand;
|
|
||||||
import com.agileboot.domain.system.post.db.SysPostEntity;
|
|
||||||
import com.agileboot.domain.system.post.db.SysPostService;
|
|
||||||
import com.agileboot.domain.system.post.dto.PostDTO;
|
|
||||||
import com.agileboot.domain.system.post.model.PostModel;
|
|
||||||
import com.agileboot.domain.system.post.model.PostModelFactory;
|
|
||||||
import com.agileboot.domain.system.post.query.PostQuery;
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author valarchie
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class PostApplicationService {
|
|
||||||
|
|
||||||
private final PostModelFactory postModelFactory;
|
|
||||||
|
|
||||||
private final SysPostService postService;
|
|
||||||
|
|
||||||
public PageDTO<PostDTO> getPostList(PostQuery query) {
|
|
||||||
Page<SysPostEntity> page = postService.page(query.toPage(), query.toQueryWrapper());
|
|
||||||
List<PostDTO> records = page.getRecords().stream().map(PostDTO::new).collect(Collectors.toList());
|
|
||||||
return new PageDTO<>(records, page.getTotal());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询满足条件的所有岗位,不分页
|
|
||||||
* @param query 查询条件
|
|
||||||
* @return 满足查询条件的岗位列表
|
|
||||||
* @author Kevin Zhang
|
|
||||||
* @date 2023-10-02
|
|
||||||
*/
|
|
||||||
public List<PostDTO> getPostListAll(PostQuery query) {
|
|
||||||
List<SysPostEntity> all = postService.list(query.toQueryWrapper());
|
|
||||||
List<PostDTO> records = all.stream().map(PostDTO::new).collect(Collectors.toList());
|
|
||||||
return records;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PostDTO getPostInfo(Long postId) {
|
|
||||||
SysPostEntity byId = postService.getById(postId);
|
|
||||||
return new PostDTO(byId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addPost(AddPostCommand addCommand) {
|
|
||||||
PostModel postModel = postModelFactory.create();
|
|
||||||
postModel.loadFromAddCommand(addCommand);
|
|
||||||
|
|
||||||
postModel.checkPostNameUnique();
|
|
||||||
postModel.checkPostCodeUnique();
|
|
||||||
|
|
||||||
postModel.insert();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updatePost(UpdatePostCommand updateCommand) {
|
|
||||||
PostModel postModel = postModelFactory.loadById(updateCommand.getPostId());
|
|
||||||
postModel.loadFromUpdateCommand(updateCommand);
|
|
||||||
|
|
||||||
postModel.checkPostNameUnique();
|
|
||||||
postModel.checkPostCodeUnique();
|
|
||||||
|
|
||||||
postModel.updateById();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void deletePost(BulkOperationCommand<Long> deleteCommand) {
|
|
||||||
for (Long id : deleteCommand.getIds()) {
|
|
||||||
PostModel postModel = postModelFactory.loadById(id);
|
|
||||||
postModel.checkCanBeDelete();
|
|
||||||
}
|
|
||||||
|
|
||||||
postService.removeBatchByIds(deleteCommand.getIds());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-37
@@ -1,37 +0,0 @@
|
|||||||
package com.agileboot.domain.system.post.command;
|
|
||||||
|
|
||||||
import javax.validation.constraints.NotBlank;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import javax.validation.constraints.PositiveOrZero;
|
|
||||||
import javax.validation.constraints.Size;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author valarchie
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class AddPostCommand {
|
|
||||||
|
|
||||||
@NotBlank(message = "岗位编码不能为空")
|
|
||||||
@Size(max = 64, message = "岗位编码长度不能超过64个字符")
|
|
||||||
protected String postCode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 岗位名称
|
|
||||||
*/
|
|
||||||
@NotBlank(message = "岗位名称不能为空")
|
|
||||||
@Size(max = 64, message = "岗位名称长度不能超过64个字符")
|
|
||||||
protected String postName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 岗位排序
|
|
||||||
*/
|
|
||||||
@NotNull(message = "显示顺序不能为空")
|
|
||||||
protected Integer postSort;
|
|
||||||
|
|
||||||
protected String remark;
|
|
||||||
|
|
||||||
@PositiveOrZero
|
|
||||||
protected String status;
|
|
||||||
|
|
||||||
}
|
|
||||||
-19
@@ -1,19 +0,0 @@
|
|||||||
package com.agileboot.domain.system.post.command;
|
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import javax.validation.constraints.Positive;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author valarchie
|
|
||||||
*/
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@Data
|
|
||||||
public class UpdatePostCommand extends AddPostCommand {
|
|
||||||
|
|
||||||
@NotNull(message = "岗位ID不能为空")
|
|
||||||
@Positive
|
|
||||||
private Long postId;
|
|
||||||
|
|
||||||
}
|
|
||||||
-60
@@ -1,60 +0,0 @@
|
|||||||
package com.agileboot.domain.system.post.db;
|
|
||||||
|
|
||||||
import com.agileboot.common.core.base.BaseEntity;
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import java.io.Serializable;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 岗位信息表
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author valarchie
|
|
||||||
* @since 2022-10-02
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@TableName("sys_post")
|
|
||||||
@ApiModel(value = "SysPostEntity对象", description = "岗位信息表")
|
|
||||||
public class SysPostEntity extends BaseEntity<SysPostEntity> {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
@ApiModelProperty("岗位ID")
|
|
||||||
@TableId(value = "post_id", type = IdType.AUTO)
|
|
||||||
private Long postId;
|
|
||||||
|
|
||||||
@ApiModelProperty("岗位编码")
|
|
||||||
@TableField("post_code")
|
|
||||||
private String postCode;
|
|
||||||
|
|
||||||
@ApiModelProperty("岗位名称")
|
|
||||||
@TableField("post_name")
|
|
||||||
private String postName;
|
|
||||||
|
|
||||||
@ApiModelProperty("显示顺序")
|
|
||||||
@TableField("post_sort")
|
|
||||||
private Integer postSort;
|
|
||||||
|
|
||||||
@ApiModelProperty("状态(1正常 0停用)")
|
|
||||||
@TableField("`status`")
|
|
||||||
private Integer status;
|
|
||||||
|
|
||||||
@ApiModelProperty("备注")
|
|
||||||
@TableField("remark")
|
|
||||||
private String remark;
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Serializable pkVal() {
|
|
||||||
return this.postId;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-15
@@ -1,15 +0,0 @@
|
|||||||
package com.agileboot.domain.system.post.db;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 岗位信息表 Mapper 接口
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author valarchie
|
|
||||||
* @since 2022-06-16
|
|
||||||
*/
|
|
||||||
public interface SysPostMapper extends BaseMapper<SysPostEntity> {
|
|
||||||
|
|
||||||
}
|
|
||||||
-40
@@ -1,40 +0,0 @@
|
|||||||
package com.agileboot.domain.system.post.db;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 岗位信息表 服务类
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author valarchie
|
|
||||||
* @since 2022-06-16
|
|
||||||
*/
|
|
||||||
public interface SysPostService extends IService<SysPostEntity> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 校验岗位名称
|
|
||||||
* @param postId 职位Id
|
|
||||||
* @param postName 职位名称
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
boolean isPostNameDuplicated(Long postId, String postName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 校验岗位编码
|
|
||||||
* @param postId 职位id
|
|
||||||
* @param postCode 职位代码
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
boolean isPostCodeDuplicated(Long postId, String postCode);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 检测职位是否分配给用户
|
|
||||||
*
|
|
||||||
* @param postId 职位id
|
|
||||||
* @return 校验结果
|
|
||||||
*/
|
|
||||||
boolean isAssignedToUsers(Long postId);
|
|
||||||
|
|
||||||
}
|
|
||||||
-55
@@ -1,55 +0,0 @@
|
|||||||
package com.agileboot.domain.system.post.db;
|
|
||||||
|
|
||||||
import com.agileboot.domain.system.user.db.SysUserEntity;
|
|
||||||
import com.agileboot.domain.system.user.db.SysUserMapper;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 岗位信息表 服务实现类
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author valarchie
|
|
||||||
* @since 2022-06-16
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class SysPostServiceImpl extends ServiceImpl<SysPostMapper, SysPostEntity> implements SysPostService {
|
|
||||||
|
|
||||||
private final SysUserMapper userMapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 校验岗位名称是否唯一
|
|
||||||
*
|
|
||||||
* @param postName 岗位名称
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean isPostNameDuplicated(Long postId, String postName) {
|
|
||||||
QueryWrapper<SysPostEntity> queryWrapper = new QueryWrapper<>();
|
|
||||||
queryWrapper.ne(postId != null, "post_id", postId)
|
|
||||||
.eq("post_name", postName);
|
|
||||||
return baseMapper.exists(queryWrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isPostCodeDuplicated(Long postId, String postCode) {
|
|
||||||
QueryWrapper<SysPostEntity> queryWrapper = new QueryWrapper<>();
|
|
||||||
queryWrapper.ne(postId != null, "post_id", postId)
|
|
||||||
.eq("post_code", postCode);
|
|
||||||
return baseMapper.exists(queryWrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isAssignedToUsers(Long postId) {
|
|
||||||
QueryWrapper<SysUserEntity> queryWrapper = new QueryWrapper<>();
|
|
||||||
queryWrapper.eq("post_id", postId);
|
|
||||||
return userMapper.exists(queryWrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
-52
@@ -1,52 +0,0 @@
|
|||||||
package com.agileboot.domain.system.post.dto;
|
|
||||||
|
|
||||||
import cn.hutool.core.bean.BeanUtil;
|
|
||||||
import com.agileboot.common.annotation.ExcelColumn;
|
|
||||||
import com.agileboot.common.enums.common.StatusEnum;
|
|
||||||
import com.agileboot.common.enums.BasicEnumUtil;
|
|
||||||
import com.agileboot.domain.system.post.db.SysPostEntity;
|
|
||||||
import java.util.Date;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author valarchie
|
|
||||||
*/
|
|
||||||
@AllArgsConstructor
|
|
||||||
@NoArgsConstructor
|
|
||||||
@Data
|
|
||||||
public class PostDTO {
|
|
||||||
|
|
||||||
public PostDTO(SysPostEntity entity) {
|
|
||||||
if (entity != null) {
|
|
||||||
BeanUtil.copyProperties(entity, this);
|
|
||||||
statusStr = BasicEnumUtil.getDescriptionByValue(StatusEnum.class, entity.getStatus());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ExcelColumn(name = "岗位ID")
|
|
||||||
private Long postId;
|
|
||||||
|
|
||||||
|
|
||||||
@ExcelColumn(name = "岗位编码")
|
|
||||||
private String postCode;
|
|
||||||
|
|
||||||
@ExcelColumn(name = "岗位名称")
|
|
||||||
private String postName;
|
|
||||||
|
|
||||||
|
|
||||||
@ExcelColumn(name = "岗位排序")
|
|
||||||
private Integer postSort;
|
|
||||||
|
|
||||||
@ExcelColumn(name = "备注")
|
|
||||||
private String remark;
|
|
||||||
|
|
||||||
private Integer status;
|
|
||||||
|
|
||||||
@ExcelColumn(name = "状态")
|
|
||||||
private String statusStr;
|
|
||||||
|
|
||||||
private Date createTime;
|
|
||||||
|
|
||||||
}
|
|
||||||
-63
@@ -1,63 +0,0 @@
|
|||||||
package com.agileboot.domain.system.post.model;
|
|
||||||
|
|
||||||
import cn.hutool.core.bean.BeanUtil;
|
|
||||||
import com.agileboot.common.exception.ApiException;
|
|
||||||
import com.agileboot.common.exception.error.ErrorCode;
|
|
||||||
import com.agileboot.domain.system.post.command.AddPostCommand;
|
|
||||||
import com.agileboot.domain.system.post.command.UpdatePostCommand;
|
|
||||||
import com.agileboot.domain.system.post.db.SysPostEntity;
|
|
||||||
import com.agileboot.domain.system.post.db.SysPostService;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author valarchie
|
|
||||||
*/
|
|
||||||
@NoArgsConstructor
|
|
||||||
public class PostModel extends SysPostEntity {
|
|
||||||
|
|
||||||
private SysPostService postService;
|
|
||||||
|
|
||||||
public PostModel(SysPostService postService) {
|
|
||||||
this.postService = postService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PostModel(SysPostEntity entity, SysPostService postService) {
|
|
||||||
if (entity != null) {
|
|
||||||
BeanUtil.copyProperties(entity, this);
|
|
||||||
}
|
|
||||||
this.postService = postService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void loadFromAddCommand(AddPostCommand addCommand) {
|
|
||||||
if (addCommand != null) {
|
|
||||||
BeanUtil.copyProperties(addCommand, this, "postId");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void loadFromUpdateCommand(UpdatePostCommand command) {
|
|
||||||
if (command != null) {
|
|
||||||
loadFromAddCommand(command);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void checkCanBeDelete() {
|
|
||||||
if (postService.isAssignedToUsers(this.getPostId())) {
|
|
||||||
throw new ApiException(ErrorCode.Business.POST_ALREADY_ASSIGNED_TO_USER_CAN_NOT_BE_DELETED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void checkPostNameUnique() {
|
|
||||||
if (postService.isPostNameDuplicated(getPostId(), getPostName())) {
|
|
||||||
throw new ApiException(ErrorCode.Business.POST_NAME_IS_NOT_UNIQUE, getPostName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void checkPostCodeUnique() {
|
|
||||||
if (postService.isPostCodeDuplicated(getPostId(), getPostCode())) {
|
|
||||||
throw new ApiException(ErrorCode.Business.POST_CODE_IS_NOT_UNIQUE, getPostCode());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-31
@@ -1,31 +0,0 @@
|
|||||||
package com.agileboot.domain.system.post.model;
|
|
||||||
|
|
||||||
import com.agileboot.common.exception.ApiException;
|
|
||||||
import com.agileboot.common.exception.error.ErrorCode.Business;
|
|
||||||
import com.agileboot.domain.system.post.db.SysPostEntity;
|
|
||||||
import com.agileboot.domain.system.post.db.SysPostService;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author valarchie
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class PostModelFactory {
|
|
||||||
|
|
||||||
private final SysPostService postService;
|
|
||||||
|
|
||||||
public PostModel loadById(Long postId) {
|
|
||||||
SysPostEntity byId = postService.getById(postId);
|
|
||||||
if (byId == null) {
|
|
||||||
throw new ApiException(Business.COMMON_OBJECT_NOT_FOUND, postId, "职位");
|
|
||||||
}
|
|
||||||
return new PostModel(byId, postService);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PostModel create() {
|
|
||||||
return new PostModel(postService);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-35
@@ -1,35 +0,0 @@
|
|||||||
package com.agileboot.domain.system.post.query;
|
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import com.agileboot.common.core.page.AbstractPageQuery;
|
|
||||||
import com.agileboot.domain.system.post.db.SysPostEntity;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author valarchie
|
|
||||||
*/
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@Data
|
|
||||||
public class PostQuery extends AbstractPageQuery<SysPostEntity> {
|
|
||||||
|
|
||||||
private String postCode;
|
|
||||||
private String postName;
|
|
||||||
private Integer status;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public QueryWrapper<SysPostEntity> addQueryCondition() {
|
|
||||||
QueryWrapper<SysPostEntity> queryWrapper = new QueryWrapper<SysPostEntity>()
|
|
||||||
.eq(status != null, "status", status)
|
|
||||||
.eq(StrUtil.isNotEmpty(postCode), "post_code", postCode)
|
|
||||||
.like(StrUtil.isNotEmpty(postName), "post_name", postName);
|
|
||||||
// 当前端没有选择排序字段时,则使用post_sort字段升序排序(在父类AbstractQuery中默认为升序)
|
|
||||||
if (StrUtil.isEmpty(this.getOrderColumn())) {
|
|
||||||
this.setOrderColumn("post_sort");
|
|
||||||
}
|
|
||||||
this.setTimeRangeColumn("create_time");
|
|
||||||
|
|
||||||
return queryWrapper;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-16
@@ -1,11 +1,9 @@
|
|||||||
package com.agileboot.domain.system.role;
|
package com.agileboot.domain.system.role;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import com.agileboot.common.core.page.PageDTO;
|
import com.agileboot.common.core.page.PageDTO;
|
||||||
import com.agileboot.domain.common.cache.CacheCenter;
|
import com.agileboot.domain.common.cache.CacheCenter;
|
||||||
import com.agileboot.domain.system.role.command.AddRoleCommand;
|
import com.agileboot.domain.system.role.command.AddRoleCommand;
|
||||||
import com.agileboot.domain.system.role.command.UpdateDataScopeCommand;
|
|
||||||
import com.agileboot.domain.system.role.command.UpdateRoleCommand;
|
import com.agileboot.domain.system.role.command.UpdateRoleCommand;
|
||||||
import com.agileboot.domain.system.role.command.UpdateStatusCommand;
|
import com.agileboot.domain.system.role.command.UpdateStatusCommand;
|
||||||
import com.agileboot.domain.system.role.dto.RoleDTO;
|
import com.agileboot.domain.system.role.dto.RoleDTO;
|
||||||
@@ -56,9 +54,6 @@ public class RoleApplicationService {
|
|||||||
public RoleDTO getRoleInfo(Long roleId) {
|
public RoleDTO getRoleInfo(Long roleId) {
|
||||||
SysRoleEntity byId = roleService.getById(roleId);
|
SysRoleEntity byId = roleService.getById(roleId);
|
||||||
RoleDTO roleDTO = new RoleDTO(byId);
|
RoleDTO roleDTO = new RoleDTO(byId);
|
||||||
List<Long> selectedDeptList = StrUtil.split(byId.getDeptIdSet(), ",")
|
|
||||||
.stream().filter(StrUtil::isNotEmpty).map(Long::new).collect(Collectors.toList());
|
|
||||||
roleDTO.setSelectedDeptList(selectedDeptList);
|
|
||||||
roleDTO.setSelectedMenuList(menuService.getMenuIdsByRoleId(roleId));
|
roleDTO.setSelectedMenuList(menuService.getMenuIdsByRoleId(roleId));
|
||||||
return roleDTO;
|
return roleDTO;
|
||||||
}
|
}
|
||||||
@@ -105,17 +100,6 @@ public class RoleApplicationService {
|
|||||||
roleModel.updateById();
|
roleModel.updateById();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateDataScope(UpdateDataScopeCommand command) {
|
|
||||||
RoleModel roleModel = roleModelFactory.loadById(command.getRoleId());
|
|
||||||
|
|
||||||
roleModel.setDeptIds(command.getDeptIds());
|
|
||||||
roleModel.setDataScope(command.getDataScope());
|
|
||||||
roleModel.generateDeptIdSet();
|
|
||||||
|
|
||||||
roleModel.updateById();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public PageDTO<UserDTO> getAllocatedUserList(AllocatedRoleQuery query) {
|
public PageDTO<UserDTO> getAllocatedUserList(AllocatedRoleQuery query) {
|
||||||
Page<SysUserEntity> page = userService.getUserListByRole(query);
|
Page<SysUserEntity> page = userService.getUserListByRole(query);
|
||||||
List<UserDTO> dtoList = page.getRecords().stream().map(UserDTO::new).collect(Collectors.toList());
|
List<UserDTO> dtoList = page.getRecords().stream().map(UserDTO::new).collect(Collectors.toList());
|
||||||
|
|||||||
-1
@@ -40,7 +40,6 @@ public class AddRoleCommand {
|
|||||||
private String remark;
|
private String remark;
|
||||||
|
|
||||||
|
|
||||||
@ExcelColumn(name = "数据范围")
|
|
||||||
private String dataScope;
|
private String dataScope;
|
||||||
|
|
||||||
@PositiveOrZero
|
@PositiveOrZero
|
||||||
|
|||||||
-26
@@ -1,26 +0,0 @@
|
|||||||
package com.agileboot.domain.system.role.command;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import javax.validation.constraints.NotEmpty;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import javax.validation.constraints.Positive;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author valarchie
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class UpdateDataScopeCommand {
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Positive
|
|
||||||
private Long roleId;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@NotEmpty
|
|
||||||
private List<Long> deptIds;
|
|
||||||
|
|
||||||
private Integer dataScope;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
+1
-5
@@ -43,14 +43,10 @@ public class SysRoleEntity extends BaseEntity<SysRoleEntity> {
|
|||||||
@TableField("role_sort")
|
@TableField("role_sort")
|
||||||
private Integer roleSort;
|
private Integer roleSort;
|
||||||
|
|
||||||
@ApiModelProperty("数据范围(1:全部数据权限 2:自定数据权限 3: 本部门数据权限 4: 本部门及以下数据权限 5: 本人权限)")
|
@ApiModelProperty("数据范围(1:全部数据权限 5: 本人权限)")
|
||||||
@TableField("data_scope")
|
@TableField("data_scope")
|
||||||
private Integer dataScope;
|
private Integer dataScope;
|
||||||
|
|
||||||
@ApiModelProperty("角色所拥有的部门数据权限")
|
|
||||||
@TableField("dept_id_set")
|
|
||||||
private String deptIdSet;
|
|
||||||
|
|
||||||
@ApiModelProperty("角色状态(1正常 0停用)")
|
@ApiModelProperty("角色状态(1正常 0停用)")
|
||||||
@TableField("`status`")
|
@TableField("`status`")
|
||||||
private Integer status;
|
private Integer status;
|
||||||
|
|||||||
+7
@@ -32,6 +32,13 @@ public interface SysRoleService extends IService<SysRoleEntity> {
|
|||||||
*/
|
*/
|
||||||
boolean isRoleKeyDuplicated(Long roleId, String roleKey);
|
boolean isRoleKeyDuplicated(Long roleId, String roleKey);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据角色标识获取可用角色
|
||||||
|
* @param roleKey 角色标识
|
||||||
|
* @return 角色信息
|
||||||
|
*/
|
||||||
|
SysRoleEntity getEnabledRoleByKey(String roleKey);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检测角色是否分配给用户
|
* 检测角色是否分配给用户
|
||||||
|
|||||||
+9
@@ -3,6 +3,7 @@ package com.agileboot.domain.system.role.db;
|
|||||||
import com.agileboot.domain.system.menu.db.SysMenuEntity;
|
import com.agileboot.domain.system.menu.db.SysMenuEntity;
|
||||||
import com.agileboot.domain.system.user.db.SysUserEntity;
|
import com.agileboot.domain.system.user.db.SysUserEntity;
|
||||||
import com.agileboot.domain.system.user.db.SysUserMapper;
|
import com.agileboot.domain.system.user.db.SysUserMapper;
|
||||||
|
import com.agileboot.common.enums.common.StatusEnum;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -39,6 +40,14 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRoleEntity
|
|||||||
return this.baseMapper.exists(queryWrapper);
|
return this.baseMapper.exists(queryWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SysRoleEntity getEnabledRoleByKey(String roleKey) {
|
||||||
|
QueryWrapper<SysRoleEntity> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("role_key", roleKey)
|
||||||
|
.eq("status", StatusEnum.ENABLE.getValue());
|
||||||
|
return getOne(queryWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAssignedToUsers(Long roleId) {
|
public boolean isAssignedToUsers(Long roleId) {
|
||||||
QueryWrapper<SysUserEntity> queryWrapper = new QueryWrapper<>();
|
QueryWrapper<SysUserEntity> queryWrapper = new QueryWrapper<>();
|
||||||
|
|||||||
-2
@@ -45,6 +45,4 @@ public class RoleDTO {
|
|||||||
private Integer dataScope;
|
private Integer dataScope;
|
||||||
|
|
||||||
private List<Long> selectedMenuList;
|
private List<Long> selectedMenuList;
|
||||||
|
|
||||||
private List<Long> selectedDeptList;
|
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-17
@@ -1,10 +1,10 @@
|
|||||||
package com.agileboot.domain.system.role.model;
|
package com.agileboot.domain.system.role.model;
|
||||||
|
|
||||||
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import com.agileboot.common.exception.ApiException;
|
import com.agileboot.common.exception.ApiException;
|
||||||
import com.agileboot.common.exception.error.ErrorCode;
|
import com.agileboot.common.exception.error.ErrorCode;
|
||||||
import com.agileboot.common.exception.error.ErrorCode.Business;
|
import com.agileboot.common.exception.error.ErrorCode.Business;
|
||||||
|
import com.agileboot.infrastructure.user.web.DataScopeEnum;
|
||||||
import com.agileboot.domain.system.role.command.AddRoleCommand;
|
import com.agileboot.domain.system.role.command.AddRoleCommand;
|
||||||
import com.agileboot.domain.system.role.command.UpdateRoleCommand;
|
import com.agileboot.domain.system.role.command.UpdateRoleCommand;
|
||||||
import com.agileboot.common.enums.common.StatusEnum;
|
import com.agileboot.common.enums.common.StatusEnum;
|
||||||
@@ -14,7 +14,6 @@ import com.agileboot.domain.system.role.db.SysRoleMenuService;
|
|||||||
import com.agileboot.domain.system.role.db.SysRoleService;
|
import com.agileboot.domain.system.role.db.SysRoleService;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
@@ -30,8 +29,6 @@ public class RoleModel extends SysRoleEntity {
|
|||||||
|
|
||||||
private List<Long> menuIds;
|
private List<Long> menuIds;
|
||||||
|
|
||||||
private List<Long> deptIds;
|
|
||||||
|
|
||||||
private SysRoleService roleService;
|
private SysRoleService roleService;
|
||||||
private SysRoleMenuService roleMenuService;
|
private SysRoleMenuService roleMenuService;
|
||||||
|
|
||||||
@@ -51,6 +48,7 @@ public class RoleModel extends SysRoleEntity {
|
|||||||
public void loadAddCommand(AddRoleCommand command) {
|
public void loadAddCommand(AddRoleCommand command) {
|
||||||
if (command != null) {
|
if (command != null) {
|
||||||
BeanUtil.copyProperties(command, this, "roleId");
|
BeanUtil.copyProperties(command, this, "roleId");
|
||||||
|
fillDefaultDataScope();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,22 +82,12 @@ public class RoleModel extends SysRoleEntity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generateDeptIdSet() {
|
private void fillDefaultDataScope() {
|
||||||
if (deptIds == null) {
|
if (getDataScope() == null) {
|
||||||
setDeptIdSet("");
|
setDataScope(DataScopeEnum.ONLY_SELF.getValue());
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deptIds.size() > new HashSet<>(deptIds).size()) {
|
|
||||||
throw new ApiException(ErrorCode.Business.ROLE_DATA_SCOPE_DUPLICATED_DEPT);
|
|
||||||
}
|
|
||||||
|
|
||||||
String deptIdSet = StrUtil.join(",", deptIds);
|
|
||||||
setDeptIdSet(deptIdSet);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean insert() {
|
public boolean insert() {
|
||||||
super.insert();
|
super.insert();
|
||||||
|
|||||||
-6
@@ -1,7 +1,5 @@
|
|||||||
package com.agileboot.domain.system.role.model;
|
package com.agileboot.domain.system.role.model;
|
||||||
|
|
||||||
import cn.hutool.core.convert.Convert;
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import com.agileboot.common.exception.ApiException;
|
import com.agileboot.common.exception.ApiException;
|
||||||
import com.agileboot.common.exception.error.ErrorCode;
|
import com.agileboot.common.exception.error.ErrorCode;
|
||||||
import com.agileboot.domain.system.role.db.SysRoleEntity;
|
import com.agileboot.domain.system.role.db.SysRoleEntity;
|
||||||
@@ -36,13 +34,9 @@ public class RoleModelFactory {
|
|||||||
queryWrapper.eq(SysRoleMenuEntity::getRoleId, roleId);
|
queryWrapper.eq(SysRoleMenuEntity::getRoleId, roleId);
|
||||||
List<Long> menuIds = roleMenuService.list(queryWrapper).stream().map(SysRoleMenuEntity::getMenuId)
|
List<Long> menuIds = roleMenuService.list(queryWrapper).stream().map(SysRoleMenuEntity::getMenuId)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
List<Long> deptIds = StrUtil.split(byId.getDeptIdSet(), ",").stream()
|
|
||||||
.map(Convert::toLong).collect( Collectors.toList());
|
|
||||||
|
|
||||||
RoleModel roleModel = new RoleModel(byId, roleService, roleMenuService);
|
RoleModel roleModel = new RoleModel(byId, roleService, roleMenuService);
|
||||||
|
|
||||||
roleModel.setMenuIds(menuIds);
|
roleModel.setMenuIds(menuIds);
|
||||||
roleModel.setDeptIds(deptIds);
|
|
||||||
|
|
||||||
return roleModel;
|
return roleModel;
|
||||||
}
|
}
|
||||||
|
|||||||
+83
-10
@@ -1,14 +1,21 @@
|
|||||||
package com.agileboot.domain.system.user;
|
package com.agileboot.domain.system.user;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.core.convert.Convert;
|
import cn.hutool.core.convert.Convert;
|
||||||
import com.agileboot.common.core.page.PageDTO;
|
import com.agileboot.common.core.page.PageDTO;
|
||||||
|
import com.agileboot.common.enums.common.ConfigKeyEnum;
|
||||||
|
import com.agileboot.common.enums.common.GenderEnum;
|
||||||
|
import com.agileboot.common.enums.common.UserStatusEnum;
|
||||||
|
import com.agileboot.common.exception.ApiException;
|
||||||
|
import com.agileboot.common.exception.error.ErrorCode;
|
||||||
import com.agileboot.domain.common.cache.CacheCenter;
|
import com.agileboot.domain.common.cache.CacheCenter;
|
||||||
|
import com.agileboot.domain.common.cache.GuavaCacheService;
|
||||||
import com.agileboot.domain.common.command.BulkOperationCommand;
|
import com.agileboot.domain.common.command.BulkOperationCommand;
|
||||||
import com.agileboot.domain.common.dto.CurrentLoginUserDTO;
|
import com.agileboot.domain.common.dto.CurrentLoginUserDTO;
|
||||||
import com.agileboot.domain.system.post.dto.PostDTO;
|
|
||||||
import com.agileboot.domain.system.role.dto.RoleDTO;
|
import com.agileboot.domain.system.role.dto.RoleDTO;
|
||||||
import com.agileboot.domain.system.user.command.AddUserCommand;
|
import com.agileboot.domain.system.user.command.AddUserCommand;
|
||||||
import com.agileboot.domain.system.user.command.ChangeStatusCommand;
|
import com.agileboot.domain.system.user.command.ChangeStatusCommand;
|
||||||
|
import com.agileboot.domain.system.user.command.RegisterUserCommand;
|
||||||
import com.agileboot.domain.system.user.command.ResetPasswordCommand;
|
import com.agileboot.domain.system.user.command.ResetPasswordCommand;
|
||||||
import com.agileboot.domain.system.user.command.UpdateProfileCommand;
|
import com.agileboot.domain.system.user.command.UpdateProfileCommand;
|
||||||
import com.agileboot.domain.system.user.command.UpdateUserAvatarCommand;
|
import com.agileboot.domain.system.user.command.UpdateUserAvatarCommand;
|
||||||
@@ -22,12 +29,12 @@ import com.agileboot.domain.system.user.model.UserModel;
|
|||||||
import com.agileboot.domain.system.user.model.UserModelFactory;
|
import com.agileboot.domain.system.user.model.UserModelFactory;
|
||||||
import com.agileboot.domain.system.user.query.SearchUserQuery;
|
import com.agileboot.domain.system.user.query.SearchUserQuery;
|
||||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||||
import com.agileboot.domain.system.post.db.SysPostEntity;
|
|
||||||
import com.agileboot.domain.system.role.db.SysRoleEntity;
|
import com.agileboot.domain.system.role.db.SysRoleEntity;
|
||||||
import com.agileboot.domain.system.user.db.SysUserEntity;
|
import com.agileboot.domain.system.user.db.SysUserEntity;
|
||||||
import com.agileboot.domain.system.post.db.SysPostService;
|
|
||||||
import com.agileboot.domain.system.role.db.SysRoleService;
|
import com.agileboot.domain.system.role.db.SysRoleService;
|
||||||
import com.agileboot.domain.system.user.db.SysUserService;
|
import com.agileboot.domain.system.user.db.SysUserService;
|
||||||
|
import com.agileboot.infrastructure.user.AuthenticationUtils;
|
||||||
|
import com.agileboot.infrastructure.user.web.DataScopeEnum;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -42,16 +49,19 @@ import org.springframework.stereotype.Service;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class UserApplicationService {
|
public class UserApplicationService {
|
||||||
|
|
||||||
|
private static final String DEFAULT_REGISTER_ROLE_KEY = "common";
|
||||||
|
|
||||||
private final SysUserService userService;
|
private final SysUserService userService;
|
||||||
|
|
||||||
private final SysRoleService roleService;
|
private final SysRoleService roleService;
|
||||||
|
|
||||||
private final SysPostService postService;
|
|
||||||
|
|
||||||
private final UserModelFactory userModelFactory;
|
private final UserModelFactory userModelFactory;
|
||||||
|
|
||||||
|
private final GuavaCacheService guavaCacheService;
|
||||||
|
|
||||||
|
|
||||||
public PageDTO<UserDTO> getUserList(SearchUserQuery<SearchUserDO> query) {
|
public PageDTO<UserDTO> getUserList(SearchUserQuery<SearchUserDO> query) {
|
||||||
|
applyOnlySelfScope(query);
|
||||||
Page<SearchUserDO> userPage = userService.getUserList(query);
|
Page<SearchUserDO> userPage = userService.getUserList(query);
|
||||||
List<UserDTO> userDTOList = userPage.getRecords().stream().map(UserDTO::new).collect(Collectors.toList());
|
List<UserDTO> userDTOList = userPage.getRecords().stream().map(UserDTO::new).collect(Collectors.toList());
|
||||||
return new PageDTO<>(userDTOList, userPage.getTotal());
|
return new PageDTO<>(userDTOList, userPage.getTotal());
|
||||||
@@ -60,10 +70,9 @@ public class UserApplicationService {
|
|||||||
public UserProfileDTO getUserProfile(Long userId) {
|
public UserProfileDTO getUserProfile(Long userId) {
|
||||||
|
|
||||||
SysUserEntity userEntity = userService.getById(userId);
|
SysUserEntity userEntity = userService.getById(userId);
|
||||||
SysPostEntity postEntity = userService.getPostOfUser(userId);
|
|
||||||
SysRoleEntity roleEntity = userService.getRoleOfUser(userId);
|
SysRoleEntity roleEntity = userService.getRoleOfUser(userId);
|
||||||
|
|
||||||
return new UserProfileDTO(userEntity, postEntity, roleEntity);
|
return new UserProfileDTO(userEntity, roleEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -102,14 +111,11 @@ public class UserApplicationService {
|
|||||||
LambdaQueryWrapper<SysRoleEntity> roleQuery = new LambdaQueryWrapper<SysRoleEntity>()
|
LambdaQueryWrapper<SysRoleEntity> roleQuery = new LambdaQueryWrapper<SysRoleEntity>()
|
||||||
.orderByAsc(SysRoleEntity::getRoleSort);
|
.orderByAsc(SysRoleEntity::getRoleSort);
|
||||||
List<RoleDTO> roleDtoList = roleService.list(roleQuery).stream().map(RoleDTO::new).collect(Collectors.toList());
|
List<RoleDTO> roleDtoList = roleService.list(roleQuery).stream().map(RoleDTO::new).collect(Collectors.toList());
|
||||||
List<PostDTO> postDtoList = postService.list().stream().map(PostDTO::new).collect(Collectors.toList());
|
|
||||||
detailDTO.setRoleOptions(roleDtoList);
|
detailDTO.setRoleOptions(roleDtoList);
|
||||||
detailDTO.setPostOptions(postDtoList);
|
|
||||||
|
|
||||||
if (userEntity != null) {
|
if (userEntity != null) {
|
||||||
detailDTO.setUser(new UserDTO(userEntity));
|
detailDTO.setUser(new UserDTO(userEntity));
|
||||||
detailDTO.setRoleId(userEntity.getRoleId());
|
detailDTO.setRoleId(userEntity.getRoleId());
|
||||||
detailDTO.setPostId(userEntity.getPostId());
|
|
||||||
}
|
}
|
||||||
return detailDTO;
|
return detailDTO;
|
||||||
}
|
}
|
||||||
@@ -127,6 +133,20 @@ public class UserApplicationService {
|
|||||||
model.insert();
|
model.insert();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void registerUser(RegisterUserCommand command) {
|
||||||
|
checkRegisterIsOpen();
|
||||||
|
checkRegisterPassword(command);
|
||||||
|
|
||||||
|
UserModel model = userModelFactory.create();
|
||||||
|
loadRegisterCommand(model, command);
|
||||||
|
|
||||||
|
model.checkUsernameIsUnique();
|
||||||
|
model.checkPhoneNumberIsUnique();
|
||||||
|
model.checkEmailIsUnique();
|
||||||
|
model.resetPassword(command.getPassword());
|
||||||
|
model.insert();
|
||||||
|
}
|
||||||
|
|
||||||
public void updateUser(UpdateUserCommand command) {
|
public void updateUser(UpdateUserCommand command) {
|
||||||
UserModel model = userModelFactory.loadById(command.getUserId());
|
UserModel model = userModelFactory.loadById(command.getUserId());
|
||||||
model.loadUpdateUserCommand(command);
|
model.loadUpdateUserCommand(command);
|
||||||
@@ -182,5 +202,58 @@ public class UserApplicationService {
|
|||||||
CacheCenter.userCache.delete(userModel.getUserId());
|
CacheCenter.userCache.delete(userModel.getUserId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkRegisterIsOpen() {
|
||||||
|
Boolean isRegisterUserOn = Convert.toBool(guavaCacheService.configCache.get(ConfigKeyEnum.REGISTER.getValue()));
|
||||||
|
if (!Boolean.TRUE.equals(isRegisterUserOn)) {
|
||||||
|
throw new ApiException(ErrorCode.Business.USER_REGISTER_IS_CLOSED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkRegisterPassword(RegisterUserCommand command) {
|
||||||
|
if (!StrUtil.equals(command.getPassword(), command.getConfirmPassword())) {
|
||||||
|
throw new ApiException(ErrorCode.Business.USER_REGISTER_PASSWORD_NOT_MATCH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyOnlySelfScope(SearchUserQuery<SearchUserDO> query) {
|
||||||
|
SystemLoginUser loginUser = AuthenticationUtils.getSystemLoginUser();
|
||||||
|
if (loginUser == null || loginUser.getRoleInfo() == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DataScopeEnum.ONLY_SELF.equals(loginUser.getRoleInfo().getDataScope())) {
|
||||||
|
query.setUserId(loginUser.getUserId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadRegisterCommand(UserModel model, RegisterUserCommand command) {
|
||||||
|
SysRoleEntity role = getDefaultRegisterRole();
|
||||||
|
model.setUsername(command.getUsername());
|
||||||
|
model.setNickname(getRegisterNickname(command));
|
||||||
|
model.setEmail(command.getEmail());
|
||||||
|
model.setPhoneNumber(command.getPhoneNumber());
|
||||||
|
model.setRoleId(role.getRoleId());
|
||||||
|
model.setStatus(UserStatusEnum.NORMAL.getValue());
|
||||||
|
model.setUserType(0);
|
||||||
|
model.setSex(GenderEnum.UNKNOWN.getValue());
|
||||||
|
model.setIsAdmin(false);
|
||||||
|
model.setRemark("自助注册用户");
|
||||||
|
}
|
||||||
|
|
||||||
|
private SysRoleEntity getDefaultRegisterRole() {
|
||||||
|
SysRoleEntity role = roleService.getEnabledRoleByKey(DEFAULT_REGISTER_ROLE_KEY);
|
||||||
|
if (role == null) {
|
||||||
|
throw new ApiException(ErrorCode.Business.COMMON_OBJECT_NOT_FOUND, DEFAULT_REGISTER_ROLE_KEY, "普通角色");
|
||||||
|
}
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getRegisterNickname(RegisterUserCommand command) {
|
||||||
|
if (StrUtil.isNotBlank(command.getNickname())) {
|
||||||
|
return command.getNickname();
|
||||||
|
}
|
||||||
|
return command.getUsername();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
-6
@@ -9,9 +9,6 @@ import lombok.Data;
|
|||||||
@Data
|
@Data
|
||||||
public class AddUserCommand {
|
public class AddUserCommand {
|
||||||
|
|
||||||
@ExcelColumn(name = "部门ID")
|
|
||||||
private Long deptId;
|
|
||||||
|
|
||||||
@ExcelColumn(name = "用户名")
|
@ExcelColumn(name = "用户名")
|
||||||
private String username;
|
private String username;
|
||||||
|
|
||||||
@@ -39,9 +36,6 @@ public class AddUserCommand {
|
|||||||
@ExcelColumn(name = "角色ID")
|
@ExcelColumn(name = "角色ID")
|
||||||
private Long roleId;
|
private Long roleId;
|
||||||
|
|
||||||
@ExcelColumn(name = "职位ID")
|
|
||||||
private Long postId;
|
|
||||||
|
|
||||||
@ExcelColumn(name = "备注")
|
@ExcelColumn(name = "备注")
|
||||||
private String remark;
|
private String remark;
|
||||||
|
|
||||||
|
|||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
package com.agileboot.domain.system.user.command;
|
||||||
|
|
||||||
|
import javax.validation.constraints.Email;
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import javax.validation.constraints.Size;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自助注册用户请求。
|
||||||
|
*
|
||||||
|
* @author codex
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class RegisterUserCommand {
|
||||||
|
|
||||||
|
@NotBlank(message = "账号不能为空")
|
||||||
|
@Size(max = 64, message = "账号长度不能超过64个字符")
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
@Size(max = 32, message = "昵称长度不能超过32个字符")
|
||||||
|
private String nickname;
|
||||||
|
|
||||||
|
@Email(message = "邮箱格式不正确")
|
||||||
|
@Size(max = 128, message = "邮箱长度不能超过128个字符")
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
@Size(max = 18, message = "手机号长度不能超过18个字符")
|
||||||
|
private String phoneNumber;
|
||||||
|
|
||||||
|
@NotBlank(message = "密码不能为空")
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
@NotBlank(message = "确认密码不能为空")
|
||||||
|
private String confirmPassword;
|
||||||
|
|
||||||
|
private String captchaCode;
|
||||||
|
|
||||||
|
private String captchaCodeKey;
|
||||||
|
|
||||||
|
}
|
||||||
+4
-1
@@ -1,5 +1,6 @@
|
|||||||
package com.agileboot.domain.system.user.command;
|
package com.agileboot.domain.system.user.command;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -9,7 +10,9 @@ import lombok.Data;
|
|||||||
public class UpdateUserPasswordCommand {
|
public class UpdateUserPasswordCommand {
|
||||||
|
|
||||||
private Long userId;
|
private Long userId;
|
||||||
|
@NotBlank(message = "密码不能为空")
|
||||||
private String newPassword;
|
private String newPassword;
|
||||||
private String oldPassword;
|
@NotBlank(message = "确认密码不能为空")
|
||||||
|
private String confirmPassword;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-4
@@ -7,11 +7,8 @@ import lombok.EqualsAndHashCode;
|
|||||||
* 如果Entity的字段和复杂查询不匹配时 自定义类来接收
|
* 如果Entity的字段和复杂查询不匹配时 自定义类来接收
|
||||||
* @author valarchie
|
* @author valarchie
|
||||||
*/
|
*/
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@Data
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
public class SearchUserDO extends SysUserEntity {
|
public class SearchUserDO extends SysUserEntity {
|
||||||
|
|
||||||
private String deptName;
|
|
||||||
private String deptLeader;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
-8
@@ -32,18 +32,10 @@ public class SysUserEntity extends BaseEntity<SysUserEntity> {
|
|||||||
@TableId(value = "user_id", type = IdType.AUTO)
|
@TableId(value = "user_id", type = IdType.AUTO)
|
||||||
private Long userId;
|
private Long userId;
|
||||||
|
|
||||||
@ApiModelProperty("职位id")
|
|
||||||
@TableField("post_id")
|
|
||||||
private Long postId;
|
|
||||||
|
|
||||||
@ApiModelProperty("角色id")
|
@ApiModelProperty("角色id")
|
||||||
@TableField("role_id")
|
@TableField("role_id")
|
||||||
private Long roleId;
|
private Long roleId;
|
||||||
|
|
||||||
@ApiModelProperty("部门ID")
|
|
||||||
@TableField("dept_id")
|
|
||||||
private Long deptId;
|
|
||||||
|
|
||||||
@ApiModelProperty("用户账号")
|
@ApiModelProperty("用户账号")
|
||||||
@TableField("username")
|
@TableField("username")
|
||||||
private String username;
|
private String username;
|
||||||
|
|||||||
+2
-18
@@ -1,6 +1,5 @@
|
|||||||
package com.agileboot.domain.system.user.db;
|
package com.agileboot.domain.system.user.db;
|
||||||
|
|
||||||
import com.agileboot.domain.system.post.db.SysPostEntity;
|
|
||||||
import com.agileboot.domain.system.role.db.SysRoleEntity;
|
import com.agileboot.domain.system.role.db.SysRoleEntity;
|
||||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
@@ -35,19 +34,6 @@ public interface SysUserMapper extends BaseMapper<SysUserEntity> {
|
|||||||
+ " AND u.user_id = #{userId}")
|
+ " AND u.user_id = #{userId}")
|
||||||
List<SysRoleEntity> getRolesByUserId(Long userId);
|
List<SysRoleEntity> getRolesByUserId(Long userId);
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询用户所属岗位组
|
|
||||||
*
|
|
||||||
* @param userId 用户名
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
@Select("SELECT p.* "
|
|
||||||
+ "FROM sys_post p "
|
|
||||||
+ " LEFT JOIN sys_user u ON p.post_id = u.post_id "
|
|
||||||
+ "WHERE u.user_id = #{userId} "
|
|
||||||
+ " AND p.deleted = 0")
|
|
||||||
List<SysPostEntity> getPostsByUserId(Long userId);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据用户ID查询权限
|
* 根据用户ID查询权限
|
||||||
*
|
*
|
||||||
@@ -71,10 +57,9 @@ public interface SysUserMapper extends BaseMapper<SysUserEntity> {
|
|||||||
* @param queryWrapper 条件选择器
|
* @param queryWrapper 条件选择器
|
||||||
* @return 分页处理后的用户列表
|
* @return 分页处理后的用户列表
|
||||||
*/
|
*/
|
||||||
@Select("SELECT DISTINCT u.user_id, u.dept_id, u.username, u.nick_name, u.email "
|
@Select("SELECT DISTINCT u.user_id, u.username, u.nick_name, u.email "
|
||||||
+ " , u.phone_number, u.status, u.create_time "
|
+ " , u.phone_number, u.status, u.create_time "
|
||||||
+ "FROM sys_user u "
|
+ "FROM sys_user u "
|
||||||
+ " LEFT JOIN sys_dept d ON u.dept_id = d.dept_id "
|
|
||||||
+ " LEFT JOIN sys_role r ON r.role_id = u.role_id"
|
+ " LEFT JOIN sys_role r ON r.role_id = u.role_id"
|
||||||
+ " ${ew.customSqlSegment}")
|
+ " ${ew.customSqlSegment}")
|
||||||
Page<SysUserEntity> getUserListByRole(Page<SysUserEntity> page,
|
Page<SysUserEntity> getUserListByRole(Page<SysUserEntity> page,
|
||||||
@@ -86,9 +71,8 @@ public interface SysUserMapper extends BaseMapper<SysUserEntity> {
|
|||||||
* @param queryWrapper 查询对象
|
* @param queryWrapper 查询对象
|
||||||
* @return 用户信息集合信息
|
* @return 用户信息集合信息
|
||||||
*/
|
*/
|
||||||
@Select("SELECT u.*, d.dept_name, d.leader_name as dept_leader "
|
@Select("SELECT u.* "
|
||||||
+ "FROM sys_user u "
|
+ "FROM sys_user u "
|
||||||
+ " LEFT JOIN sys_dept d ON u.dept_id = d.dept_id "
|
|
||||||
+ "${ew.customSqlSegment}")
|
+ "${ew.customSqlSegment}")
|
||||||
Page<SearchUserDO> getUserList(Page<SearchUserDO> page,
|
Page<SearchUserDO> getUserList(Page<SearchUserDO> page,
|
||||||
@Param(Constants.WRAPPER) Wrapper<SearchUserDO> queryWrapper);
|
@Param(Constants.WRAPPER) Wrapper<SearchUserDO> queryWrapper);
|
||||||
|
|||||||
-8
@@ -1,7 +1,6 @@
|
|||||||
package com.agileboot.domain.system.user.db;
|
package com.agileboot.domain.system.user.db;
|
||||||
|
|
||||||
import com.agileboot.common.core.page.AbstractPageQuery;
|
import com.agileboot.common.core.page.AbstractPageQuery;
|
||||||
import com.agileboot.domain.system.post.db.SysPostEntity;
|
|
||||||
import com.agileboot.domain.system.role.db.SysRoleEntity;
|
import com.agileboot.domain.system.role.db.SysRoleEntity;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
@@ -49,13 +48,6 @@ public interface SysUserService extends IService<SysUserEntity> {
|
|||||||
*/
|
*/
|
||||||
SysRoleEntity getRoleOfUser(Long userId);
|
SysRoleEntity getRoleOfUser(Long userId);
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取用户的岗位
|
|
||||||
* @param userId 用户id
|
|
||||||
* @return 用户岗位
|
|
||||||
*/
|
|
||||||
SysPostEntity getPostOfUser(Long userId);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取用户的权限列表
|
* 获取用户的权限列表
|
||||||
* @param userId 用户id
|
* @param userId 用户id
|
||||||
|
|||||||
-8
@@ -1,7 +1,6 @@
|
|||||||
package com.agileboot.domain.system.user.db;
|
package com.agileboot.domain.system.user.db;
|
||||||
|
|
||||||
import com.agileboot.common.core.page.AbstractPageQuery;
|
import com.agileboot.common.core.page.AbstractPageQuery;
|
||||||
import com.agileboot.domain.system.post.db.SysPostEntity;
|
|
||||||
import com.agileboot.domain.system.role.db.SysRoleEntity;
|
import com.agileboot.domain.system.role.db.SysRoleEntity;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
@@ -55,13 +54,6 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUserEntity
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SysPostEntity getPostOfUser(Long userId) {
|
|
||||||
List<SysPostEntity> list = baseMapper.getPostsByUserId(userId);
|
|
||||||
return list.isEmpty() ? null : list.get(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<String> getMenuPermissionsForUser(Long userId) {
|
public Set<String> getMenuPermissionsForUser(Long userId) {
|
||||||
return baseMapper.getMenuPermsByUserId(userId);
|
return baseMapper.getMenuPermsByUserId(userId);
|
||||||
|
|||||||
+1
-25
@@ -4,11 +4,9 @@ import cn.hutool.core.bean.BeanUtil;
|
|||||||
import com.agileboot.common.annotation.ExcelColumn;
|
import com.agileboot.common.annotation.ExcelColumn;
|
||||||
import com.agileboot.common.annotation.ExcelSheet;
|
import com.agileboot.common.annotation.ExcelSheet;
|
||||||
import com.agileboot.domain.common.cache.CacheCenter;
|
import com.agileboot.domain.common.cache.CacheCenter;
|
||||||
import com.agileboot.domain.system.dept.db.SysDeptEntity;
|
|
||||||
import com.agileboot.domain.system.post.db.SysPostEntity;
|
|
||||||
import com.agileboot.domain.system.role.db.SysRoleEntity;
|
import com.agileboot.domain.system.role.db.SysRoleEntity;
|
||||||
import com.agileboot.domain.system.user.db.SysUserEntity;
|
|
||||||
import com.agileboot.domain.system.user.db.SearchUserDO;
|
import com.agileboot.domain.system.user.db.SearchUserDO;
|
||||||
|
import com.agileboot.domain.system.user.db.SysUserEntity;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@@ -23,11 +21,6 @@ public class UserDTO {
|
|||||||
if (entity != null) {
|
if (entity != null) {
|
||||||
BeanUtil.copyProperties(entity, this);
|
BeanUtil.copyProperties(entity, this);
|
||||||
|
|
||||||
SysDeptEntity dept = CacheCenter.deptCache.get(entity.getDeptId() + "");
|
|
||||||
if (dept != null) {
|
|
||||||
this.deptName = dept.getDeptName();
|
|
||||||
}
|
|
||||||
|
|
||||||
SysUserEntity creator = CacheCenter.userCache.getObjectById(entity.getCreatorId());
|
SysUserEntity creator = CacheCenter.userCache.getObjectById(entity.getCreatorId());
|
||||||
if (creator != null) {
|
if (creator != null) {
|
||||||
this.creatorName = creator.getUsername();
|
this.creatorName = creator.getUsername();
|
||||||
@@ -38,11 +31,6 @@ public class UserDTO {
|
|||||||
this.roleName = roleEntity != null ? roleEntity.getRoleName() : "";
|
this.roleName = roleEntity != null ? roleEntity.getRoleName() : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entity.getPostId() != null) {
|
|
||||||
SysPostEntity post = CacheCenter.postCache.getObjectById(entity.getRoleId());
|
|
||||||
this.postName = post != null ? post.getPostName() : "";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,24 +49,12 @@ public class UserDTO {
|
|||||||
@ExcelColumn(name = "用户ID")
|
@ExcelColumn(name = "用户ID")
|
||||||
private Long userId;
|
private Long userId;
|
||||||
|
|
||||||
@ExcelColumn(name = "职位ID")
|
|
||||||
private Long postId;
|
|
||||||
|
|
||||||
@ExcelColumn(name = "职位名称")
|
|
||||||
private String postName;
|
|
||||||
|
|
||||||
@ExcelColumn(name = "角色ID")
|
@ExcelColumn(name = "角色ID")
|
||||||
private Long roleId;
|
private Long roleId;
|
||||||
|
|
||||||
@ExcelColumn(name = "角色名称")
|
@ExcelColumn(name = "角色名称")
|
||||||
private String roleName;
|
private String roleName;
|
||||||
|
|
||||||
@ExcelColumn(name = "部门ID")
|
|
||||||
private Long deptId;
|
|
||||||
|
|
||||||
@ExcelColumn(name = "部门名称")
|
|
||||||
private String deptName;
|
|
||||||
|
|
||||||
@ExcelColumn(name = "用户名")
|
@ExcelColumn(name = "用户名")
|
||||||
private String username;
|
private String username;
|
||||||
|
|
||||||
|
|||||||
-8
@@ -1,6 +1,5 @@
|
|||||||
package com.agileboot.domain.system.user.dto;
|
package com.agileboot.domain.system.user.dto;
|
||||||
|
|
||||||
import com.agileboot.domain.system.post.dto.PostDTO;
|
|
||||||
import com.agileboot.domain.system.role.dto.RoleDTO;
|
import com.agileboot.domain.system.role.dto.RoleDTO;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -19,13 +18,6 @@ public class UserDetailDTO {
|
|||||||
*/
|
*/
|
||||||
private List<RoleDTO> roleOptions;
|
private List<RoleDTO> roleOptions;
|
||||||
|
|
||||||
/**
|
|
||||||
* 返回所有posts
|
|
||||||
*/
|
|
||||||
private List<PostDTO> postOptions;
|
|
||||||
|
|
||||||
private Long postId;
|
|
||||||
|
|
||||||
private Long roleId;
|
private Long roleId;
|
||||||
|
|
||||||
private Set<String> permissions;
|
private Set<String> permissions;
|
||||||
|
|||||||
+1
-7
@@ -1,6 +1,5 @@
|
|||||||
package com.agileboot.domain.system.user.dto;
|
package com.agileboot.domain.system.user.dto;
|
||||||
|
|
||||||
import com.agileboot.domain.system.post.db.SysPostEntity;
|
|
||||||
import com.agileboot.domain.system.role.db.SysRoleEntity;
|
import com.agileboot.domain.system.role.db.SysRoleEntity;
|
||||||
import com.agileboot.domain.system.user.db.SysUserEntity;
|
import com.agileboot.domain.system.user.db.SysUserEntity;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@@ -11,15 +10,11 @@ import lombok.Data;
|
|||||||
@Data
|
@Data
|
||||||
public class UserProfileDTO {
|
public class UserProfileDTO {
|
||||||
|
|
||||||
public UserProfileDTO(SysUserEntity userEntity, SysPostEntity postEntity, SysRoleEntity roleEntity) {
|
public UserProfileDTO(SysUserEntity userEntity, SysRoleEntity roleEntity) {
|
||||||
if (userEntity != null) {
|
if (userEntity != null) {
|
||||||
this.user = new UserDTO(userEntity);
|
this.user = new UserDTO(userEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (postEntity != null) {
|
|
||||||
this.postName = postEntity.getPostName();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (roleEntity != null) {
|
if (roleEntity != null) {
|
||||||
this.roleName = roleEntity.getRoleName();
|
this.roleName = roleEntity.getRoleName();
|
||||||
}
|
}
|
||||||
@@ -27,6 +22,5 @@ public class UserProfileDTO {
|
|||||||
|
|
||||||
private UserDTO user;
|
private UserDTO user;
|
||||||
private String roleName;
|
private String roleName;
|
||||||
private String postName;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-25
@@ -6,8 +6,6 @@ import com.agileboot.common.config.AgileBootConfig;
|
|||||||
import com.agileboot.common.exception.ApiException;
|
import com.agileboot.common.exception.ApiException;
|
||||||
import com.agileboot.common.exception.error.ErrorCode;
|
import com.agileboot.common.exception.error.ErrorCode;
|
||||||
import com.agileboot.common.exception.error.ErrorCode.Business;
|
import com.agileboot.common.exception.error.ErrorCode.Business;
|
||||||
import com.agileboot.domain.system.dept.model.DeptModelFactory;
|
|
||||||
import com.agileboot.domain.system.post.model.PostModelFactory;
|
|
||||||
import com.agileboot.domain.system.role.model.RoleModelFactory;
|
import com.agileboot.domain.system.role.model.RoleModelFactory;
|
||||||
import com.agileboot.domain.system.user.command.AddUserCommand;
|
import com.agileboot.domain.system.user.command.AddUserCommand;
|
||||||
import com.agileboot.domain.system.user.command.UpdateProfileCommand;
|
import com.agileboot.domain.system.user.command.UpdateProfileCommand;
|
||||||
@@ -32,26 +30,18 @@ public class UserModel extends SysUserEntity {
|
|||||||
|
|
||||||
private SysUserService userService;
|
private SysUserService userService;
|
||||||
|
|
||||||
private PostModelFactory postModelFactory;
|
|
||||||
|
|
||||||
private DeptModelFactory deptModelFactory;
|
|
||||||
|
|
||||||
private RoleModelFactory roleModelFactory;
|
private RoleModelFactory roleModelFactory;
|
||||||
|
|
||||||
public UserModel(SysUserEntity entity, SysUserService userService, PostModelFactory postModelFactory,
|
public UserModel(SysUserEntity entity, SysUserService userService, RoleModelFactory roleModelFactory) {
|
||||||
DeptModelFactory deptModelFactory, RoleModelFactory roleModelFactory) {
|
this(userService, roleModelFactory);
|
||||||
this(userService, postModelFactory, deptModelFactory, roleModelFactory);
|
|
||||||
|
|
||||||
if (entity != null) {
|
if (entity != null) {
|
||||||
BeanUtil.copyProperties(entity, this);
|
BeanUtil.copyProperties(entity, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public UserModel(SysUserService userService, PostModelFactory postModelFactory,
|
public UserModel(SysUserService userService, RoleModelFactory roleModelFactory) {
|
||||||
DeptModelFactory deptModelFactory, RoleModelFactory roleModelFactory) {
|
|
||||||
this.userService = userService;
|
this.userService = userService;
|
||||||
this.postModelFactory = postModelFactory;
|
|
||||||
this.deptModelFactory = deptModelFactory;
|
|
||||||
this.roleModelFactory = roleModelFactory;
|
this.roleModelFactory = roleModelFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,19 +82,9 @@ public class UserModel extends SysUserEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void checkFieldRelatedEntityExist() {
|
public void checkFieldRelatedEntityExist() {
|
||||||
|
|
||||||
if (getPostId() != null) {
|
|
||||||
postModelFactory.loadById(getPostId());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getDeptId() != null) {
|
|
||||||
deptModelFactory.loadById(getDeptId());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getRoleId() != null) {
|
if (getRoleId() != null) {
|
||||||
roleModelFactory.loadById(getRoleId());
|
roleModelFactory.loadById(getRoleId());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -123,8 +103,13 @@ public class UserModel extends SysUserEntity {
|
|||||||
|
|
||||||
|
|
||||||
public void modifyPassword(UpdateUserPasswordCommand command) {
|
public void modifyPassword(UpdateUserPasswordCommand command) {
|
||||||
if (!AuthenticationUtils.matchesPassword(command.getOldPassword(), getPassword())) {
|
if (command == null || StrUtil.isBlank(command.getNewPassword())
|
||||||
throw new ApiException(ErrorCode.Business.USER_PASSWORD_IS_NOT_CORRECT);
|
|| StrUtil.isBlank(command.getConfirmPassword())) {
|
||||||
|
throw new ApiException(ErrorCode.Business.USER_PASSWORD_IS_EMPTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!StrUtil.equals(command.getNewPassword(), command.getConfirmPassword())) {
|
||||||
|
throw new ApiException(ErrorCode.Business.USER_REGISTER_PASSWORD_NOT_MATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AuthenticationUtils.matchesPassword(command.getNewPassword(), getPassword())) {
|
if (AuthenticationUtils.matchesPassword(command.getNewPassword(), getPassword())) {
|
||||||
|
|||||||
+2
-8
@@ -2,8 +2,6 @@ package com.agileboot.domain.system.user.model;
|
|||||||
|
|
||||||
import com.agileboot.common.exception.ApiException;
|
import com.agileboot.common.exception.ApiException;
|
||||||
import com.agileboot.common.exception.error.ErrorCode;
|
import com.agileboot.common.exception.error.ErrorCode;
|
||||||
import com.agileboot.domain.system.dept.model.DeptModelFactory;
|
|
||||||
import com.agileboot.domain.system.post.model.PostModelFactory;
|
|
||||||
import com.agileboot.domain.system.role.model.RoleModelFactory;
|
import com.agileboot.domain.system.role.model.RoleModelFactory;
|
||||||
import com.agileboot.domain.system.user.db.SysUserEntity;
|
import com.agileboot.domain.system.user.db.SysUserEntity;
|
||||||
import com.agileboot.domain.system.user.db.SysUserService;
|
import com.agileboot.domain.system.user.db.SysUserService;
|
||||||
@@ -20,10 +18,6 @@ public class UserModelFactory {
|
|||||||
|
|
||||||
private final SysUserService userService;
|
private final SysUserService userService;
|
||||||
|
|
||||||
private final PostModelFactory postModelFactory;
|
|
||||||
|
|
||||||
private final DeptModelFactory deptModelFactory;
|
|
||||||
|
|
||||||
private final RoleModelFactory roleModelFactory;
|
private final RoleModelFactory roleModelFactory;
|
||||||
|
|
||||||
public UserModel loadById(Long userId) {
|
public UserModel loadById(Long userId) {
|
||||||
@@ -31,11 +25,11 @@ public class UserModelFactory {
|
|||||||
if (byId == null) {
|
if (byId == null) {
|
||||||
throw new ApiException(ErrorCode.Business.COMMON_OBJECT_NOT_FOUND, userId, "用户");
|
throw new ApiException(ErrorCode.Business.COMMON_OBJECT_NOT_FOUND, userId, "用户");
|
||||||
}
|
}
|
||||||
return new UserModel(byId, userService, postModelFactory, deptModelFactory, roleModelFactory);
|
return new UserModel(byId, userService, roleModelFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
public UserModel create() {
|
public UserModel create() {
|
||||||
return new UserModel(userService, postModelFactory, deptModelFactory, roleModelFactory);
|
return new UserModel(userService, roleModelFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-7
@@ -18,7 +18,6 @@ public class SearchUserQuery<T> extends AbstractPageQuery<T> {
|
|||||||
protected String username;
|
protected String username;
|
||||||
protected Integer status;
|
protected Integer status;
|
||||||
protected String phoneNumber;
|
protected String phoneNumber;
|
||||||
protected Long deptId;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public QueryWrapper<T> addQueryCondition() {
|
public QueryWrapper<T> addQueryCondition() {
|
||||||
@@ -28,12 +27,7 @@ public class SearchUserQuery<T> extends AbstractPageQuery<T> {
|
|||||||
.like(StrUtil.isNotEmpty(phoneNumber), "u.phone_number", phoneNumber)
|
.like(StrUtil.isNotEmpty(phoneNumber), "u.phone_number", phoneNumber)
|
||||||
.eq(userId != null, "u.user_id", userId)
|
.eq(userId != null, "u.user_id", userId)
|
||||||
.eq(status != null, "u.status", status)
|
.eq(status != null, "u.status", status)
|
||||||
.eq("u.deleted", 0)
|
.eq("u.deleted", 0);
|
||||||
.and(deptId != null, o ->
|
|
||||||
o.eq("u.dept_id", deptId)
|
|
||||||
.or()
|
|
||||||
.apply("u.dept_id IN ( SELECT t.dept_id FROM sys_dept t WHERE find_in_set(" + deptId
|
|
||||||
+ ", ancestors))"));
|
|
||||||
|
|
||||||
// 设置排序字段
|
// 设置排序字段
|
||||||
this.timeRangeColumn = "u.create_time";
|
this.timeRangeColumn = "u.create_time";
|
||||||
|
|||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
package com.agileboot.domain.collaboration.record.enumtype;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
class SettlementStatusEnumTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void aggregateShouldIgnoreNoneStatus() {
|
||||||
|
String status = SettlementStatusEnum.aggregate(Arrays.asList("NONE", "SETTLED"));
|
||||||
|
|
||||||
|
Assertions.assertEquals("SETTLED", status);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void aggregateShouldReturnPartialWhenStatusesAreMixed() {
|
||||||
|
String status = SettlementStatusEnum.aggregate(Arrays.asList("SETTLED", "UNSETTLED"));
|
||||||
|
|
||||||
|
Assertions.assertEquals("PARTIAL", status);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void aggregateShouldReturnNoneWhenNoEffectiveStatusExists() {
|
||||||
|
String status = SettlementStatusEnum.aggregate(Collections.singletonList("NONE"));
|
||||||
|
|
||||||
|
Assertions.assertEquals("NONE", status);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void aggregateShouldReturnNoneWhenStatusListIsEmpty() {
|
||||||
|
String status = SettlementStatusEnum.aggregate(Collections.emptyList());
|
||||||
|
|
||||||
|
Assertions.assertEquals("NONE", status);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
-157
@@ -1,157 +0,0 @@
|
|||||||
package com.agileboot.domain.system.dept.model;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
|
||||||
import static org.mockito.Mockito.eq;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import com.agileboot.common.exception.ApiException;
|
|
||||||
import com.agileboot.common.exception.error.ErrorCode.Business;
|
|
||||||
import com.agileboot.domain.system.dept.db.SysDeptEntity;
|
|
||||||
import com.agileboot.domain.system.dept.db.SysDeptService;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.mockito.ArgumentMatchers;
|
|
||||||
|
|
||||||
class DeptModelTest {
|
|
||||||
|
|
||||||
private static final Long DEPT_ID = 1L;
|
|
||||||
private static final Long PARENT_ID = 2L;
|
|
||||||
|
|
||||||
private final SysDeptService deptService = mock(SysDeptService.class);
|
|
||||||
|
|
||||||
private final DeptModelFactory deptModelFactory = new DeptModelFactory(deptService);
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testCheckDeptNameUnique() {
|
|
||||||
DeptModel deptModel = deptModelFactory.create();
|
|
||||||
deptModel.setDeptName("dept 1");
|
|
||||||
when(
|
|
||||||
deptService.isDeptNameDuplicated(ArgumentMatchers.any(), ArgumentMatchers.any(),
|
|
||||||
ArgumentMatchers.any())).thenReturn(true);
|
|
||||||
|
|
||||||
ApiException exception = assertThrows(ApiException.class, deptModel::checkDeptNameUnique);
|
|
||||||
Assertions.assertEquals(Business.DEPT_NAME_IS_NOT_UNIQUE, exception.getErrorCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testCheckParentIdConflict() {
|
|
||||||
DeptModel deptModel = deptModelFactory.create();
|
|
||||||
Long sameId = 1L;
|
|
||||||
deptModel.setDeptId(sameId);
|
|
||||||
deptModel.setParentId(sameId);
|
|
||||||
|
|
||||||
ApiException exception = assertThrows(ApiException.class, deptModel::checkParentIdConflict);
|
|
||||||
|
|
||||||
Assertions.assertEquals(Business.DEPT_PARENT_ID_IS_NOT_ALLOWED_SELF, exception.getErrorCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testCheckHasChildDept() {
|
|
||||||
DeptModel deptModel = deptModelFactory.create();
|
|
||||||
deptModel.setDeptId(DEPT_ID);
|
|
||||||
when(deptService.hasChildrenDept((DEPT_ID), eq(null))).thenReturn(true);
|
|
||||||
|
|
||||||
ApiException exception = assertThrows(ApiException.class, deptModel::checkHasChildDept);
|
|
||||||
|
|
||||||
Assertions.assertEquals(Business.DEPT_EXIST_CHILD_DEPT_NOT_ALLOW_DELETE, exception.getErrorCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testCheckDeptAssignedToUsers() {
|
|
||||||
DeptModel deptModel = deptModelFactory.create();
|
|
||||||
deptModel.setDeptId(DEPT_ID);
|
|
||||||
when(deptService.isDeptAssignedToUsers(DEPT_ID)).thenReturn(true);
|
|
||||||
|
|
||||||
ApiException exception = assertThrows(ApiException.class,
|
|
||||||
deptModel::checkDeptAssignedToUsers);
|
|
||||||
|
|
||||||
Assertions.assertEquals(Business.DEPT_EXIST_LINK_USER_NOT_ALLOW_DELETE, exception.getErrorCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testGenerateAncestorsWhenParentIdZero() {
|
|
||||||
DeptModel deptModel = deptModelFactory.create();
|
|
||||||
deptModel.setParentId(0L);
|
|
||||||
|
|
||||||
deptModel.generateAncestors();
|
|
||||||
|
|
||||||
Assertions.assertEquals(deptModel.getAncestors(), deptModel.getParentId().toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testGenerateAncestorsWhenParentDeptNotExist() {
|
|
||||||
DeptModel deptModel = deptModelFactory.create();
|
|
||||||
deptModel.setParentId(PARENT_ID);
|
|
||||||
when(deptService.getById(PARENT_ID)).thenReturn(null);
|
|
||||||
|
|
||||||
ApiException exception = assertThrows(ApiException.class, deptModel::generateAncestors);
|
|
||||||
|
|
||||||
Assertions.assertEquals(Business.DEPT_PARENT_DEPT_NO_EXIST_OR_DISABLED, exception.getErrorCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testGenerateAncestorsWhenParentDeptDisabled() {
|
|
||||||
DeptModel deptModel = deptModelFactory.create();
|
|
||||||
deptModel.setParentId(PARENT_ID);
|
|
||||||
SysDeptEntity parentDept = new SysDeptEntity();
|
|
||||||
parentDept.setStatus(0);
|
|
||||||
|
|
||||||
when(deptService.getById(PARENT_ID)).thenReturn(parentDept);
|
|
||||||
|
|
||||||
ApiException exception = assertThrows(ApiException.class, deptModel::generateAncestors);
|
|
||||||
Assertions.assertEquals(Business.DEPT_PARENT_DEPT_NO_EXIST_OR_DISABLED, exception.getErrorCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testGenerateAncestorsSuccessful() {
|
|
||||||
DeptModel deptModel = deptModelFactory.create();
|
|
||||||
deptModel.setParentId(PARENT_ID);
|
|
||||||
SysDeptEntity parentDept = new SysDeptEntity();
|
|
||||||
parentDept.setStatus(1);
|
|
||||||
parentDept.setAncestors("1,100");
|
|
||||||
when(deptService.getById(PARENT_ID)).thenReturn(parentDept);
|
|
||||||
deptModel.generateAncestors();
|
|
||||||
|
|
||||||
Assertions.assertEquals("1,100,2", deptModel.getAncestors());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testCheckStatusAllowChangeWhenDisableButHasChildDept() {
|
|
||||||
DeptModel deptModel = deptModelFactory.create();
|
|
||||||
deptModel.setDeptId(DEPT_ID);
|
|
||||||
deptModel.setStatus(0);
|
|
||||||
when(deptService.hasChildrenDept(DEPT_ID, true)).thenReturn(true);
|
|
||||||
|
|
||||||
ApiException exception = assertThrows(ApiException.class, deptModel::checkStatusAllowChange);
|
|
||||||
|
|
||||||
Assertions.assertEquals(Business.DEPT_STATUS_ID_IS_NOT_ALLOWED_CHANGE, exception.getErrorCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testCheckStatusAllowChangeWhenDisableButNoChildDept() {
|
|
||||||
DeptModel deptModel = deptModelFactory.create();
|
|
||||||
deptModel.setDeptId(DEPT_ID);
|
|
||||||
deptModel.setStatus(0);
|
|
||||||
when(deptService.hasChildrenDept(DEPT_ID, true)).thenReturn(false);
|
|
||||||
|
|
||||||
Assertions.assertDoesNotThrow(deptModel::checkStatusAllowChange);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testCheckStatusAllowChangeWhenEnableAndHasChildDept() {
|
|
||||||
DeptModel deptModel = deptModelFactory.create();
|
|
||||||
deptModel.setDeptId(DEPT_ID);
|
|
||||||
deptModel.setStatus(1);
|
|
||||||
when(deptService.hasChildrenDept(DEPT_ID, true)).thenReturn(true);
|
|
||||||
Assertions.assertDoesNotThrow(deptModel::checkStatusAllowChange);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-86
@@ -1,86 +0,0 @@
|
|||||||
package com.agileboot.domain.system.post.model;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import com.agileboot.common.exception.ApiException;
|
|
||||||
import com.agileboot.common.exception.error.ErrorCode.Business;
|
|
||||||
import com.agileboot.domain.system.post.db.SysPostService;
|
|
||||||
import org.junit.jupiter.api.AfterEach;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.mockito.Mockito;
|
|
||||||
|
|
||||||
class PostModelTest {
|
|
||||||
|
|
||||||
private final SysPostService postService = mock(SysPostService.class);
|
|
||||||
|
|
||||||
private final PostModelFactory postModelFactory = new PostModelFactory(postService);
|
|
||||||
|
|
||||||
private static final long POST_ID = 1L;
|
|
||||||
|
|
||||||
@AfterEach
|
|
||||||
public void clean() {
|
|
||||||
Mockito.reset(postService);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testCheckCanBeDeleteWhenFailed() {
|
|
||||||
PostModel postModel = postModelFactory.create();
|
|
||||||
postModel.setPostId(POST_ID);
|
|
||||||
|
|
||||||
when(postService.isAssignedToUsers(POST_ID)).thenReturn(true);
|
|
||||||
|
|
||||||
ApiException exception = assertThrows(ApiException.class, postModel::checkCanBeDelete);
|
|
||||||
Assertions.assertEquals(Business.POST_ALREADY_ASSIGNED_TO_USER_CAN_NOT_BE_DELETED, exception.getErrorCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testCheckCanBeDeleteWhenSuccessful() {
|
|
||||||
PostModel postModel = postModelFactory.create();
|
|
||||||
postModel.setPostId(POST_ID);
|
|
||||||
|
|
||||||
when(postService.isAssignedToUsers(POST_ID)).thenReturn(true);
|
|
||||||
|
|
||||||
ApiException exception = assertThrows(ApiException.class, postModel::checkCanBeDelete);
|
|
||||||
Assertions.assertEquals(Business.POST_ALREADY_ASSIGNED_TO_USER_CAN_NOT_BE_DELETED, exception.getErrorCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testCheckPostNameUnique() {
|
|
||||||
PostModel postWithSameName = postModelFactory.create();
|
|
||||||
postWithSameName.setPostId(POST_ID);
|
|
||||||
postWithSameName.setPostName("post 1");
|
|
||||||
PostModel postWithNewName = postModelFactory.create();
|
|
||||||
postWithNewName.setPostName("post 2");
|
|
||||||
postWithNewName.setPostId(POST_ID);
|
|
||||||
|
|
||||||
when(postService.isPostNameDuplicated(POST_ID, eq("post 1"))).thenReturn(true);
|
|
||||||
when(postService.isPostNameDuplicated(POST_ID, eq("post 2"))).thenReturn(false);
|
|
||||||
|
|
||||||
ApiException exception = assertThrows(ApiException.class, postWithSameName::checkPostNameUnique);
|
|
||||||
Assertions.assertEquals(Business.POST_NAME_IS_NOT_UNIQUE, exception.getErrorCode());
|
|
||||||
Assertions.assertDoesNotThrow(postWithNewName::checkPostNameUnique);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testCheckPostCodeUnique() {
|
|
||||||
PostModel postWithSameCode = postModelFactory.create();
|
|
||||||
postWithSameCode.setPostId(POST_ID);
|
|
||||||
postWithSameCode.setPostCode("code 1");
|
|
||||||
PostModel postWithNewCode = postModelFactory.create();
|
|
||||||
postWithNewCode.setPostId(POST_ID);
|
|
||||||
postWithNewCode.setPostCode("code 2");
|
|
||||||
|
|
||||||
when(postService.isPostCodeDuplicated(POST_ID, "code 1")).thenReturn(true);
|
|
||||||
when(postService.isPostCodeDuplicated(POST_ID, "code 2")).thenReturn(false);
|
|
||||||
|
|
||||||
ApiException exception = assertThrows(ApiException.class, postWithSameCode::checkPostCodeUnique);
|
|
||||||
Assertions.assertEquals(Business.POST_CODE_IS_NOT_UNIQUE, exception.getErrorCode());
|
|
||||||
Assertions.assertDoesNotThrow(postWithNewCode::checkPostCodeUnique);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user