Compare commits
6 Commits
Author | SHA1 | Date |
---|---|---|
|
af2c9e82f1 | |
|
62a6ae474e | |
|
93dc470633 | |
|
3dbff6aa39 | |
|
213a66971d | |
|
d38475418b |
|
@ -0,0 +1,54 @@
|
|||
# 定义CI/CD流水线的阶段
|
||||
stages:
|
||||
- build # 第一阶段:构建应用程序
|
||||
- build-docker # 第二阶段:构建Docker镜像
|
||||
- deploy # 第三阶段:部署应用程序
|
||||
|
||||
cache: # 缓存内容
|
||||
paths:
|
||||
- node_modules/
|
||||
- docker/dist/
|
||||
|
||||
# 定义全局变量
|
||||
variables:
|
||||
CONTAINER_NAME: 'auth-web' # Docker容器名称
|
||||
DOCKER_TAG: '1.0.0' # Docker镜像标签版本
|
||||
|
||||
# 构建任务
|
||||
build-job:
|
||||
stage: build # 指定此任务属于build阶段
|
||||
script:
|
||||
# 打印编译开始信息
|
||||
- echo "Compiling the code..."
|
||||
# 使用Maven编译Java项目,跳过测试
|
||||
- npm i -g pnpm && pnpm i && pnpm build
|
||||
# 打印编译完成信息
|
||||
- echo "Compile complete."
|
||||
# 从Docker Hub拉取OpenJDK基础镜像
|
||||
- docker pull nginx:1.27.3
|
||||
# 打印拉取完成信息
|
||||
- echo "docker pull complete."
|
||||
# 使用Dockerfile构建Docker镜像,并打上标签
|
||||
- cd docker && docker build -f Dockerfile -t $CONTAINER_NAME:$DOCKER_TAG .
|
||||
# 打印构建成功信息
|
||||
- echo "Application successfully deployed."
|
||||
|
||||
# 部署任务
|
||||
deploy-job:
|
||||
stage: deploy # 指定此任务属于deploy阶段
|
||||
environment: production # 指定部署环境为production
|
||||
script:
|
||||
# 打印部署开始信息
|
||||
- echo "Deploying application..."
|
||||
# 停止正在运行的容器(如果存在),|| true确保命令失败不会中断脚本
|
||||
- docker stop $CONTAINER_NAME || true
|
||||
# 删除容器(如果存在)
|
||||
- docker rm $CONTAINER_NAME || true
|
||||
# 运行新的Docker容器
|
||||
# -d: 后台运行
|
||||
# -p: 端口映射(7070和8000)
|
||||
# --name: 容器名称
|
||||
# --restart always: 总是自动重启
|
||||
- docker run -d -p 8800:80 --name $CONTAINER_NAME --restart always $CONTAINER_NAME:$DOCKER_TAG
|
||||
# 打印部署成功信息
|
||||
- echo "Application successfully deployed."
|
|
@ -0,0 +1,283 @@
|
|||
# BunnyAuth Dynamic Permission Control Introduction
|
||||
|
||||
   <img alt="GitHub License" src="https://img.shields.io/github/license/BunnyMaster/bunny-admin-server">  
