Publish apes-Authon via gitea-publish skill
This commit is contained in:
+25
@@ -0,0 +1,25 @@
|
||||
# Build output
|
||||
target/
|
||||
*.class
|
||||
|
||||
# IDE
|
||||
.idea/
|
||||
*.iml
|
||||
.vscode/
|
||||
.settings/
|
||||
.project
|
||||
.classpath
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Logs
|
||||
logs/
|
||||
*.log
|
||||
nohup.out
|
||||
|
||||
# Maven
|
||||
*.jar
|
||||
*.war
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
@@ -0,0 +1,203 @@
|
||||
# apes-Authon — 账权独立服务
|
||||
|
||||
> 从 saas-service(账权平台)提取的纯净认证/授权/用户/角色/权限/多租户体系
|
||||
> 目标:作为独立微服务运行,为所有业务系统提供统一的账权能力
|
||||
|
||||
## 项目背景
|
||||
|
||||
本项目源自 `saas-service`(账权平台)单体应用,经过耦合度分析确认账权模块与业务模块零直接 Service 调用,具备独立服务化条件。本仓库是提取后的纯净账权代码,不包含任何业务逻辑(溯源、称重、水肥、巡检、维修、农大同步等)。
|
||||
|
||||
### 提取依据
|
||||
|
||||
- AuthContext 被 52 个文件 / 111 处引用,但业务 Service → 账权 Service 直接调用为 **0 个**
|
||||
- 账权模块仅通过 ThreadLocal(AuthContext)与业务模块间接耦合
|
||||
- 新增业务模块(如巡检、维修)均不直接调用账权 Service,验证了独立服务化的可行性
|
||||
|
||||
## 技术栈
|
||||
|
||||
| 组件 | 版本 | 用途 |
|
||||
|------|------|------|
|
||||
| Spring Boot | 2.2.1.RELEASE | Web 框架 |
|
||||
| Java | 11 | 运行时 |
|
||||
| MyBatis Plus | 3.5.7 | ORM |
|
||||
| dynamic-datasource | 3.6.1 | 多租户数据源切换 |
|
||||
| Redisson | 3.35.0 | Redis 客户端 / 分布式锁 |
|
||||
| Hutool | 5.8.16 | 通用工具 |
|
||||
| apes-commons | 0.0.7-SNAPSHOT | 认证核心(AuthContext / @Login / Res / DbEntity) |
|
||||
|
||||
## 代码结构
|
||||
|
||||
```
|
||||
src/main/java/cn/apes/
|
||||
├── AuthonApplication.java # 主启动类
|
||||
└── cloud/
|
||||
├── controller/ # 11 个 Controller
|
||||
│ ├── UserController.java # 用户认证(登录/注册/改密/多企业切换)
|
||||
│ ├── PermissionController.java # 权限管理(菜单/权限码/角色/成员角色)
|
||||
│ ├── AccessTokenController.java # 外部 API Token 管理
|
||||
│ ├── CustomerController.java # 客户/企业管理
|
||||
│ ├── CustomerPackageController.java # 客户套餐管理
|
||||
│ ├── AppController.java # 应用管理
|
||||
│ ├── SysOrganizationController.java # 组织架构
|
||||
│ ├── SysPackagePlanController.java # 套餐方案
|
||||
│ ├── SysQuotaController.java # 配额模板
|
||||
│ ├── SysOperationLogController.java # 操作日志
|
||||
│ └── UserPreferenceController.java # 用户偏好
|
||||
├── domain/
|
||||
│ ├── entity/ # 23 个实体类
|
||||
│ ├── dto/ # 12 个 DTO(含公共 PageDTO)
|
||||
│ ├── vo/ # 3 个 VO
|
||||
│ └── huoban/ # 11 个伙伴云 API 模型(SSO 依赖)
|
||||
├── service/ # 6 个 Service 接口
|
||||
│ └── impl/ # 16 个 Service 实现
|
||||
├── mapper/ # 23 个 Mapper
|
||||
├── config/ # 5 个配置类
|
||||
│ ├── AccessTokenFilterConfig.java # Token 过滤器注册
|
||||
│ ├── DataSourceHeaderAspect.java # 多租户数据源 AOP 切面
|
||||
│ ├── TenantSource.java # @TenantSource 注解
|
||||
│ ├── HbTokenContext.java # 伙伴云 Token ThreadLocal
|
||||
│ └── SiteConfig.java # 站点配置
|
||||
├── filter/
|
||||
│ └── AccessTokenFilter.java # 外部 API 鉴权过滤器
|
||||
└── util/
|
||||
├── OperationLogUtil.java # 操作日志工具
|
||||
└── RsaUtil.java # RSA 加解密工具
|
||||
```
|
||||
|
||||
## 模块说明
|
||||
|
||||
### 1. 用户认证
|
||||
|
||||
- **密码登录**:`UserController.loginPwd()` → `UserInfoServiceImpl` → Redis 会话
|
||||
- **多企业切换**:`UserController.selectCustomer()` → 切换 Redis 中的企业上下文
|
||||
- **企业认证**:`UserController.certifyEnterprise()` → 提交企业资质
|
||||
- **注册/改密**:`UserController.register()` / `UserController.updatePwd()`
|
||||
|
||||
### 2. RBAC 权限模型
|
||||
|
||||
```
|
||||
AppInfo(应用)
|
||||
└── SysMenu(菜单)── SysPermission(权限码)
|
||||
└── SysRole(角色)── SysRolePermission(角色-权限关联)
|
||||
└── SysMemberRole(成员-角色关联)
|
||||
```
|
||||
|
||||
- 菜单树:`PermissionController.menuTree()`
|
||||
- 权限码:`PermissionController.permissionCodes()`
|
||||
- 角色管理:`PermissionController` 的 role CRUD
|
||||
- 成员角色:`PermissionController` 的 member-role 分配
|
||||
|
||||
### 3. 多租户管理
|
||||
|
||||
- **数据源切换**:`@TenantSource` 注解 + `DataSourceHeaderAspect` AOP,从 `X-Tenant-ID` 请求头读取数据源标识
|
||||
- **租户隔离**:业务数据通过 `AuthContext.getLoginInfo().getCustomer().getId()` 获取 customerId 过滤
|
||||
|
||||
### 4. 外部 API 鉴权
|
||||
|
||||
- `AccessTokenFilter`(order=1)拦截所有请求
|
||||
- 校验 `X-Access-Token` / `Bearer` Token
|
||||
- 校验通过后将用户/企业信息写入 Redis,使 `@Login` AOP 正常工作
|
||||
|
||||
### 5. SSO 单点登录
|
||||
|
||||
- 伙伴云 SSO V1:`SsoServiceImpl` → HMAC-SHA256 签名 → 伙伴云 `/sso/get_token`
|
||||
- 伙伴云 SSO V2:`Sso2ServiceImpl` → 同上,不同 baseUrl
|
||||
|
||||
### 6. 套餐与配额
|
||||
|
||||
```
|
||||
SysPackagePlan(套餐方案)── SysPackagePlanPermission(套餐-权限)
|
||||
└── SysPackagePlanQuota(套餐-配额)
|
||||
CustomerPackage(客户套餐)── CustomerPackageQuota(客户配额)
|
||||
└── CustomerPackageExtendApply(延期申请)
|
||||
SysQuota(配额模板)
|
||||
```
|
||||
|
||||
## 外部依赖
|
||||
|
||||
### apes-commons JAR
|
||||
|
||||
本服务依赖 `cn.apes:apes-commons:0.0.7-SNAPSHOT`,提供以下核心类:
|
||||
|
||||
| 类 | 说明 |
|
||||
|----|------|
|
||||
| `AuthContext` | ThreadLocal 认证上下文,存储 UserSession |
|
||||
| `UserSession` | 会话对象(LoginUser + LoginCustomer) |
|
||||
| `LoginUser` | 登录用户信息 |
|
||||
| `LoginCustomer` | 登录客户/企业信息 |
|
||||
| `@Login` | 方法级注解,AOP 自动注入登录信息 |
|
||||
| `Res` | 统一 API 响应包装 |
|
||||
| `DbEntity` | 基础实体(id / createTime / updateTime / isDel) |
|
||||
|
||||
**安装方式**:将 `apes-commons-0.0.7-SNAPSHOT.jar` 安装到本地 Maven 仓库:
|
||||
|
||||
```bash
|
||||
mvn install:install-file \
|
||||
-Dfile=apes-commons-0.0.7-SNAPSHOT.jar \
|
||||
-DgroupId=cn.apes \
|
||||
-DartifactId=apes-commons \
|
||||
-Dversion=0.0.7-SNAPSHOT \
|
||||
-Dpackaging=jar
|
||||
```
|
||||
|
||||
## 启动方式
|
||||
|
||||
```bash
|
||||
# 1. 安装 apes-commons JAR
|
||||
mvn install:install-file -Dfile=apes-commons-0.0.7-SNAPSHOT.jar ...
|
||||
|
||||
# 2. 编译打包
|
||||
mvn clean package -DskipTests
|
||||
|
||||
# 3. 运行
|
||||
java -jar target/apes-authon.jar
|
||||
```
|
||||
|
||||
服务默认端口 `8090`,context-path `/authon`。
|
||||
|
||||
## 待完成事项
|
||||
|
||||
### Phase 1: 验证编译(当前)
|
||||
- [ ] 安装 apes-commons JAR 后验证编译通过
|
||||
- [ ] 补充缺失的 MyBatis XML(如有)
|
||||
- [ ] 编写基础单元测试
|
||||
|
||||
### Phase 2: 包名重构
|
||||
- [ ] `cn.apes.cloud` → `cn.apes.authon` 全局包名重构
|
||||
- [ ] 调整 MapperScan 路径
|
||||
- [ ] 更新所有 import
|
||||
|
||||
### Phase 3: SDK 化
|
||||
- [ ] 将 `AuthContext` 改造为可远程调用的 SDK
|
||||
- [ ] 提供 `authon-sdk` 模块供业务系统引用
|
||||
- [ ] Token 校验改为 HTTP API 调用
|
||||
|
||||
### Phase 4: 网关集成
|
||||
- [ ] 接入 API 网关(Spring Cloud Gateway / Nginx)
|
||||
- [ ] 请求头注入认证信息(替代 ThreadLocal)
|
||||
- [ ] 多租户数据源改为网关路由模式
|
||||
|
||||
## 从原项目提取的文件清单
|
||||
|
||||
共提取 **114 个 Java 文件**:
|
||||
|
||||
| 类型 | 数量 |
|
||||
|------|------|
|
||||
| Controller | 11 |
|
||||
| Entity | 23 |
|
||||
| DTO | 12 |
|
||||
| VO | 3 |
|
||||
| Service 接口 | 6 |
|
||||
| Service 实现 | 16 |
|
||||
| Mapper | 23 |
|
||||
| Config | 5 |
|
||||
| Filter | 1 |
|
||||
| Util | 2 |
|
||||
| Huoban DTO | 11 |
|
||||
| 主启动类 | 1 |
|
||||
|
||||
## 关联仓库
|
||||
|
||||
- 源仓库:[apes-Authdata](https://gitea.apescale.com/figmar/apes-Authdata) — 完整单体应用(含业务代码)
|
||||
- 方案文档:`docs/账权模块独立服务化方案.html`(在 apes-Authdata 仓库中)
|
||||
- 源码对比:`docs/源码版本对比分析-20260809.md`(在 apes-Authdata 仓库中)
|
||||
@@ -0,0 +1,144 @@
|
||||
# 账权模块提取说明
|
||||
|
||||
> 提取日期:2026-08-09
|
||||
> 源仓库:apes-Authdata (saas-service)
|
||||
> 目标仓库:apes-Authon
|
||||
|
||||
## 一、提取原则
|
||||
|
||||
1. **纯账权逻辑**:只提取认证、授权、用户、角色、菜单、权限、多租户、套餐、配额、SSO、操作日志相关的代码
|
||||
2. **零业务代码**:不包含溯源(Trace*)、称重(Weight*)、水肥(Fei*)、巡检(Inspection*)、维修(Repair*)、农大同步(Nongda*)、LLM Agent 等任何业务逻辑
|
||||
3. **保留包名**:暂保留 `cn.apes.cloud` 包名以最小化改动,后续 Phase 2 再统一重构为 `cn.apes.authon`
|
||||
4. **保留依赖**:`apes-commons` 外部 JAR 作为核心依赖保留,提供 AuthContext / @Login / Res / DbEntity 等基础设施
|
||||
|
||||
## 二、提取文件清单
|
||||
|
||||
### Controller(11 个)
|
||||
|
||||
| 文件 | 核心功能 |
|
||||
|------|---------|
|
||||
| UserController | 密码登录、注册、改密、用户CRUD、企业认证、多企业切换 |
|
||||
| PermissionController | 菜单树、权限码、角色CRUD、角色权限分配、成员角色管理 |
|
||||
| AccessTokenController | 外部 API Token 的创建/查询/撤销/启用/重新生成 |
|
||||
| CustomerController | 客户/企业CRUD、员工管理、应用关联、SSO配置 |
|
||||
| CustomerPackageController | 客户套餐管理、配额管理、延期申请 |
|
||||
| AppController | 应用CRUD、应用详情(含菜单+权限+关联客户) |
|
||||
| SysOrganizationController | 组织架构CRUD、组织树 |
|
||||
| SysPackagePlanController | 套餐方案CRUD、套餐权限分配 |
|
||||
| SysQuotaController | 配额模板CRUD |
|
||||
| SysOperationLogController | 操作日志查询 |
|
||||
| UserPreferenceController | 用户偏好(UI尺寸)查询/更新 |
|
||||
|
||||
### Entity(23 个)
|
||||
|
||||
UserInfo, SysRole, SysMenu, SysPermission, SysRolePermission, SysMemberRole, SysAccessToken, CustomerInfo, CustomerUser, CustomerApp, CustomerPackage, CustomerPackageQuota, CustomerPackageExtendApply, CustomerQuotaChangeLog, SsoConfig, SysOrganization, SysPackagePlan, SysPackagePlanPermission, SysPackagePlanQuota, SysQuota, UserPreference, SysOperationLog, AppInfo
|
||||
|
||||
### Service 接口(6 个)
|
||||
|
||||
CustomerPackageService, SysAccessTokenService, SysOperationLogService, SysPackagePlanQuotaService, SysPackagePlanService, SysQuotaService
|
||||
|
||||
### Service 实现(16 个)
|
||||
|
||||
PermissionServiceImpl, UserInfoServiceImpl, SysAccessTokenServiceImpl, SsoServiceImpl, Sso2ServiceImpl, CustomerUserServiceImpl, CustomerInfoServiceImpl, CustomerAppServiceImpl, SysOrganizationServiceImpl, SysPackagePlanServiceImpl, CustomerPackageServiceImpl, SysQuotaServiceImpl, SysPackagePlanQuotaServiceImpl, UserPreferenceServiceImpl, SysOperationLogServiceImpl, AppInfoServiceImpl
|
||||
|
||||
### Mapper(23 个)
|
||||
|
||||
对应每个 Entity 各一个 Mapper。
|
||||
|
||||
### Config(5 个)
|
||||
|
||||
| 文件 | 说明 |
|
||||
|------|------|
|
||||
| AccessTokenFilterConfig | 注册 AccessTokenFilter(order=1,拦截 /*) |
|
||||
| DataSourceHeaderAspect | @TenantSource AOP 切面,多租户数据源切换 |
|
||||
| TenantSource | @TenantSource 注解定义 |
|
||||
| HbTokenContext | 伙伴云 Token 的 ThreadLocal 上下文 |
|
||||
| SiteConfig | 站点配置(支付域名、Cookie域名) |
|
||||
|
||||
### Filter(1 个)
|
||||
|
||||
AccessTokenFilter — 外部 API 鉴权(X-Access-Token / Bearer)
|
||||
|
||||
### Util(2 个)
|
||||
|
||||
| 文件 | 说明 |
|
||||
|------|------|
|
||||
| OperationLogUtil | 操作日志工具(@PostConstruct 抓 bean + AuthContext 获取操作人) |
|
||||
| RsaUtil | RSA 加解密(密码加密/解密) |
|
||||
|
||||
### DTO/VO(15 个)
|
||||
|
||||
LoginDTO, RegisterDTO, PwdDTO, UserSearchDTO, RoleSearchDTO, SysRoleDTO, CustomerSearchDTO, EnterpriseCertifyDTO, SelectCustomerDTO, PageDTO, RelationDTO, AppSearchDTO, CustomerPackageVO, CustomerPackageExtendApplyVO, CustomerAppVO
|
||||
|
||||
### Huoban DTO(11 个)
|
||||
|
||||
UpsertOne, DataCreate, DataUpdate, DataFilter, DataFilterCondition, DataUpsert, BulkDel, TableSub, TableColumn, TableInfo, CategoryConfig — 伙伴云 API 请求/响应模型,被 CustomerInfoServiceImpl 用于同步客户数据到伙伴云
|
||||
|
||||
## 三、未提取的文件(排除原因)
|
||||
|
||||
| 文件 | 排除原因 |
|
||||
|------|---------|
|
||||
| CustomerUiConfigServiceImpl | 依赖 `cn.apes.cloud.domain.weight.CustomerUiConfig`(weight 业务包) |
|
||||
| CommonController | 混合业务(文件上传等),非纯账权 |
|
||||
| WeightController | 称重业务 |
|
||||
| TrackingConfigController | 追踪配置业务 |
|
||||
| 所有 Trace*/Weight*/Fei*/Llm*/Nongda* 文件 | 业务模块 |
|
||||
| RedissonConfiguration | 通用配置,需按实际部署环境重新配置 |
|
||||
| MybatisPlusConfig | 通用配置,需按实际部署环境重新配置 |
|
||||
| OssConfiguration | OSS 配置,账权服务不需要 |
|
||||
| WebSocketConfig | WebSocket 配置,账权服务不需要 |
|
||||
| RestTemplateConfiguration | HTTP 客户端配置,按需添加 |
|
||||
| SchedulingConfig | 定时任务配置,按需添加 |
|
||||
| JacksonAutoConfiguration | Jackson 配置,Spring Boot 自动配置 |
|
||||
|
||||
## 四、外部依赖分析
|
||||
|
||||
### apes-commons 0.0.7-SNAPSHOT
|
||||
|
||||
提供以下核心类(全部为接口级别依赖,无源码):
|
||||
|
||||
```
|
||||
cn.apes.commons.Res → 统一 API 响应包装
|
||||
cn.apes.commons.auth.AuthContext → ThreadLocal 认证上下文
|
||||
cn.apes.commons.auth.Login → @Login 注解(方法级,AOP 自动注入)
|
||||
cn.apes.commons.auth.LoginUser → 登录用户信息
|
||||
cn.apes.commons.auth.LoginCustomer → 登录客户/企业信息
|
||||
cn.apes.commons.auth.UserSession → 会话对象(user + customer)
|
||||
cn.apes.commons.domain.DbEntity → 基础实体(id/createTime/updateTime/isDel)
|
||||
```
|
||||
|
||||
### 第三方依赖
|
||||
|
||||
| 依赖 | 用途 |
|
||||
|------|------|
|
||||
| spring-boot-starter-web | REST API |
|
||||
| spring-boot-starter-aop | @TenantSource 切面 / @Login AOP |
|
||||
| spring-boot-starter-data-redis | Redis 会话管理 |
|
||||
| mybatis-plus-boot-starter | ORM |
|
||||
| dynamic-datasource-spring-boot-starter | 多租户数据源 |
|
||||
| mysql-connector-java | MySQL 驱动 |
|
||||
| lombok | 简化代码 |
|
||||
| hutool-all | 通用工具(HMAC 签名、HTTP 调用等) |
|
||||
| redisson | Redis 客户端 |
|
||||
| fastjson | JSON 序列化 |
|
||||
|
||||
## 五、耦合度验证
|
||||
|
||||
提取过程中验证了以下耦合点:
|
||||
|
||||
1. **业务 Service → 账权 Service 直接调用:0 个** ✅
|
||||
2. **业务 Controller → 账权 Controller 直接调用:0 个** ✅
|
||||
3. **账权 Service → 业务 Mapper 直接调用:0 个** ✅
|
||||
4. **唯一的业务包交叉引用**:`CustomerInfoServiceImpl` → `cn.apes.cloud.domain.huoban.UpsertOne`
|
||||
- 解决方案:将 huoban DTO 包一起提取(11 个纯 DTO 文件,无业务逻辑)
|
||||
5. **外部 JAR 依赖**:`apes-commons` 提供 AuthContext 等核心类
|
||||
- 解决方案:保留为 Maven 依赖,后续 Phase 3 改造为 SDK
|
||||
|
||||
## 六、后续路线图
|
||||
|
||||
| 阶段 | 目标 | 状态 |
|
||||
|------|------|------|
|
||||
| Phase 1 | 验证编译通过 | 待执行 |
|
||||
| Phase 2 | 包名重构 cn.apes.cloud → cn.apes.authon | 待启动 |
|
||||
| Phase 3 | SDK 化(AuthContext → 远程调用) | 待设计 |
|
||||
| Phase 4 | 网关集成(ThreadLocal → HTTP Header) | 待设计 |
|
||||
@@ -0,0 +1,162 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>cn.apes</groupId>
|
||||
<artifactId>apes-authon</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
<name>apes-Authon</name>
|
||||
<description>账权独立服务 — 从 saas-service 提取的纯净认证/授权/用户/角色/权限/多租户体系</description>
|
||||
|
||||
<properties>
|
||||
<java.version>11</java.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
|
||||
<spring-boot.version>2.2.1.RELEASE</spring-boot.version>
|
||||
<lombok.version>1.18.36</lombok.version>
|
||||
<mysql-connector-java.version>8.0.15</mysql-connector-java.version>
|
||||
<mybatis-plus-boot-starter.version>3.5.7</mybatis-plus-boot-starter.version>
|
||||
<redisson.version>3.35.0</redisson.version>
|
||||
<hutool.version>5.8.16</hutool.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-dependencies</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<!-- Spring Boot Web -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<!-- Spring Boot AOP -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
<!-- Spring Boot Data Redis -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- MyBatis Plus -->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
<version>${mybatis-plus-boot-starter.version}</version>
|
||||
</dependency>
|
||||
<!-- Dynamic DataSource -->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
|
||||
<version>3.6.1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- MySQL Driver -->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>${mysql-connector-java.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Lombok -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Hutool -->
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>${hutool.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Redisson -->
|
||||
<dependency>
|
||||
<groupId>org.redisson</groupId>
|
||||
<artifactId>redisson</artifactId>
|
||||
<version>${redisson.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Fastjson -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.83</version>
|
||||
</dependency>
|
||||
|
||||
<!-- apes-commons (外部 JAR,需手动安装到本地 Maven 仓库) -->
|
||||
<dependency>
|
||||
<groupId>cn.apes</groupId>
|
||||
<artifactId>apes-commons</artifactId>
|
||||
<version>0.0.7-SNAPSHOT</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- Test -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>apes-authon</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<configuration>
|
||||
<source>11</source>
|
||||
<target>11</target>
|
||||
<encoding>UTF-8</encoding>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
<configuration>
|
||||
<mainClass>cn.apes.AuthonApplication</mainClass>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,30 @@
|
||||
package cn.apes;
|
||||
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
/**
|
||||
* 账权独立服务 — 从 saas-service 提取的纯净认证/授权/用户/角色/权限/多租户体系
|
||||
*
|
||||
* 本服务包含:
|
||||
* - 用户认证(密码登录 / Redis 会话 / Token 管理)
|
||||
* - RBAC 权限模型(菜单 / 权限码 / 角色 / 成员角色)
|
||||
* - 多租户管理(客户/企业 / 组织架构 / 数据源切换)
|
||||
* - 套餐与配额管理
|
||||
* - SSO 单点登录(伙伴云)
|
||||
* - 操作日志
|
||||
* - 用户偏好
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@EnableAsync
|
||||
@EnableScheduling
|
||||
@MapperScan("cn.apes.cloud.mapper")
|
||||
public class AuthonApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AuthonApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package cn.apes.cloud.config;
|
||||
|
||||
import cn.apes.cloud.filter.AccessTokenFilter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import javax.servlet.DispatcherType;
|
||||
|
||||
/**
|
||||
* AccessToken 过滤器注册
|
||||
* 注册为最高优先级,确保在 Spring 其他拦截之前执行
|
||||
*/
|
||||
@Configuration
|
||||
public class AccessTokenFilterConfig {
|
||||
|
||||
@Autowired
|
||||
private AccessTokenFilter accessTokenFilter;
|
||||
|
||||
@Bean
|
||||
public FilterRegistrationBean<AccessTokenFilter> accessTokenFilterRegistration() {
|
||||
FilterRegistrationBean<AccessTokenFilter> registration = new FilterRegistrationBean<>();
|
||||
registration.setFilter(accessTokenFilter);
|
||||
registration.addUrlPatterns("/*");
|
||||
registration.setOrder(1); // 最高优先级
|
||||
registration.setDispatcherTypes(DispatcherType.REQUEST);
|
||||
registration.setName("accessTokenFilter");
|
||||
return registration;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package cn.apes.cloud.config;
|
||||
|
||||
|
||||
import cn.apes.commons.Res;
|
||||
import cn.apes.commons.auth.AuthContext;
|
||||
import cn.apes.commons.auth.Login;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.redisson.api.RBucket;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@Aspect
|
||||
@Component
|
||||
@Order(1)
|
||||
public class DataSourceHeaderAspect {
|
||||
|
||||
|
||||
List<String> heads = CollUtil.newArrayList("user", "zx","plant");
|
||||
|
||||
@Around("@within(tenantSource)")
|
||||
public Object clazz(ProceedingJoinPoint pjp, TenantSource tenantSource) throws Throwable {
|
||||
return exc(pjp, tenantSource);
|
||||
}
|
||||
|
||||
@Around("@annotation(tenantSource)")
|
||||
public Object menthod(ProceedingJoinPoint pjp, TenantSource tenantSource) throws Throwable {
|
||||
return exc(pjp, tenantSource);
|
||||
}
|
||||
|
||||
Object exc(ProceedingJoinPoint pjp, TenantSource tenantSource) throws Throwable {
|
||||
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
||||
// 保留 AccessToken 过滤器已设置的认证上下文
|
||||
if (request.getAttribute("accessTokenVerified") == null) {
|
||||
AuthContext.clean();
|
||||
}
|
||||
String head = request.getHeader("X-Tenant-ID");
|
||||
if (StrUtil.isEmpty(head)) {
|
||||
head="user";
|
||||
}
|
||||
if(!heads.contains(head)) {
|
||||
throw new RuntimeException("数据源ID有误");
|
||||
}
|
||||
DynamicDataSourceContextHolder.push(head);
|
||||
|
||||
return pjp.proceed();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package cn.apes.cloud.config;
|
||||
|
||||
|
||||
public class HbTokenContext {
|
||||
|
||||
private static final ThreadLocal<String> LOGIN_THREAD_LOCAL = new ThreadLocal<>();
|
||||
|
||||
/**
|
||||
* 设置伙伴云token
|
||||
*
|
||||
* @param loginInfo 登录信息
|
||||
*/
|
||||
public static void setHbToken(String loginInfo) {
|
||||
LOGIN_THREAD_LOCAL.set(loginInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录token
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getHbToken() {
|
||||
return LOGIN_THREAD_LOCAL.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空登录用户信息
|
||||
*/
|
||||
public static void clean() {
|
||||
LOGIN_THREAD_LOCAL.remove();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package cn.apes.cloud.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Data
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "sit.config")
|
||||
public class SiteConfig {
|
||||
|
||||
@Value("${sit.config.payment.domain}")
|
||||
private String paymentDomain;
|
||||
|
||||
@Value("${sit.config.payment.cookieDomain}")
|
||||
private String cookieDomain;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package cn.apes.cloud.config;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Target({ElementType.METHOD, ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface TenantSource {
|
||||
String value() default "user";
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
package cn.apes.cloud.controller;
|
||||
|
||||
import cn.apes.cloud.domain.entity.SysAccessToken;
|
||||
import cn.apes.cloud.service.SysAccessTokenService;
|
||||
import cn.apes.cloud.util.OperationLogUtil;
|
||||
import cn.apes.commons.auth.AuthContext;
|
||||
import cn.apes.commons.auth.Login;
|
||||
import cn.apes.commons.auth.LoginCustomer;
|
||||
import cn.apes.commons.auth.UserSession;
|
||||
import cn.apes.commons.Res;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* AccessToken 管理接口
|
||||
*/
|
||||
@Login
|
||||
@RestController
|
||||
@RequestMapping("/sysAccessToken")
|
||||
public class AccessTokenController {
|
||||
|
||||
@Autowired
|
||||
private SysAccessTokenService accessTokenService;
|
||||
|
||||
/**
|
||||
* 创建 AccessToken
|
||||
*/
|
||||
@PostMapping("/create")
|
||||
public Res create(@RequestBody Map<String, Object> params) {
|
||||
UserSession authUserInfo = AuthContext.getLoginInfo();
|
||||
LoginCustomer customer = authUserInfo.getCustomer();
|
||||
if (customer == null || customer.getId() == null) {
|
||||
return Res.fail("未找到当前登录客户信息");
|
||||
}
|
||||
|
||||
SysAccessToken record = new SysAccessToken();
|
||||
record.setCustomerId(customer.getId());
|
||||
record.setName((String) params.get("name"));
|
||||
record.setScope(params.get("scope") != null ? (String) params.get("scope") : "*");
|
||||
record.setWhitelistIps(params.get("whitelistIps") != null ? (String) params.get("whitelistIps") : "");
|
||||
record.setStatus(1);
|
||||
|
||||
if (params.get("expireTime") != null) {
|
||||
try {
|
||||
record.setExpireTime(new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse((String) params.get("expireTime")));
|
||||
} catch (Exception e) {
|
||||
return Res.fail("过期时间格式错误,应为 yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
}
|
||||
|
||||
String token = accessTokenService.generateToken();
|
||||
record.setToken(token);
|
||||
record.setCreateBy(authUserInfo.getUser() != null ? authUserInfo.getUser().getId() : null);
|
||||
accessTokenService.save(record);
|
||||
|
||||
OperationLogUtil.log("AccessToken管理", "创建", "创建AccessToken[" + record.getName() + "]");
|
||||
|
||||
// 返回完整 Token(只在创建时展示一次)
|
||||
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("id", record.getId());
|
||||
result.put("name", record.getName());
|
||||
result.put("token", token);
|
||||
result.put("customerId", record.getCustomerId());
|
||||
result.put("scope", record.getScope());
|
||||
result.put("expireTime", record.getExpireTime() != null ? sdf.format(record.getExpireTime()) : null);
|
||||
result.put("message", "Token 仅在创建时显示一次,请妥善保存");
|
||||
return Res.success(result);
|
||||
}
|
||||
|
||||
private Long parseId(Map<String, Object> params) {
|
||||
Object val = params.get("id");
|
||||
if (val == null) return null;
|
||||
return Long.parseLong(val.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询列表
|
||||
*/
|
||||
@PostMapping("/page")
|
||||
public Res page(@RequestBody Map<String, Object> params) {
|
||||
UserSession authUserInfo = AuthContext.getLoginInfo();
|
||||
LoginCustomer customer = authUserInfo.getCustomer();
|
||||
if (customer == null || customer.getId() == null) {
|
||||
return Res.fail("未找到当前登录客户信息");
|
||||
}
|
||||
|
||||
int pageIndex = params.get("pageIndex") != null ? Integer.parseInt(params.get("pageIndex").toString()) : 1;
|
||||
int pageSize = params.get("pageSize") != null ? Integer.parseInt(params.get("pageSize").toString()) : 10;
|
||||
|
||||
LambdaQueryWrapper<SysAccessToken> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(SysAccessToken::getCustomerId, customer.getId());
|
||||
wrapper.orderByDesc(SysAccessToken::getCreateTime);
|
||||
|
||||
Page<SysAccessToken> page = accessTokenService.page(new Page<>(pageIndex, pageSize), wrapper);
|
||||
|
||||
// 脱敏:不返回完整 token
|
||||
for (SysAccessToken item : page.getRecords()) {
|
||||
if (item.getToken() != null && item.getToken().length() > 8) {
|
||||
item.setToken(item.getToken().substring(0, 6) + "****" + item.getToken().substring(item.getToken().length() - 2));
|
||||
}
|
||||
}
|
||||
|
||||
return Res.success(page);
|
||||
}
|
||||
|
||||
/**
|
||||
* 撤销 Token
|
||||
*/
|
||||
@PostMapping("/revoke")
|
||||
public Res revoke(@RequestBody Map<String, Object> params) {
|
||||
Long id = parseId(params);
|
||||
if (id == null) return Res.fail("缺少 id 参数");
|
||||
SysAccessToken record = accessTokenService.getById(id);
|
||||
String name = record != null ? record.getName() : "id=" + id;
|
||||
accessTokenService.revoke(id);
|
||||
OperationLogUtil.log("AccessToken管理", "停用", "停用AccessToken[" + name + "]");
|
||||
return Res.success("已撤销");
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用 Token
|
||||
*/
|
||||
@PostMapping("/enable")
|
||||
public Res enable(@RequestBody Map<String, Object> params) {
|
||||
Long id = parseId(params);
|
||||
if (id == null) return Res.fail("缺少 id 参数");
|
||||
SysAccessToken record = accessTokenService.getById(id);
|
||||
String name = record != null ? record.getName() : "id=" + id;
|
||||
accessTokenService.enable(id);
|
||||
OperationLogUtil.log("AccessToken管理", "启用", "启用AccessToken[" + name + "]");
|
||||
return Res.success("已启用");
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新生成 Token
|
||||
*/
|
||||
@PostMapping("/regenerate")
|
||||
public Res regenerate(@RequestBody Map<String, Object> params) {
|
||||
Long id = parseId(params);
|
||||
if (id == null) return Res.fail("缺少 id 参数");
|
||||
SysAccessToken record = accessTokenService.getById(id);
|
||||
String name = record != null ? record.getName() : "id=" + id;
|
||||
String newToken = accessTokenService.regenerate(id);
|
||||
OperationLogUtil.log("AccessToken管理", "重新生成", "重新生成AccessToken[" + name + "]");
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("token", newToken);
|
||||
result.put("message", "新 Token 已生成,旧 Token 立即失效");
|
||||
return Res.success(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除 Token
|
||||
*/
|
||||
@PostMapping("/delete")
|
||||
public Res delete(@RequestBody Map<String, Object> params) {
|
||||
Long id = parseId(params);
|
||||
if (id == null) return Res.fail("缺少 id 参数");
|
||||
SysAccessToken record = accessTokenService.getById(id);
|
||||
String name = record != null ? record.getName() : "id=" + id;
|
||||
accessTokenService.removeById(id);
|
||||
OperationLogUtil.log("AccessToken管理", "删除", "删除AccessToken[" + name + "]");
|
||||
return Res.success("已删除");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
package cn.apes.cloud.controller;
|
||||
|
||||
import cn.apes.commons.Res;
|
||||
import cn.apes.commons.auth.Login;
|
||||
import cn.apes.cloud.config.TenantSource;
|
||||
import cn.apes.cloud.domain.dto.AppSearchDTO;
|
||||
import cn.apes.cloud.domain.entity.AppInfo;
|
||||
import cn.apes.cloud.domain.entity.SysMenu;
|
||||
import cn.apes.cloud.domain.entity.SysPermission;
|
||||
import cn.apes.cloud.domain.entity.CustomerInfo;
|
||||
import cn.apes.cloud.domain.entity.CustomerApp;
|
||||
import cn.apes.cloud.service.impl.AppInfoServiceImpl;
|
||||
import cn.apes.cloud.service.impl.CustomerAppServiceImpl;
|
||||
import cn.apes.cloud.service.impl.CustomerInfoServiceImpl;
|
||||
import cn.apes.cloud.mapper.SysMenuMapper;
|
||||
import cn.apes.cloud.mapper.SysPermissionMapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Login
|
||||
@RestController
|
||||
@TenantSource
|
||||
@RequestMapping("/app")
|
||||
public class AppController {
|
||||
@Autowired
|
||||
AppInfoServiceImpl appInfoService;
|
||||
|
||||
@Autowired
|
||||
CustomerAppServiceImpl customerAppService;
|
||||
|
||||
@Autowired
|
||||
CustomerInfoServiceImpl customerInfoService;
|
||||
|
||||
@Autowired
|
||||
SysMenuMapper sysMenuMapper;
|
||||
|
||||
@Autowired
|
||||
SysPermissionMapper sysPermissionMapper;
|
||||
|
||||
/**
|
||||
* 分页查询应用列表
|
||||
*/
|
||||
@PostMapping("/pageApp")
|
||||
public Res pageApp(@RequestBody AppSearchDTO searchDTO) {
|
||||
return appInfoService.pageApp(searchDTO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增/编辑应用
|
||||
*/
|
||||
@PostMapping("/saveApp")
|
||||
public Res saveApp(@RequestBody AppInfo appInfo) {
|
||||
return appInfoService.saveApp(appInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除应用
|
||||
*/
|
||||
@PostMapping("/deleteApp")
|
||||
public Res deleteApp(@RequestBody AppInfo appInfo) {
|
||||
return appInfoService.deleteApp(appInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取应用详情(基本信息 + 菜单 + 权限 + 关联客户)
|
||||
*/
|
||||
@PostMapping("/getAppDetail")
|
||||
public Res getAppDetail(@RequestBody AppInfo param) {
|
||||
String appKey = param.getAppKey();
|
||||
AppInfo appInfo = appInfoService.getById(appKey);
|
||||
if (appInfo == null) {
|
||||
return Res.fail("应用不存在");
|
||||
}
|
||||
|
||||
// 隐藏敏感字段
|
||||
appInfo.setRemark(null);
|
||||
|
||||
// 查询关联的菜单列表
|
||||
List<SysMenu> menuList = sysMenuMapper.selectList(
|
||||
new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getAppName, appKey)
|
||||
);
|
||||
|
||||
// 查询关联的权限列表
|
||||
List<SysPermission> permissionList = sysPermissionMapper.selectList(
|
||||
new LambdaQueryWrapper<SysPermission>().eq(SysPermission::getAppName, appKey)
|
||||
);
|
||||
|
||||
// 查询关联的客户列表
|
||||
List<Long> customerIds = customerAppService.getCustomerIdsByAppKey(appKey);
|
||||
List<CustomerInfo> customerList = new ArrayList<>();
|
||||
if (!customerIds.isEmpty()) {
|
||||
customerList = customerInfoService.listByIds(customerIds);
|
||||
}
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("appInfo", appInfo);
|
||||
result.put("menuList", menuList);
|
||||
result.put("permissionList", permissionList);
|
||||
result.put("customerList", customerList);
|
||||
|
||||
return Res.success(result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
package cn.apes.cloud.controller;
|
||||
|
||||
import cn.apes.commons.Res;
|
||||
import cn.apes.commons.auth.AuthContext;
|
||||
import cn.apes.commons.auth.Login;
|
||||
import cn.apes.commons.auth.LoginCustomer;
|
||||
import cn.apes.cloud.config.TenantSource;
|
||||
import cn.apes.cloud.domain.dto.CustomerSearchDTO;
|
||||
import cn.apes.cloud.domain.entity.CustomerInfo;
|
||||
import cn.apes.cloud.domain.entity.SsoConfig;
|
||||
import cn.apes.cloud.service.impl.CustomerAppServiceImpl;
|
||||
import cn.apes.cloud.service.impl.CustomerInfoServiceImpl;
|
||||
import cn.apes.cloud.service.impl.CustomerUserServiceImpl;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@Login
|
||||
@RestController
|
||||
@TenantSource
|
||||
@RequestMapping("/customer")
|
||||
public class CustomerController {
|
||||
|
||||
@Autowired
|
||||
CustomerInfoServiceImpl customerInfoService;
|
||||
|
||||
@Autowired
|
||||
CustomerUserServiceImpl customerUserService;
|
||||
|
||||
@Autowired
|
||||
CustomerAppServiceImpl customerAppService;
|
||||
|
||||
@PostMapping("/pageCustomer")
|
||||
public Res pageCustomer(@RequestBody CustomerSearchDTO searchDTO) {
|
||||
return customerInfoService.pageCustomer(searchDTO);
|
||||
}
|
||||
|
||||
@GetMapping("/getCustomerDetail")
|
||||
public Res getCustomerDetail(@RequestParam("id") Long id) {
|
||||
return customerInfoService.getCustomerDetail(id);
|
||||
}
|
||||
|
||||
@GetMapping("/addUser")
|
||||
public Res addUser(Long customerId, Long userId) {
|
||||
return customerUserService.addUser(customerId, userId);
|
||||
}
|
||||
|
||||
@GetMapping("/delUser")
|
||||
public Res delUser(Long customerId, Long userId) {
|
||||
return customerUserService.delUser(customerId, userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询员工列表(customerId 从登录上下文获取)
|
||||
*/
|
||||
@PostMapping("/employee/page")
|
||||
public Res pageEmployee(@RequestBody JSONObject data) {
|
||||
int pageIndex = data.getIntValue("pageIndex");
|
||||
int pageSize = data.getIntValue("pageSize");
|
||||
Long orgId = data.getLong("orgId");
|
||||
if (pageIndex <= 0) pageIndex = 1;
|
||||
if (pageSize <= 0) pageSize = 10;
|
||||
return customerUserService.pageEmployee(pageIndex, pageSize, orgId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取员工详情(编辑用)
|
||||
*/
|
||||
@GetMapping("/employee/detail")
|
||||
public Res getEmployeeDetail(@RequestParam("userId") Long userId) {
|
||||
return customerUserService.getEmployeeDetail(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新员工信息
|
||||
*/
|
||||
@PostMapping("/employee/update")
|
||||
public Res updateEmployee(@RequestBody JSONObject data) {
|
||||
Long userId = data.getLong("userId");
|
||||
Long orgId = data.getLong("orgId");
|
||||
String name = data.getString("name");
|
||||
String title = data.getString("title");
|
||||
String position = data.getString("position");
|
||||
String appIds = data.getString("appIds");
|
||||
return customerUserService.updateEmployee(userId, orgId, name, title, position, appIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增/编辑客户
|
||||
*/
|
||||
@PostMapping("/saveCustomer")
|
||||
public Res saveCustomer(@RequestBody CustomerInfo customerInfo) {
|
||||
return customerInfoService.saveCustomer(customerInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除客户
|
||||
*/
|
||||
@PostMapping("/deleteCustomer")
|
||||
public Res deleteCustomer(@RequestBody CustomerInfo customerInfo) {
|
||||
return customerInfoService.deleteCustomer(customerInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询当前登录客户已关联的应用列表(从登录上下文获取 customerId)
|
||||
*/
|
||||
@GetMapping("/getMyApps")
|
||||
public Res getMyApps() {
|
||||
LoginCustomer customer = AuthContext.getLoginInfo().getCustomer();
|
||||
if (customer == null || customer.getId() == null) {
|
||||
return Res.fail("未找到当前登录客户信息");
|
||||
}
|
||||
return Res.success(customerAppService.getMyAppsWithSource(customer.getId()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询指定客户已关联的应用列表(管理端用)
|
||||
*/
|
||||
@GetMapping("/getCustomerApps")
|
||||
public Res getCustomerApps(@RequestParam("customerId") Long customerId) {
|
||||
return Res.success(customerAppService.getApps(customerId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 关联应用给客户
|
||||
*/
|
||||
@PostMapping("/addCustomerApp")
|
||||
public Res addCustomerApp(@RequestBody JSONObject data) {
|
||||
Long customerId = data.getLong("customerId");
|
||||
String appKey = data.getString("appKey");
|
||||
return customerAppService.addApp(customerId, appKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解绑客户的应用
|
||||
*/
|
||||
@PostMapping("/removeCustomerApp")
|
||||
public Res removeCustomerApp(@RequestBody JSONObject data) {
|
||||
Long customerId = data.getLong("customerId");
|
||||
String appKey = data.getString("appKey");
|
||||
return customerAppService.removeApp(customerId, appKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有应用(用于选择器)
|
||||
*/
|
||||
@GetMapping("/getAllApps")
|
||||
public Res getAllApps() {
|
||||
return Res.success(customerAppService.getAllApps());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取客户SSO配置(公司级别 user_id=0)
|
||||
*/
|
||||
@GetMapping("/getSSOConfig")
|
||||
public Res getSSOConfig(@RequestParam("customerId") Long customerId) {
|
||||
return customerInfoService.getSSOConfig(customerId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存客户SSO配置(公司级别 user_id=0)
|
||||
*/
|
||||
@PostMapping("/saveSSOConfig")
|
||||
public Res saveSSOConfig(@RequestBody SsoConfig ssoConfig) {
|
||||
return customerInfoService.saveSSOConfig(ssoConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新客户状态
|
||||
*/
|
||||
@PostMapping("/updateCustomerStatus")
|
||||
public Res updateCustomerStatus(@RequestBody CustomerInfo customerInfo) {
|
||||
return customerInfoService.updateCustomerStatus(customerInfo.getId(), customerInfo.getCustomerStatus());
|
||||
}
|
||||
|
||||
/**
|
||||
* 审核企业认证(通过/拒绝)
|
||||
*/
|
||||
@PostMapping("/auditCertification")
|
||||
public Res auditCertification(@RequestBody JSONObject data) {
|
||||
Long customerId = data.getLong("customerId");
|
||||
Integer auditStatus = data.getInteger("customerStatus"); // 1=通过, 5=拒绝
|
||||
String auditRemark = data.getString("auditRemark"); // 拒绝原因
|
||||
return customerInfoService.auditCertification(customerId, auditStatus, auditRemark);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 同步全部租户信息到伙伴云(使用 upsetOne 接口)
|
||||
*/
|
||||
@PostMapping("/syncTenantsToHuoban")
|
||||
public Res syncTenantsToHuoban() {
|
||||
return customerInfoService.syncAllTenantsToHuoban();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
package cn.apes.cloud.controller;
|
||||
|
||||
import cn.apes.commons.Res;
|
||||
import cn.apes.commons.auth.AuthContext;
|
||||
import cn.apes.commons.auth.Login;
|
||||
import cn.apes.commons.auth.LoginCustomer;
|
||||
import cn.apes.cloud.domain.entity.CustomerPackage;
|
||||
import cn.apes.cloud.service.CustomerPackageService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@Login
|
||||
@RestController
|
||||
@RequestMapping("/customerPackage")
|
||||
public class CustomerPackageController {
|
||||
|
||||
@Autowired
|
||||
private CustomerPackageService customerPackageService;
|
||||
|
||||
/**
|
||||
* 获取客户的套餐列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public Object list(@RequestParam Long customerId) {
|
||||
return customerPackageService.getCustomerPackages(customerId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增客户套餐
|
||||
*/
|
||||
@PostMapping("/add")
|
||||
public Object add(@RequestBody CustomerPackage customerPackage) {
|
||||
return customerPackageService.addCustomerPackage(customerPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑客户套餐
|
||||
*/
|
||||
@PostMapping("/edit")
|
||||
public Object edit(@RequestBody java.util.Map<String, Object> data) {
|
||||
return customerPackageService.editCustomerPackage(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除客户套餐
|
||||
*/
|
||||
@PostMapping("/delete")
|
||||
public Object delete(@RequestBody CustomerPackage customerPackage) {
|
||||
return customerPackageService.deleteCustomerPackage(customerPackage.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存客户套餐配额
|
||||
*/
|
||||
@PostMapping("/saveQuotas")
|
||||
public Object saveQuotas(@RequestBody java.util.Map<String, Object> data) {
|
||||
Long packageId = data.get("packageId") != null ? Long.parseLong(data.get("packageId").toString()) : null;
|
||||
@SuppressWarnings("unchecked")
|
||||
java.util.Map<String, Object> quotaValues = (java.util.Map<String, Object>) data.get("quotaValues");
|
||||
return customerPackageService.saveCustomerPackageQuotas(packageId, quotaValues);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取客户套餐配额
|
||||
*/
|
||||
@GetMapping("/getQuotas")
|
||||
public Object getQuotas(@RequestParam Long packageId) {
|
||||
return customerPackageService.getCustomerPackageQuotas(packageId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前登录客户的套餐列表(从登录上下文获取 customerId)
|
||||
*/
|
||||
@GetMapping("/myPackages")
|
||||
public Res myPackages() {
|
||||
LoginCustomer customer = AuthContext.getLoginInfo().getCustomer();
|
||||
if (customer == null || customer.getId() == null) {
|
||||
return Res.fail("未找到当前登录客户信息");
|
||||
}
|
||||
return customerPackageService.getMyPackages(customer.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 管理端:查询所有客户的套餐概况
|
||||
*/
|
||||
@PostMapping("/overview")
|
||||
public Object overview(@RequestBody java.util.Map<String, Object> params) {
|
||||
return customerPackageService.getCustomerPackageOverview(params);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 提交套餐延期申请
|
||||
*/
|
||||
@PostMapping("/submitExtendApply")
|
||||
public Object submitExtendApply(@RequestBody java.util.Map<String, Object> params) {
|
||||
params.put("userId", AuthContext.getLoginInfo().getCustomer().getId());
|
||||
return customerPackageService.submitExtendApply(params);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 管理端:查询套餐延期申请记录列表
|
||||
*/
|
||||
@PostMapping("/extendApplyList")
|
||||
public Object extendApplyList(@RequestBody java.util.Map<String, Object> params) {
|
||||
return customerPackageService.getExtendApplyList(params);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 审核延期申请(同意/拒绝)
|
||||
*/
|
||||
@PostMapping("/reviewExtendApply")
|
||||
public Object reviewExtendApply(@RequestBody java.util.Map<String, Object> params) {
|
||||
return customerPackageService.reviewExtendApply(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加客户套餐额度
|
||||
*/
|
||||
@PostMapping("/increaseQuota")
|
||||
public Object increaseQuota(@RequestBody java.util.Map<String, Object> params) {
|
||||
return customerPackageService.increaseQuota(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 减少客户套餐额度
|
||||
*/
|
||||
@PostMapping("/decreaseQuota")
|
||||
public Object decreaseQuota(@RequestBody java.util.Map<String, Object> params) {
|
||||
return customerPackageService.decreaseQuota(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配额变更日志列表
|
||||
*/
|
||||
@GetMapping("/quotaChangeLogs")
|
||||
public Object getQuotaChangeLogs(@RequestParam java.util.Map<String, Object> params) {
|
||||
return customerPackageService.getQuotaChangeLogs(params);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
package cn.apes.cloud.controller;
|
||||
|
||||
import cn.apes.commons.Res;
|
||||
import cn.apes.commons.auth.AuthContext;
|
||||
import cn.apes.commons.auth.UserSession;
|
||||
import cn.apes.cloud.config.TenantSource;
|
||||
import cn.apes.cloud.domain.dto.RoleSearchDTO;
|
||||
import cn.apes.cloud.domain.entity.SysMenu;
|
||||
import cn.apes.cloud.domain.entity.SysPermission;
|
||||
import cn.apes.cloud.domain.entity.SysRole;
|
||||
import cn.apes.cloud.service.impl.PermissionServiceImpl;
|
||||
import cn.apes.commons.auth.Login;
|
||||
import cn.apes.commons.auth.LoginCustomer;
|
||||
import cn.hutool.http.server.HttpServerResponse;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
@Login
|
||||
@RestController
|
||||
@TenantSource
|
||||
@RequestMapping("/permission")
|
||||
public class PermissionController {
|
||||
|
||||
@Autowired
|
||||
PermissionServiceImpl permissionService;
|
||||
|
||||
@GetMapping("/currentMenus")
|
||||
public Res getCurrentMenus() {
|
||||
UserSession authUserInfo = AuthContext.getLoginInfo();
|
||||
return permissionService.getMemberMenus(authUserInfo.getUser().getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定应用的全部菜单树(按用户权限过滤)
|
||||
*/
|
||||
@GetMapping("/getAppMenus")
|
||||
public Res getAppMenus(@RequestParam("appName") String appName) {
|
||||
UserSession authUserInfo = AuthContext.getLoginInfo();
|
||||
return permissionService.getAppMenus(authUserInfo.getUser().getId(), appName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前用户在当前企业的所有权限code,按应用名分组
|
||||
* 返回格式: {"BASE_APP": ["code1", "code2"], "guobang": ["code1"]}
|
||||
*/
|
||||
@GetMapping("/getMyPermissionCodes")
|
||||
public Res getMyPermissionCodes() {
|
||||
UserSession authUserInfo = AuthContext.getLoginInfo();
|
||||
return permissionService.getMyPermissionCodesByApp(authUserInfo.getUser().getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定应用的菜单树(按客户套餐权限过滤)
|
||||
*/
|
||||
@GetMapping("/getPackageAppMenus")
|
||||
public Res getPackageAppMenus(@RequestParam("appName") String appName) {
|
||||
UserSession authUserInfo = AuthContext.getLoginInfo();
|
||||
LoginCustomer customer = authUserInfo.getCustomer();
|
||||
if (customer == null || customer.getId() == null) {
|
||||
return Res.fail("未找到当前登录客户信息");
|
||||
}
|
||||
Long userId = authUserInfo.getUser() != null ? authUserInfo.getUser().getId() : null;
|
||||
if (userId == null) {
|
||||
return Res.fail("未找到当前登录用户信息");
|
||||
}
|
||||
return permissionService.getPackageAppMenus(userId, customer.getId(), appName);
|
||||
}
|
||||
|
||||
// @GetMapping("/getOldMemberMenus")
|
||||
// public Res getOldMemberMenus(@RequestHeader("version") String version){
|
||||
// AuthUserInfo authUserInfo = AuthContext.getLoginInfo();
|
||||
// AppInfo appInfo = AuthContext.getAppInfo();
|
||||
// return permissionService.getOldMemberMenus(authUserInfo.getMemberNo(),appInfo.getAppName(),version);
|
||||
// }
|
||||
|
||||
// @GetMapping("/getRolePermission")
|
||||
// public Res getRolePermission(){
|
||||
// UserSession authUserInfo = AuthContext.getLoginInfo();
|
||||
// return permissionService.getRolePermission(authUserInfo.getUser().getId());
|
||||
// }
|
||||
|
||||
@PostMapping("/saveMenu")
|
||||
public Res saveMenu(@RequestBody SysMenu menu) {
|
||||
return permissionService.saveMenu(menu);
|
||||
}
|
||||
|
||||
@GetMapping("/getAllMenu")
|
||||
public Res getAllMenu(@RequestParam("appName") String appName) {
|
||||
return permissionService.getAllMenu(appName);
|
||||
}
|
||||
|
||||
@PostMapping("/savePermission")
|
||||
public Res savePermission(@RequestBody SysPermission menu) {
|
||||
return permissionService.savePermission(menu);
|
||||
}
|
||||
|
||||
@GetMapping("/getAllPermission")
|
||||
public Res getAllPermission(String appName) {
|
||||
return permissionService.getAllPermission(appName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定套餐下指定应用的权限树(仅包含该套餐拥有的权限)
|
||||
*/
|
||||
@GetMapping("/getPlanPermissionTree")
|
||||
public Res getPlanPermissionTree(@RequestParam("planId") Long planId, @RequestParam("appName") String appName) {
|
||||
return permissionService.getPlanPermissionTree(planId, appName);
|
||||
}
|
||||
|
||||
@PostMapping("/deletePermission")
|
||||
public Res deletePermission(@RequestBody JSONObject data) {
|
||||
Long permissionId = data.getLong("permissionId");
|
||||
return permissionService.deletePermission(permissionId);
|
||||
}
|
||||
|
||||
@PostMapping("/deleteMenu")
|
||||
public Res deleteMenu(@RequestBody JSONObject data) {
|
||||
Long menuId = data.getLong("menuId");
|
||||
return permissionService.deleteMenu(menuId);
|
||||
}
|
||||
|
||||
@PostMapping("/getAllRole")
|
||||
public Res getAllRole(@RequestBody RoleSearchDTO searchDTO) {
|
||||
return permissionService.getAllRole(searchDTO);
|
||||
}
|
||||
|
||||
@PostMapping("/getAllRoleByAppName")
|
||||
public Res getAllRoleByAppName(@RequestBody RoleSearchDTO searchDTO) {
|
||||
return permissionService.getAllRoleByAppName(searchDTO);
|
||||
}
|
||||
|
||||
@PostMapping("/saveRole")
|
||||
public Res saveRole(@RequestBody SysRole role) {
|
||||
return permissionService.saveRole(role);
|
||||
}
|
||||
|
||||
@PostMapping("/deleteRole")
|
||||
public Res deleteRole(@RequestBody JSONObject data) {
|
||||
Long roleId = data.getLong("roleId");
|
||||
return permissionService.deleteRole(roleId);
|
||||
}
|
||||
|
||||
@PostMapping("/setRolePermission")
|
||||
public Res setRolePermission(@RequestBody JSONObject data) {
|
||||
return permissionService.setRolePermission(data);
|
||||
}
|
||||
|
||||
@GetMapping("/getRolePermission")
|
||||
public Res getRolePermission(Long roleId) {
|
||||
return permissionService.getRolePermission(roleId);
|
||||
}
|
||||
|
||||
@PostMapping("/setMemberRole")
|
||||
public Res setMemberRole(@RequestBody JSONObject data) {
|
||||
return permissionService.setMemberRole(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get available roles for current customer (based on plan's apps)
|
||||
*/
|
||||
@GetMapping("/getMemberAvailableRoles")
|
||||
public Res getMemberAvailableRoles() {
|
||||
LoginCustomer customer = AuthContext.getLoginInfo().getCustomer();
|
||||
if (customer == null || customer.getId() == null) {
|
||||
return Res.fail("未找到当前登录客户信息");
|
||||
}
|
||||
return permissionService.getAvailableRolesForCustomer(customer.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get member's assigned roles (scoped by current customer)
|
||||
*/
|
||||
@GetMapping("/getMemberAssignedRoles")
|
||||
public Res getMemberAssignedRoles(@RequestParam("userId") Long userId) {
|
||||
LoginCustomer customer = AuthContext.getLoginInfo().getCustomer();
|
||||
if (customer == null || customer.getId() == null) {
|
||||
return Res.fail("未找到当前登录客户信息");
|
||||
}
|
||||
return permissionService.getMemberRolesByCustomer(customer.getId(), userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set member roles (scoped by current customer)
|
||||
*/
|
||||
@PostMapping("/setMemberRolesByCustomer")
|
||||
public Res setMemberRolesByCustomer(@RequestBody JSONObject data) {
|
||||
LoginCustomer customer = AuthContext.getLoginInfo().getCustomer();
|
||||
if (customer == null || customer.getId() == null) {
|
||||
return Res.fail("未找到当前登录客户信息");
|
||||
}
|
||||
data.put("customerId", customer.getId());
|
||||
return permissionService.setMemberRoleByCustomer(data);
|
||||
}
|
||||
|
||||
@GetMapping("/getHuoBanUrl")
|
||||
public Res getPageUrl(Long menuId) {
|
||||
return permissionService.getPageUrl(menuId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取伙伴云 SSO Token 信息(不需要菜单,不返回 pageUrl/menu)
|
||||
*/
|
||||
@GetMapping("/getHuobanToken")
|
||||
public Res getHuobanToken() {
|
||||
return permissionService.getHuobanToken();
|
||||
}
|
||||
|
||||
@GetMapping("/getMenu")
|
||||
public Res getMenu(Long menuId) {
|
||||
return permissionService.getMenu(menuId);
|
||||
}
|
||||
|
||||
@GetMapping("/getPaymentMenu")
|
||||
public Res getMenu(Long menuId, HttpServletResponse response, HttpServletRequest request) {
|
||||
return permissionService.getPaymentUrl(menuId, response, request);
|
||||
}
|
||||
|
||||
@GetMapping("/changePaymentGroup")
|
||||
public Res changePaymentGroup(Integer group, HttpServletRequest request){
|
||||
return permissionService.changePaymentGroup(group, request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package cn.apes.cloud.controller;
|
||||
|
||||
import cn.apes.commons.Res;
|
||||
import cn.apes.commons.auth.Login;
|
||||
import cn.apes.cloud.config.TenantSource;
|
||||
import cn.apes.cloud.service.impl.SysOperationLogServiceImpl;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 操作日志控制器
|
||||
*/
|
||||
@Login
|
||||
@RestController
|
||||
@TenantSource
|
||||
@RequestMapping("/operationLog")
|
||||
public class SysOperationLogController {
|
||||
|
||||
@Autowired
|
||||
private SysOperationLogServiceImpl operationLogService;
|
||||
|
||||
/**
|
||||
* 分页查询操作日志
|
||||
*/
|
||||
@PostMapping("/page")
|
||||
public Res pageLogs(@RequestBody Map<String, Object> params) {
|
||||
int pageIndex = params.get("pageIndex") != null ? ((Number) params.get("pageIndex")).intValue() : 1;
|
||||
int pageSize = params.get("pageSize") != null ? ((Number) params.get("pageSize")).intValue() : 10;
|
||||
Long customerId = params.get("customerId") != null ? ((Number) params.get("customerId")).longValue() : null;
|
||||
Long userId = params.get("userId") != null ? ((Number) params.get("userId")).longValue() : null;
|
||||
String startDate = params.get("startDate") != null ? params.get("startDate").toString() : null;
|
||||
String endDate = params.get("endDate") != null ? params.get("endDate").toString() : null;
|
||||
IPage<Map<String, Object>> result = operationLogService.pageLogs(
|
||||
pageIndex, pageSize, customerId, userId, startDate, endDate);
|
||||
Map<String, Object> pageData = new java.util.HashMap<>();
|
||||
pageData.put("records", result.getRecords());
|
||||
pageData.put("total", result.getTotal());
|
||||
return Res.success(pageData);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取企业列表(用于下拉筛选)
|
||||
*/
|
||||
@GetMapping("/listCustomers")
|
||||
public Res listCustomers() {
|
||||
return Res.success(operationLogService.listCustomers());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package cn.apes.cloud.controller;
|
||||
|
||||
import cn.apes.commons.Res;
|
||||
import cn.apes.commons.auth.Login;
|
||||
import cn.apes.cloud.config.TenantSource;
|
||||
import cn.apes.cloud.domain.entity.SysOrganization;
|
||||
import cn.apes.cloud.service.impl.SysOrganizationServiceImpl;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* 组织管理控制器
|
||||
*/
|
||||
@Login
|
||||
@RestController
|
||||
@TenantSource
|
||||
@RequestMapping("/organization")
|
||||
public class SysOrganizationController {
|
||||
|
||||
@Autowired
|
||||
private SysOrganizationServiceImpl organizationService;
|
||||
|
||||
/**
|
||||
* 分页查询组织列表
|
||||
*/
|
||||
@PostMapping("/page")
|
||||
public Res pageOrganizations(@RequestParam(required = false) String orgName) {
|
||||
return organizationService.pageOrganizations(orgName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询组织树
|
||||
*/
|
||||
@GetMapping("/tree")
|
||||
public Res getOrganizationTree() {
|
||||
return organizationService.getOrganizationTree();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询组织详情
|
||||
*/
|
||||
@GetMapping("/detail")
|
||||
public Res detail(@RequestParam Long id) {
|
||||
return organizationService.getDetail(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增组织
|
||||
*/
|
||||
@PostMapping("/add")
|
||||
public Res addOrganization(@RequestBody SysOrganization org) {
|
||||
return organizationService.addOrganization(org);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新组织
|
||||
*/
|
||||
@PostMapping("/update")
|
||||
public Res updateOrganization(@RequestBody SysOrganization org) {
|
||||
return organizationService.updateOrganization(org);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除组织
|
||||
*/
|
||||
@PostMapping("/delete")
|
||||
public Res deleteOrganization(@RequestParam Long id) {
|
||||
return organizationService.deleteOrganization(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有启用的组织列表
|
||||
*/
|
||||
@GetMapping("/listAll")
|
||||
public Res listAllOrganizations() {
|
||||
return organizationService.listAllOrganizations();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
package cn.apes.cloud.controller;
|
||||
|
||||
import cn.apes.cloud.domain.entity.SysPackagePlan;
|
||||
import cn.apes.cloud.service.impl.SysPackagePlanServiceImpl;
|
||||
import cn.apes.commons.Res;
|
||||
import cn.apes.commons.auth.Login;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Login
|
||||
@RestController
|
||||
@RequestMapping("/packagePlan")
|
||||
public class SysPackagePlanController {
|
||||
|
||||
@Autowired
|
||||
private SysPackagePlanServiceImpl sysPackagePlanService;
|
||||
|
||||
@Autowired
|
||||
private cn.apes.cloud.service.SysPackagePlanQuotaService sysPackagePlanQuotaService;
|
||||
|
||||
@PostMapping("/page")
|
||||
public Res pagePackagePlan(@RequestBody JSONObject data) {
|
||||
int pageIndex = data.getIntValue("pageIndex");
|
||||
int pageSize = data.getIntValue("pageSize");
|
||||
if (pageIndex <= 0) pageIndex = 1;
|
||||
if (pageSize <= 0) pageSize = 10;
|
||||
String planName = data.getString("planName");
|
||||
return Res.success(sysPackagePlanService.pagePackagePlan(pageIndex, pageSize, planName));
|
||||
}
|
||||
|
||||
@PostMapping("/add")
|
||||
public Res addPackagePlan(@RequestBody SysPackagePlan plan) {
|
||||
return sysPackagePlanService.addPackagePlan(plan);
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
public Res updatePackagePlan(@RequestBody SysPackagePlan plan) {
|
||||
return sysPackagePlanService.updatePackagePlan(plan);
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
public Res deletePackagePlan(@RequestBody JSONObject data) {
|
||||
Long id = data.getLong("id");
|
||||
return sysPackagePlanService.deletePackagePlan(id);
|
||||
}
|
||||
|
||||
@PostMapping("/toggleStatus")
|
||||
public Res toggleStatus(@RequestBody JSONObject data) {
|
||||
Long id = data.getLong("id");
|
||||
Integer status = data.getInteger("status");
|
||||
return sysPackagePlanService.toggleStatus(id, status);
|
||||
}
|
||||
|
||||
@GetMapping("/detail")
|
||||
public Res getDetail(@RequestParam Long id) {
|
||||
SysPackagePlan plan = sysPackagePlanService.getById(id);
|
||||
if (plan == null) return Res.fail("套餐不存在");
|
||||
return Res.success(plan);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取套餐已分配的权限
|
||||
*/
|
||||
@GetMapping("/getPermissions")
|
||||
public Res getPermissions(@RequestParam Long planId) {
|
||||
return Res.success(sysPackagePlanService.getPlanPermissions(planId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存套餐权限关联
|
||||
*/
|
||||
@PostMapping("/savePermissions")
|
||||
public Res savePermissions(@RequestBody JSONObject data) {
|
||||
Long planId = data.getLong("planId");
|
||||
Map<String, List<Long>> appPermissions = new java.util.HashMap<>();
|
||||
JSONObject appPermsObj = data.getJSONObject("appPermissions");
|
||||
if (appPermsObj != null) {
|
||||
for (String appKey : appPermsObj.keySet()) {
|
||||
List<Long> permIds = new java.util.ArrayList<>();
|
||||
Object val = appPermsObj.get(appKey);
|
||||
if (val instanceof List) {
|
||||
for (Object item : (List<?>) val) {
|
||||
if (item instanceof Number) {
|
||||
permIds.add(((Number) item).longValue());
|
||||
} else if (item != null) {
|
||||
try {
|
||||
permIds.add(Long.parseLong(item.toString()));
|
||||
} catch (NumberFormatException e) {
|
||||
// skip
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
appPermissions.put(appKey, permIds);
|
||||
}
|
||||
}
|
||||
return sysPackagePlanService.savePlanPermissions(planId, appPermissions);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取套餐配额配置(已绑定的)
|
||||
*/
|
||||
@GetMapping("/getQuotas")
|
||||
public Res getPlanQuotas(@RequestParam Long planId) {
|
||||
return sysPackagePlanQuotaService.getPlanQuotas(planId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有配额模板 + 标记当前套餐是否已配置
|
||||
*/
|
||||
@GetMapping("/getAllQuotas")
|
||||
public Res getAllQuotas(@RequestParam Long planId) {
|
||||
return sysPackagePlanQuotaService.getAllQuotas(planId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取套餐关联的应用列表
|
||||
*/
|
||||
@GetMapping("/getPlanApps")
|
||||
public Res getPlanApps(@RequestParam Long planId) {
|
||||
return sysPackagePlanService.getPlanApps(planId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存套餐配额配置
|
||||
*/
|
||||
@RequestMapping(value = "/saveQuotas", method = {org.springframework.web.bind.annotation.RequestMethod.GET, org.springframework.web.bind.annotation.RequestMethod.POST})
|
||||
public Res savePlanQuotas(@RequestBody(required = false) JSONObject data) {
|
||||
// 兼容 GET 请求(可能被重定向转换)
|
||||
if (data == null || data.isEmpty()) {
|
||||
// 尝试从 request parameters 获取
|
||||
javax.servlet.http.HttpServletRequest request = ((org.springframework.web.context.request.ServletRequestAttributes) org.springframework.web.context.request.RequestContextHolder.getRequestAttributes()).getRequest();
|
||||
Long planId = request.getParameter("planId") != null ? Long.parseLong(request.getParameter("planId")) : null;
|
||||
String quotaValuesStr = request.getParameter("quotaValues");
|
||||
Map<Long, String> quotaValues = new java.util.HashMap<>();
|
||||
if (quotaValuesStr != null) {
|
||||
try {
|
||||
JSONObject qv = JSONObject.parseObject(quotaValuesStr);
|
||||
for (String key : qv.keySet()) {
|
||||
Object val = qv.get(key);
|
||||
quotaValues.put(Long.parseLong(key), val != null ? val.toString() : null);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return Res.fail("quotaValues格式错误");
|
||||
}
|
||||
}
|
||||
return sysPackagePlanQuotaService.savePlanQuotas(planId, quotaValues);
|
||||
}
|
||||
Long planId = data.getLong("planId");
|
||||
JSONObject quotaValuesObj = data.getJSONObject("quotaValues");
|
||||
Map<Long, String> quotaValues = new java.util.HashMap<>();
|
||||
if (quotaValuesObj != null) {
|
||||
for (String key : quotaValuesObj.keySet()) {
|
||||
Object val = quotaValuesObj.get(key);
|
||||
quotaValues.put(Long.parseLong(key), val != null ? val.toString() : null);
|
||||
}
|
||||
}
|
||||
return sysPackagePlanQuotaService.savePlanQuotas(planId, quotaValues);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package cn.apes.cloud.controller;
|
||||
|
||||
import cn.apes.cloud.domain.entity.SysQuota;
|
||||
import cn.apes.cloud.service.impl.SysQuotaServiceImpl;
|
||||
import cn.apes.commons.Res;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/quota")
|
||||
public class SysQuotaController {
|
||||
|
||||
@Autowired
|
||||
private SysQuotaServiceImpl sysQuotaService;
|
||||
|
||||
@PostMapping("/page")
|
||||
public Res pageQuota(@RequestBody JSONObject data) {
|
||||
int pageIndex = data.getIntValue("pageIndex");
|
||||
int pageSize = data.getIntValue("pageSize");
|
||||
if (pageIndex <= 0) pageIndex = 1;
|
||||
if (pageSize <= 0) pageSize = 10;
|
||||
String appKey = data.getString("appKey");
|
||||
String quotaName = data.getString("quotaName");
|
||||
String quotaCode = data.getString("quotaCode");
|
||||
return Res.success(sysQuotaService.pageQuota(pageIndex, pageSize, appKey, quotaName, quotaCode));
|
||||
}
|
||||
|
||||
@PostMapping("/add")
|
||||
public Res addQuota(@RequestBody SysQuota quota) {
|
||||
return sysQuotaService.addQuota(quota);
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
public Res updateQuota(@RequestBody SysQuota quota) {
|
||||
return sysQuotaService.updateQuota(quota);
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
public Res deleteQuota(@RequestBody JSONObject data) {
|
||||
Long id = data.getLong("id");
|
||||
return sysQuotaService.deleteQuota(id);
|
||||
}
|
||||
|
||||
@GetMapping("/detail")
|
||||
public Res getDetail(@RequestParam Long id) {
|
||||
SysQuota quota = sysQuotaService.getById(id);
|
||||
if (quota == null) return Res.fail("配额不存在");
|
||||
return Res.success(quota);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
package cn.apes.cloud.controller;
|
||||
|
||||
import cn.apes.commons.Res;
|
||||
import cn.apes.commons.auth.AuthContext;
|
||||
import cn.apes.commons.auth.Login;
|
||||
import cn.apes.cloud.config.TenantSource;
|
||||
import cn.apes.cloud.domain.dto.LoginDTO;
|
||||
import cn.apes.cloud.domain.dto.PwdDTO;
|
||||
import cn.apes.cloud.domain.dto.RegisterDTO;
|
||||
import cn.apes.cloud.domain.dto.SelectCustomerDTO;
|
||||
import cn.apes.cloud.domain.dto.UserSearchDTO;
|
||||
import cn.apes.cloud.domain.dto.EnterpriseCertifyDTO;
|
||||
import cn.apes.cloud.domain.entity.CustomerInfo;
|
||||
import cn.apes.cloud.domain.entity.UserInfo;
|
||||
import cn.apes.cloud.service.impl.UserInfoServiceImpl;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@Slf4j
|
||||
@RestController
|
||||
@TenantSource
|
||||
@RequestMapping("/user")
|
||||
public class UserController {
|
||||
|
||||
@Autowired
|
||||
UserInfoServiceImpl userInfoService;
|
||||
|
||||
@Login
|
||||
@PostMapping("/saveUserInfo")
|
||||
public Res saveUserInfo(@RequestBody UserInfo userInfo) {
|
||||
return userInfoService.saveUserInfo(userInfo);
|
||||
}
|
||||
|
||||
@Login
|
||||
// @CrossOrigin("*")
|
||||
@PostMapping("/pageUser")
|
||||
public Res pageUser(@RequestBody UserSearchDTO searchDTO) {
|
||||
return userInfoService.pageUser(searchDTO);
|
||||
}
|
||||
|
||||
@PostMapping("/loginPwd")
|
||||
public Res loginPwd(@RequestBody LoginDTO loginDTO) {
|
||||
log.info("开始登录了");
|
||||
return userInfoService.loginPwd(loginDTO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户注册
|
||||
*/
|
||||
@PostMapping("/register")
|
||||
public Res register(@RequestBody RegisterDTO dto) {
|
||||
return userInfoService.register(dto);
|
||||
}
|
||||
|
||||
@Login
|
||||
@PostMapping("/resetPwd")
|
||||
public Res resetPwd(@RequestBody UserInfo userInfo) {
|
||||
return userInfoService.resetPwd(userInfo);
|
||||
}
|
||||
|
||||
@Login
|
||||
@GetMapping("/getCurrentUser")
|
||||
public Res getCurrentUser() {
|
||||
try {
|
||||
Object loginInfo = AuthContext.getLoginInfo();
|
||||
if (loginInfo == null) {
|
||||
return Res.fail("未登录");
|
||||
}
|
||||
return Res.success(loginInfo);
|
||||
} catch (Exception e) {
|
||||
return Res.fail("获取用户信息失败");
|
||||
}
|
||||
}
|
||||
|
||||
@Login
|
||||
@PostMapping("/editPwd")
|
||||
public Res editPwd(@RequestBody PwdDTO pwdDTO) {
|
||||
return userInfoService.editPwd(pwdDTO);
|
||||
}
|
||||
|
||||
@Login
|
||||
@GetMapping("/getUserByPhone")
|
||||
public Res getUserByPhone(String phone) {
|
||||
return userInfoService.getUser(phone);
|
||||
}
|
||||
|
||||
@Login
|
||||
@GetMapping("/getCustomerUser")
|
||||
public Res getCustomerUser(Long customerId) {
|
||||
return userInfoService.getCustomerUser(customerId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 多客户时用户选择企业
|
||||
*/
|
||||
@PostMapping("/selectCustomer")
|
||||
public Res selectCustomer(@RequestBody SelectCustomerDTO dto) {
|
||||
return userInfoService.selectCustomer(dto.getToken(), dto.getCustomerId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前用户关联的企业列表(用于切换企业场景)
|
||||
*/
|
||||
@Login
|
||||
@GetMapping("/getMyCustomers")
|
||||
public Res getMyCustomers() {
|
||||
return userInfoService.getMyCustomers();
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑当前用户的个人资料(昵称、头像)
|
||||
*/
|
||||
@Login
|
||||
@PostMapping("/editProfile")
|
||||
public Res editProfile(@RequestBody UserInfo userInfo) {
|
||||
return userInfoService.editProfile(userInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑当前企业信息(仅更新当前登录用户的所属企业)
|
||||
*/
|
||||
@Login
|
||||
@PostMapping("/customer/editCurrent")
|
||||
public Res editCurrentCustomer(@RequestBody CustomerInfo customerInfo) {
|
||||
return userInfoService.editCurrentCustomer(customerInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前企业信息(从数据库直接读取,不走Redis缓存)
|
||||
*/
|
||||
@Login
|
||||
@GetMapping("/customer/getCurrent")
|
||||
public Res getCurrentCustomer() {
|
||||
return userInfoService.getCurrentCustomerFromDb();
|
||||
}
|
||||
|
||||
/**
|
||||
* 企业认证:用户提交认证表单,创建客户记录并关联当前用户
|
||||
* 使用登录返回的 token(无需额外登录态校验)
|
||||
*/
|
||||
@PostMapping("/certifyEnterprise")
|
||||
public Res certifyEnterprise(@RequestBody EnterpriseCertifyDTO dto) {
|
||||
if (dto == null || cn.hutool.core.util.StrUtil.isBlank(dto.getToken())) {
|
||||
return Res.fail("token不能为空");
|
||||
}
|
||||
CustomerInfo customerInfo = new CustomerInfo();
|
||||
customerInfo.setCustomerName(dto.getCustomerName());
|
||||
customerInfo.setLogo(dto.getLogo());
|
||||
customerInfo.setShortName(dto.getShortName());
|
||||
customerInfo.setCustomerType(dto.getCustomerType());
|
||||
customerInfo.setCustomerIdNumber(dto.getCustomerIdNumber());
|
||||
customerInfo.setLegalName(dto.getLegalName());
|
||||
customerInfo.setLegalIdFront(dto.getLegalIdFront());
|
||||
customerInfo.setLegalIdBack(dto.getLegalIdBack());
|
||||
customerInfo.setAdminName(dto.getAdminName());
|
||||
customerInfo.setAdminPhone(dto.getAdminPhone());
|
||||
customerInfo.setAdminIdNumber(dto.getAdminIdNumber());
|
||||
customerInfo.setResponsibleIdFront(dto.getResponsibleIdFront());
|
||||
customerInfo.setResponsibleIdBack(dto.getResponsibleIdBack());
|
||||
customerInfo.setIndustry(dto.getIndustry());
|
||||
customerInfo.setIndustrySub(dto.getIndustrySub());
|
||||
customerInfo.setSalesChannel(dto.getSalesChannel());
|
||||
customerInfo.setIndustryType(dto.getIndustryType());
|
||||
customerInfo.setProvince(dto.getProvince());
|
||||
customerInfo.setCity(dto.getCity());
|
||||
customerInfo.setBusinessLicense(dto.getBusinessLicense());
|
||||
return userInfoService.certifyEnterprise(dto.getToken(), customerInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前用户的企业信息(用于重新编辑)
|
||||
*/
|
||||
@GetMapping("/getPendingCustomer")
|
||||
public Res getPendingCustomer(@RequestParam("token") String token) {
|
||||
return userInfoService.getPendingCustomer(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新提交企业认证
|
||||
*/
|
||||
@PostMapping("/recertifyEnterprise")
|
||||
public Res recertifyEnterprise(@RequestBody EnterpriseCertifyDTO dto) {
|
||||
CustomerInfo customerInfo = new CustomerInfo();
|
||||
customerInfo.setCustomerName(dto.getCustomerName());
|
||||
customerInfo.setShortName(dto.getShortName());
|
||||
customerInfo.setCustomerIdNumber(dto.getCustomerIdNumber());
|
||||
customerInfo.setAdminName(dto.getAdminName());
|
||||
customerInfo.setAdminPhone(dto.getAdminPhone());
|
||||
customerInfo.setAdminIdNumber(dto.getAdminIdNumber());
|
||||
customerInfo.setLegalName(dto.getLegalName());
|
||||
customerInfo.setLegalIdFront(dto.getLegalIdFront());
|
||||
customerInfo.setLegalIdBack(dto.getLegalIdBack());
|
||||
customerInfo.setResponsibleIdFront(dto.getResponsibleIdFront());
|
||||
customerInfo.setResponsibleIdBack(dto.getResponsibleIdBack());
|
||||
customerInfo.setLogo(dto.getLogo());
|
||||
customerInfo.setIndustry(dto.getIndustry());
|
||||
customerInfo.setIndustrySub(dto.getIndustrySub());
|
||||
customerInfo.setSalesChannel(dto.getSalesChannel());
|
||||
customerInfo.setIndustryType(dto.getIndustryType());
|
||||
customerInfo.setProvince(dto.getProvince());
|
||||
customerInfo.setCity(dto.getCity());
|
||||
customerInfo.setBusinessLicense(dto.getBusinessLicense());
|
||||
return userInfoService.recertifyEnterprise(dto.getToken(), customerInfo);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package cn.apes.cloud.controller;
|
||||
|
||||
import cn.apes.cloud.config.TenantSource;
|
||||
import cn.apes.cloud.domain.entity.UserPreference;
|
||||
import cn.apes.cloud.service.impl.UserPreferenceServiceImpl;
|
||||
import cn.apes.commons.Res;
|
||||
import cn.apes.commons.auth.Login;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 用户个性化配置控制器
|
||||
*
|
||||
* @author OpenClaw
|
||||
* @since 2026-08-06
|
||||
*/
|
||||
@RestController
|
||||
@TenantSource
|
||||
@RequestMapping("/userPreference")
|
||||
public class UserPreferenceController {
|
||||
|
||||
@Resource
|
||||
private UserPreferenceServiceImpl userPreferenceService;
|
||||
|
||||
/**
|
||||
* 查询指定用户的个性化配置
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return Res 响应对象
|
||||
* - code: 状态码,1表示成功
|
||||
* - data: 个性化配置对象(未配置时返回默认值 uiSize=2)
|
||||
*/
|
||||
@Login
|
||||
@PostMapping("/get")
|
||||
public Res getUserPreference(@RequestParam Long userId) {
|
||||
return userPreferenceService.getUserPreference(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询当前登录用户的个性化配置
|
||||
*
|
||||
* @return Res 响应对象
|
||||
* - code: 状态码,1表示成功
|
||||
* - data: 当前用户的个性化配置对象(未配置时返回默认值 uiSize=2)
|
||||
*/
|
||||
@Login
|
||||
@PostMapping("/mine")
|
||||
public Res getCurrentUserPreference() {
|
||||
return userPreferenceService.getCurrentUserPreference();
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增用户个性化配置
|
||||
*
|
||||
* @param preference 配置对象
|
||||
* - userId: 用户ID(必填)
|
||||
* - uiSize: UI尺寸 1-最大 2-中等 3-最小(必填)
|
||||
* @return Res 响应对象
|
||||
* - code: 状态码,1表示成功
|
||||
* - msg: 操作结果消息
|
||||
*/
|
||||
@Login
|
||||
@PostMapping("/add")
|
||||
public Res addUserPreference(@RequestBody UserPreference preference) {
|
||||
return userPreferenceService.addUserPreference(preference);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用户个性化配置
|
||||
*
|
||||
* @param preference 配置对象
|
||||
* - userId: 用户ID(必填)
|
||||
* - uiSize: UI尺寸 1-最大 2-中等 3-最小(必填)
|
||||
* @return Res 响应对象
|
||||
* - code: 状态码,1表示成功
|
||||
* - msg: 操作结果消息
|
||||
*/
|
||||
@Login
|
||||
@PostMapping("/update")
|
||||
public Res updateUserPreference(@RequestBody UserPreference preference) {
|
||||
return userPreferenceService.updateUserPreference(preference);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存当前登录用户的个性化配置(不存在则新增,已存在则更新)
|
||||
*
|
||||
* @param preference 配置对象
|
||||
* - uiSize: UI尺寸 1-最大 2-中等 3-最小(必填)
|
||||
* @return Res 响应对象
|
||||
* - code: 状态码,1表示成功
|
||||
* - msg: 操作结果消息
|
||||
*/
|
||||
@Login
|
||||
@PostMapping("/save")
|
||||
public Res saveCurrentUserPreference(@RequestBody UserPreference preference) {
|
||||
return userPreferenceService.saveCurrentUserPreference(preference);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户个性化配置(逻辑删除)
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return Res 响应对象
|
||||
* - code: 状态码,1表示成功
|
||||
* - msg: 操作结果消息
|
||||
*/
|
||||
@Login
|
||||
@PostMapping("/delete")
|
||||
public Res deleteUserPreference(@RequestParam Long userId) {
|
||||
return userPreferenceService.deleteUserPreference(userId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package cn.apes.cloud.domain.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class AppSearchDTO extends PageDTO {
|
||||
private String appName;
|
||||
private String appKey;
|
||||
private Boolean userVisible;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package cn.apes.cloud.domain.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class CustomerSearchDTO extends PageDTO{
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package cn.apes.cloud.domain.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class EnterpriseCertifyDTO {
|
||||
/** 企业名称 */
|
||||
private String customerName;
|
||||
/** 企业LOGO */
|
||||
private String logo;
|
||||
/** 企业简称 */
|
||||
private String shortName;
|
||||
/** 主体类型 1.个人 2.企业 3.个体户 4.政府 */
|
||||
private Integer customerType;
|
||||
/** 营业执照号/证件号 */
|
||||
private String customerIdNumber;
|
||||
/** 法人姓名 */
|
||||
private String legalName;
|
||||
/** 法人身份证正面 */
|
||||
private String legalIdFront;
|
||||
/** 法人身份证反面 */
|
||||
private String legalIdBack;
|
||||
/** 负责人姓名 */
|
||||
private String adminName;
|
||||
/** 负责人手机 */
|
||||
private String adminPhone;
|
||||
/** 负责人证件号 */
|
||||
private String adminIdNumber;
|
||||
/** 负责人身份证正面 */
|
||||
private String responsibleIdFront;
|
||||
/** 负责人身份证反面 */
|
||||
private String responsibleIdBack;
|
||||
/** 行业(一级) */
|
||||
private String industry;
|
||||
/** 行业(二级细分) */
|
||||
private String industrySub;
|
||||
/** 销售渠道 */
|
||||
private String salesChannel;
|
||||
/** 行业类型 */
|
||||
private String industryType;
|
||||
/** 省份 */
|
||||
private String province;
|
||||
/** 城市 */
|
||||
private String city;
|
||||
/** 营业执照 */
|
||||
private String businessLicense;
|
||||
|
||||
/**
|
||||
* Token from login response
|
||||
*/
|
||||
private String token;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package cn.apes.cloud.domain.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class LoginDTO {
|
||||
String phone;
|
||||
String password;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package cn.apes.cloud.domain.dto;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class PageDTO {
|
||||
Integer pageIndex;
|
||||
Integer pageSize;
|
||||
|
||||
|
||||
Integer page;
|
||||
Integer perPage;
|
||||
|
||||
public IPage getPage() {
|
||||
if (page != null && perPage != null) {
|
||||
return new Page(page, perPage);
|
||||
}
|
||||
if (pageIndex != null && pageSize != null) {
|
||||
return new Page(pageIndex, pageSize);
|
||||
}
|
||||
return new Page(1, 10);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package cn.apes.cloud.domain.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class PwdDTO {
|
||||
String oldPwd;
|
||||
String pwd1;
|
||||
String pwd2;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package cn.apes.cloud.domain.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class RegisterDTO {
|
||||
/**
|
||||
* 用户昵称
|
||||
*/
|
||||
private String nickname;
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
private String phone;
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
private String password;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package cn.apes.cloud.domain.dto;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class RelationDTO {
|
||||
String fieldName;
|
||||
Long fieldId;
|
||||
List<Long> dataIds =new ArrayList<>();
|
||||
List<JSONObject> dataList;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package cn.apes.cloud.domain.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@Data
|
||||
public class RoleSearchDTO extends PageDTO{
|
||||
Long userNo;
|
||||
String appName;
|
||||
Set<String> appNames;
|
||||
Long planId;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package cn.apes.cloud.domain.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class SelectCustomerDTO {
|
||||
String token;
|
||||
Long customerId;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package cn.apes.cloud.domain.dto;
|
||||
|
||||
import cn.apes.cloud.domain.entity.SysRole;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* description
|
||||
*
|
||||
* @date 2024/7/9 09:44
|
||||
*/
|
||||
@Data
|
||||
public class SysRoleDTO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String appName;
|
||||
|
||||
private List<SysRole> SysRoleList;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package cn.apes.cloud.domain.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class UserSearchDTO extends PageDTO{
|
||||
String nickName;
|
||||
String phone;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package cn.apes.cloud.domain.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
public class AppInfo {
|
||||
@TableId
|
||||
private String appKey;
|
||||
private String appIcon;
|
||||
private String appName;
|
||||
private String appShortName;
|
||||
private String appType;
|
||||
private String remark;
|
||||
private Boolean userVisible;
|
||||
private String huobanSpaceId; // 伙伴云工作区ID
|
||||
private String huobanSpaceGroupId; // 伙伴云工作区用户组ID
|
||||
private Date createTime;
|
||||
private Date updateTime;
|
||||
@TableLogic
|
||||
private Boolean isDel;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package cn.apes.cloud.domain.entity;
|
||||
|
||||
import cn.apes.commons.domain.DbEntity;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class CustomerApp extends DbEntity implements Serializable {
|
||||
|
||||
private Long customerId;
|
||||
|
||||
private String appKey;
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
package cn.apes.cloud.domain.entity;
|
||||
|
||||
import cn.apes.commons.domain.DbEntity;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class CustomerInfo extends DbEntity implements Serializable {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 客户类型 1.个人 2.企业 3.个体户 4.政府
|
||||
*/
|
||||
private Integer customerType;
|
||||
|
||||
/**
|
||||
* 客户名称
|
||||
*/
|
||||
private String customerName;
|
||||
|
||||
/**
|
||||
* 客户LOGO图片URL
|
||||
*/
|
||||
private String logo;
|
||||
|
||||
/**
|
||||
* 客户名称
|
||||
*/
|
||||
private String shortName;
|
||||
|
||||
/**
|
||||
* 证件号,确保唯一性并不允许空值。
|
||||
*/
|
||||
private String customerIdNumber;
|
||||
|
||||
/**
|
||||
* 企业状态:0=待审核,1=使用中,3=已注销,4=暂停服务,5=审核拒绝
|
||||
*/
|
||||
private Integer customerStatus;
|
||||
|
||||
/**
|
||||
* 审核拒绝原因
|
||||
*/
|
||||
private String auditRemark;
|
||||
|
||||
/**
|
||||
* 审核时间
|
||||
*/
|
||||
private java.util.Date auditTime;
|
||||
|
||||
/**
|
||||
* 管理员姓名,不允许空值。
|
||||
*/
|
||||
private String adminName;
|
||||
|
||||
/**
|
||||
* 管理员手机号,不允许空值。
|
||||
*/
|
||||
private String adminPhone;
|
||||
|
||||
/**
|
||||
* 管理员证件号,确保唯一性并不允许空值。
|
||||
*/
|
||||
private String adminIdNumber;
|
||||
|
||||
// ========== 资质管理 ==========
|
||||
|
||||
/**
|
||||
* 营业执照图片URL
|
||||
*/
|
||||
private String businessLicense;
|
||||
|
||||
/**
|
||||
* 法人姓名
|
||||
*/
|
||||
private String legalName;
|
||||
|
||||
/**
|
||||
* 法人身份证正面图片URL
|
||||
*/
|
||||
private String legalIdFront;
|
||||
|
||||
/**
|
||||
* 法人身份证反面图片URL
|
||||
*/
|
||||
private String legalIdBack;
|
||||
|
||||
/**
|
||||
* 负责人身份证正面图片URL
|
||||
*/
|
||||
private String responsibleIdFront;
|
||||
|
||||
/**
|
||||
* 负责人身份证反面图片URL
|
||||
*/
|
||||
private String responsibleIdBack;
|
||||
|
||||
// ========== 行业 / 区域 / 渠道 ==========
|
||||
|
||||
/**
|
||||
* 行业(一级)
|
||||
*/
|
||||
private String industry;
|
||||
|
||||
/**
|
||||
* 行业(二级细分)
|
||||
*/
|
||||
private String industrySub;
|
||||
|
||||
/**
|
||||
* 销售渠道
|
||||
*/
|
||||
private String salesChannel;
|
||||
|
||||
/**
|
||||
* 行业类型:供应商/加工商/经销商/零售商
|
||||
*/
|
||||
private String industryType;
|
||||
|
||||
/**
|
||||
* 省份
|
||||
*/
|
||||
private String province;
|
||||
|
||||
/**
|
||||
* 城市
|
||||
*/
|
||||
private String city;
|
||||
|
||||
/**
|
||||
* 关联套餐列表(非数据库字段)
|
||||
*/
|
||||
@com.baomidou.mybatisplus.annotation.TableField(exist = false)
|
||||
private List<SysPackagePlan> plans;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package cn.apes.cloud.domain.entity;
|
||||
|
||||
import cn.apes.commons.domain.DbEntity;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@TableName("customer_package")
|
||||
public class CustomerPackage extends DbEntity implements Serializable {
|
||||
|
||||
/**
|
||||
* 客户ID
|
||||
*/
|
||||
private Long customerId;
|
||||
|
||||
/**
|
||||
* 套餐ID
|
||||
*/
|
||||
private Long planId;
|
||||
|
||||
/**
|
||||
* 到期时间
|
||||
*/
|
||||
private Date expireTime;
|
||||
|
||||
/**
|
||||
* 套餐名称(非数据库字段)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String planName;
|
||||
|
||||
/**
|
||||
* 套餐级别(非数据库字段)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private Integer planLevel;
|
||||
|
||||
/**
|
||||
* 收费模式(非数据库字段)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String chargeMode;
|
||||
|
||||
/**
|
||||
* 金额(非数据库字段)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private java.math.BigDecimal amount;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package cn.apes.cloud.domain.entity;
|
||||
|
||||
import cn.apes.commons.domain.DbEntity;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@TableName("customer_package_extend_apply")
|
||||
public class CustomerPackageExtendApply extends DbEntity {
|
||||
|
||||
/** 客户ID */
|
||||
private Long customerId;
|
||||
|
||||
/** 套餐ID */
|
||||
private Long planId;
|
||||
|
||||
/** 申请用户ID */
|
||||
private Long userId;
|
||||
|
||||
/** 联系电话 */
|
||||
private String contactPhone;
|
||||
|
||||
/** 延期原因 */
|
||||
private String reason;
|
||||
|
||||
/** 申请延期天数 */
|
||||
private Integer applyDays;
|
||||
|
||||
/** 状态:0-申请中 1-已调整 2-已拒绝 */
|
||||
private Integer status;
|
||||
|
||||
/** 操作人ID(同意/拒绝的人) */
|
||||
private Long operatorId;
|
||||
|
||||
/** 操作人姓名 */
|
||||
private String operatorName;
|
||||
|
||||
/** 操作时间 */
|
||||
private java.util.Date operateTime;
|
||||
|
||||
/** 申请时间 */
|
||||
private java.util.Date applyTime;
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package cn.apes.cloud.domain.entity;
|
||||
|
||||
import cn.apes.commons.domain.DbEntity;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
@TableName("customer_package_quota")
|
||||
public class CustomerPackageQuota extends DbEntity implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 客户套餐关联ID
|
||||
*/
|
||||
private Long customerPackageId;
|
||||
|
||||
/**
|
||||
* 配额模板ID
|
||||
*/
|
||||
private Long quotaId;
|
||||
|
||||
/**
|
||||
* 应用标识
|
||||
*/
|
||||
private String appKey;
|
||||
|
||||
/**
|
||||
* 配额编码
|
||||
*/
|
||||
private String quotaCode;
|
||||
|
||||
/**
|
||||
* 配额名称
|
||||
*/
|
||||
private String quotaName;
|
||||
|
||||
/**
|
||||
* 数据类型
|
||||
*/
|
||||
private String dataType;
|
||||
|
||||
/**
|
||||
* 配额值
|
||||
*/
|
||||
private String quotaValue;
|
||||
|
||||
/**
|
||||
* 应用名称(非数据库字段)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String appName;
|
||||
|
||||
/**
|
||||
* 单位(非数据库字段,来自sys_quota)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String unit;
|
||||
|
||||
/**
|
||||
* 重置周期(非数据库字段,来自sys_quota)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String resetCycle;
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package cn.apes.cloud.domain.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 客户配额变更日志
|
||||
*/
|
||||
@Data
|
||||
@TableName("customer_quota_change_log")
|
||||
public class CustomerQuotaChangeLog implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 客户套餐关联ID
|
||||
*/
|
||||
private Long customerPackageId;
|
||||
|
||||
/**
|
||||
* 配额编码
|
||||
*/
|
||||
private String quotaCode;
|
||||
|
||||
/**
|
||||
* 配额名称
|
||||
*/
|
||||
private String quotaName;
|
||||
|
||||
/**
|
||||
* 变更类型:1=增加,2=减少
|
||||
*/
|
||||
private Integer changeType;
|
||||
|
||||
/**
|
||||
* 变更数量
|
||||
*/
|
||||
private Integer changeAmount;
|
||||
|
||||
/**
|
||||
* 变更前值
|
||||
*/
|
||||
private String oldValue;
|
||||
|
||||
/**
|
||||
* 变更后值
|
||||
*/
|
||||
private String newValue;
|
||||
|
||||
/**
|
||||
* 变更原因
|
||||
*/
|
||||
private String reason;
|
||||
|
||||
/**
|
||||
* 操作人ID
|
||||
*/
|
||||
private Long operatorId;
|
||||
|
||||
/**
|
||||
* 操作人姓名
|
||||
*/
|
||||
private String operatorName;
|
||||
|
||||
/**
|
||||
* 操作时间
|
||||
*/
|
||||
private Date operateTime;
|
||||
|
||||
/**
|
||||
* 客户名称(非数据库字段,用于展示)
|
||||
*/
|
||||
@com.baomidou.mybatisplus.annotation.TableField(exist = false)
|
||||
private String customerName;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package cn.apes.cloud.domain.entity;
|
||||
|
||||
import cn.apes.commons.domain.DbEntity;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class CustomerUser extends DbEntity implements Serializable {
|
||||
|
||||
private long userId;
|
||||
|
||||
private long customerId;
|
||||
|
||||
/** 所属组织ID */
|
||||
private Long orgId;
|
||||
|
||||
/** 姓名 */
|
||||
private String name;
|
||||
|
||||
/** 职称 */
|
||||
private String title;
|
||||
|
||||
/** 岗位 */
|
||||
private String position;
|
||||
|
||||
/** 应用ID集合(逗号分隔) */
|
||||
private String appIds;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package cn.apes.cloud.domain.entity;
|
||||
|
||||
import cn.apes.commons.domain.DbEntity;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class SsoConfig extends DbEntity implements Serializable {
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long userId; // 用户ID
|
||||
private Long customerId;
|
||||
//伙伴云配置
|
||||
private String huobanMobile; // 伙伴云绑定手机号
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long huobanCompanyId; // 伙伴云公司ID
|
||||
private String huobanName; // 伙伴云用户名
|
||||
private Integer huobanStatus;
|
||||
private Long huobanUserId; // 伙伴云用户ID
|
||||
private String huobanUserName; // 伙伴云用户名(搜索返回的name)
|
||||
private String huobanAvatar; // 伙伴云用户头像
|
||||
|
||||
//交易平台配置
|
||||
private String paymentUserName;
|
||||
private String paymentPassword;
|
||||
private Integer paymentGroup;
|
||||
private Integer paymentStatus;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package cn.apes.cloud.domain.entity;
|
||||
|
||||
import cn.apes.commons.domain.DbEntity;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 外部系统调用用的 AccessToken 表
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class SysAccessToken extends DbEntity implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Token 值(明文存储)
|
||||
*/
|
||||
private String token;
|
||||
|
||||
/**
|
||||
* 名称,用于管理识别
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 所属客户(企业)ID
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long customerId;
|
||||
|
||||
/**
|
||||
* 接口范围:* 表示全部,否则为逗号分隔的 Ant 路径
|
||||
*/
|
||||
private String scope;
|
||||
|
||||
/**
|
||||
* IP 白名单,多个用逗号分隔,为空表示不限制
|
||||
*/
|
||||
private String whitelistIps;
|
||||
|
||||
/**
|
||||
* 状态 1=启用 2=停用
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 过期时间,NULL 表示永不过期
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date expireTime;
|
||||
|
||||
/**
|
||||
* 最后使用时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date lastUsedTime;
|
||||
|
||||
/**
|
||||
* 最后使用 IP
|
||||
*/
|
||||
private String lastUsedIp;
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long createBy;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package cn.apes.cloud.domain.entity;
|
||||
|
||||
import cn.apes.commons.domain.DbEntity;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
public class SysMemberRole extends DbEntity implements Serializable {
|
||||
|
||||
|
||||
private String appName;
|
||||
/**
|
||||
* 角色id
|
||||
*/
|
||||
private Long roleId;
|
||||
|
||||
/**
|
||||
* 账号id
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 角色附加数据 一般用于子账号保存主账号userno
|
||||
*/
|
||||
private String roleData;
|
||||
|
||||
/**
|
||||
* 角色所属客户(企业),系统角色为0
|
||||
*/
|
||||
private Long customerId;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package cn.apes.cloud.domain.entity;
|
||||
|
||||
import cn.apes.commons.domain.DbEntity;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author
|
||||
* @description sys_menu
|
||||
* @date 2023-06-29
|
||||
*/
|
||||
@Data
|
||||
public class SysMenu extends DbEntity implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 菜单名称
|
||||
*/
|
||||
|
||||
private String menuTitle;
|
||||
|
||||
/**
|
||||
* 菜单路径
|
||||
*/
|
||||
private String menuPath;
|
||||
|
||||
/**
|
||||
* 菜单类型 1.vue菜单2.伙伴云菜单 3.交易系统菜单
|
||||
*/
|
||||
private Integer menuType;
|
||||
|
||||
private String configJson;
|
||||
|
||||
@TableField(exist = false)
|
||||
private JSONObject config;
|
||||
|
||||
private String vuePath;
|
||||
private String vueName;
|
||||
|
||||
private Long amisId;
|
||||
/**
|
||||
* 菜单图片
|
||||
*/
|
||||
private String menuIcon;
|
||||
|
||||
/**
|
||||
* 父级id 根为0
|
||||
*/
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 平台类型
|
||||
*/
|
||||
private String appName;
|
||||
|
||||
/**
|
||||
* 对应的权限code
|
||||
*/
|
||||
private String permissionCode;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@JsonIgnore
|
||||
private String remark;
|
||||
/**
|
||||
* 低版本
|
||||
*/
|
||||
@JsonIgnore
|
||||
private String lowVersion;
|
||||
/**
|
||||
* 高版本
|
||||
*/
|
||||
@JsonIgnore
|
||||
private String highVersion;
|
||||
|
||||
private Integer sort;
|
||||
|
||||
private boolean hidden;
|
||||
|
||||
/**
|
||||
* 是否在看板显示
|
||||
*/
|
||||
private Boolean showOnBoard;
|
||||
|
||||
@TableField(exist = false)
|
||||
private List<SysMenu> child;
|
||||
|
||||
public SysMenu() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package cn.apes.cloud.domain.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 操作日志表
|
||||
*/
|
||||
@Data
|
||||
@TableName("sys_operation_log")
|
||||
public class SysOperationLog {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/** 用户ID */
|
||||
private Long userId;
|
||||
|
||||
/** 用户名 */
|
||||
private String userName;
|
||||
|
||||
/** 租户/企业ID */
|
||||
private Long customerId;
|
||||
|
||||
/** 企业名称 */
|
||||
private String customerName;
|
||||
|
||||
/** 模块名称 */
|
||||
private String module;
|
||||
|
||||
/** 操作名称 */
|
||||
private String action;
|
||||
|
||||
/** 日志说明 */
|
||||
private String description;
|
||||
|
||||
/** IP地址 */
|
||||
private String ip;
|
||||
|
||||
/** 浏览器/设备信息 */
|
||||
private String userAgent;
|
||||
|
||||
/** 登录地址(预留) */
|
||||
private String loginLocation;
|
||||
|
||||
/** 请求方法 */
|
||||
private String requestMethod;
|
||||
|
||||
/** 请求URL */
|
||||
private String requestUrl;
|
||||
|
||||
/** 请求参数 */
|
||||
private String requestParams;
|
||||
|
||||
/** 操作时间 */
|
||||
private Date operateTime;
|
||||
|
||||
private String createBy;
|
||||
|
||||
private Date createTime;
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package cn.apes.cloud.domain.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 组织表
|
||||
*/
|
||||
@Data
|
||||
@TableName("sys_organization")
|
||||
public class SysOrganization {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/** 租户ID */
|
||||
private Long customerId;
|
||||
|
||||
/** 组织名称 */
|
||||
private String orgName;
|
||||
|
||||
/** 上级组织ID,根节点为0 */
|
||||
private Long parentId;
|
||||
|
||||
/** 组织类型 */
|
||||
private String orgType;
|
||||
|
||||
/** 组织说明 */
|
||||
private String description;
|
||||
|
||||
/** 排序 */
|
||||
private Integer sortOrder;
|
||||
|
||||
/** 状态 1启用/0停用 */
|
||||
private Integer status;
|
||||
|
||||
/** 逻辑删除 0正常/1删除 */
|
||||
private Integer isDel;
|
||||
|
||||
private String createBy;
|
||||
|
||||
private Date createTime;
|
||||
|
||||
private String updateBy;
|
||||
|
||||
private Date updateTime;
|
||||
|
||||
/** 子节点列表(非数据库字段) */
|
||||
@TableField(exist = false)
|
||||
private List<SysOrganization> children;
|
||||
|
||||
/** 父级名称(非数据库字段) */
|
||||
@TableField(exist = false)
|
||||
private String parentName;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package cn.apes.cloud.domain.entity;
|
||||
|
||||
import cn.apes.commons.domain.DbEntity;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class SysPackagePlan extends DbEntity implements Serializable {
|
||||
|
||||
/**
|
||||
* 套餐名称
|
||||
*/
|
||||
private String planName;
|
||||
|
||||
/**
|
||||
* 套餐级别: 1/2/3
|
||||
*/
|
||||
private Integer planLevel;
|
||||
|
||||
/**
|
||||
* 套餐说明
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 收费模式: monthly/yearly
|
||||
*/
|
||||
private String chargeMode;
|
||||
|
||||
/**
|
||||
* 金额
|
||||
*/
|
||||
private java.math.BigDecimal amount;
|
||||
|
||||
/**
|
||||
* 状态: 1启用 0停用
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 图标URL
|
||||
*/
|
||||
private String iconUrl;
|
||||
|
||||
/**
|
||||
* 应用ID集合,逗号分隔
|
||||
*/
|
||||
private String appIds;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package cn.apes.cloud.domain.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@TableName("sys_package_plan_permission")
|
||||
public class SysPackagePlanPermission implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 套餐ID
|
||||
*/
|
||||
private Long planId;
|
||||
|
||||
/**
|
||||
* 应用Key
|
||||
*/
|
||||
private String appKey;
|
||||
|
||||
/**
|
||||
* 权限ID
|
||||
*/
|
||||
private Long permissionId;
|
||||
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date createTime;
|
||||
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date updateTime;
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package cn.apes.cloud.domain.entity;
|
||||
|
||||
import cn.apes.commons.domain.DbEntity;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
@TableName("sys_package_plan_quota")
|
||||
public class SysPackagePlanQuota extends DbEntity implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 套餐ID
|
||||
*/
|
||||
private Long planId;
|
||||
|
||||
/**
|
||||
* 配额模板ID
|
||||
*/
|
||||
private Long quotaId;
|
||||
|
||||
/**
|
||||
* 配额值
|
||||
*/
|
||||
private String quotaValue;
|
||||
|
||||
/**
|
||||
* 配额名称(非数据库字段)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String quotaName;
|
||||
|
||||
/**
|
||||
* 配额编码(非数据库字段)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String quotaCode;
|
||||
|
||||
/**
|
||||
* 数据类型(非数据库字段)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String dataType;
|
||||
|
||||
/**
|
||||
* 应用标识(非数据库字段)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String appKey;
|
||||
|
||||
/**
|
||||
* 应用名称(非数据库字段)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String appName;
|
||||
|
||||
/**
|
||||
* 最大配额(非数据库字段)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private Long maxQuota;
|
||||
|
||||
/**
|
||||
* 最大配额值-小数(非数据库字段)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private java.math.BigDecimal maxQuotaValue;
|
||||
|
||||
/**
|
||||
* 枚举值(非数据库字段)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String enumValues;
|
||||
|
||||
/**
|
||||
* 单位(非数据库字段)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String unit;
|
||||
|
||||
/**
|
||||
* 重置周期(非数据库字段)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String resetCycle;
|
||||
|
||||
/**
|
||||
* 默认值(非数据库字段)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String defaultValue;
|
||||
|
||||
/**
|
||||
* 是否已在当前套餐中配置(非数据库字段)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private Boolean configured;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package cn.apes.cloud.domain.entity;
|
||||
|
||||
import cn.apes.commons.domain.DbEntity;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @description sys_permission
|
||||
* @author zhengkai.blog.csdn.net
|
||||
* @date 2023-06-29
|
||||
*/
|
||||
@Data
|
||||
public class SysPermission extends DbEntity implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 权限名称
|
||||
*/
|
||||
private String permissionName;
|
||||
|
||||
/**
|
||||
* 权限code
|
||||
*/
|
||||
private String permissionCode;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 父级id 根为0
|
||||
*/
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 平台类型
|
||||
*/
|
||||
private String appName;
|
||||
|
||||
|
||||
|
||||
@TableField(exist = false)
|
||||
private List<SysPermission> child;
|
||||
|
||||
|
||||
public SysPermission() {}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package cn.apes.cloud.domain.entity;
|
||||
|
||||
import cn.apes.commons.domain.DbEntity;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class SysQuota extends DbEntity implements Serializable {
|
||||
|
||||
/**
|
||||
* 配额名称
|
||||
*/
|
||||
private String quotaName;
|
||||
|
||||
/**
|
||||
* 标识编码
|
||||
*/
|
||||
private String quotaCode;
|
||||
|
||||
/**
|
||||
* 数据类型: integer/decimal/boolean/enum
|
||||
*/
|
||||
private String dataType;
|
||||
|
||||
/**
|
||||
* 最大配额(整数类型)
|
||||
*/
|
||||
private Long maxQuota;
|
||||
|
||||
/**
|
||||
* 最大配额单位(整数类型)
|
||||
*/
|
||||
private String maxQuotaUnit;
|
||||
|
||||
/**
|
||||
* 最大配额值(小数类型)
|
||||
*/
|
||||
private java.math.BigDecimal maxQuotaValue;
|
||||
|
||||
/**
|
||||
* 单位(小数类型)
|
||||
*/
|
||||
private String unit;
|
||||
|
||||
/**
|
||||
* 枚举值,JSON数组格式
|
||||
*/
|
||||
private String enumValues;
|
||||
|
||||
/**
|
||||
* 默认值
|
||||
*/
|
||||
private String defaultValue;
|
||||
|
||||
/**
|
||||
* 重置周期: none/daily/weekly/monthly/yearly
|
||||
*/
|
||||
private String resetCycle;
|
||||
|
||||
/**
|
||||
* 是否显示: 1显示 0隐藏
|
||||
*/
|
||||
private Integer isVisible;
|
||||
|
||||
/**
|
||||
* 说明
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 关联应用标识
|
||||
*/
|
||||
private String appKey;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package cn.apes.cloud.domain.entity;
|
||||
|
||||
|
||||
import cn.apes.commons.domain.DbEntity;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
public class SysRole extends DbEntity implements Serializable {
|
||||
|
||||
/**
|
||||
* 角色名
|
||||
*/
|
||||
private String roleName;
|
||||
|
||||
/**
|
||||
* 角色标识
|
||||
*/
|
||||
private String roleKey;
|
||||
|
||||
/**
|
||||
* 角色所属用户,系统角色为0
|
||||
*/
|
||||
private Long userNo;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 所属套餐ID
|
||||
*/
|
||||
private Long planId;
|
||||
|
||||
/**
|
||||
* @deprecated 已废弃,角色不再直接关联应用,改为通过套餐关联
|
||||
* 保留该字段是为了兼容存量数据
|
||||
*/
|
||||
@Deprecated
|
||||
private String appName;
|
||||
|
||||
@TableField(exist = false)
|
||||
private cn.apes.cloud.domain.entity.SysPackagePlan planInfo;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package cn.apes.cloud.domain.entity;
|
||||
|
||||
import cn.apes.commons.domain.DbEntity;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @description 角色权限表
|
||||
* @author zhengkai.blog.csdn.net
|
||||
* @date 2023-06-29
|
||||
*/
|
||||
@Data
|
||||
public class SysRolePermission extends DbEntity implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 角色id
|
||||
*/
|
||||
private Long roleId;
|
||||
|
||||
/**
|
||||
* 权限id
|
||||
*/
|
||||
private Long permissionId;
|
||||
|
||||
/**
|
||||
* 应用Key
|
||||
*/
|
||||
private String appKey;
|
||||
|
||||
public SysRolePermission() {}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package cn.apes.cloud.domain.entity;
|
||||
|
||||
import cn.apes.commons.domain.DbEntity;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户信息实体类
|
||||
*
|
||||
* @author [你的名字]
|
||||
* @since [创建时间]
|
||||
*/
|
||||
@Data
|
||||
|
||||
public class UserInfo extends DbEntity implements Serializable {
|
||||
|
||||
|
||||
/**
|
||||
* 用户昵称
|
||||
*/
|
||||
private String nickName;
|
||||
|
||||
/**
|
||||
* 用户头像链接
|
||||
*/
|
||||
private String portrait;
|
||||
|
||||
/**
|
||||
* 用户手机号码
|
||||
*/
|
||||
private String phone;
|
||||
|
||||
/**
|
||||
* 邮箱
|
||||
*/
|
||||
private String email;
|
||||
|
||||
/**
|
||||
* 备用邮箱
|
||||
*/
|
||||
private String backupEmail;
|
||||
|
||||
/**
|
||||
* 用户密码(加密存储)
|
||||
*/
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 用户状态(1.正常 2.禁止登录)
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 用户备注信息
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
|
||||
@TableField(exist = false)
|
||||
List<CustomerInfo> customerList;
|
||||
@TableField(exist = false)
|
||||
List<SysRole> roles;
|
||||
@TableField(exist = false)
|
||||
|
||||
private Integer paymentStatus;
|
||||
@TableField(exist = false)
|
||||
|
||||
private Integer huobanStatus;
|
||||
@TableField(exist = false)
|
||||
private Date bindTime;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package cn.apes.cloud.domain.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 用户个性化配置实体类
|
||||
* <p>
|
||||
* 注意:该表以 user_id 作为主键(无自增 id 列),因此不继承 DbEntity,
|
||||
* 避免父类 id 字段映射到不存在的列。
|
||||
*
|
||||
* @author OpenClaw
|
||||
* @since 2026-08-06
|
||||
*/
|
||||
@Data
|
||||
@TableName("user_preference")
|
||||
public class UserPreference {
|
||||
|
||||
/**
|
||||
* 用户ID(主键)
|
||||
*/
|
||||
@TableId(type = IdType.INPUT)
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* UI尺寸 1-最大 2-中等 3-最小
|
||||
*/
|
||||
private Integer uiSize;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
* 逻辑删除 0-正常 1-删除
|
||||
*/
|
||||
@TableLogic
|
||||
private Integer isDel;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package cn.apes.cloud.domain.huoban;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class BulkDel {
|
||||
private String tableId;
|
||||
private List<Long> itemIds;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package cn.apes.cloud.domain.huoban;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class CategoryConfig {
|
||||
private List<Option> options;
|
||||
private int isMulti;
|
||||
private int isTile;
|
||||
|
||||
@Data
|
||||
public static class Option {
|
||||
private String name;
|
||||
private Integer id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package cn.apes.cloud.domain.huoban;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class DataCreate {
|
||||
|
||||
public DataCreate() {
|
||||
|
||||
}
|
||||
|
||||
public DataCreate(Long tableId, JSONObject fields) {
|
||||
setFields(fields);
|
||||
setTableId(tableId);
|
||||
}
|
||||
|
||||
private Long tableId;
|
||||
private String tableName;
|
||||
|
||||
private JSONObject fields;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package cn.apes.cloud.domain.huoban;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class DataFilter {
|
||||
|
||||
public DataFilter() {
|
||||
|
||||
}
|
||||
|
||||
public DataFilter(Long tableId) {
|
||||
setTableId(tableId);
|
||||
setRelations(new ArrayList<>());
|
||||
}
|
||||
|
||||
private Long tableId;
|
||||
private String tableName;
|
||||
|
||||
private String orderField;
|
||||
private String orderType;
|
||||
|
||||
private Integer limit;
|
||||
private Integer offset;
|
||||
|
||||
private Object filter;
|
||||
|
||||
private List<String> relations;
|
||||
|
||||
List<DataFilterCondition> conditions = new ArrayList<>();
|
||||
|
||||
List<TableSub> subTables;
|
||||
|
||||
public void addSubTable(String tableName,Long tableId,String tableField) {
|
||||
if (subTables == null) {
|
||||
subTables = new ArrayList<>();
|
||||
}
|
||||
TableSub tableSub = new TableSub();
|
||||
tableSub.setTableId(tableId);
|
||||
tableSub.setTableName(tableName);
|
||||
tableSub.setTableField(tableField);
|
||||
subTables.add(tableSub);
|
||||
}
|
||||
|
||||
public void addCondition(String filedName, String oper, Object value) {
|
||||
DataFilterCondition condition = new DataFilterCondition();
|
||||
condition.setValue(value);
|
||||
condition.setFieldName(filedName);
|
||||
condition.setOperator(oper);
|
||||
if (conditions == null) {
|
||||
conditions = new ArrayList<DataFilterCondition>();
|
||||
}
|
||||
conditions.add(condition);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package cn.apes.cloud.domain.huoban;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class DataFilterCondition {
|
||||
|
||||
public DataFilterCondition() {
|
||||
|
||||
}
|
||||
|
||||
public DataFilterCondition(String fieldName, String operator, Object value) {
|
||||
setFieldName(fieldName);
|
||||
setOperator(operator);
|
||||
setValue(value);
|
||||
}
|
||||
|
||||
private String fieldName;
|
||||
private Object value;
|
||||
|
||||
private String operator;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package cn.apes.cloud.domain.huoban;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class DataUpdate {
|
||||
public DataUpdate(){
|
||||
|
||||
}
|
||||
private Long tableId;
|
||||
private String tableName;
|
||||
|
||||
private Long itemId;
|
||||
|
||||
public DataUpdate(Long tableId, Long itemId,JSONObject fields) {
|
||||
setTableId(tableId);
|
||||
setItemId(itemId);
|
||||
setFields(fields);
|
||||
}
|
||||
|
||||
private JSONObject fields;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package cn.apes.cloud.domain.huoban;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.Data;
|
||||
|
||||
import java.security.PublicKey;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Data
|
||||
public class DataUpsert {
|
||||
public DataUpsert(){
|
||||
|
||||
}
|
||||
public DataUpsert(Long tableId,String... _updateFields){
|
||||
setTableId(tableId);
|
||||
setUpdateFields(Arrays.asList(_updateFields));
|
||||
items = new ArrayList<>();
|
||||
}
|
||||
public DataUpsert(Long tableId,List<JSONObject> dataItems,String... _updateFields){
|
||||
setTableId(tableId);
|
||||
setUpdateFields(Arrays.asList(_updateFields));
|
||||
setItems(dataItems);
|
||||
}
|
||||
public void addItem(JSONObject data){
|
||||
items.add(data);
|
||||
}
|
||||
private Long tableId;
|
||||
private List<String> updateFields;
|
||||
private List<JSONObject> items;
|
||||
private String tableName;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package cn.apes.cloud.domain.huoban;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
@TableName("huoban_table_column")
|
||||
@Data
|
||||
public class TableColumn {
|
||||
@TableId
|
||||
@JSONField(name = "field_id")
|
||||
private Long fieldId;
|
||||
private Long relationFieldId;
|
||||
|
||||
private Long tableId;
|
||||
private Long spaceId;
|
||||
|
||||
private String name;
|
||||
private String alias;
|
||||
private String formName;
|
||||
private String groupName;
|
||||
@JSONField(name = "field_type")
|
||||
private String fieldType;
|
||||
@JSONField(name = "data_type")
|
||||
private String dataType;
|
||||
private Boolean required;
|
||||
private String description;
|
||||
private String columnConfig;
|
||||
private Integer relationField;
|
||||
private Integer canAdd;
|
||||
private Integer canEdit;
|
||||
private String defaultValue;
|
||||
private Integer sortValue;
|
||||
private String remark;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package cn.apes.cloud.domain.huoban;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@TableName("huoban_table_info")
|
||||
@Data
|
||||
public class TableInfo {
|
||||
@TableId
|
||||
@JSONField(name = "table_id")
|
||||
private Long tableId;
|
||||
private String name;
|
||||
private String formName;
|
||||
private String showName;
|
||||
private String groupConfig;
|
||||
private String addButton;
|
||||
private String editButton;
|
||||
private String alias;
|
||||
@JSONField(name = "space_id")
|
||||
private Long spaceId;
|
||||
@JSONField(name = "created_on")
|
||||
private Date createdOn;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package cn.apes.cloud.domain.huoban;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class TableSub {
|
||||
private String tableName;
|
||||
private Long tableId;
|
||||
private String tableField;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package cn.apes.cloud.domain.huoban;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class UpsertOne {
|
||||
public UpsertOne() {
|
||||
|
||||
}
|
||||
public UpsertOne(Long tableId, JSONObject fields) {
|
||||
setFields(fields);
|
||||
setTableId(tableId);
|
||||
}
|
||||
|
||||
private Long tableId;
|
||||
private String tableName;
|
||||
|
||||
private JSONObject fields;
|
||||
|
||||
private List<String> updateFields;
|
||||
|
||||
/**
|
||||
* 操作 one_update 发现一条数据更新,zero_create 未找到数据新增数据,one_none 有数据时不执行任何操作
|
||||
*/
|
||||
private String action;
|
||||
|
||||
public DataCreate getDataCreate() {
|
||||
DataCreate dataCreate = new DataCreate();
|
||||
dataCreate.setTableId(tableId);
|
||||
dataCreate.setTableName(tableName);
|
||||
dataCreate.setFields(fields);
|
||||
return dataCreate;
|
||||
}
|
||||
|
||||
public DataUpdate getDataUpdate(Long itemId) {
|
||||
DataUpdate dataUpdate = new DataUpdate();
|
||||
dataUpdate.setTableId(tableId);
|
||||
dataUpdate.setTableName(tableName);
|
||||
dataUpdate.setFields(fields);
|
||||
dataUpdate.setItemId(itemId);
|
||||
return dataUpdate;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package cn.apes.cloud.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
public class CustomerAppVO implements Serializable {
|
||||
|
||||
private String appKey;
|
||||
private String appName;
|
||||
private String appShortName;
|
||||
private String appIcon;
|
||||
/**
|
||||
* 应用类型: basic=基础, internal=内部, paid=付费
|
||||
*/
|
||||
private String appType;
|
||||
private String remark;
|
||||
private Integer userVisible;
|
||||
private Date createTime;
|
||||
/**
|
||||
* 应用来源: package=套餐包含, app=客户直接关联
|
||||
*/
|
||||
private String source;
|
||||
|
||||
/**
|
||||
* 是否过期(仅 source=package 时有效)
|
||||
*/
|
||||
private Boolean expired;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package cn.apes.cloud.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
public class CustomerPackageExtendApplyVO implements Serializable {
|
||||
|
||||
private Long id;
|
||||
private Long customerId;
|
||||
private String customerName;
|
||||
private String shortName;
|
||||
private String adminPhone;
|
||||
private Long planId;
|
||||
private String planName;
|
||||
private Long userId;
|
||||
private String contactPhone;
|
||||
private String reason;
|
||||
private Integer applyDays;
|
||||
private Date applyTime;
|
||||
private Integer status;
|
||||
private String statusText;
|
||||
private Long operatorId;
|
||||
private String operatorName;
|
||||
private Date operateTime;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package cn.apes.cloud.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
public class CustomerPackageVO implements Serializable {
|
||||
|
||||
private Long customerId;
|
||||
private String shortName;
|
||||
private String customerName;
|
||||
private String adminPhone;
|
||||
private Long packageId;
|
||||
private Long planId;
|
||||
private String planName;
|
||||
private Date expireTime;
|
||||
/** 剩余天数(负数表示已过期) */
|
||||
private Long remainingDays;
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
package cn.apes.cloud.filter;
|
||||
|
||||
import cn.apes.commons.auth.AuthContext;
|
||||
import cn.apes.commons.auth.LoginCustomer;
|
||||
import cn.apes.commons.auth.LoginUser;
|
||||
import cn.apes.commons.auth.UserSession;
|
||||
import cn.apes.cloud.domain.entity.CustomerInfo;
|
||||
import cn.apes.cloud.domain.entity.SysAccessToken;
|
||||
import cn.apes.cloud.service.impl.CustomerInfoServiceImpl;
|
||||
import cn.apes.cloud.service.SysAccessTokenService;
|
||||
import cn.apes.cloud.util.OperationLogUtil;
|
||||
import cn.apes.commons.Res;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.redisson.api.RBucket;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletRequestWrapper;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* AccessToken 校验过滤器
|
||||
*
|
||||
* 逻辑:
|
||||
* 1. 检查请求头是否携带 X-Access-Token 或 Authorization: Bearer <token>
|
||||
* 2. 如果有,走 AccessToken 校验逻辑
|
||||
* 3. 校验通过则:
|
||||
* - 将 Redis 数据写入 Redis(user + customer),使后续 @Login AOP 能正常读取
|
||||
* - 包装 request,将 token 注入 "token" header,使 @Login AOP 能取到
|
||||
* 4. 校验失败返回 401
|
||||
* 5. 如果没有携带 Token,放行,交给后续的 @Login AOP 处理
|
||||
*/
|
||||
@Component
|
||||
public class AccessTokenFilter implements Filter {
|
||||
|
||||
@Autowired
|
||||
private SysAccessTokenService accessTokenService;
|
||||
|
||||
@Autowired
|
||||
private CustomerInfoServiceImpl customerInfoService;
|
||||
|
||||
@Autowired
|
||||
private RedissonClient redissonClient;
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
|
||||
throws IOException, ServletException {
|
||||
|
||||
HttpServletRequest request = (HttpServletRequest) servletRequest;
|
||||
HttpServletResponse response = (HttpServletResponse) servletResponse;
|
||||
|
||||
String token = extractToken(request);
|
||||
|
||||
if (token != null && !token.isEmpty()) {
|
||||
// 有 Token → 校验
|
||||
String clientIp = getClientIp(request);
|
||||
SysAccessToken record = accessTokenService.validate(token, clientIp);
|
||||
|
||||
if (record == null) {
|
||||
// 无效 Token → 返回 401
|
||||
String method = request.getMethod();
|
||||
String uri = request.getRequestURI();
|
||||
OperationLogUtil.logDirect(0L, "外部系统", null, null, "AccessToken", "调用失败(无效Token)",
|
||||
method + " " + uri, clientIp, request.getHeader("User-Agent"));
|
||||
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.getWriter().write(JSON.toJSONString(Res.fail("无效或已失效的 AccessToken")));
|
||||
return;
|
||||
}
|
||||
|
||||
// 校验通过 → 将数据写入 Redis,使 @Login AOP 能正常读取
|
||||
String redisToken = record.getToken();
|
||||
writeTokenToRedis(redisToken, record);
|
||||
|
||||
// 包装 request,注入 "token" header
|
||||
final String finalToken = redisToken;
|
||||
request = new HttpServletRequestWrapper(request) {
|
||||
@Override
|
||||
public String getHeader(String name) {
|
||||
if ("token".equalsIgnoreCase(name)) {
|
||||
return finalToken;
|
||||
}
|
||||
return super.getHeader(name);
|
||||
}
|
||||
@Override
|
||||
public Enumeration<String> getHeaderNames() {
|
||||
List<String> names = Collections.list(super.getHeaderNames());
|
||||
if (!names.contains("token")) {
|
||||
names.add("token");
|
||||
}
|
||||
return Collections.enumeration(names);
|
||||
}
|
||||
};
|
||||
|
||||
// 标记 AccessToken 已验证
|
||||
request.setAttribute("accessTokenVerified", true);
|
||||
request.setAttribute("accessTokenCustomerId", record.getCustomerId());
|
||||
|
||||
// 记录外部系统调用日志
|
||||
String method = request.getMethod();
|
||||
String uri = request.getRequestURI();
|
||||
String userAgent = request.getHeader("User-Agent");
|
||||
OperationLogUtil.logDirect(0L, "AccessToken:" + record.getName(), record.getCustomerId(), null,
|
||||
"AccessToken", "调用", method + " " + uri, clientIp, userAgent);
|
||||
}
|
||||
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
|
||||
private void writeTokenToRedis(String redisToken, SysAccessToken record) {
|
||||
try {
|
||||
// 写入用户信息 (key = token)
|
||||
// 必须使用 JSONObject 对象写入,使 JsonJacksonCodec 能正确序列化
|
||||
// 这样 LoginAspect 反序列化时才能得到 JSONObject
|
||||
JSONObject userObj = new JSONObject();
|
||||
userObj.put("id", 0L);
|
||||
userObj.put("nickName", "AccessToken:" + record.getName());
|
||||
userObj.put("phone", "");
|
||||
RBucket<JSONObject> userBucket = redissonClient.getBucket(redisToken);
|
||||
userBucket.set(userObj, 1, TimeUnit.DAYS);
|
||||
|
||||
// 查询企业信息表,获取完整企业信息
|
||||
CustomerInfo customerInfo = customerInfoService.getById(record.getCustomerId());
|
||||
|
||||
// 写入企业信息 (key = token:customer)
|
||||
JSONObject customerObj = new JSONObject();
|
||||
if (customerInfo != null) {
|
||||
customerObj.put("id", customerInfo.getId());
|
||||
customerObj.put("customerType", customerInfo.getCustomerType());
|
||||
customerObj.put("customerName", customerInfo.getCustomerName());
|
||||
customerObj.put("logo", customerInfo.getLogo());
|
||||
customerObj.put("shortName", customerInfo.getShortName());
|
||||
customerObj.put("customerIdNumber", customerInfo.getCustomerIdNumber());
|
||||
customerObj.put("customerStatus", customerInfo.getCustomerStatus());
|
||||
customerObj.put("auditRemark", customerInfo.getAuditRemark());
|
||||
customerObj.put("auditTime", customerInfo.getAuditTime());
|
||||
customerObj.put("adminName", customerInfo.getAdminName());
|
||||
customerObj.put("adminPhone", customerInfo.getAdminPhone());
|
||||
customerObj.put("adminIdNumber", customerInfo.getAdminIdNumber());
|
||||
customerObj.put("businessLicense", customerInfo.getBusinessLicense());
|
||||
customerObj.put("legalName", customerInfo.getLegalName());
|
||||
customerObj.put("legalIdFront", customerInfo.getLegalIdFront());
|
||||
customerObj.put("legalIdBack", customerInfo.getLegalIdBack());
|
||||
customerObj.put("responsibleIdFront", customerInfo.getResponsibleIdFront());
|
||||
customerObj.put("responsibleIdBack", customerInfo.getResponsibleIdBack());
|
||||
customerObj.put("industry", customerInfo.getIndustry());
|
||||
customerObj.put("industrySub", customerInfo.getIndustrySub());
|
||||
customerObj.put("salesChannel", customerInfo.getSalesChannel());
|
||||
customerObj.put("industryType", customerInfo.getIndustryType());
|
||||
customerObj.put("province", customerInfo.getProvince());
|
||||
customerObj.put("city", customerInfo.getCity());
|
||||
} else {
|
||||
customerObj.put("id", record.getCustomerId());
|
||||
customerObj.put("customerName", "");
|
||||
}
|
||||
RBucket<JSONObject> customerBucket = redissonClient.getBucket(redisToken + ":customer");
|
||||
customerBucket.set(customerObj, 1, TimeUnit.DAYS);
|
||||
} catch (Exception e) {
|
||||
// Redis 写入失败不影响主流程
|
||||
}
|
||||
}
|
||||
|
||||
private String extractToken(HttpServletRequest request) {
|
||||
// 优先取 X-Access-Token
|
||||
String token = request.getHeader("X-Access-Token");
|
||||
if (token != null && !token.isEmpty()) {
|
||||
return token;
|
||||
}
|
||||
|
||||
// 其次取 Authorization: Bearer
|
||||
String authHeader = request.getHeader("Authorization");
|
||||
if (authHeader != null && authHeader.startsWith("Bearer ")) {
|
||||
return authHeader.substring(7).trim();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getClientIp(HttpServletRequest request) {
|
||||
String ip = request.getHeader("X-Forwarded-For");
|
||||
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("X-Real-IP");
|
||||
}
|
||||
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getRemoteAddr();
|
||||
}
|
||||
if (ip != null && ip.contains(",")) {
|
||||
ip = ip.split(",")[0].trim();
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package cn.apes.cloud.mapper;
|
||||
|
||||
import cn.apes.cloud.domain.entity.AppInfo;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
public interface AppInfoMapper extends BaseMapper<AppInfo> {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package cn.apes.cloud.mapper;
|
||||
|
||||
import cn.apes.cloud.domain.entity.CustomerApp;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
public interface CustomerAppMapper extends BaseMapper<CustomerApp> {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package cn.apes.cloud.mapper;
|
||||
|
||||
import cn.apes.cloud.domain.entity.CustomerInfo;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
public interface CustomerInfoMapper extends BaseMapper<CustomerInfo> {
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package cn.apes.cloud.mapper;
|
||||
|
||||
import cn.apes.cloud.domain.entity.CustomerPackageExtendApply;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface CustomerPackageExtendApplyMapper extends BaseMapper<CustomerPackageExtendApply> {
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package cn.apes.cloud.mapper;
|
||||
|
||||
import cn.apes.cloud.domain.entity.CustomerPackage;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.apache.ibatis.annotations.Update;
|
||||
import java.util.Date;
|
||||
|
||||
@Mapper
|
||||
public interface CustomerPackageMapper extends BaseMapper<CustomerPackage> {
|
||||
|
||||
/**
|
||||
* 绕过 @TableLogic 查询所有记录(含软删除)
|
||||
*/
|
||||
@Select("SELECT id, customer_id, plan_id, expire_time, is_del, create_time, update_time FROM customer_package WHERE customer_id = #{customerId} AND plan_id = #{planId} ORDER BY id DESC LIMIT 1")
|
||||
CustomerPackage selectOneIgnoreLogic(@Param("customerId") Long customerId, @Param("planId") Long planId);
|
||||
|
||||
/**
|
||||
* 绕过 @TableLogic 恢复软删除记录
|
||||
*/
|
||||
@Update("UPDATE customer_package SET is_del = 0, expire_time = #{expireTime}, update_time = NOW() WHERE id = #{id}")
|
||||
int restoreRecord(@Param("id") Long id, @Param("expireTime") Date expireTime);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package cn.apes.cloud.mapper;
|
||||
|
||||
import cn.apes.cloud.domain.entity.CustomerPackageQuota;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Delete;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface CustomerPackageQuotaMapper extends BaseMapper<CustomerPackageQuota> {
|
||||
|
||||
/**
|
||||
* 物理删除(不走逻辑删除)
|
||||
*/
|
||||
@Delete("DELETE FROM customer_package_quota WHERE customer_package_id = #{packageId}")
|
||||
int physicalDeleteByPackageId(Long packageId);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package cn.apes.cloud.mapper;
|
||||
|
||||
import cn.apes.cloud.domain.entity.CustomerQuotaChangeLog;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface CustomerQuotaChangeLogMapper extends BaseMapper<CustomerQuotaChangeLog> {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package cn.apes.cloud.mapper;
|
||||
|
||||
import cn.apes.cloud.domain.entity.CustomerUser;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
public interface CustomerUserMapper extends BaseMapper<CustomerUser> {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package cn.apes.cloud.mapper;
|
||||
|
||||
import cn.apes.cloud.domain.entity.SsoConfig;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
public interface SsoConfigMapper extends BaseMapper<SsoConfig> {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package cn.apes.cloud.mapper;
|
||||
|
||||
import cn.apes.cloud.domain.entity.SysAccessToken;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* AccessToken Mapper
|
||||
*/
|
||||
public interface SysAccessTokenMapper extends BaseMapper<SysAccessToken> {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package cn.apes.cloud.mapper;
|
||||
|
||||
import cn.apes.cloud.domain.entity.SysMemberRole;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
public interface SysMemberRoleMapper extends BaseMapper<SysMemberRole> {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package cn.apes.cloud.mapper;
|
||||
|
||||
import cn.apes.cloud.domain.entity.SysMenu;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
public interface SysMenuMapper extends BaseMapper<SysMenu> {
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package cn.apes.cloud.mapper;
|
||||
|
||||
import cn.apes.cloud.domain.entity.SysOperationLog;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface SysOperationLogMapper extends BaseMapper<SysOperationLog> {
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package cn.apes.cloud.mapper;
|
||||
|
||||
import cn.apes.cloud.domain.entity.SysOrganization;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface SysOrganizationMapper extends BaseMapper<SysOrganization> {
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package cn.apes.cloud.mapper;
|
||||
|
||||
import cn.apes.cloud.domain.entity.SysPackagePlan;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface SysPackagePlanMapper extends BaseMapper<SysPackagePlan> {
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package cn.apes.cloud.mapper;
|
||||
|
||||
import cn.apes.cloud.domain.entity.SysPackagePlanPermission;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface SysPackagePlanPermissionMapper extends BaseMapper<SysPackagePlanPermission> {
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package cn.apes.cloud.mapper;
|
||||
|
||||
import cn.apes.cloud.domain.entity.SysPackagePlanQuota;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface SysPackagePlanQuotaMapper extends BaseMapper<SysPackagePlanQuota> {
|
||||
@org.apache.ibatis.annotations.Delete("DELETE FROM sys_package_plan_quota WHERE plan_id = #{planId}")
|
||||
int physicalDeleteByPlanId(Long planId);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package cn.apes.cloud.mapper;
|
||||
|
||||
import cn.apes.cloud.domain.entity.SysPermission;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
public interface SysPermissionMapper extends BaseMapper<SysPermission> {
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package cn.apes.cloud.mapper;
|
||||
|
||||
import cn.apes.cloud.domain.entity.SysQuota;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface SysQuotaMapper extends BaseMapper<SysQuota> {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package cn.apes.cloud.mapper;
|
||||
|
||||
import cn.apes.cloud.domain.entity.SysRole;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface SysRoleMapper extends BaseMapper<SysRole> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package cn.apes.cloud.mapper;
|
||||
|
||||
import cn.apes.cloud.domain.entity.SysRolePermission;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
public interface SysRolePermissionMapper extends BaseMapper<SysRolePermission> {
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package cn.apes.cloud.mapper;
|
||||
|
||||
import cn.apes.cloud.domain.entity.UserInfo;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface UserInfoMapper extends BaseMapper<UserInfo> {
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package cn.apes.cloud.mapper;
|
||||
|
||||
import cn.apes.cloud.domain.entity.UserPreference;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.apache.ibatis.annotations.Update;
|
||||
|
||||
/**
|
||||
* 用户个性化配置 Mapper接口
|
||||
*
|
||||
* @author OpenClaw
|
||||
* @since 2026-08-06
|
||||
*/
|
||||
public interface UserPreferenceMapper extends BaseMapper<UserPreference> {
|
||||
|
||||
/**
|
||||
* 更新指定用户的配置(包含已逻辑删除的行,同时恢复 is_del=0)
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param uiSize UI尺寸 1-最大 2-中等 3-最小
|
||||
* @return int 影响行数,0表示该用户不存在任何记录(含已删除)
|
||||
*/
|
||||
@Update("update user_preference set ui_size = #{uiSize}, is_del = 0 where user_id = #{userId}")
|
||||
int updateIncludeDeleted(@Param("userId") Long userId, @Param("uiSize") Integer uiSize);
|
||||
|
||||
/**
|
||||
* 统计指定用户的记录数(包含已逻辑删除的行)
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return int 记录数(含已删除)
|
||||
*/
|
||||
@Select("select count(1) from user_preference where user_id = #{userId}")
|
||||
int countIncludeDeleted(@Param("userId") Long userId);
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package cn.apes.cloud.service;
|
||||
|
||||
import cn.apes.cloud.domain.entity.CustomerPackage;
|
||||
import cn.apes.cloud.domain.vo.CustomerPackageVO;
|
||||
import cn.apes.cloud.domain.vo.CustomerPackageExtendApplyVO;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface CustomerPackageService extends IService<CustomerPackage> {
|
||||
|
||||
/**
|
||||
* 获取客户的套餐列表
|
||||
*/
|
||||
cn.apes.commons.Res getCustomerPackages(Long customerId);
|
||||
|
||||
/**
|
||||
* 为客户添加套餐
|
||||
*/
|
||||
cn.apes.commons.Res addCustomerPackage(CustomerPackage customerPackage);
|
||||
|
||||
/**
|
||||
* 编辑客户套餐
|
||||
*/
|
||||
cn.apes.commons.Res editCustomerPackage(java.util.Map<String, Object> data);
|
||||
|
||||
/**
|
||||
* 删除客户套餐
|
||||
*/
|
||||
cn.apes.commons.Res deleteCustomerPackage(Long id);
|
||||
|
||||
/**
|
||||
* 保存客户套餐配额
|
||||
*/
|
||||
cn.apes.commons.Res saveCustomerPackageQuotas(Long packageId, java.util.Map<String, Object> quotaValues);
|
||||
|
||||
/**
|
||||
* 获取客户套餐配额
|
||||
*/
|
||||
cn.apes.commons.Res getCustomerPackageQuotas(Long packageId);
|
||||
|
||||
/**
|
||||
* 获取当前客户套餐详情(含配额,用于前端展示)
|
||||
*/
|
||||
cn.apes.commons.Res getMyPackages(Long customerId);
|
||||
|
||||
/**
|
||||
* 查询所有客户的套餐概况(管理端)
|
||||
*/
|
||||
cn.apes.commons.Res getCustomerPackageOverview(java.util.Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* 提交套餐延期申请
|
||||
*/
|
||||
cn.apes.commons.Res submitExtendApply(java.util.Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* 查询套餐延期申请记录列表(管理端)
|
||||
*/
|
||||
cn.apes.commons.Res getExtendApplyList(java.util.Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* 审核延期申请(同意/拒绝)
|
||||
*/
|
||||
cn.apes.commons.Res reviewExtendApply(java.util.Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* 增加客户套餐额度
|
||||
*/
|
||||
cn.apes.commons.Res increaseQuota(java.util.Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* 减少客户套餐额度
|
||||
*/
|
||||
cn.apes.commons.Res decreaseQuota(java.util.Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* 获取配额变更日志列表
|
||||
*/
|
||||
cn.apes.commons.Res getQuotaChangeLogs(java.util.Map<String, Object> params);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package cn.apes.cloud.service;
|
||||
|
||||
import cn.apes.cloud.domain.entity.SysAccessToken;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* AccessToken Service
|
||||
*/
|
||||
public interface SysAccessTokenService extends IService<SysAccessToken> {
|
||||
|
||||
/**
|
||||
* 校验 Token 是否有效
|
||||
* @param token token 值
|
||||
* @return 匹配的 SysAccessToken,无效则返回 null
|
||||
*/
|
||||
SysAccessToken validate(String token, String clientIp);
|
||||
|
||||
/**
|
||||
* 生成新的 Token 值
|
||||
*/
|
||||
String generateToken();
|
||||
|
||||
/**
|
||||
* 撤销 Token
|
||||
*/
|
||||
void revoke(Long id);
|
||||
|
||||
/**
|
||||
* 启用 Token
|
||||
*/
|
||||
void enable(Long id);
|
||||
|
||||
/**
|
||||
* 重新生成 Token(旧 Token 立即失效)
|
||||
*/
|
||||
String regenerate(Long id);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package cn.apes.cloud.service;
|
||||
|
||||
import cn.apes.cloud.domain.entity.SysOperationLog;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 操作日志服务接口
|
||||
*/
|
||||
public interface SysOperationLogService {
|
||||
|
||||
/**
|
||||
* 记录操作日志(公共方法)
|
||||
*/
|
||||
void log(Long userId, String userName, Long customerId, String customerName,
|
||||
String module, String action, String description);
|
||||
|
||||
/**
|
||||
* 记录操作日志(带完整参数)
|
||||
*/
|
||||
void log(Long userId, String userName, Long customerId, String customerName,
|
||||
String module, String action, String description, String ip, String userAgent);
|
||||
|
||||
/**
|
||||
* 分页查询日志列表
|
||||
*/
|
||||
IPage<Map<String, Object>> pageLogs(int pageIndex, int pageSize,
|
||||
Long customerId, Long userId,
|
||||
String startDate, String endDate);
|
||||
|
||||
/**
|
||||
* 获取企业列表(用于下拉筛选)
|
||||
*/
|
||||
java.util.List<Map<String, Object>> listCustomers();
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package cn.apes.cloud.service;
|
||||
|
||||
import cn.apes.cloud.domain.entity.SysPackagePlanQuota;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface SysPackagePlanQuotaService extends IService<SysPackagePlanQuota> {
|
||||
|
||||
/**
|
||||
* 获取套餐的配额配置列表
|
||||
*/
|
||||
cn.apes.commons.Res getPlanQuotas(Long planId);
|
||||
|
||||
/**
|
||||
* 保存套餐的配额配置
|
||||
* @param planId 套餐ID
|
||||
* @param quotaValues Map<quotaId, quotaValue>
|
||||
*/
|
||||
cn.apes.commons.Res savePlanQuotas(Long planId, Map<Long, String> quotaValues);
|
||||
|
||||
/**
|
||||
* 获取所有配额模板 + 标记是否已在当前套餐中配置
|
||||
*/
|
||||
cn.apes.commons.Res getAllQuotas(Long planId);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package cn.apes.cloud.service;
|
||||
|
||||
import cn.apes.cloud.domain.entity.SysPackagePlan;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface SysPackagePlanService extends IService<SysPackagePlan> {
|
||||
|
||||
/**
|
||||
* 获取套餐已分配的权限
|
||||
*/
|
||||
Map<String, List<Long>> getPlanPermissions(Long planId);
|
||||
|
||||
/**
|
||||
* 保存套餐权限关联
|
||||
*/
|
||||
cn.apes.commons.Res savePlanPermissions(Long planId, Map<String, List<Long>> appPermissions);
|
||||
|
||||
/**
|
||||
* 获取套餐关联的应用列表
|
||||
*/
|
||||
cn.apes.commons.Res getPlanApps(Long planId);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package cn.apes.cloud.service;
|
||||
|
||||
import cn.apes.cloud.domain.entity.SysQuota;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
public interface SysQuotaService extends IService<SysQuota> {
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user