Compare commits
10 Commits
1f2f11f80f
...
731d7420f1
| Author | SHA1 | Date | |
|---|---|---|---|
| 731d7420f1 | |||
| 3a6f764819 | |||
| 0989bb2209 | |||
| 3d77f7a3dc | |||
|
|
8a1cf9ed55 | ||
|
|
600e06904b | ||
|
|
6281609d9e | ||
|
|
2cf825dd3d | ||
|
|
245baa705b | ||
|
|
cfe076ebd0 |
4
.gitignore
vendored
4
.gitignore
vendored
@ -45,3 +45,7 @@ nbdist/
|
||||
!*/build/*.java
|
||||
!*/build/*.html
|
||||
!*/build/*.xml
|
||||
|
||||
# 项目运行时生成的目录
|
||||
uploads/
|
||||
logs/
|
||||
|
||||
150
CLAUDE.md
Normal file
150
CLAUDE.md
Normal file
@ -0,0 +1,150 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
RuoYi-Vue v3.9.1 is a rapid development platform with Spring Boot + Vue.js separated architecture. It provides a complete admin dashboard system with JWT authentication, role-based access control, code generation, and 18 built-in functional modules.
|
||||
|
||||
**Technology Stack:**
|
||||
- Backend: Spring Boot 2.5.15, Spring Security 5.7.14, MyBatis, Redis, JWT
|
||||
- Frontend: Vue 2.6.12, Element UI 2.15.14, Vuex 3.6.0, Vue Router 3.4.9
|
||||
- Database: MySQL with Druid connection pool
|
||||
- Build: Maven (backend), Vue CLI 4.4.6 (frontend)
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
RuoYi-Vue/
|
||||
├── pom.xml # Root Maven configuration
|
||||
├── ruoyi-admin/ # Web service entry point (Controllers, Config)
|
||||
├── ruoyi-framework/ # Core framework (Security, AOP, Interceptors)
|
||||
├── ruoyi-system/ # System business logic (Services, Mappers)
|
||||
├── ruoyi-common/ # Common utilities, constants, exceptions
|
||||
├── ruoyi-quartz/ # Scheduled tasks module
|
||||
├── ruoyi-generator/ # Code generation module
|
||||
└── ruoyi-ui/ # Frontend Vue.js application
|
||||
├── package.json
|
||||
├── vue.config.js # Webpack config with proxy to backend
|
||||
├── .env.development # Dev environment (VUE_APP_BASE_API=/dev-api)
|
||||
├── .env.production # Prod environment (VUE_APP_BASE_API=/prod-api)
|
||||
└── src/
|
||||
├── api/ # API service layer
|
||||
├── components/ # Reusable components
|
||||
├── directive/ # Custom directives (permission, etc.)
|
||||
├── layout/ # Layout components
|
||||
├── plugins/ # Plugins (cache, modal, download)
|
||||
├── router/ # Vue Router configuration
|
||||
├── store/ # Vuex store modules
|
||||
├── utils/ # Utility functions
|
||||
└── views/ # Page views (login, system, monitor, tool)
|
||||
```
|
||||
|
||||
## Development Commands
|
||||
|
||||
### Backend (Maven)
|
||||
|
||||
```bash
|
||||
# Package application (skips tests)
|
||||
mvn clean package -Dmaven.test.skip=true
|
||||
|
||||
# Run application from JAR
|
||||
cd ruoyi-admin/target
|
||||
java -jar ruoyi-admin.jar
|
||||
|
||||
# Or use provided scripts from project root
|
||||
./ry.sh start|stop|restart|status # Unix
|
||||
ry.bat # Windows
|
||||
```
|
||||
|
||||
### Frontend (npm)
|
||||
|
||||
```bash
|
||||
cd ruoyi-ui
|
||||
|
||||
# Install dependencies
|
||||
npm install
|
||||
|
||||
# Development server (runs on port 80, proxies /dev-api to localhost:8080)
|
||||
npm run dev
|
||||
|
||||
# Production build
|
||||
npm run build:prod
|
||||
|
||||
# Staging build
|
||||
npm run build:stage
|
||||
|
||||
# Preview production build
|
||||
npm run preview
|
||||
```
|
||||
|
||||
## Architecture Patterns
|
||||
|
||||
### Backend Architecture
|
||||
|
||||
**Module Dependencies:**
|
||||
- `ruoyi-admin` → `ruoyi-framework` → `ruoyi-system` → `ruoyi-common`
|
||||
- `ruoyi-generator` and `ruoyi-quartz` are independent modules
|
||||
|
||||
**Key Patterns:**
|
||||
1. **Layered Architecture:** Controller → Service → Mapper → Domain
|
||||
2. **Security:** JWT + Spring Security with role-based access control
|
||||
3. **Dynamic Datasource:** Primary/secondary database support via Druid
|
||||
4. **AOP:** Aspect-oriented logging (`@Log` annotation) and data scope filtering
|
||||
5. **Global Exception Handling:** `GlobalExceptionHandler` with `AjaxResult` wrapper
|
||||
6. **XSS Prevention:** Built-in XSS filtering via `XssFilter`
|
||||
7. **Repeat Submit Prevention:** `@RepeatSubmit` annotation with interceptor
|
||||
|
||||
**Key Files:**
|
||||
- `ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java` - Entry point
|
||||
- `ruoyi-admin/src/main/resources/application.yml` - Main configuration
|
||||
- `ruoyi-admin/src/main/resources/application-druid.yml` - Database configuration
|
||||
- `ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java` - Security config
|
||||
- `ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java` - Logging aspect
|
||||
|
||||
### Frontend Architecture
|
||||
|
||||
**Key Patterns:**
|
||||
1. **Route Guards:** `permission.js` handles JWT token validation and dynamic route generation
|
||||
2. **Axios Interceptors:** Request/response handling in `utils/request.js`
|
||||
3. **Global Methods:** Mounted on Vue prototype (e.g., `this.getDicts()`, `this.parseTime()`)
|
||||
4. **Global Components:** `DictTag`, `Pagination`, `RightToolbar`, `Editor`, `FileUpload`, `ImageUpload`
|
||||
5. **Store Modules:** `user`, `app`, `tagsView`, `permission`, `settings`
|
||||
6. **Directives:** `v-hasPermi`, `v-hasRole`, `v-debounce`, `v-copy`, `v-ellipsis`
|
||||
|
||||
**API Proxy Configuration:**
|
||||
- Development: `/dev-api` → `http://localhost:8080`
|
||||
- Production: `/prod-api` → configured via nginx or context
|
||||
|
||||
**Key Files:**
|
||||
- `ruoyi-ui/src/main.js` - Entry point with global registrations
|
||||
- `ruoyi-ui/src/permission.js` - Route permission control
|
||||
- `ruoyi-ui/src/utils/request.js` - Axios configuration
|
||||
- `ruoyi-ui/src/utils/ruoyi.js` - Common utility functions
|
||||
- `ruoyi-ui/src/store/modules/permission.js` - Dynamic route generation
|
||||
|
||||
## Code Generation
|
||||
|
||||
The code generator creates CRUD operations from database tables:
|
||||
|
||||
1. Access the generator UI at System → Code Generator
|
||||
2. Import a table from the database
|
||||
3. Configure field types, validation, and UI options
|
||||
4. Generate code (creates backend + frontend files)
|
||||
5. Copy generated files to appropriate directories
|
||||
|
||||
Templates are in `ruoyi-generator/src/main/resources/vm/`
|
||||
|
||||
## Database
|
||||
|
||||
- Main schema: `sql/ry_20250522.sql`
|
||||
- Quartz tables: `sql/quartz.sql`
|
||||
- Default login: admin/admin123
|
||||
|
||||
## Common Development Notes
|
||||
|
||||
- Backend runs on port 8080 by default
|
||||
- Frontend dev server runs on port 80 with proxy to backend
|
||||
- Swagger API docs available at `/swagger-ui/index.html` when enabled
|
||||
- Redis required for caching and session storage
|
||||
- File upload path configured in `application.yml` under `ruoyi.profile`
|
||||
22
README.md
22
README.md
@ -18,9 +18,8 @@
|
||||
* 权限认证使用Jwt,支持多终端认证系统。
|
||||
* 支持加载动态权限菜单,多方式轻松权限控制。
|
||||
* 高效率开发,使用代码生成器可以一键生成前后端代码。
|
||||
* 提供了技术栈([Vue3](https://v3.cn.vuejs.org) [Element Plus](https://element-plus.org/zh-CN) [Vite](https://cn.vitejs.dev))版本[RuoYi-Vue3](https://gitcode.com/yangzongzhuan/RuoYi-Vue3),保持同步更新。
|
||||
* 提供了单应用版本[RuoYi-Vue-fast](https://gitcode.com/yangzongzhuan/RuoYi-Vue-fast),Oracle版本[RuoYi-Vue-Oracle](https://gitcode.com/yangzongzhuan/RuoYi-Vue-Oracle),保持同步更新。
|
||||
* 不分离版本,请移步[RuoYi](https://gitee.com/y_project/RuoYi),微服务版本,请移步[RuoYi-Cloud](https://gitee.com/y_project/RuoYi-Cloud)
|
||||
* 提供了技术栈(Vue3 Element Plus Vite)的 [RuoYi-Vue3](https://gitcode.com/yangzongzhuan/RuoYi-Vue3)版本,以及技术栈(TypeScript)的 [RuoYi-Vue3-TypeScript](https://gitcode.com/yangzongzhuan/RuoYi-Vue3/tree/typescript)版本,两者保持同步更新。
|
||||
* 提供了适配 Spring Boot 3 的版本分支 [RuoYi-Vue (springboot3)](https://gitee.com/y_project/RuoYi-Vue/tree/springboot3),以及特定需求的 单应用版本 [RuoYi-Vue-fast](https://gitcode.com/yangzongzhuan/RuoYi-Vue-fast) 与 Oracle数据库版本 [RuoYi-Vue-Oracle](https://gitcode.com/yangzongzhuan/RuoYi-Vue-Oracle),均保持同步更新。
|
||||
* 阿里云折扣场:[点我进入](http://aly.ruoyi.vip),腾讯云秒杀场:[点我进入](http://txy.ruoyi.vip)
|
||||
|
||||
## 内置功能
|
||||
@ -44,6 +43,21 @@
|
||||
17. 在线构建器:拖动表单元素生成相应的HTML代码。
|
||||
18. 连接池监视:监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈。
|
||||
|
||||
# 版本对比
|
||||
|
||||
RuoYi-Vue 前端项目的三个主要演进版本,方便你直观对比其技术栈差异(并行开发维护)。
|
||||
|
||||
| 项目名称 | **RuoYi-Vue** | **RuoYi-Vue3** | **RuoYi-Vue3-TypeScript** |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| **前端框架** | Vue 2 | Vue 3 | Vue 3 |
|
||||
| **脚本语言** | JavaScript | JavaScript | TypeScript |
|
||||
| **构建工具** | Vue CLI | Vite | Vite |
|
||||
| **UI 组件库** | Element UI | Element Plus | Element Plus |
|
||||
| **状态管理** | Vuex | Pinia | Pinia |
|
||||
| **路由管理** | Vue Router 3 | Vue Router 4 | Vue Router 4 |
|
||||
| **核心特点** | 1. 技术栈经典稳定<br>2. 社区资料丰富<br>3. 当前维护重心已转移 | 1. 现代前端技术栈<br>2. 开发体验与性能更优<br>3. 官方主推的活跃版本 | 1. 类型加持,减少沟通成本<br>2. 开发时有提示,效率更高<br>3. 多人协作企业级开发项目 |
|
||||
| **仓库地址** | [RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue) | [RuoYi-Vue3](https://gitcode.com/yangzongzhuan/RuoYi-Vue3) | [RuoYi-Vue3-TypeScript](https://gitcode.com/yangzongzhuan/RuoYi-Vue3/tree/typescript) |
|
||||
|
||||
## 在线体验
|
||||
|
||||
- admin/admin123
|
||||
@ -92,4 +106,4 @@
|
||||
|
||||
## 若依前后端分离交流群
|
||||
|
||||
QQ群: [](https://jq.qq.com/?_wv=1027&k=5bVB1og) [](https://jq.qq.com/?_wv=1027&k=5eiA4DH) [](https://jq.qq.com/?_wv=1027&k=5AxMKlC) [](https://jq.qq.com/?_wv=1027&k=51G72yr) [](https://jq.qq.com/?_wv=1027&k=VvjN2nvu) [](https://jq.qq.com/?_wv=1027&k=5vYAqA05) [](https://jq.qq.com/?_wv=1027&k=kOIINEb5) [](https://jq.qq.com/?_wv=1027&k=UKtX5jhs) [](https://jq.qq.com/?_wv=1027&k=EI9an8lJ) [](https://jq.qq.com/?_wv=1027&k=SWCtLnMz) [](https://jq.qq.com/?_wv=1027&k=96Dkdq0k) [](https://jq.qq.com/?_wv=1027&k=0fsNiYZt) [](https://jq.qq.com/?_wv=1027&k=7xw4xUG1) [](https://jq.qq.com/?_wv=1027&k=eCx8eyoJ) [](https://jq.qq.com/?_wv=1027&k=SpyH2875) [](https://jq.qq.com/?_wv=1027&k=tKEt51dz) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=0vBbSb0ztbBgVtn3kJS-Q4HUNYwip89G&authKey=8irq5PhutrZmWIvsUsklBxhj57l%2F1nOZqjzigkXZVoZE451GG4JHPOqW7AW6cf0T&noverify=0&group_code=143961921) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=ZFAPAbp09S2ltvwrJzp7wGlbopsc0rwi&authKey=HB2cxpxP2yspk%2Bo3WKTBfktRCccVkU26cgi5B16u0KcAYrVu7sBaE7XSEqmMdFQp&noverify=0&group_code=174951577) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=Fn2aF5IHpwsy8j6VlalNJK6qbwFLFHat&authKey=uyIT%2B97x2AXj3odyXpsSpVaPMC%2Bidw0LxG5MAtEqlrcBcWJUA%2FeS43rsF1Tg7IRJ&noverify=0&group_code=161281055) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=XIzkm_mV2xTsUtFxo63bmicYoDBA6Ifm&authKey=dDW%2F4qsmw3x9govoZY9w%2FoWAoC4wbHqGal%2BbqLzoS6VBarU8EBptIgPKN%2FviyC8j&noverify=0&group_code=138988063) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=DkugnCg68PevlycJSKSwjhFqfIgrWWwR&authKey=pR1Pa5lPIeGF%2FFtIk6d%2FGB5qFi0EdvyErtpQXULzo03zbhopBHLWcuqdpwY241R%2F&noverify=0&group_code=151450850) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=F58bgRa-Dp-rsQJThiJqIYv8t4-lWfXh&authKey=UmUs4CVG5OPA1whvsa4uSespOvyd8%2FAr9olEGaWAfdLmfKQk%2FVBp2YU3u2xXXt76&noverify=0&group_code=224622315) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=Nxb2EQ5qozWa218Wbs7zgBnjLSNk_tVT&authKey=obBKXj6SBKgrFTJZx0AqQnIYbNOvBB2kmgwWvGhzxR67RoRr84%2Bus5OadzMcdJl5&noverify=0&group_code=287842588) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=numtK1M_I4eVd2Gvg8qtbuL8JgX42qNh&authKey=giV9XWMaFZTY%2FqPlmWbkB9g3fi0Ev5CwEtT9Tgei0oUlFFCQLDp4ozWRiVIzubIm&noverify=0&group_code=187944233) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=G6r5KGCaa3pqdbUSXNIgYloyb8e0_L0D&authKey=4w8tF1eGW7%2FedWn%2FHAypQksdrML%2BDHolQSx7094Agm7Luakj9EbfPnSTxSi2T1LQ&noverify=0&group_code=228578329) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=GsOo-OLz53J8y_9TPoO6XXSGNRTgbFxA&authKey=R7Uy%2Feq%2BZsoKNqHvRKhiXpypW7DAogoWapOawUGHokJSBIBIre2%2FoiAZeZBSLuBc&noverify=0&group_code=191164766) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=PmYavuzsOthVqfdAPbo4uAeIbu7Ttjgc&authKey=p52l8%2FXa4PS1JcEmS3VccKSwOPJUZ1ZfQ69MEKzbrooNUljRtlKjvsXf04bxNp3G&noverify=0&group_code=174569686) 点击按钮入群。
|
||||
QQ群: [](https://jq.qq.com/?_wv=1027&k=5bVB1og) [](https://jq.qq.com/?_wv=1027&k=5eiA4DH) [](https://jq.qq.com/?_wv=1027&k=5AxMKlC) [](https://jq.qq.com/?_wv=1027&k=51G72yr) [](https://jq.qq.com/?_wv=1027&k=VvjN2nvu) [](https://jq.qq.com/?_wv=1027&k=5vYAqA05) [](https://jq.qq.com/?_wv=1027&k=kOIINEb5) [](https://jq.qq.com/?_wv=1027&k=UKtX5jhs) [](https://jq.qq.com/?_wv=1027&k=EI9an8lJ) [](https://jq.qq.com/?_wv=1027&k=SWCtLnMz) [](https://jq.qq.com/?_wv=1027&k=96Dkdq0k) [](https://jq.qq.com/?_wv=1027&k=0fsNiYZt) [](https://jq.qq.com/?_wv=1027&k=7xw4xUG1) [](https://jq.qq.com/?_wv=1027&k=eCx8eyoJ) [](https://jq.qq.com/?_wv=1027&k=SpyH2875) [](https://jq.qq.com/?_wv=1027&k=tKEt51dz) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=0vBbSb0ztbBgVtn3kJS-Q4HUNYwip89G&authKey=8irq5PhutrZmWIvsUsklBxhj57l%2F1nOZqjzigkXZVoZE451GG4JHPOqW7AW6cf0T&noverify=0&group_code=143961921) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=ZFAPAbp09S2ltvwrJzp7wGlbopsc0rwi&authKey=HB2cxpxP2yspk%2Bo3WKTBfktRCccVkU26cgi5B16u0KcAYrVu7sBaE7XSEqmMdFQp&noverify=0&group_code=174951577) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=Fn2aF5IHpwsy8j6VlalNJK6qbwFLFHat&authKey=uyIT%2B97x2AXj3odyXpsSpVaPMC%2Bidw0LxG5MAtEqlrcBcWJUA%2FeS43rsF1Tg7IRJ&noverify=0&group_code=161281055) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=XIzkm_mV2xTsUtFxo63bmicYoDBA6Ifm&authKey=dDW%2F4qsmw3x9govoZY9w%2FoWAoC4wbHqGal%2BbqLzoS6VBarU8EBptIgPKN%2FviyC8j&noverify=0&group_code=138988063) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=DkugnCg68PevlycJSKSwjhFqfIgrWWwR&authKey=pR1Pa5lPIeGF%2FFtIk6d%2FGB5qFi0EdvyErtpQXULzo03zbhopBHLWcuqdpwY241R%2F&noverify=0&group_code=151450850) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=F58bgRa-Dp-rsQJThiJqIYv8t4-lWfXh&authKey=UmUs4CVG5OPA1whvsa4uSespOvyd8%2FAr9olEGaWAfdLmfKQk%2FVBp2YU3u2xXXt76&noverify=0&group_code=224622315) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=Nxb2EQ5qozWa218Wbs7zgBnjLSNk_tVT&authKey=obBKXj6SBKgrFTJZx0AqQnIYbNOvBB2kmgwWvGhzxR67RoRr84%2Bus5OadzMcdJl5&noverify=0&group_code=287842588) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=numtK1M_I4eVd2Gvg8qtbuL8JgX42qNh&authKey=giV9XWMaFZTY%2FqPlmWbkB9g3fi0Ev5CwEtT9Tgei0oUlFFCQLDp4ozWRiVIzubIm&noverify=0&group_code=187944233) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=G6r5KGCaa3pqdbUSXNIgYloyb8e0_L0D&authKey=4w8tF1eGW7%2FedWn%2FHAypQksdrML%2BDHolQSx7094Agm7Luakj9EbfPnSTxSi2T1LQ&noverify=0&group_code=228578329) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=GsOo-OLz53J8y_9TPoO6XXSGNRTgbFxA&authKey=R7Uy%2Feq%2BZsoKNqHvRKhiXpypW7DAogoWapOawUGHokJSBIBIre2%2FoiAZeZBSLuBc&noverify=0&group_code=191164766) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=PmYavuzsOthVqfdAPbo4uAeIbu7Ttjgc&authKey=p52l8%2FXa4PS1JcEmS3VccKSwOPJUZ1ZfQ69MEKzbrooNUljRtlKjvsXf04bxNp3G&noverify=0&group_code=174569686) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=M9y5NjAl44lAL_Vh2crmEehZU_PMU6KS&authKey=ZSDz8hEREWSaPuxQV3gEwqGIaGjfRNnkB4rJjf0IvXhrSUGSGwQFmBA%2Boe8HFxyl&noverify=0&group_code=127358632) 点击按钮入群。
|
||||
79
docker-compose.yml
Normal file
79
docker-compose.yml
Normal file
@ -0,0 +1,79 @@
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:8.0
|
||||
container_name: ruoyi-mysql
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "3306:3306"
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: password
|
||||
MYSQL_DATABASE: ry-vue
|
||||
volumes:
|
||||
- mysql_data:/var/lib/mysql
|
||||
- ./sql/ry_20250522.sql:/docker-entrypoint-initdb.d/01-ry_20250522.sql
|
||||
- ./sql/quartz.sql:/docker-entrypoint-initdb.d/02-quartz.sql
|
||||
command: >
|
||||
--default-authentication-plugin=mysql_native_password
|
||||
--character-set-server=utf8mb4
|
||||
--collation-server=utf8mb4_unicode_ci
|
||||
networks:
|
||||
- ruoyi-network
|
||||
healthcheck:
|
||||
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-ppassword"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 30s
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
container_name: ruoyi-redis
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "6379:6379"
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
networks:
|
||||
- ruoyi-network
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "ping"]
|
||||
interval: 10s
|
||||
timeout: 3s
|
||||
retries: 3
|
||||
|
||||
phpmyadmin:
|
||||
image: phpmyadmin:5
|
||||
container_name: ruoyi-phpmyadmin
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "8081:80"
|
||||
environment:
|
||||
PMA_HOST: mysql
|
||||
PMA_PORT: 3306
|
||||
MYSQL_ROOT_PASSWORD: password
|
||||
depends_on:
|
||||
- mysql
|
||||
networks:
|
||||
- ruoyi-network
|
||||
|
||||
redisinsight:
|
||||
image: redis/redisinsight:2.64
|
||||
container_name: ruoyi-redisinsight
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "8001:5540"
|
||||
volumes:
|
||||
- redisinsight_data:/data
|
||||
depends_on:
|
||||
- redis
|
||||
networks:
|
||||
- ruoyi-network
|
||||
|
||||
volumes:
|
||||
mysql_data:
|
||||
redis_data:
|
||||
redisinsight_data:
|
||||
|
||||
networks:
|
||||
ruoyi-network:
|
||||
driver: bridge
|
||||
@ -93,6 +93,10 @@ public class SysMenuController extends BaseController
|
||||
{
|
||||
return error("新增菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头");
|
||||
}
|
||||
else if (!menuService.checkRouteConfigUnique(menu))
|
||||
{
|
||||
return error("新增菜单'" + menu.getMenuName() + "'失败,路由名称或地址已存在");
|
||||
}
|
||||
menu.setCreateBy(getUsername());
|
||||
return toAjax(menuService.insertMenu(menu));
|
||||
}
|
||||
@ -117,6 +121,10 @@ public class SysMenuController extends BaseController
|
||||
{
|
||||
return error("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己");
|
||||
}
|
||||
else if (!menuService.checkRouteConfigUnique(menu))
|
||||
{
|
||||
return error("修改菜单'" + menu.getMenuName() + "'失败,路由名称或地址已存在");
|
||||
}
|
||||
menu.setUpdateBy(getUsername());
|
||||
return toAjax(menuService.updateMenu(menu));
|
||||
}
|
||||
|
||||
@ -6,8 +6,8 @@ ruoyi:
|
||||
version: 3.9.1
|
||||
# 版权年份
|
||||
copyrightYear: 2026
|
||||
# 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
|
||||
profile: D:/ruoyi/uploadPath
|
||||
# 文件路径(相对路径,基于项目根目录)
|
||||
profile: ./uploads
|
||||
# 获取ip地址开关
|
||||
addressEnabled: false
|
||||
# 验证码类型 math 数字计算 char 字符验证
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<!-- 日志存放路径 -->
|
||||
<property name="log.path" value="/home/ruoyi/logs" />
|
||||
<property name="log.path" value="./logs" />
|
||||
<!-- 日志输出格式 -->
|
||||
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
|
||||
|
||||
|
||||
@ -122,4 +122,13 @@ public interface SysMenuMapper
|
||||
* @return 结果
|
||||
*/
|
||||
public SysMenu checkMenuNameUnique(@Param("menuName") String menuName, @Param("parentId") Long parentId);
|
||||
|
||||
/**
|
||||
* 根据路由路径或名称查询菜单信息(用于唯一性校验)
|
||||
*
|
||||
* @param path 路由地址
|
||||
* @param routeName 路由名称
|
||||
* @return 匹配的菜单列表
|
||||
*/
|
||||
public List<SysMenu> selectMenusByPathOrRouteName(@Param("path") String path, @Param("routeName") String routeName);
|
||||
}
|
||||
|
||||
@ -141,4 +141,12 @@ public interface ISysMenuService
|
||||
* @return 结果
|
||||
*/
|
||||
public boolean checkMenuNameUnique(SysMenu menu);
|
||||
|
||||
/**
|
||||
* 校验路由组合是否唯一
|
||||
*
|
||||
* @param menu 菜单信息
|
||||
* @return 结果
|
||||
*/
|
||||
public boolean checkRouteConfigUnique(SysMenu menu);
|
||||
}
|
||||
|
||||
@ -8,6 +8,8 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.ruoyi.common.constant.Constants;
|
||||
@ -32,8 +34,12 @@ import com.ruoyi.system.service.ISysMenuService;
|
||||
@Service
|
||||
public class SysMenuServiceImpl implements ISysMenuService
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(SysMenuServiceImpl.class);
|
||||
|
||||
public static final String PREMISSION_STRING = "perms[\"{0}\"]";
|
||||
|
||||
public static final Long MENU_ROOT_ID = 0L;
|
||||
|
||||
@Autowired
|
||||
private SysMenuMapper menuMapper;
|
||||
|
||||
@ -138,7 +144,7 @@ public class SysMenuServiceImpl implements ISysMenuService
|
||||
{
|
||||
menus = menuMapper.selectMenuTreeByUserId(userId);
|
||||
}
|
||||
return getChildPerms(menus, 0);
|
||||
return getChildPerms(menus, MENU_ROOT_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -193,7 +199,7 @@ public class SysMenuServiceImpl implements ISysMenuService
|
||||
childrenList.add(children);
|
||||
router.setChildren(childrenList);
|
||||
}
|
||||
else if (menu.getParentId().intValue() == 0 && isInnerLink(menu))
|
||||
else if (menu.getParentId().intValue() == MENU_ROOT_ID && isInnerLink(menu))
|
||||
{
|
||||
router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon()));
|
||||
router.setPath("/");
|
||||
@ -345,6 +351,47 @@ public class SysMenuServiceImpl implements ISysMenuService
|
||||
return UserConstants.UNIQUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验路由名称是否唯一
|
||||
*
|
||||
* @param menu 菜单信息
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public boolean checkRouteConfigUnique(SysMenu menu)
|
||||
{
|
||||
Long menuId = StringUtils.isNull(menu.getMenuId()) ? -1L : menu.getMenuId();
|
||||
Long parentId = menu.getParentId();
|
||||
String path = menu.getPath();
|
||||
String routeName = StringUtils.isEmpty(menu.getRouteName()) ? path : menu.getRouteName();
|
||||
List<SysMenu> sysMenuList = menuMapper.selectMenusByPathOrRouteName(path, routeName);
|
||||
for (SysMenu sysMenu : sysMenuList)
|
||||
{
|
||||
if (sysMenu.getMenuId().longValue() != menuId.longValue())
|
||||
{
|
||||
Long dbParentId = sysMenu.getParentId();
|
||||
String dbPath = sysMenu.getPath();
|
||||
String dbRouteName = StringUtils.isEmpty(sysMenu.getRouteName()) ? dbPath : sysMenu.getRouteName();
|
||||
if (StringUtils.equalsAnyIgnoreCase(path, dbPath) && parentId.longValue() == dbParentId.longValue())
|
||||
{
|
||||
log.warn("[同级路由冲突] 同级下已存在相同路由路径 '{}',冲突菜单:{}", dbPath, sysMenu.getMenuName());
|
||||
return UserConstants.NOT_UNIQUE;
|
||||
}
|
||||
else if (StringUtils.equalsAnyIgnoreCase(path, dbPath) && parentId.longValue() == MENU_ROOT_ID)
|
||||
{
|
||||
log.warn("[根目录路由冲突] 根目录下路由 '{}' 必须唯一,已被菜单 '{}' 占用", path, sysMenu.getMenuName());
|
||||
return UserConstants.NOT_UNIQUE;
|
||||
}
|
||||
else if (StringUtils.equalsAnyIgnoreCase(routeName, dbRouteName))
|
||||
{
|
||||
log.warn("[路由名称冲突] 路由名称 '{}' 需全局唯一,已被菜单 '{}' 使用", routeName, sysMenu.getMenuName());
|
||||
return UserConstants.NOT_UNIQUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return UserConstants.UNIQUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取路由名称
|
||||
*
|
||||
@ -384,12 +431,12 @@ public class SysMenuServiceImpl implements ISysMenuService
|
||||
{
|
||||
String routerPath = menu.getPath();
|
||||
// 内链打开外网方式
|
||||
if (menu.getParentId().intValue() != 0 && isInnerLink(menu))
|
||||
if (menu.getParentId().intValue() != MENU_ROOT_ID && isInnerLink(menu))
|
||||
{
|
||||
routerPath = innerLinkReplaceEach(routerPath);
|
||||
}
|
||||
// 非外链并且是一级目录(类型为目录)
|
||||
if (0 == menu.getParentId().intValue() && UserConstants.TYPE_DIR.equals(menu.getMenuType())
|
||||
if (MENU_ROOT_ID == menu.getParentId().intValue() && UserConstants.TYPE_DIR.equals(menu.getMenuType())
|
||||
&& UserConstants.NO_FRAME.equals(menu.getIsFrame()))
|
||||
{
|
||||
routerPath = "/" + menu.getPath();
|
||||
@ -415,7 +462,7 @@ public class SysMenuServiceImpl implements ISysMenuService
|
||||
{
|
||||
component = menu.getComponent();
|
||||
}
|
||||
else if (StringUtils.isEmpty(menu.getComponent()) && menu.getParentId().intValue() != 0 && isInnerLink(menu))
|
||||
else if (StringUtils.isEmpty(menu.getComponent()) && menu.getParentId().intValue() != MENU_ROOT_ID && isInnerLink(menu))
|
||||
{
|
||||
component = UserConstants.INNER_LINK;
|
||||
}
|
||||
@ -434,10 +481,21 @@ public class SysMenuServiceImpl implements ISysMenuService
|
||||
*/
|
||||
public boolean isMenuFrame(SysMenu menu)
|
||||
{
|
||||
return menu.getParentId().intValue() == 0 && UserConstants.TYPE_MENU.equals(menu.getMenuType())
|
||||
return menu.getParentId().intValue() == MENU_ROOT_ID && UserConstants.TYPE_MENU.equals(menu.getMenuType())
|
||||
&& menu.getIsFrame().equals(UserConstants.NO_FRAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为parent_view组件
|
||||
*
|
||||
* @param menu 菜单信息
|
||||
* @return 结果
|
||||
*/
|
||||
public boolean isParentView(SysMenu menu)
|
||||
{
|
||||
return menu.getParentId().intValue() != MENU_ROOT_ID && UserConstants.TYPE_DIR.equals(menu.getMenuType());
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为内链组件
|
||||
*
|
||||
@ -449,17 +507,6 @@ public class SysMenuServiceImpl implements ISysMenuService
|
||||
return menu.getIsFrame().equals(UserConstants.NO_FRAME) && StringUtils.ishttp(menu.getPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为parent_view组件
|
||||
*
|
||||
* @param menu 菜单信息
|
||||
* @return 结果
|
||||
*/
|
||||
public boolean isParentView(SysMenu menu)
|
||||
{
|
||||
return menu.getParentId().intValue() != 0 && UserConstants.TYPE_DIR.equals(menu.getMenuType());
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据父节点的ID获取所有子节点
|
||||
*
|
||||
@ -467,7 +514,7 @@ public class SysMenuServiceImpl implements ISysMenuService
|
||||
* @param parentId 传入的父节点ID
|
||||
* @return String
|
||||
*/
|
||||
public List<SysMenu> getChildPerms(List<SysMenu> list, int parentId)
|
||||
public List<SysMenu> getChildPerms(List<SysMenu> list, long parentId)
|
||||
{
|
||||
List<SysMenu> returnList = new ArrayList<SysMenu>();
|
||||
for (Iterator<SysMenu> iterator = list.iterator(); iterator.hasNext();)
|
||||
|
||||
@ -133,6 +133,11 @@
|
||||
where menu_name= #{menuName} and parent_id = #{parentId} limit 1
|
||||
</select>
|
||||
|
||||
<select id="selectMenusByPathOrRouteName" parameterType="SysMenu" resultMap="SysMenuResult">
|
||||
<include refid="selectMenuVo"/>
|
||||
where menu_type in ('M', 'C') and (path = #{path} or path = #{routeName} or route_name = #{path} or route_name = #{routeName})
|
||||
</select>
|
||||
|
||||
<update id="updateMenu" parameterType="SysMenu">
|
||||
update sys_menu
|
||||
<set>
|
||||
|
||||
@ -68,5 +68,6 @@
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions"
|
||||
]
|
||||
],
|
||||
"packageManager": "pnpm@10.28.0+sha512.05df71d1421f21399e053fde567cea34d446fa02c76571441bfc1c7956e98e363088982d940465fd34480d4d90a0668bc12362f8aa88000a64e83d0b0e47be48"
|
||||
}
|
||||
|
||||
11342
ruoyi-ui/pnpm-lock.yaml
Normal file
11342
ruoyi-ui/pnpm-lock.yaml
Normal file
File diff suppressed because it is too large
Load Diff
5
ruoyi-ui/pnpm-workspace.yaml
Normal file
5
ruoyi-ui/pnpm-workspace.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
onlyBuiltDependencies:
|
||||
- core-js
|
||||
- ejs
|
||||
- fsevents
|
||||
- highlight.js
|
||||
@ -1,5 +1,5 @@
|
||||
import request from '@/utils/request'
|
||||
import { parseStrEmpty } from "@/utils/ruoyi";
|
||||
import { parseStrEmpty } from "@/utils/ruoyi"
|
||||
|
||||
// 查询用户列表
|
||||
export function listUser(query) {
|
||||
|
||||
@ -118,8 +118,6 @@ export default {
|
||||
this.fuse = new Fuse(list, {
|
||||
shouldSort: true,
|
||||
threshold: 0.4,
|
||||
location: 0,
|
||||
distance: 100,
|
||||
minMatchCharLength: 1,
|
||||
keys: [{
|
||||
name: 'title',
|
||||
|
||||
@ -26,6 +26,8 @@ service.interceptors.request.use(config => {
|
||||
const isToken = (config.headers || {}).isToken === false
|
||||
// 是否需要防止数据重复提交
|
||||
const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
|
||||
// 间隔时间(ms),小于此时间视为重复提交
|
||||
const interval = (config.headers || {}).interval || 1000
|
||||
if (getToken() && !isToken) {
|
||||
config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
|
||||
}
|
||||
@ -55,7 +57,6 @@ service.interceptors.request.use(config => {
|
||||
const s_url = sessionObj.url // 请求地址
|
||||
const s_data = sessionObj.data // 请求数据
|
||||
const s_time = sessionObj.time // 请求时间
|
||||
const interval = 1000 // 间隔时间(ms),小于此时间视为重复提交
|
||||
if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
|
||||
const message = '数据正在处理,请勿重复提交'
|
||||
console.warn(`[${s_url}]: ` + message)
|
||||
@ -115,7 +116,7 @@ service.interceptors.response.use(res => {
|
||||
} else if (message.includes("timeout")) {
|
||||
message = "系统接口请求超时"
|
||||
} else if (message.includes("Request failed with status code")) {
|
||||
message = "系统接口" + message.substr(message.length - 3) + "异常"
|
||||
message = "系统接口" + message.slice(-3) + "异常"
|
||||
}
|
||||
Message({ message: message, type: 'error', duration: 5 * 1000 })
|
||||
return Promise.reject(error)
|
||||
|
||||
@ -88,7 +88,7 @@
|
||||
<s> 满101046199 </s> <s> 满136919097 </s> <s> 满143961921 </s> <s> 满174951577 </s>
|
||||
<s> 满161281055 </s> <s> 满138988063 </s> <s> 满151450850 </s> <s> 满224622315 </s>
|
||||
<s> 满287842588 </s> <s> 满187944233 </s> <s> 满228578329 </s> <s> 满191164766 </s>
|
||||
<a href="http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=EeCBXu51I1zPWRia2uskpjDRx6VrbnFN&authKey=Xm8yDxk0%2FyYGI11oxhXaQnTn4K7UwCk7Kn2MZTh3P1JxLctollAkyeySjnaILDkb&noverify=0&group_code=174569686" target="_blank">174569686</a>
|
||||
<s> 满174569686 </s> <a href="http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=M9y5NjAl44lAL_Vh2crmEehZU_PMU6KS&authKey=ZSDz8hEREWSaPuxQV3gEwqGIaGjfRNnkB4rJjf0IvXhrSUGSGwQFmBA%2Boe8HFxyl&noverify=0&group_code=127358632" target="_blank">127358632</a>
|
||||
</p>
|
||||
<p>
|
||||
<i class="el-icon-chat-dot-round"></i> 微信:<a
|
||||
|
||||
@ -477,13 +477,13 @@ export default {
|
||||
this.$refs["form"].validate(valid => {
|
||||
if (valid) {
|
||||
if (this.form.jobId != undefined) {
|
||||
updateJob(this.form).then(response => {
|
||||
updateJob(this.form).then(() => {
|
||||
this.$modal.msgSuccess("修改成功")
|
||||
this.open = false
|
||||
this.getList()
|
||||
})
|
||||
} else {
|
||||
addJob(this.form).then(response => {
|
||||
addJob(this.form).then(() => {
|
||||
this.$modal.msgSuccess("新增成功")
|
||||
this.open = false
|
||||
this.getList()
|
||||
|
||||
@ -128,7 +128,7 @@ export default {
|
||||
this.$refs.registerForm.validate(valid => {
|
||||
if (valid) {
|
||||
this.loading = true
|
||||
register(this.registerForm).then(res => {
|
||||
register(this.registerForm).then(() => {
|
||||
const username = this.registerForm.username
|
||||
this.$alert("<font color='red'>恭喜你,您的账号 " + username + " 注册成功!</font>", '系统提示', {
|
||||
dangerouslyUseHTMLString: true,
|
||||
|
||||
@ -301,13 +301,13 @@ export default {
|
||||
this.$refs["form"].validate(valid => {
|
||||
if (valid) {
|
||||
if (this.form.configId != undefined) {
|
||||
updateConfig(this.form).then(response => {
|
||||
updateConfig(this.form).then(() => {
|
||||
this.$modal.msgSuccess("修改成功")
|
||||
this.open = false
|
||||
this.getList()
|
||||
})
|
||||
} else {
|
||||
addConfig(this.form).then(response => {
|
||||
addConfig(this.form).then(() => {
|
||||
this.$modal.msgSuccess("新增成功")
|
||||
this.open = false
|
||||
this.getList()
|
||||
|
||||
@ -311,13 +311,13 @@ export default {
|
||||
this.$refs["form"].validate(valid => {
|
||||
if (valid) {
|
||||
if (this.form.deptId != undefined) {
|
||||
updateDept(this.form).then(response => {
|
||||
updateDept(this.form).then(() => {
|
||||
this.$modal.msgSuccess("修改成功")
|
||||
this.open = false
|
||||
this.getList()
|
||||
})
|
||||
} else {
|
||||
addDept(this.form).then(response => {
|
||||
addDept(this.form).then(() => {
|
||||
this.$modal.msgSuccess("新增成功")
|
||||
this.open = false
|
||||
this.getList()
|
||||
|
||||
@ -363,14 +363,14 @@ export default {
|
||||
this.$refs["form"].validate(valid => {
|
||||
if (valid) {
|
||||
if (this.form.dictCode != undefined) {
|
||||
updateData(this.form).then(response => {
|
||||
updateData(this.form).then(() => {
|
||||
this.$store.dispatch('dict/removeDict', this.queryParams.dictType)
|
||||
this.$modal.msgSuccess("修改成功")
|
||||
this.open = false
|
||||
this.getList()
|
||||
})
|
||||
} else {
|
||||
addData(this.form).then(response => {
|
||||
addData(this.form).then(() => {
|
||||
this.$store.dispatch('dict/removeDict', this.queryParams.dictType)
|
||||
this.$modal.msgSuccess("新增成功")
|
||||
this.open = false
|
||||
|
||||
@ -304,13 +304,13 @@ export default {
|
||||
this.$refs["form"].validate(valid => {
|
||||
if (valid) {
|
||||
if (this.form.dictId != undefined) {
|
||||
updateType(this.form).then(response => {
|
||||
updateType(this.form).then(() => {
|
||||
this.$modal.msgSuccess("修改成功")
|
||||
this.open = false
|
||||
this.getList()
|
||||
})
|
||||
} else {
|
||||
addType(this.form).then(response => {
|
||||
addType(this.form).then(() => {
|
||||
this.$modal.msgSuccess("新增成功")
|
||||
this.open = false
|
||||
this.getList()
|
||||
|
||||
@ -448,13 +448,13 @@ export default {
|
||||
this.$refs["form"].validate(valid => {
|
||||
if (valid) {
|
||||
if (this.form.menuId != undefined) {
|
||||
updateMenu(this.form).then(response => {
|
||||
updateMenu(this.form).then(() => {
|
||||
this.$modal.msgSuccess("修改成功")
|
||||
this.open = false
|
||||
this.getList()
|
||||
})
|
||||
} else {
|
||||
addMenu(this.form).then(response => {
|
||||
addMenu(this.form).then(() => {
|
||||
this.$modal.msgSuccess("新增成功")
|
||||
this.open = false
|
||||
this.getList()
|
||||
|
||||
@ -282,13 +282,13 @@ export default {
|
||||
this.$refs["form"].validate(valid => {
|
||||
if (valid) {
|
||||
if (this.form.noticeId != undefined) {
|
||||
updateNotice(this.form).then(response => {
|
||||
updateNotice(this.form).then(() => {
|
||||
this.$modal.msgSuccess("修改成功")
|
||||
this.open = false
|
||||
this.getList()
|
||||
})
|
||||
} else {
|
||||
addNotice(this.form).then(response => {
|
||||
addNotice(this.form).then(() => {
|
||||
this.$modal.msgSuccess("新增成功")
|
||||
this.open = false
|
||||
this.getList()
|
||||
|
||||
@ -273,13 +273,13 @@ export default {
|
||||
this.$refs["form"].validate(valid => {
|
||||
if (valid) {
|
||||
if (this.form.postId != undefined) {
|
||||
updatePost(this.form).then(response => {
|
||||
updatePost(this.form).then(() => {
|
||||
this.$modal.msgSuccess("修改成功")
|
||||
this.open = false
|
||||
this.getList()
|
||||
})
|
||||
} else {
|
||||
addPost(this.form).then(response => {
|
||||
addPost(this.form).then(() => {
|
||||
this.$modal.msgSuccess("新增成功")
|
||||
this.open = false
|
||||
this.getList()
|
||||
|
||||
@ -184,7 +184,7 @@ export default {
|
||||
}).catch(() => {})
|
||||
},
|
||||
/** 批量取消授权按钮操作 */
|
||||
cancelAuthUserAll(row) {
|
||||
cancelAuthUserAll() {
|
||||
const roleId = this.queryParams.roleId
|
||||
const userIds = this.userIds.join(",")
|
||||
this.$modal.confirm('是否取消选中用户授权数据项?').then(function() {
|
||||
|
||||
@ -557,14 +557,14 @@ export default {
|
||||
if (valid) {
|
||||
if (this.form.roleId != undefined) {
|
||||
this.form.menuIds = this.getMenuAllCheckedKeys()
|
||||
updateRole(this.form).then(response => {
|
||||
updateRole(this.form).then(() => {
|
||||
this.$modal.msgSuccess("修改成功")
|
||||
this.open = false
|
||||
this.getList()
|
||||
})
|
||||
} else {
|
||||
this.form.menuIds = this.getMenuAllCheckedKeys()
|
||||
addRole(this.form).then(response => {
|
||||
addRole(this.form).then(() => {
|
||||
this.$modal.msgSuccess("新增成功")
|
||||
this.open = false
|
||||
this.getList()
|
||||
@ -577,7 +577,7 @@ export default {
|
||||
submitDataScope: function() {
|
||||
if (this.form.roleId != undefined) {
|
||||
this.form.deptIds = this.getDeptAllCheckedKeys()
|
||||
dataScope(this.form).then(response => {
|
||||
dataScope(this.form).then(() => {
|
||||
this.$modal.msgSuccess("修改成功")
|
||||
this.openDataScope = false
|
||||
this.getList()
|
||||
|
||||
@ -108,7 +108,7 @@ export default {
|
||||
submitForm() {
|
||||
const userId = this.form.userId
|
||||
const roleIds = this.roleIds.join(",")
|
||||
updateAuthRole({ userId: userId, roleIds: roleIds }).then((response) => {
|
||||
updateAuthRole({ userId: userId, roleIds: roleIds }).then(() => {
|
||||
this.$modal.msgSuccess("授权成功")
|
||||
this.close()
|
||||
})
|
||||
|
||||
@ -476,7 +476,7 @@ export default {
|
||||
}
|
||||
},
|
||||
}).then(({ value }) => {
|
||||
resetUserPwd(row.userId, value).then(response => {
|
||||
resetUserPwd(row.userId, value).then(() => {
|
||||
this.$modal.msgSuccess("修改成功,新密码是:" + value)
|
||||
})
|
||||
}).catch(() => {})
|
||||
@ -491,13 +491,13 @@ export default {
|
||||
this.$refs["form"].validate(valid => {
|
||||
if (valid) {
|
||||
if (this.form.userId != undefined) {
|
||||
updateUser(this.form).then(response => {
|
||||
updateUser(this.form).then(() => {
|
||||
this.$modal.msgSuccess("修改成功")
|
||||
this.open = false
|
||||
this.getList()
|
||||
})
|
||||
} else {
|
||||
addUser(this.form).then(response => {
|
||||
addUser(this.form).then(() => {
|
||||
this.$modal.msgSuccess("新增成功")
|
||||
this.open = false
|
||||
this.getList()
|
||||
|
||||
@ -55,7 +55,7 @@ export default {
|
||||
submit() {
|
||||
this.$refs["form"].validate(valid => {
|
||||
if (valid) {
|
||||
updateUserPwd(this.user.oldPassword, this.user.newPassword).then(response => {
|
||||
updateUserPwd(this.user.oldPassword, this.user.newPassword).then(() => {
|
||||
this.$modal.msgSuccess("修改成功")
|
||||
})
|
||||
}
|
||||
|
||||
@ -72,7 +72,7 @@ export default {
|
||||
submit() {
|
||||
this.$refs["form"].validate(valid => {
|
||||
if (valid) {
|
||||
updateUserProfile(this.form).then(response => {
|
||||
updateUserProfile(this.form).then(() => {
|
||||
this.$modal.msgSuccess("修改成功")
|
||||
this.user.phonenumber = this.form.phonenumber
|
||||
this.user.email = this.form.email
|
||||
|
||||
@ -98,9 +98,9 @@
|
||||
<span>{{(queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="表名称" align="center" prop="tableName" :show-overflow-tooltip="true" width="120" />
|
||||
<el-table-column label="表描述" align="center" prop="tableComment" :show-overflow-tooltip="true" width="120" />
|
||||
<el-table-column label="实体" align="center" prop="className" :show-overflow-tooltip="true" width="120" />
|
||||
<el-table-column label="表名称" align="center" prop="tableName" :show-overflow-tooltip="true" width="140" />
|
||||
<el-table-column label="表描述" align="center" prop="tableComment" :show-overflow-tooltip="true" width="140" />
|
||||
<el-table-column label="实体" align="center" prop="className" :show-overflow-tooltip="true" width="140" />
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" sortable="custom" :sort-orders="['descending', 'ascending']" width="160" />
|
||||
<el-table-column label="更新时间" align="center" prop="updateTime" sortable="custom" :sort-orders="['descending', 'ascending']" width="160" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
@ -262,7 +262,7 @@ export default {
|
||||
return
|
||||
}
|
||||
if(row.genType === "1") {
|
||||
genCode(row.tableName).then(response => {
|
||||
genCode(row.tableName).then(() => {
|
||||
this.$modal.msgSuccess("成功生成到自定义路径:" + row.genPath)
|
||||
})
|
||||
} else {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
SET NAMES 'utf8';
|
||||
DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
|
||||
DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
|
||||
DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
SET NAMES 'utf8';
|
||||
-- ----------------------------
|
||||
-- 1、部门表
|
||||
-- ----------------------------
|
||||
|
||||
Loading…
Reference in New Issue
Block a user