|
||||
|
||||
> [!IMPORTANT]
|
||||
>
|
||||
> Open-source permission template: [Pure-admin](https://pure-admin.github.io/vue-pure-admin/)
|
||||
>
|
||||
> **Pure-admin Documentation**: https://pure-admin.github.io/pure-admin-doc
|
||||
>
|
||||
> **Default Credentials**
|
||||
>
|
||||
> The project includes a default administrator with user `id` `1` in the database:
|
||||
>
|
||||
> Username: `Administrator`
|
||||
>
|
||||
> Password: `admin123`
|
||||
|
||||
> [!WARNING]
|
||||
>
|
||||
> If the password for the administrator [`Administrator`] is incorrect during initial login:
|
||||
>
|
||||
> Locate the `sys_user` table in the database and replace the password for `Administrator` with the following:
|
||||
>
|
||||
> `$2a$10$h5BUwmMaVcEuu7Bz0TPPy.PQV8JP6CFJlbHTgT78G1s0YPIu2kfXe`
|
||||
|
||||
Flexible permission control with multi-platform file upload support.
|
||||
|
||||
## 📽️ Video Tutorials
|
||||
|
||||
**Introduction Videos**
|
||||
|
||||
- [RBAC URL Permission Database and Backend Design](https://www.bilibili.com/video/BV1nGVazrEKf/)
|
||||
- [Bunny-Admin Configuration Guide](https://www.bilibili.com/video/BV177VazMEiM/)
|
||||
- [Bunny-Admin User Operations](https://www.bilibili.com/video/BV1B7VazME72/)
|
||||
- [Bunny-Admin Role Permissions](https://www.bilibili.com/video/BV1ELVazzEnC/)
|
||||
- [Bunny-Admin Remaining Business Logic](https://www.bilibili.com/video/BV1ELVazzE7S/)
|
||||
- [Code Generator](https://www.bilibili.com/video/BV1d4Lxz9E3j/?vd_source=d42b5b664efb958be39eef8ee1196a7e)
|
||||
|
||||
**GitHub Repositories**
|
||||
|
||||
- Permission Backend: https://github.com/BunnyMaster/bunny-admin-server
|
||||
- Permission Frontend: https://github.com/BunnyMaster/bunny-admin-web
|
||||
- Code Generator: https://github.com/BunnyMaster/generator-code-server
|
||||
|
||||
**Gitee Repositories**
|
||||
|
||||
- Permission Backend: https://gitee.com/BunnyBoss/bunny-admin-server
|
||||
- Permission Frontend: https://gitee.com/BunnyBoss/bunny-admin-web
|
||||
- Code Generator: https://gitee.com/BunnyBoss/generator-code-server
|
||||
|
||||
## 🚀 Project Overview
|
||||
|
||||
A modern dynamic permission control system based on Spring Security 6, providing a complete RBAC permission management solution. Supports frontend-backend separation architecture and flexible fine-grained permission control.
|
||||
|
||||
## 😋 Controller Annotation Guide
|
||||
|
||||
The project is URL-based for easy permission interface definition. Permissions can be added or deleted via URLs, even if the interface does not exist in the project.
|
||||
|
||||
For example, if a role needs access to all interfaces under `dept`, the URL can be written as `api/dept/**`. For specific interfaces like `/api/dept/aaa/bbb`, the URL can be customized accordingly.
|
||||
|
||||
For paginated queries with URL parameters, use `/api/dept/*/*` for flexible permission control.
|
||||
|
||||
In scenarios where interfaces directly represent permissions, manually adding each URL is tedious. Instead, Swagger annotations and the custom `PermissionTag` annotation can be used. Reflection-based permission addition is also supported. Refer to the `ReadMe` in the controller directory for details.
|
||||
|
||||
## ✨ Major Updates
|
||||
|
||||
### Core Improvements
|
||||
|
||||
**v4.0.0**
|
||||
|
||||
- **Complete Refactoring**: Backend interfaces, entity classes, and frontend optimizations.
|
||||
- **Batch Operations Support**:
|
||||
- ✅ Menu Management: Enhanced attribute content.
|
||||
- ✅ Permission Management: JSON/Excel import/export.
|
||||
- ✅ Role Management: Excel batch updates.
|
||||
- ✅ Multi-language Configuration: JSON/Excel updates (full replacement mode).
|
||||
|
||||
**v4.0.1**
|
||||
|
||||
- File system supports multiple platforms with manual configuration.
|
||||
- Reference documentation: https://x-file-storage.xuyanwu.cn/#/
|
||||
- File deletion and download require implementing the `FileRecorder` interface. The code and controllers are in the `file` directory. Modify as needed based on the [x-file-storage] documentation.
|
||||
|
||||
## 🧠 Usage Tips
|
||||
|
||||
> [!TIP]
|
||||
>
|
||||
> Multi-language Usage Tips:
|
||||
>
|
||||
> While direct JSON file manipulation may be challenging for some users, JSON offers unique advantages in multi-language projects:
|
||||
>
|
||||
> 1. Structured format for easy AI parsing.
|
||||
> 2. Efficient translation workflow:
|
||||
> - Developers only need to complete the Chinese version.
|
||||
> - Upload JSON to AI translation tools.
|
||||
> - Simple commands generate English/Traditional Chinese/Korean versions.
|
||||
> 3. Saves significant development time with a "write once, adapt for multiple languages" approach.
|
||||
|
||||
## 🔐 Permission Control System
|
||||
|
||||

|
||||
|
||||
### Access Rules Configuration
|
||||
|
||||
Configured via `WebSecurityConfig`:
|
||||
|
||||
| Path Type | Example | Access Requirement | Configuration Method |
|
||||
| ----------------- | ----------------- | ------------------ | ------------------------------- |
|
||||
| Public Interface | `/api/public/**` | No authentication | Path contains `public` keyword |
|
||||
| Private Interface | `/api/private/**` | Requires login | Path contains `private` keyword |
|
||||
|
||||
### Path Matching Strategy
|
||||
|
||||
```java
|
||||
public static String[] annotations = { ... };
|
||||
|
||||
// Configuration Example
|
||||
http.authorizeHttpRequests(auth -> auth
|
||||
.authorizeHttpRequests(authorize -> authorize
|
||||
.requestMatchers(annotations).permitAll()
|
||||
);
|
||||
```
|
||||
|
||||
### Maven Project Structure
|
||||
|
||||
```
|
||||
bunny-auth/
|
||||
├── auth-system # System Module
|
||||
├── core-common # Core and base...
|
||||
│ ├── context # Context
|
||||
│ └── exception # Exception
|
||||
│ └── ...... # And more...
|
||||
├── domain # Domain
|
||||
└─services # Service and Mapper
|
||||
```
|
||||
|
||||
## 🛠️ Use Cases
|
||||
|
||||
### 1. Frontend-Only Control Mode
|
||||
|
||||
Frontend details: https://pure-admin.cn/pages/RBAC/#%E5%A6%82%E4%BD%95%E9%85%8D%E7%BD%AE
|
||||
|
||||

|
||||
|
||||
- **Page Control**:
|
||||
1. Assign roles to route menus.
|
||||
2. Assign roles to users.
|
||||
- **Button Control**:
|
||||
```ts
|
||||
// Frontend Permission Codes
|
||||
const auth = {
|
||||
add: ['i18nType::add'],
|
||||
update: ['i18nType::update'],
|
||||
delete: ['i18nType::delete'],
|
||||
};
|
||||
```
|
||||
|
||||
### 2. Backend-Only Control Mode
|
||||
|
||||
- Interface-level permissions: For pagination, use `/api/permission/*/*`.
|
||||
|
||||
```java
|
||||
@Tag(name = "System Permissions")
|
||||
@PermissionTag(permission = "permission::*")
|
||||
@RestController
|
||||
@RequestMapping("api/permission")
|
||||
public class PermissionController {
|
||||
@Operation(summary = "Pagination Query")
|
||||
@PermissionTag(permission = "permission::query")
|
||||
@GetMapping("{page}/{limit}")
|
||||
public Result<PageResult<PermissionVo>> getPermissionPage(
|
||||
@PathVariable Integer page,
|
||||
@PathVariable Integer limit) {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Full-Stack Control Mode
|
||||
|
||||
Combine the above two approaches.
|
||||
|
||||
## 🛡️ Security Configuration
|
||||
|
||||
### Path Matching Strategy
|
||||
|
||||
AntPath details: https://juejin.cn/spost/7498247273660743732
|
||||
|
||||
| Pattern | Example | Description |
|
||||
| --------------- | --------------- | ----------------------- |
|
||||
| Exact Match | `/api/user` | Matches exact path |
|
||||
| Single Wildcard | `/api/user/*` | Matches single level |
|
||||
| Multi Wildcard | `/api/user/**` | Matches multiple levels |
|
||||
| Method Specific | `GET /api/user` | Matches HTTP method |
|
||||
|
||||
## 🧰 Technology Stack
|
||||
|
||||
### 😄 Frontend
|
||||
|
||||
- Vue 3 + PureAdmin Template
|
||||
- Custom Permission Components
|
||||
- Internationalization Support
|
||||
|
||||
### 😃 Backend
|
||||
|
||||
- Spring Boot 3 + Spring Security 6
|
||||
- JDK 17
|
||||
- MySQL + Redis + MinIO
|
||||
- Swagger + Knife4j Documentation
|
||||
|
||||
### 😀 Development Environment
|
||||
|
||||
Docker startup varies by version:
|
||||
|
||||
```bash
|
||||
# Start dependency services with one command
|
||||
docker-compose up -d
|
||||
# For newer Docker versions
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
## 📚 Best Practices
|
||||
|
||||
1. **Annotation Standards**:
|
||||
```java
|
||||
@Tag(name = "Module Name", description = "Module Description")
|
||||
@Operation(summary = "Interface Summary", tags = {"Permission Code"})
|
||||
// Or
|
||||
@Operation(summary = "Interface Summary", tags = "Permission Code")
|
||||
```
|
||||
2. **Permission Code Design**:
|
||||
- Module::Operation (e.g., `user::create`).
|
||||
- Hierarchical design (e.g., `system:user:update`).
|
||||
3. **Batch Operations**:
|
||||
- Manage permissions via Excel/JSON.
|
||||
- Regularly backup permission configurations.
|
||||
|
||||
## 🌟 Project Advantages
|
||||
|
||||
1. **True Dynamic Control** – No hardcoded permission logic.
|
||||
2. **Flexible Data Import** – Supports multiple file formats.
|
||||
3. **Fine-Grained Control** – Multi-level permissions from pages to buttons.
|
||||
4. **Modern Tech Stack** – Based on the latest Spring ecosystem.
|
||||
5. **Out-of-the-Box** – Complete Docker deployment solution.
|
||||
|
||||
## 📌 Notes
|
||||
|
||||
1. Multi-language updates fully replace existing configurations.
|
||||
2. Disable Swagger endpoints in production.
|
||||
3. Use Excel for complex permission management.
|
||||
|
||||
## 📈 Future Plans
|
||||
|
||||
None at the moment.
|
||||
|
||||
## 📏 Frontend-Backend Interface Standards
|
||||
|
||||
### 🌐 Frontend Example Standards
|
||||
|
||||
| **Action** | **API Layer** | **Pinia Layer** |
|
||||
| :----------- | :------------ | :-------------- |
|
||||
| Query Single | `getUser` | `loadUser` |
|
||||
| Query List | `getUserList` | `loadUserList` |
|
||||
| Pagination | `getUserPage` | `fetchUserPage` |
|
||||
| Add Data | `createUser` | `addUser` |
|
||||
| Update Data | `updateUser` | `editUser` |
|
||||
| Delete Data | `deleteUser` | `removeUser` |
|
||||
|
||||
### 🛟 Backend Interface Example Standards
|
||||
|
||||
Follows RESTful standards.
|
||||
|
||||
| **Action** | **RESTful** |
|
||||
| :----------- | :-------------------------- |
|
||||
| Query List | `GET /users` |
|
||||
| Pagination | `GET /users/{page}/{limit}` |
|
||||
| Query Single | `GET /users/{id}` |
|
||||
| Add | `POST /users` |
|
||||
| Update | `PUT /users/{id}` |
|
||||
| Delete | `DELETE /users/{id}` |
|
||||
|
||||

|
15
ReadMe.md
15
ReadMe.md
|
@ -1,5 +1,8 @@
|
|||
# BunnyAuth动态权限控制简介
|
||||
|
||||
|
||||
<img alt="GitHub License" src="https://img.shields.io/github/license/BunnyMaster/bunny-admin-server">
|
||||
|
||||
> [!IMPORTANT]
|
||||
>
|
||||
> 开源权限模板[Pure-admin](https://pure-admin.github.io/vue-pure-admin/)
|
||||
|
@ -126,13 +129,13 @@ http.authorizeHttpRequests(auth -> auth
|
|||
|
||||
```
|
||||
bunny-auth/
|
||||
├── auth-api # 接口定义层
|
||||
├── auth-core # 核心模块
|
||||
│ ├── config # 安全配置
|
||||
│ └── domain # domain
|
||||
├── auth-system # 系统模块
|
||||
├── core-common # 配置和基础模块
|
||||
│ ├── exception # exception
|
||||
│ └── context # context
|
||||
│ └── ...... # 还要很多...
|
||||
├── service # 业务实现
|
||||
└── dao # 数据持久层
|
||||
├── domain # domain
|
||||
└─services # 服务和mapper
|
||||
```
|
||||
|
||||
## 🛠️ 应用场景
|
||||
|
|
|
@ -23,14 +23,6 @@ server {
|
|||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
# 后端跨域请求
|
||||
location ~/peiqi/ {
|
||||
proxy_pass http://172.17.0.1:8000;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
error_page 404 404.html;
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import type { BaseResult } from '@/api/service/types';
|
|||
|
||||
/** 读取web配置文件并返回给前端 */
|
||||
export const getWebConfig = () => {
|
||||
return http.request<any>('get', '/config/public/webConfig');
|
||||
return http.request<any>('get', '/config/public/web-config');
|
||||
};
|
||||
|
||||
/** 更新web配置文件 */
|
||||
|
|
|
@ -3,27 +3,27 @@ import type { BaseResult, ResultTable } from '@/api/service/types';
|
|||
|
||||
/** 邮件模板表---分页查询邮件模板 */
|
||||
export const getEmailTemplatePage = (data: any) => {
|
||||
return http.request<BaseResult<ResultTable>>('get', `emailTemplate/${data.currentPage}/${data.pageSize}`, {
|
||||
return http.request<BaseResult<ResultTable>>('get', `email-template/${data.currentPage}/${data.pageSize}`, {
|
||||
params: data,
|
||||
});
|
||||
};
|
||||
|
||||
/** 邮件模板表---添加邮件模板 */
|
||||
export const createEmailTemplate = (data: any) => {
|
||||
return http.request<BaseResult<object>>('post', 'emailTemplate', { data });
|
||||
return http.request<BaseResult<object>>('post', 'email-template', { data });
|
||||
};
|
||||
|
||||
/** 邮件模板表---更新邮件模板 */
|
||||
export const updateEmailTemplate = (data: any) => {
|
||||
return http.request<BaseResult<object>>('put', 'emailTemplate', { data });
|
||||
return http.request<BaseResult<object>>('put', 'email-template', { data });
|
||||
};
|
||||
|
||||
/** 邮件模板表---删除邮件模板 */
|
||||
export const deleteEmailTemplate = (data: any) => {
|
||||
return http.request<BaseResult<object>>('delete', 'emailTemplate', { data });
|
||||
return http.request<BaseResult<object>>('delete', 'email-template', { data });
|
||||
};
|
||||
|
||||
/** 邮件模板表---获取全部邮件类型列表 */
|
||||
export const getEmailTypeList = () => {
|
||||
return http.request<BaseResult<any>>('get', 'emailTemplate/private');
|
||||
return http.request<BaseResult<any>>('get', 'email-template/private');
|
||||
};
|
||||
|
|
|
@ -3,27 +3,27 @@ import type { BaseResult, ResultTable } from '@/api/service/types';
|
|||
|
||||
/** 邮箱用户发送配置管理---分页查询邮箱用户发送配置 */
|
||||
export const getEmailUserPage = (data: any) => {
|
||||
return http.request<BaseResult<ResultTable>>('get', `emailUsers/${data.currentPage}/${data.pageSize}`, {
|
||||
return http.request<BaseResult<ResultTable>>('get', `email-users/${data.currentPage}/${data.pageSize}`, {
|
||||
params: data,
|
||||
});
|
||||
};
|
||||
|
||||
/** 邮箱用户发送配置管理---添加邮箱用户发送配置 */
|
||||
export const createEmailUsers = (data: any) => {
|
||||
return http.request<BaseResult<object>>('post', 'emailUsers', { data });
|
||||
return http.request<BaseResult<object>>('post', 'email-users', { data });
|
||||
};
|
||||
|
||||
/** 邮箱用户发送配置管理---更新邮箱用户发送配置 */
|
||||
export const updateEmailUsers = (data: any) => {
|
||||
return http.request<BaseResult<object>>('put', 'emailUsers', { data });
|
||||
return http.request<BaseResult<object>>('put', 'email-users', { data });
|
||||
};
|
||||
|
||||
/** 邮箱用户发送配置管理---删除邮箱用户 */
|
||||
export const deleteEmailUsers = (data: any) => {
|
||||
return http.request<BaseResult<object>>('delete', 'emailUsers', { data });
|
||||
return http.request<BaseResult<object>>('delete', 'email-users', { data });
|
||||
};
|
||||
|
||||
/** 邮箱用户发送配置管理---获取全部邮件用户配置 */
|
||||
export const getEmailUserList = () => {
|
||||
return http.request<BaseResult<any>>('get', 'emailUsers/private');
|
||||
return http.request<BaseResult<any>>('get', 'email-users/private');
|
||||
};
|
||||
|
|
|
@ -31,5 +31,5 @@ export const downloadFilesByFileId = (data: any) => {
|
|||
|
||||
/** 系统文件管理---获取所有文件存储基础路径 */
|
||||
export const getFilesStoragePath = () => {
|
||||
return http.request<BaseResult<any>>('get', `files/private/getAllFilesStoragePath`);
|
||||
return http.request<BaseResult<any>>('get', `files/private/file-storage-paths`);
|
||||
};
|
||||
|
|
|
@ -44,22 +44,22 @@ export const uploadI18nFile = (data: any) => {
|
|||
|
||||
/** 多语言类型管理---添加多语言类型 */
|
||||
export const createI18Type = (data: any) => {
|
||||
return http.request<BaseResult<object>>('post', 'i18nType', { data });
|
||||
return http.request<BaseResult<object>>('post', 'i18n-type', { data });
|
||||
};
|
||||
|
||||
/** 多语言类型管理---更新多语言类型 */
|
||||
export const updateI18nType = (data: any) => {
|
||||
return http.request<BaseResult<object>>('put', 'i18nType', { data });
|
||||
return http.request<BaseResult<object>>('put', 'i18n-type', { data });
|
||||
};
|
||||
|
||||
/** 多语言类型管理---删除多语言类型 */
|
||||
export const deleteI18nType = (data: any) => {
|
||||
return http.request<BaseResult<object>>('delete', 'i18nType', { data });
|
||||
return http.request<BaseResult<object>>('delete', 'i18n-type', { data });
|
||||
};
|
||||
|
||||
/** 多语言类型管理---获取全部多语言类型列表 */
|
||||
export const getI18nTypeList = (data: any) => {
|
||||
return http.request<BaseResult<ResultTable>>('get', 'i18nType/public', {
|
||||
return http.request<BaseResult<ResultTable>>('get', 'i18n-type/public', {
|
||||
params: data,
|
||||
});
|
||||
};
|
||||
|
|
|
@ -3,14 +3,14 @@ import type { BaseResult, ResultTable } from '@/api/service/types';
|
|||
|
||||
/** 调度任务执行日志---分页查询调度任务执行日志 */
|
||||
export const getScheduleExecuteLogPage = (data: any) => {
|
||||
return http.request<BaseResult<ResultTable>>('get', `scheduleExecuteLog/${data.currentPage}/${data.pageSize}`, {
|
||||
return http.request<BaseResult<ResultTable>>('get', `schedule-execute-log/${data.currentPage}/${data.pageSize}`, {
|
||||
params: data,
|
||||
});
|
||||
};
|
||||
|
||||
/** 调度任务执行日志---删除调度任务执行日志 */
|
||||
export const deleteScheduleExecuteLog = (data: any) => {
|
||||
return http.request<BaseResult<object>>('delete', 'scheduleExecuteLog', {
|
||||
return http.request<BaseResult<object>>('delete', 'schedule-execute-log', {
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
|
|
@ -3,17 +3,17 @@ import type { BaseResult, ResultTable } from '@/api/service/types';
|
|||
|
||||
/** 用户登录日志---获取用户登录日志列表 */
|
||||
export const getUserLoginLogPageByAdmin = (data: any) => {
|
||||
return http.request<BaseResult<ResultTable>>('get', `userLoginLog/${data.currentPage}/${data.pageSize}`, {
|
||||
return http.request<BaseResult<ResultTable>>('get', `user-login-log/${data.currentPage}/${data.pageSize}`, {
|
||||
params: data,
|
||||
});
|
||||
};
|
||||
|
||||
/** 用户登录日志---删除用户登录日志 */
|
||||
export const deleteUserLoginLog = (data: any) => {
|
||||
return http.request<BaseResult<object>>('delete', 'userLoginLog', { data });
|
||||
return http.request<BaseResult<object>>('delete', 'user-login-log', { data });
|
||||
};
|
||||
|
||||
/** 用户登录日志---获取用户登录日志列表 */
|
||||
export const getUserLoginLogPageByUser = (data: any) => {
|
||||
return http.request<BaseResult<ResultTable>>('get', `userLoginLog/private/${data.currentPage}/${data.pageSize}`);
|
||||
return http.request<BaseResult<ResultTable>>('get', `user-login-log/private/${data.currentPage}/${data.pageSize}`);
|
||||
};
|
||||
|
|
|
@ -3,12 +3,7 @@ import type { BaseResult } from '@/api/service/types';
|
|||
|
||||
/** 菜单管理-列表 */
|
||||
export const getRouterList = () => {
|
||||
return http.request<BaseResult<any>>('get', `router/routerList`);
|
||||
};
|
||||
|
||||
/* 根据路由id获取所有角色 */
|
||||
export const getRoleListByRouterId = (data: any) => {
|
||||
return http.request<BaseResult<any>>('get', `routerRole/private/getRoleListByRouterId`, { params: data });
|
||||
return http.request<BaseResult<any>>('get', `router/routers`);
|
||||
};
|
||||
|
||||
/** 菜单管理-添加菜单 */
|
||||
|
@ -16,13 +11,6 @@ export const createRouter = (data?: any) => {
|
|||
return http.request<BaseResult<any>>('post', `router`, { data });
|
||||
};
|
||||
|
||||
/** 菜单管理-清除选中菜单所有角色 */
|
||||
export const clearRouterRole = (data: any) => {
|
||||
return http.request<BaseResult<any>>('delete', `routerRole/clearRouterRole`, {
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
/** 菜单管理-更新菜单 */
|
||||
export const updateRouter = (data?: any) => {
|
||||
return http.request<BaseResult<any>>('put', `router`, { data });
|
||||
|
@ -32,3 +20,15 @@ export const updateRouter = (data?: any) => {
|
|||
export const deletedRouterByIds = (data?: any) => {
|
||||
return http.request<BaseResult<any>>('delete', `router`, { data });
|
||||
};
|
||||
|
||||
/* 根据路由id获取所有角色 */
|
||||
export const getRoleListByRouterId = (data: any) => {
|
||||
return http.request<BaseResult<any>>('get', `router-role/private/roles/${data.routerId}`);
|
||||
};
|
||||
|
||||
/** 菜单管理-清除选中菜单所有角色 */
|
||||
export const clearRouterRole = (data: any) => {
|
||||
return http.request<BaseResult<any>>('delete', `router-role/batch`, {
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
|
|
@ -3,29 +3,29 @@ import type { BaseResult, ResultTable } from '@/api/service/types';
|
|||
|
||||
/** 系统菜单图标---分页查询系统菜单图标 */
|
||||
export const getMenuIconPage = (data: any) => {
|
||||
return http.request<BaseResult<ResultTable>>('get', `menuIcon/${data.currentPage}/${data.pageSize}`, {
|
||||
return http.request<BaseResult<ResultTable>>('get', `menu-icon/${data.currentPage}/${data.pageSize}`, {
|
||||
params: data,
|
||||
});
|
||||
};
|
||||
|
||||
/** 系统菜单图标---添加系统菜单图标 */
|
||||
export const createMenuIcon = (data: any) => {
|
||||
return http.request<BaseResult<object>>('post', 'menuIcon', { data });
|
||||
return http.request<BaseResult<object>>('post', 'menu-icon', { data });
|
||||
};
|
||||
|
||||
/** 系统菜单图标---更新系统菜单图标 */
|
||||
export const updateMenuIcon = (data: any) => {
|
||||
return http.request<BaseResult<object>>('put', 'menuIcon', { data });
|
||||
return http.request<BaseResult<object>>('put', 'menu-icon', { data });
|
||||
};
|
||||
|
||||
/** 系统菜单图标---删除系统菜单图标 */
|
||||
export const deleteMenuIcon = (data: any) => {
|
||||
return http.request<BaseResult<object>>('delete', 'menuIcon', { data });
|
||||
return http.request<BaseResult<object>>('delete', 'menu-icon', { data });
|
||||
};
|
||||
|
||||
/** 系统菜单图标---根据名称搜索图标 */
|
||||
export const getIconNameListByIconName = (data: any) => {
|
||||
return http.request<BaseResult<object>>('get', 'menuIcon/public', {
|
||||
return http.request<BaseResult<object>>('get', 'menu-icon/public', {
|
||||
params: data,
|
||||
});
|
||||
};
|
||||
|
|
|
@ -3,36 +3,36 @@ import type { BaseResult, ResultTable } from '@/api/service/types';
|
|||
|
||||
/** 管理员操作用户消息---管理员分页查询用户消息 */
|
||||
export const getMessageReceivedPage = (data: any) => {
|
||||
return http.request<BaseResult<ResultTable>>('get', `messageReceived/${data.currentPage}/${data.pageSize}`, {
|
||||
return http.request<BaseResult<ResultTable>>('get', `message-received/${data.currentPage}/${data.pageSize}`, {
|
||||
params: data,
|
||||
});
|
||||
};
|
||||
|
||||
/** 管理员操作用户消息---管理员将用户消息标为已读 */
|
||||
export const updateMessageReceivedByAdmin = (data: any) => {
|
||||
return http.request<BaseResult<object>>('put', 'messageReceived', { data });
|
||||
return http.request<BaseResult<object>>('put', 'message-received', { data });
|
||||
};
|
||||
|
||||
/** 管理员操作用户消息---管理删除用户消息 */
|
||||
export const deleteMessageReceivedByAdmin = (data: any) => {
|
||||
return http.request<BaseResult<object>>('delete', 'messageReceived', {
|
||||
return http.request<BaseResult<object>>('delete', 'message-received', {
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
/** 用户系统消息---用户获取系统消息列表 */
|
||||
export const getMessageReceivedPageByUser = (data: any) => {
|
||||
return http.request<BaseResult<ResultTable>>('get', `messageReceived/private/${data.currentPage}/${data.pageSize}`, {
|
||||
return http.request<BaseResult<ResultTable>>('get', `message-received/private/${data.currentPage}/${data.pageSize}`, {
|
||||
params: data,
|
||||
});
|
||||
};
|
||||
|
||||
/** 系统消息---用户将消息标为已读 */
|
||||
export const updateMessageByUser = (data: any) => {
|
||||
return http.request<BaseResult<object>>('put', 'messageReceived/private/markAsRead', { data });
|
||||
return http.request<BaseResult<object>>('put', 'message-received/private/user/messages/read-status', { data });
|
||||
};
|
||||
|
||||
/** 系统消息---用户删除系统消息 */
|
||||
export const deleteMessageReceivedByUser = (data: any) => {
|
||||
return http.request<BaseResult<object>>('delete', 'messageReceived/private/deleteMessage', { data });
|
||||
return http.request<BaseResult<object>>('delete', 'message-received/private/user/messages', { data });
|
||||
};
|
||||
|
|
|
@ -25,10 +25,10 @@ export const deleteMessage = (data: any) => {
|
|||
|
||||
/** 用户系统消息---根据消息id查询消息详情 */
|
||||
export const getMessageDetailById = (data: any) => {
|
||||
return http.request<BaseResult<any>>('get', `message/private/getMessageDetailById`, { params: data });
|
||||
return http.request<BaseResult<any>>('get', `message/private/message/${data.id}`);
|
||||
};
|
||||
|
||||
/** 系统消息---根据消息id获取接收人信息 */
|
||||
export const getReceivedUserinfoByMessageId = (data: any) => {
|
||||
return http.request<BaseResult<any>>('get', `message/private/getReceivedUserinfoByMessageId`, { params: data });
|
||||
return http.request<BaseResult<any>>('get', `message/private/messages/${data.messageId}/recipients`);
|
||||
};
|
||||
|
|
|
@ -25,5 +25,5 @@ export const deleteMessageType = (data: any) => {
|
|||
|
||||
/** 系统消息类型---获取所有消息列表 */
|
||||
export const getMessageTypeList = () => {
|
||||
return http.request<BaseResult<ResultTable>>('get', '/messageType/private/getMessageList');
|
||||
return http.request<BaseResult<ResultTable>>('get', '/messageType/private/messages');
|
||||
};
|
||||
|
|
|
@ -3,29 +3,29 @@ import type { BaseResult, ResultTable } from '@/api/service/types';
|
|||
|
||||
/** 任务调度分组---分页查询任务调度分组 */
|
||||
export const getSchedulersGroupPage = (data: any) => {
|
||||
return http.request<BaseResult<ResultTable>>('get', `schedulersGroup/${data.currentPage}/${data.pageSize}`, {
|
||||
return http.request<BaseResult<ResultTable>>('get', `schedulers-group/${data.currentPage}/${data.pageSize}`, {
|
||||
params: data,
|
||||
});
|
||||
};
|
||||
|
||||
/** 任务调度分组---添加任务调度分组 */
|
||||
export const createSchedulersGroup = (data: any) => {
|
||||
return http.request<BaseResult<object>>('post', 'schedulersGroup', { data });
|
||||
return http.request<BaseResult<object>>('post', 'schedulers-group', { data });
|
||||
};
|
||||
|
||||
/** 任务调度分组---更新任务调度分组 */
|
||||
export const updateSchedulersGroup = (data: any) => {
|
||||
return http.request<BaseResult<object>>('put', 'schedulersGroup', { data });
|
||||
return http.request<BaseResult<object>>('put', 'schedulers-group', { data });
|
||||
};
|
||||
|
||||
/** 任务调度分组---删除任务调度分组 */
|
||||
export const deleteSchedulersGroup = (data: any) => {
|
||||
return http.request<BaseResult<object>>('delete', 'schedulersGroup', {
|
||||
return http.request<BaseResult<object>>('delete', 'schedulers-group', {
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
/** 任务调度分组---获取所有任务调度分组 */
|
||||
export const getSchedulersGroupList = () => {
|
||||
return http.request<BaseResult<ResultTable>>('get', 'schedulersGroup/getSchedulersGroupList');
|
||||
return http.request<BaseResult<ResultTable>>('get', 'schedulers-group/scheduler-groups');
|
||||
};
|
||||
|
|
|
@ -56,20 +56,18 @@ export const deleteUserByAdmin = (data: any) => {
|
|||
};
|
||||
|
||||
/** 用户管理---根据用户id查询 */
|
||||
export const loadUserinfoById = (data?: object) => {
|
||||
return http.request<BaseResult<UserResult>>('get', 'user/private/getUserinfoById', { params: data });
|
||||
export const loadUserinfoById = (data?: any) => {
|
||||
return http.request<BaseResult<UserResult>>('get', `user/private/users/${data.id}`);
|
||||
};
|
||||
|
||||
/** 用户信息---根据用户名查询用户列表 */
|
||||
export const getUserListByKeyword = (data: any) => {
|
||||
return http.request<BaseResult<object>>('get', 'user/private/getUserListByKeyword', { params: data });
|
||||
return http.request<BaseResult<object>>('get', 'user/private/users/search', { params: data });
|
||||
};
|
||||
|
||||
/** 用户管理---强制用户下线 */
|
||||
export const forcedOfflineByAdmin = (data: any) => {
|
||||
return http.request<BaseResult<UserResult>>('put', 'user/forcedOffline', {
|
||||
data,
|
||||
});
|
||||
return http.request<BaseResult<UserResult>>('put', `user/${data.id}/force-logout`);
|
||||
};
|
||||
|
||||
// -----------------------------------------
|
||||
|
@ -83,12 +81,12 @@ export const userLogin = (data?: object) => {
|
|||
|
||||
/** 刷新`token` */
|
||||
export const refreshTokenApi = (data?: object) => {
|
||||
return http.request<BaseResult<RefreshTokenResult>>('post', 'user/public/refreshToken', { data });
|
||||
return http.request<BaseResult<RefreshTokenResult>>('post', 'user/private/refresh-token', { data });
|
||||
};
|
||||
|
||||
/** 发送邮件 */
|
||||
export const sendLoginEmail = (data: any) => {
|
||||
return http.request<BaseResult<any>>('post', '/user/public/sendLoginEmail', { data }, { headers: { 'Content-Type': 'multipart/form-data' } });
|
||||
return http.request<BaseResult<any>>('post', '/user/public/email-code', { data }, { headers: { 'Content-Type': 'multipart/form-data' } });
|
||||
};
|
||||
|
||||
/** 获取用户信息,根据当前token获取 */
|
||||
|
@ -113,5 +111,5 @@ export const updateUserPassword = (data: any) => {
|
|||
|
||||
/* 查询缓存中的已登录的用户 */
|
||||
export const getCacheLoggedInPage = (data: any) => {
|
||||
return http.request<BaseResult<any>>('get', `user/getCacheUserPage/${data.currentPage}/${data.pageSize}`, { data });
|
||||
return http.request<BaseResult<any>>('get', `user/users/logged-in/${data.currentPage}/${data.pageSize}`, { data });
|
||||
};
|
||||
|
|
|
@ -25,5 +25,5 @@ export const deleteDept = (data: any) => {
|
|||
|
||||
/** 部门管理---获取所有部门管理列表 */
|
||||
export const getDeptList = () => {
|
||||
return http.request<BaseResult<object>>('get', 'dept/private/getDeptList');
|
||||
return http.request<BaseResult<object>>('get', 'dept/private/departments');
|
||||
};
|
||||
|
|
|
@ -35,27 +35,25 @@ export const importPermission = (data: any) => {
|
|||
|
||||
/** 权限---获取所有权限 */
|
||||
export const getPermissionList = () => {
|
||||
return http.request<BaseResult<any>>('get', `permission/private/getPermissionList`);
|
||||
return http.request<BaseResult<any>>('get', `permission/private/permissions`);
|
||||
};
|
||||
|
||||
/* 权限---获取系统API信息 */
|
||||
export const getSystemApiInfoList = () => {
|
||||
return http.request<BaseResult<any>>('get', 'permission/private/getSystemApiInfoList');
|
||||
return http.request<BaseResult<any>>('get', 'permission/private/system/apis');
|
||||
};
|
||||
|
||||
/** 权限---批量修改权限父级 */
|
||||
export const updatePermissionListByParentId = (data: any) => {
|
||||
return http.request<BaseResult<object>>('patch', 'permission/update/permissionListByParentId', { data });
|
||||
return http.request<BaseResult<object>>('patch', 'permission/update/permissions/parent', { data });
|
||||
};
|
||||
|
||||
/** 权限---批量更新权限 */
|
||||
export const updatePermissionBatch = (data: any) => {
|
||||
return http.request<BaseResult<object>>('patch', 'permission/update/permissionBatch', { data });
|
||||
return http.request<BaseResult<object>>('patch', 'permission/update/permissions/batch', { data });
|
||||
};
|
||||
|
||||
/** 角色和权限---根据角色id获取权限内容 */
|
||||
export const getPowerListByRoleId = (data: any) => {
|
||||
return http.request<BaseResult<object>>('get', 'rolePermission/private/getPermissionListByRoleId', {
|
||||
params: data,
|
||||
});
|
||||
return http.request<BaseResult<object>>('get', `rolePermission/private/permissions/${data.id}`);
|
||||
};
|
|
@ -41,12 +41,12 @@ export const updateRoleByFile = (data: any) => {
|
|||
|
||||
/** 为用户分配角色---根据用户id获取所有角色 */
|
||||
export const getRoleListByUserId = (data: any) => {
|
||||
return http.request<BaseResult<any>>('get', `userRole/private/getRoleListByUserId`, { params: data });
|
||||
return http.request<BaseResult<any>>('get', `user-role/private/roles/${data.userId}`);
|
||||
};
|
||||
|
||||
/** 为用户分配角色---为用户分配角色 */
|
||||
export const createUserRole = (data: object) => {
|
||||
return http.request<BaseResult<any>>('post', 'userRole', { data });
|
||||
return http.request<BaseResult<any>>('post', 'user-role', { data });
|
||||
};
|
||||
|
||||
/** 角色和权限---为角色分配权限 */
|
||||
|
|
|
@ -3,15 +3,15 @@ import type { BaseResult } from '@/api/service/types';
|
|||
|
||||
/** 系统管理-用户路由获取 */
|
||||
export const fetchRouterAsync = () => {
|
||||
return http.request<BaseResult<any>>('get', 'router/private/routerAsync');
|
||||
return http.request<BaseResult<any>>('get', 'router/private/router-async');
|
||||
};
|
||||
|
||||
/** 上传文件 */
|
||||
export const uploadFile = (data: any) => {
|
||||
return http.request<BaseResult<any>>('post', '/files/private/upload', { data }, { headers: { 'Content-Type': 'multipart/form-data' } });
|
||||
return http.request<BaseResult<any>>('post', '/files/private/file', { data }, { headers: { 'Content-Type': 'multipart/form-data' } });
|
||||
};
|
||||
|
||||
/** 上传文件 */
|
||||
export const uploadImage = (data: any) => {
|
||||
return http.request<BaseResult<any>>('post', '/files/private/uploadImage', { data }, { headers: { 'Content-Type': 'multipart/form-data' } });
|
||||
return http.request<BaseResult<any>>('post', '/files/private/image', { data }, { headers: { 'Content-Type': 'multipart/form-data' } });
|
||||
};
|
||||
|
|
|
@ -32,7 +32,7 @@ export const getPlatformConfig = async (app: App): Promise<undefined> => {
|
|||
return axios({
|
||||
method: 'get',
|
||||
// TODO 後端讀取 platform-config.json
|
||||
url: `/api/config/public/webConfig`,
|
||||
url: `/api/config/public/web-config`,
|
||||
})
|
||||
.then(({ data: config }) => {
|
||||
let $config = app.config.globalProperties.$config;
|
||||
|
|
|
@ -44,7 +44,6 @@ export const useMessageUserStore = defineStore('messageUserStore', {
|
|||
const data = { ...this.pagination, ...this.form };
|
||||
delete data.pageSizes;
|
||||
delete data.total;
|
||||
delete data.background;
|
||||
|
||||
// 获取系统消息列表
|
||||
const result = await getMessageReceivedPageByUser(data);
|
||||
|
@ -62,7 +61,7 @@ export const useMessageUserStore = defineStore('messageUserStore', {
|
|||
this.messageDetail = result.data;
|
||||
|
||||
// 解码消息内容
|
||||
this.messageDetail.content = decode(this.messageDetail?.content);
|
||||
(this.messageDetail as any).content = decode((this.messageDetail as any)?.content);
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -63,7 +63,6 @@ export const useAdminUserStore = defineStore('adminUserStore', {
|
|||
const data = { ...this.pagination, ...this.form };
|
||||
delete data.pageSizes;
|
||||
delete data.total;
|
||||
delete data.background;
|
||||
|
||||
// 获取用户信息列表
|
||||
const result = await getUserPageByAdmin(data);
|
||||
|
@ -93,7 +92,7 @@ export const useAdminUserStore = defineStore('adminUserStore', {
|
|||
|
||||
/** 强制用户下线 */
|
||||
async forcedOffline(data: any) {
|
||||
const result = await forcedOfflineByAdmin(data);
|
||||
const result = await forcedOfflineByAdmin({ data });
|
||||
return storeMessage(result);
|
||||
},
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import {
|
|||
updatePermission,
|
||||
updatePermissionBatch,
|
||||
updatePermissionListByParentId,
|
||||
} from '@/api/v1/system/power';
|
||||
} from '@/api/v1/system/permission';
|
||||
import { pageSizes } from '@/enums/baseConstant';
|
||||
import { storeMessage } from '@/utils/message';
|
||||
import { storePagination } from '@/store/useStorePagination';
|
||||
|
|
|
@ -95,12 +95,12 @@ onMounted(() => {
|
|||
<PureTableBar :columns="columns" :title="$t('emailTemplate')" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
||||
<!-- 新增 -->
|
||||
<template #buttons>
|
||||
<el-button : :icon="useRenderIcon(AddFill)" plain type="success" @click="onAdd">
|
||||
<el-button :icon="useRenderIcon(AddFill)" plain type="success" @click="onAdd">
|
||||
{{ $t('addNew') }}
|
||||
</el-button>
|
||||
|
||||
<!-- 批量删除按钮 -->
|
||||
<el-button : :disabled="!(selectRows.length > 0)" :icon="useRenderIcon(Delete)" plain type="danger" @click="onDeleteBatch">
|
||||
<el-button :disabled="!(selectRows.length > 0)" :icon="useRenderIcon(Delete)" plain type="danger" @click="onDeleteBatch">
|
||||
{{ $t('deleteBatches') }}
|
||||
</el-button>
|
||||
</template>
|
||||
|
@ -154,12 +154,12 @@ onMounted(() => {
|
|||
</el-button>
|
||||
|
||||
<!-- 修改 -->
|
||||
<el-button : :icon="useRenderIcon(EditPen)" :size="size" class="reset-margin" link type="primary" @click="onUpdate(row)">
|
||||
<el-button :icon="useRenderIcon(EditPen)" :size="size" class="reset-margin" link type="primary" @click="onUpdate(row)">
|
||||
{{ $t('modify') }}
|
||||
</el-button>
|
||||
|
||||
<!-- 删除 -->
|
||||
<el-popconfirm : :title="`${$t('delete')} ${row.templateName}?`" @confirm="onDelete(row)">
|
||||
<el-popconfirm :title="`${$t('delete')} ${row.templateName}?`" @confirm="onDelete(row)">
|
||||
<template #reference>
|
||||
<el-button :icon="useRenderIcon(Delete)" :size="size" class="reset-margin" link type="primary">
|
||||
{{ $t('delete') }}
|
||||
|
|
|
@ -8,7 +8,7 @@ export const columns: TableColumnList = [
|
|||
{
|
||||
type: 'index',
|
||||
index: (index: number) => index + 1,
|
||||
label: $t("index"),
|
||||
label: $t('index'),
|
||||
width: 60,
|
||||
},
|
||||
// 模板名称
|
||||
|
|
|
@ -100,12 +100,12 @@ onMounted(() => {
|
|||
|
||||
<PureTableBar :columns="columns" :title="$t('email_user_send_config')" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
||||
<template #buttons>
|
||||
<el-button : :icon="useRenderIcon(AddFill)" plain type="success" @click="onAdd">
|
||||
<el-button :icon="useRenderIcon(AddFill)" plain type="success" @click="onAdd">
|
||||
{{ $t('addNew') }}
|
||||
</el-button>
|
||||
|
||||
<!-- 批量删除按钮 -->
|
||||
<el-button : :disabled="!(deleteIds.length > 0)" :icon="useRenderIcon(Delete)" plain type="danger" @click="onDeleteBatch">
|
||||
<el-button :disabled="!(deleteIds.length > 0)" :icon="useRenderIcon(Delete)" plain type="danger" @click="onDeleteBatch">
|
||||
{{ $t('deleteBatches') }}
|
||||
</el-button>
|
||||
</template>
|
||||
|
@ -162,16 +162,16 @@ onMounted(() => {
|
|||
|
||||
<!-- 插槽-更新用户 -->
|
||||
<template #updateUser="{ row }">
|
||||
<el-button v-show="row.updateUser" : link type="primary" @click="selectUserinfo(row.updateUser)">
|
||||
<el-button v-show="row.updateUser" link type="primary" @click="selectUserinfo(row.updateUser)">
|
||||
{{ row.updateUsername }}
|
||||
</el-button>
|
||||
</template>
|
||||
|
||||
<template #operation="{ row }">
|
||||
<el-button : :icon="useRenderIcon(EditPen)" :size="size" class="reset-margin" link type="primary" @click="onUpdate(row)">
|
||||
<el-button :icon="useRenderIcon(EditPen)" :size="size" class="reset-margin" link type="primary" @click="onUpdate(row)">
|
||||
{{ $t('modify') }}
|
||||
</el-button>
|
||||
<el-popconfirm : :title="`${$t('delete')}${row.email}?`" @confirm="onDelete(row)">
|
||||
<el-popconfirm :title="`${$t('delete')}${row.email}?`" @confirm="onDelete(row)">
|
||||
<template #reference>
|
||||
<el-button :icon="useRenderIcon(Delete)" :size="size" class="reset-margin" link type="primary">
|
||||
{{ $t('delete') }}
|
||||
|
|
|
@ -66,12 +66,12 @@ onMounted(() => {
|
|||
|
||||
<PureTableBar :columns="columns" :title="$t('menuIcon')" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
||||
<template #buttons>
|
||||
<el-button : :icon="useRenderIcon(AddFill)" plain type="success" @click="onAdd">
|
||||
<el-button :icon="useRenderIcon(AddFill)" plain type="success" @click="onAdd">
|
||||
{{ $t('addNew') }}
|
||||
</el-button>
|
||||
|
||||
<!-- 批量删除按钮 -->
|
||||
<el-button : :disabled="!(deleteIds.length > 0)" :icon="useRenderIcon(Delete)" plain type="danger" @click="onDeleteBatch">
|
||||
<el-button :disabled="!(deleteIds.length > 0)" :icon="useRenderIcon(Delete)" plain type="danger" @click="onDeleteBatch">
|
||||
{{ $t('deleteBatches') }}
|
||||
</el-button>
|
||||
</template>
|
||||
|
@ -119,10 +119,10 @@ onMounted(() => {
|
|||
</template>
|
||||
|
||||
<template #operation="{ row }">
|
||||
<el-button : :icon="useRenderIcon(EditPen)" :size="size" class="reset-margin" link type="primary" @click="onUpdate(row)">
|
||||
<el-button :icon="useRenderIcon(EditPen)" :size="size" class="reset-margin" link type="primary" @click="onUpdate(row)">
|
||||
{{ $t('modify') }}
|
||||
</el-button>
|
||||
<el-popconfirm : :title="`${$t('delete')}${row.iconName}?`" @confirm="onDelete(row)">
|
||||
<el-popconfirm :title="`${$t('delete')}${row.iconName}?`" @confirm="onDelete(row)">
|
||||
<template #reference>
|
||||
<el-button :icon="useRenderIcon(Delete)" :size="size" class="reset-margin" link type="primary">
|
||||
{{ $t('delete') }}
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
<script lang="ts" setup>
|
||||
import ReAuth from '@/components/ReAuth/src/auth';
|
||||
import { useRenderIcon } from '@/components/ReIcon/src/hooks';
|
||||
import { PureTableBar } from '@/components/RePureTableBar';
|
||||
import { selectUserinfo } from '@/components/Table/Userinfo/columns';
|
||||
import { $t } from '@/plugins/i18n';
|
||||
import { hasAuth } from '@/router/utils';
|
||||
import { userI18nStore } from '@/store/i18n/i18n';
|
||||
import {
|
||||
auth,
|
||||
columns,
|
||||
deleteIds,
|
||||
downloadI18nSetting,
|
||||
|
@ -64,34 +61,32 @@ onMounted(() => {
|
|||
|
||||
<template>
|
||||
<div class="main">
|
||||
<ReAuth :value="auth.query">
|
||||
<el-form ref="pageFormRef" :inline="true" :model="i18nStore.form" class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px] overflow-auto">
|
||||
<el-form-item :label="$t('i18n.keyName')" prop="keyName">
|
||||
<el-input v-model="i18nStore.form.keyName" :placeholder="`${$t('input')}${$t('i18n.keyName')}`" class="!w-[180px]" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('i18n.translation')" prop="translation">
|
||||
<el-input v-model="i18nStore.form.translation" :placeholder="`${$t('input')}${$t('i18n.translation')}`" class="!w-[180px]" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('i18n.typeName')" prop="typeName">
|
||||
<el-input v-model="i18nStore.form.typeName" :placeholder="`${$t('input')}${$t('i18n.typeName')}`" class="!w-[180px]" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<!-- 表格頂部搜索 -->
|
||||
<el-button :icon="useRenderIcon('ri/search-line')" :loading="i18nStore.loading" type="primary" @click="onSearch">
|
||||
{{ $t('search') }}
|
||||
</el-button>
|
||||
<!-- 表格頂部重置 -->
|
||||
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm(pageFormRef)">
|
||||
{{ $t('buttons.reset') }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ReAuth>
|
||||
<el-form ref="pageFormRef" :inline="true" :model="i18nStore.form" class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px] overflow-auto">
|
||||
<el-form-item :label="$t('i18n.keyName')" prop="keyName">
|
||||
<el-input v-model="i18nStore.form.keyName" :placeholder="`${$t('input')}${$t('i18n.keyName')}`" class="!w-[180px]" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('i18n.translation')" prop="translation">
|
||||
<el-input v-model="i18nStore.form.translation" :placeholder="`${$t('input')}${$t('i18n.translation')}`" class="!w-[180px]" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('i18n.typeName')" prop="typeName">
|
||||
<el-input v-model="i18nStore.form.typeName" :placeholder="`${$t('input')}${$t('i18n.typeName')}`" class="!w-[180px]" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<!-- 表格頂部搜索 -->
|
||||
<el-button :icon="useRenderIcon('ri/search-line')" :loading="i18nStore.loading" type="primary" @click="onSearch">
|
||||
{{ $t('search') }}
|
||||
</el-button>
|
||||
<!-- 表格頂部重置 -->
|
||||
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm(pageFormRef)">
|
||||
{{ $t('buttons.reset') }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<PureTableBar :columns="columns" :title="$t('multilingualManagement')" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
||||
<template #buttons>
|
||||
<!-- 下载多语言配置 -->
|
||||
<el-dropdown v-if="hasAuth(auth.download)" class="mr-1" type="primary">
|
||||
<el-dropdown class="mr-1" type="primary">
|
||||
<el-button :icon="useRenderIcon(Download)" plain type="primary">
|
||||
{{ $t('download_configuration') }}
|
||||
</el-button>
|
||||
|
@ -106,7 +101,7 @@ onMounted(() => {
|
|||
</el-dropdown>
|
||||
|
||||
<!-- 更新多语言配置 -->
|
||||
<el-dropdown v-if="hasAuth(auth.update)" class="mr-1" type="primary">
|
||||
<el-dropdown class="mr-1" type="primary">
|
||||
<el-button :icon="useRenderIcon(Upload)" plain type="primary">{{ $t('file_import') }}</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
|
@ -117,12 +112,12 @@ onMounted(() => {
|
|||
</el-dropdown>
|
||||
|
||||
<!-- 添加多语言 -->
|
||||
<el-button v-if="hasAuth(auth.add)" :icon="useRenderIcon(AddFill)" plain type="success" @click="onAdd">
|
||||
<el-button :icon="useRenderIcon(AddFill)" plain type="success" @click="onAdd">
|
||||
{{ $t('addNew') }}
|
||||
</el-button>
|
||||
|
||||
<!-- 批量删除按钮 -->
|
||||
<el-button v-if="hasAuth(auth.deleted)" :disabled="!(deleteIds.length > 0)" :icon="useRenderIcon(Delete)" plain type="danger" @click="onDeleteBatch">
|
||||
<el-button :disabled="!(deleteIds.length > 0)" :icon="useRenderIcon(Delete)" plain type="danger" @click="onDeleteBatch">
|
||||
{{ $t('deleteBatches') }}
|
||||
</el-button>
|
||||
</template>
|
||||
|
@ -168,12 +163,12 @@ onMounted(() => {
|
|||
|
||||
<template #operation="{ row }">
|
||||
<!-- 修改 -->
|
||||
<el-button v-if="hasAuth(auth.update)" :icon="useRenderIcon(EditPen)" :size="size" class="reset-margin" link type="primary" @click="onUpdate(row)">
|
||||
<el-button :icon="useRenderIcon(EditPen)" :size="size" class="reset-margin" link type="primary" @click="onUpdate(row)">
|
||||
{{ $t('modify') }}
|
||||
</el-button>
|
||||
|
||||
<!-- 刪除確認 -->
|
||||
<el-popconfirm v-if="hasAuth(auth.deleted)" :title="`${$t('confirmDelete')} ${row.translation}`" @confirm="onDelete(row)">
|
||||
<el-popconfirm :title="`${$t('confirmDelete')} ${row.translation}`" @confirm="onDelete(row)">
|
||||
<template #reference>
|
||||
<el-button :icon="useRenderIcon(Delete)" :size="size" class="reset-margin" link type="primary">
|
||||
{{ $t('delete') }}
|
||||
|
|
|
@ -49,7 +49,7 @@ onMounted(() => {
|
|||
|
||||
<PureTableBar :columns="columns" :title="$t('i18n_type')" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
||||
<template #buttons>
|
||||
<el-button : :icon="useRenderIcon(AddFill)" plain type="success" @click="onAdd">
|
||||
<el-button :icon="useRenderIcon(AddFill)" plain type="success" @click="onAdd">
|
||||
{{ $t('addNew') }}
|
||||
</el-button>
|
||||
</template>
|
||||
|
@ -91,10 +91,10 @@ onMounted(() => {
|
|||
</template>
|
||||
|
||||
<template #operation="{ row }">
|
||||
<el-button : :icon="useRenderIcon(EditPen)" :size="size" class="reset-margin" link type="primary" @click="onUpdate(row)">
|
||||
<el-button :icon="useRenderIcon(EditPen)" :size="size" class="reset-margin" link type="primary" @click="onUpdate(row)">
|
||||
{{ $t('modify') }}
|
||||
</el-button>
|
||||
<el-popconfirm : :title="`${$t('delete')} ${row.typeName}?`" @confirm="onDelete(row)">
|
||||
<el-popconfirm :title="`${$t('delete')} ${row.typeName}?`" @confirm="onDelete(row)">
|
||||
<template #reference>
|
||||
<el-button :icon="useRenderIcon(Delete)" :size="size" class="reset-margin" link type="primary">
|
||||
{{ $t('delete') }}
|
||||
|
|
|
@ -15,7 +15,7 @@ const token = ref(getToken().token);
|
|||
|
||||
editorConfig.MENU_CONF['uploadImage'] = {
|
||||
// 服务端上传地址,根据实际业务改写
|
||||
server: `${defaultConfig.baseURL}/files/private/upload`,
|
||||
server: `${defaultConfig.baseURL}/files/private/file`,
|
||||
// form-data 的 fieldName,根据实际业务改写
|
||||
fieldName: 'file',
|
||||
// 选择文件时的类型限制,根据实际业务改写
|
||||
|
|
|
@ -14,7 +14,7 @@ const token = ref(getToken().token);
|
|||
|
||||
editorConfig.MENU_CONF['uploadImage'] = {
|
||||
// 服务端上传地址,根据实际业务改写
|
||||
server: '/api/files/private/upload',
|
||||
server: '/api/files/private/file',
|
||||
// form-data 的 fieldName,根据实际业务改写
|
||||
fieldName: 'file',
|
||||
// 选择文件时的类型限制,根据实际业务改写
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
<script lang="ts" setup>
|
||||
import ReAuth from '@/components/ReAuth/src/auth';
|
||||
import { useRenderIcon } from '@/components/ReIcon/src/hooks';
|
||||
import { PureTableBar } from '@/components/RePureTableBar';
|
||||
import { selectUserinfo } from '@/components/Table/Userinfo/columns';
|
||||
import { $t } from '@/plugins/i18n';
|
||||
import { useSchedulersStore } from '@/store/scheduler/schedulers';
|
||||
import { auth, columns, onAdd, onDelete, onPause, onResume, onSearch, onUpdate } from '@/views/scheduler/schedulers/utils';
|
||||
import { columns, onAdd, onDelete, onPause, onResume, onSearch, onUpdate } from '@/views/scheduler/schedulers/utils';
|
||||
import PureTable from '@pureadmin/table';
|
||||
import { FormInstance } from 'element-plus';
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
@ -122,34 +121,30 @@ onMounted(() => {
|
|||
</el-button>
|
||||
|
||||
<!-- 暂停-->
|
||||
<ReAuth :value="auth.pause">
|
||||
<el-button
|
||||
v-if="row.triggerState !== 'PAUSED'"
|
||||
:icon="useRenderIcon('line-md:pause')"
|
||||
:size="size"
|
||||
class="reset-margin"
|
||||
link
|
||||
type="primary"
|
||||
@click="onPause(row)"
|
||||
>
|
||||
{{ $t('pause') }}
|
||||
</el-button>
|
||||
</ReAuth>
|
||||
<el-button
|
||||
v-if="row.triggerState !== 'PAUSED'"
|
||||
:icon="useRenderIcon('line-md:pause')"
|
||||
:size="size"
|
||||
class="reset-margin"
|
||||
link
|
||||
type="primary"
|
||||
@click="onPause(row)"
|
||||
>
|
||||
{{ $t('pause') }}
|
||||
</el-button>
|
||||
|
||||
<!-- 恢复 -->
|
||||
<ReAuth :value="auth.resume">
|
||||
<el-button
|
||||
v-if="row.triggerState === 'PAUSED'"
|
||||
:icon="useRenderIcon('material-symbols:resume')"
|
||||
:size="size"
|
||||
class="reset-margin"
|
||||
link
|
||||
type="primary"
|
||||
@click="onResume(row)"
|
||||
>
|
||||
{{ $t('resume') }}
|
||||
</el-button>
|
||||
</ReAuth>
|
||||
<el-button
|
||||
v-if="row.triggerState === 'PAUSED'"
|
||||
:icon="useRenderIcon('material-symbols:resume')"
|
||||
:size="size"
|
||||
class="reset-margin"
|
||||
link
|
||||
type="primary"
|
||||
@click="onResume(row)"
|
||||
>
|
||||
{{ $t('resume') }}
|
||||
</el-button>
|
||||
|
||||
<!-- 删除 -->
|
||||
<el-popconfirm :title="`${$t('delete')}${row.jobName}?`" @confirm="onDelete(row)">
|
||||
|
|
|
@ -10,7 +10,8 @@ export const columns: TableColumnList = [
|
|||
// 文件在服务器上的存储路径
|
||||
{ label: $t('files_filepath'), prop: 'filepath' },
|
||||
// 文件的MIME类型
|
||||
{ label: $t('files_fileType'), prop: 'fileType', width: 180 },
|
||||
{ label: $t('files_fileType'), prop: 'contentType', width: 180 },
|
||||
{ label: '缩略图类型', prop: 'thContentType', width: 180 },
|
||||
// 下载数量
|
||||
{ label: $t('files_downloadCount'), prop: 'downloadCount', width: 115 },
|
||||
{ label: $t('table.updateTime'), prop: 'updateTime', sortable: true, width: 160 },
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
<script lang="ts" setup>
|
||||
import ReAuth from '@/components/ReAuth/src/auth';
|
||||
import { useRenderIcon } from '@/components/ReIcon/src/hooks';
|
||||
import { PureTableBar } from '@/components/RePureTableBar';
|
||||
import { selectUserinfo } from '@/components/Table/Userinfo/columns';
|
||||
import { $t } from '@/plugins/i18n';
|
||||
import { userMenuStore } from '@/store/system/menu';
|
||||
import { auth, clearAllRolesSelect, columns, mergeArgs, onAdd, onDelete, onSearch, onUpdate, selectIds, tableRef } from '@/views/system/menu/utils';
|
||||
import { clearAllRolesSelect, columns, mergeArgs, onAdd, onDelete, onSearch, onUpdate, selectIds, tableRef } from '@/views/system/menu/utils';
|
||||
import PureTable from '@pureadmin/table';
|
||||
import { FormInstance } from 'element-plus';
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
@ -46,20 +45,18 @@ onMounted(() => {
|
|||
|
||||
<template>
|
||||
<div class="main">
|
||||
<ReAuth :value="auth.search">
|
||||
<el-form ref="formRef" :inline="true" :model="routerStore.form" class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px] overflow-auto">
|
||||
<el-form-item label="菜单名称" prop="title">
|
||||
<el-input v-model="routerStore.form.title" :placeholder="$t('input')" class="!w-[180px]" clearable />
|
||||
</el-form-item>
|
||||
<el-form ref="formRef" :inline="true" :model="routerStore.form" class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px] overflow-auto">
|
||||
<el-form-item label="菜单名称" prop="title">
|
||||
<el-input v-model="routerStore.form.title" :placeholder="$t('input')" class="!w-[180px]" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button :icon="useRenderIcon('ri/search-line')" :loading="routerStore.loading" type="primary" @click="onSearch">
|
||||
{{ $t('search') }}
|
||||
</el-button>
|
||||
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm(formRef)">{{ $t('buttons.reset') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ReAuth>
|
||||
<el-form-item>
|
||||
<el-button :icon="useRenderIcon('ri/search-line')" :loading="routerStore.loading" type="primary" @click="onSearch">
|
||||
{{ $t('search') }}
|
||||
</el-button>
|
||||
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm(formRef)">{{ $t('buttons.reset') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<PureTableBar
|
||||
:columns="columns"
|
||||
|
@ -123,19 +120,9 @@ onMounted(() => {
|
|||
</el-button>
|
||||
|
||||
<!-- 新增 -->
|
||||
<ReAuth :value="auth.add">
|
||||
<el-button
|
||||
v-show="row.menuType !== 3"
|
||||
:icon="useRenderIcon(AddFill)"
|
||||
:size="size"
|
||||
class="reset-margin"
|
||||
link
|
||||
type="primary"
|
||||
@click="onAdd(row.id)"
|
||||
>
|
||||
{{ $t('addNew') }}
|
||||
</el-button>
|
||||
</ReAuth>
|
||||
<el-button v-show="row.menuType !== 3" :icon="useRenderIcon(AddFill)" :size="size" class="reset-margin" link type="primary" @click="onAdd(row.id)">
|
||||
{{ $t('addNew') }}
|
||||
</el-button>
|
||||
|
||||
<!-- 删除操作 -->
|
||||
<el-popconfirm :title="`${$t('delete')} ${$t(row.title)}?`" @confirm="onDelete(row)">
|
||||
|
|
|
@ -34,9 +34,6 @@ const form = ref(props.formInline);
|
|||
const powerStore = usePermissionStore();
|
||||
const { allPowerList, systemApiInfoList } = storeToRefs(powerStore);
|
||||
|
||||
// tab 默认选中项
|
||||
const activeName = ref('system');
|
||||
|
||||
// 过滤搜索
|
||||
const queryText = ref('');
|
||||
|
||||
|
@ -54,9 +51,7 @@ const onNodeClick = (node) => {
|
|||
form.value.powerName = node.summary;
|
||||
form.value.requestMethod = node.httpMethod;
|
||||
form.value.requestUrl = node.path;
|
||||
if (node.powerCodes && node.powerCodes.length > 0) {
|
||||
form.value.powerCode = node.powerCodes[0];
|
||||
}
|
||||
form.value.powerCode = node.powerCode;
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
|
|
|
@ -5,7 +5,7 @@ import { h, ref } from 'vue';
|
|||
import { messageBox } from '@/utils/message';
|
||||
import type { FormItemProps } from '@/views/system/role/utils/types';
|
||||
import { $t } from '@/plugins/i18n';
|
||||
import { getPowerListByRoleId } from '@/api/v1/system/power';
|
||||
import { getPowerListByRoleId } from '@/api/v1/system/permission';
|
||||
|
||||
// 表格ref
|
||||
export const tableRef = ref();
|
||||
|
|
Loading…
Reference in New Issue