pangu-user-platform/docs/应用管理技术方案.md

17 KiB
Raw Permalink Blame History

应用管理技术方案

一、功能概述

应用管理模块用于管理接入盘古用户认证中心的第三方应用系统,实现应用注册、密钥管理、接口授权等功能。

二、数据库设计

2.1 ER 关系图

┌─────────────────┐       ┌─────────────────┐       ┌─────────────────┐
│  pg_application │       │   pg_app_api    │       │   pg_api_dict   │
│  (第三方应用表)  │ 1───n │ (应用API授权表) │ n───1 │ (API接口字典表) │
└─────────────────┘       └─────────────────┘       └─────────────────┘

2.2 表结构设计

2.2.1 第三方应用表 (pg_application)

字段名 类型 必填 说明
app_id bigint 应用ID主键雪花算法
app_code varchar(32) 应用编码唯一格式YY000001
app_name varchar(100) 应用名称
app_secret varchar(100) 应用密钥32位UUID
contact_person varchar(50) 联系人
contact_phone varchar(20) 联系电话
status char(1) 状态0正常 1停用
tenant_id varchar(20) 租户编号
create_dept bigint 创建部门
create_by bigint 创建者
create_time datetime 创建时间
update_by bigint 更新者
update_time datetime 更新时间
del_flag char(1) 删除标志0存在 1删除
remark varchar(500) 备注

索引

  • PRIMARY KEY (app_id)
  • UNIQUE KEY uk_app_code (app_code)

2.2.2 API接口字典表 (pg_api_dict)

字段名 类型 必填 说明
api_id bigint API ID主键
api_code varchar(50) API编码唯一
api_name varchar(100) API名称
api_path varchar(200) API路径
api_method varchar(10) 请求方法GET/POST/PUT/DELETE
api_desc varchar(500) API描述
status char(1) 状态0正常 1停用
order_num int 排序号

索引

  • PRIMARY KEY (api_id)
  • UNIQUE KEY uk_api_code (api_code)

2.2.3 应用API授权表 (pg_app_api)

字段名 类型 必填 说明
id bigint 主键
app_id bigint 应用ID
api_id bigint API ID
create_time datetime 创建时间

索引

  • PRIMARY KEY (id)
  • UNIQUE KEY uk_app_api (app_id, api_id)

2.3 SQL 脚本

-- 第三方应用表
DROP TABLE IF EXISTS `pg_application`;
CREATE TABLE `pg_application` (
  `app_id` bigint NOT NULL COMMENT '应用ID',
  `app_code` varchar(32) NOT NULL COMMENT '应用编码',
  `app_name` varchar(100) NOT NULL COMMENT '应用名称',
  `app_secret` varchar(100) NOT NULL COMMENT '应用密钥',
  `contact_person` varchar(50) DEFAULT NULL COMMENT '联系人',
  `contact_phone` varchar(20) DEFAULT NULL COMMENT '联系电话',
  `status` char(1) DEFAULT '0' COMMENT '状态0正常 1停用',
  `tenant_id` varchar(20) DEFAULT '000000' COMMENT '租户编号',
  `create_dept` bigint DEFAULT NULL COMMENT '创建部门',
  `create_by` bigint DEFAULT NULL COMMENT '创建者',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_by` bigint DEFAULT NULL COMMENT '更新者',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  `del_flag` char(1) DEFAULT '0' COMMENT '删除标志0存在 1删除',
  `remark` varchar(500) DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`app_id`),
  UNIQUE KEY `uk_app_code` (`app_code`)
) ENGINE=InnoDB COMMENT='第三方应用表';

-- API接口字典表
DROP TABLE IF EXISTS `pg_api_dict`;
CREATE TABLE `pg_api_dict` (
  `api_id` bigint NOT NULL COMMENT 'API ID',
  `api_code` varchar(50) NOT NULL COMMENT 'API编码',
  `api_name` varchar(100) NOT NULL COMMENT 'API名称',
  `api_path` varchar(200) NOT NULL COMMENT 'API路径',
  `api_method` varchar(10) DEFAULT 'GET' COMMENT '请求方法',
  `api_desc` varchar(500) DEFAULT NULL COMMENT 'API描述',
  `status` char(1) DEFAULT '0' COMMENT '状态0正常 1停用',
  `order_num` int DEFAULT 0 COMMENT '排序',
  PRIMARY KEY (`api_id`),
  UNIQUE KEY `uk_api_code` (`api_code`)
) ENGINE=InnoDB COMMENT='API接口字典表';

-- 应用API授权表
DROP TABLE IF EXISTS `pg_app_api`;
CREATE TABLE `pg_app_api` (
  `id` bigint NOT NULL COMMENT '主键',
  `app_id` bigint NOT NULL COMMENT '应用ID',
  `api_id` bigint NOT NULL COMMENT 'API ID',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_app_api` (`app_id`, `api_id`)
) ENGINE=InnoDB COMMENT='应用API授权表';

-- 菜单数据
INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query_param, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time)
VALUES (2300, '应用管理', 0, 4, 'application', 'business/application/index', '', 1, 0, 'C', '0', '0', 'business:application:list', 'component', 103, 1, NOW());
INSERT INTO sys_menu VALUES (2301, '应用查询', 2300, 1, '', '', '', 1, 0, 'F', '0', '0', 'business:application:query', '#', 103, 1, NOW(), NULL, NULL, '');
INSERT INTO sys_menu VALUES (2302, '应用新增', 2300, 2, '', '', '', 1, 0, 'F', '0', '0', 'business:application:add', '#', 103, 1, NOW(), NULL, NULL, '');
INSERT INTO sys_menu VALUES (2303, '应用修改', 2300, 3, '', '', '', 1, 0, 'F', '0', '0', 'business:application:edit', '#', 103, 1, NOW(), NULL, NULL, '');
INSERT INTO sys_menu VALUES (2304, '应用删除', 2300, 4, '', '', '', 1, 0, 'F', '0', '0', 'business:application:remove', '#', 103, 1, NOW(), NULL, NULL, '');
INSERT INTO sys_menu VALUES (2305, '重置密钥', 2300, 5, '', '', '', 1, 0, 'F', '0', '0', 'business:application:resetSecret', '#', 103, 1, NOW(), NULL, NULL, '');
INSERT INTO sys_menu VALUES (2306, '接口授权', 2300, 6, '', '', '', 1, 0, 'F', '0', '0', 'business:application:api', '#', 103, 1, NOW(), NULL, NULL, '');

-- API字典初始数据
INSERT INTO pg_api_dict (api_id, api_code, api_name, api_path, api_method, api_desc, status, order_num)
VALUES (1700000000000000001, 'OPEN_STUDENT_LIST', '学生列表', '/open/api/student/list', 'GET', '开放API-学生列表分页查询', '0', 10);

三、后端代码结构

3.1 目录结构

pangu-modules/pangu-business/src/main/java/org/dromara/pangu/application/
├── controller/
│   └── PgApplicationController.java    # 应用管理控制器
├── domain/
│   ├── PgApplication.java              # 第三方应用实体
│   ├── PgApiDict.java                  # API字典实体
│   └── PgAppApi.java                   # 应用API授权实体
├── mapper/
│   ├── PgApplicationMapper.java        # 应用Mapper
│   ├── PgApiDictMapper.java            # API字典Mapper
│   └── PgAppApiMapper.java             # 应用API授权Mapper
└── service/
    ├── IPgApplicationService.java      # 应用服务接口
    ├── IPgApiDictService.java          # API字典服务接口
    └── impl/
        ├── PgApplicationServiceImpl.java   # 应用服务实现
        └── PgApiDictServiceImpl.java       # API字典服务实现

3.2 API 接口列表

接口 方法 路径 权限标识 说明
应用列表 GET /business/application/list business:application:list 分页查询应用列表
应用详情 GET /business/application/{appId} business:application:query 获取应用详情
新增应用 POST /business/application business:application:add 新增第三方应用
修改应用 PUT /business/application business:application:edit 修改应用信息
删除应用 DELETE /business/application/{appIds} business:application:remove 删除应用
重置密钥 PUT /business/application/resetSecret/{appId} business:application:edit 重置应用密钥
接口列表 GET /business/application/apiList business:application:list 获取可授权的API列表

3.3 核心代码

3.3.1 控制器 (PgApplicationController.java)

@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/application")
public class PgApplicationController extends BaseController {

    private final IPgApplicationService applicationService;
    private final IPgApiDictService apiDictService;

    @SaCheckPermission("business:application:list")
    @GetMapping("/list")
    public TableDataInfo<PgApplication> list(PgApplication app, PageQuery pageQuery) {
        return applicationService.selectPageList(app, pageQuery);
    }

    @SaCheckPermission("business:application:edit")
    @Log(title = "应用管理", businessType = BusinessType.UPDATE)
    @PutMapping("/resetSecret/{appId}")
    public R<PgApplication> resetSecret(@PathVariable Long appId) {
        PgApplication app = applicationService.selectById(appId);
        if (app == null) {
            return R.fail("应用不存在");
        }
        String newSecret = IdUtil.fastSimpleUUID();
        app.setAppSecret(newSecret);
        applicationService.update(app);
        return R.ok(app);
    }
}

3.3.2 服务实现 (PgApplicationServiceImpl.java)

@RequiredArgsConstructor
@Service
public class PgApplicationServiceImpl implements IPgApplicationService {

    private final PgApplicationMapper baseMapper;
    private final PgAppApiMapper appApiMapper;
    private final PgApiDictMapper apiDictMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insert(PgApplication app) {
        // 自动生成应用编码格式YY000001
        String appCode = generateAppCode();
        app.setAppCode(appCode);
        // 自动生成32位密钥
        app.setAppSecret(IdUtil.fastSimpleUUID());
        int rows = baseMapper.insert(app);
        // 保存接口授权
        if (rows > 0 && app.getApiCodes() != null && !app.getApiCodes().isEmpty()) {
            saveAppApis(app.getAppId(), app.getApiCodes());
        }
        return rows;
    }

    private String generateAppCode() {
        // 查询当前最大编码,生成下一个序号
        // 格式YY + 6位数字如 YY000001
    }

    @Override
    public boolean checkApiPermission(String appCode, String apiPath) {
        // 校验应用是否有访问该接口的权限
        List<String> paths = appApiMapper.selectApiPathsByAppCode(appCode);
        return paths != null && paths.contains(apiPath);
    }
}

3.3.3 实体类 (PgApplication.java)

@Data
@EqualsAndHashCode(callSuper = true)
@TableName("pg_application")
public class PgApplication extends BaseEntity {

    @TableId(type = IdType.ASSIGN_ID)
    private Long appId;
    private String appCode;
    private String appName;
    private String appSecret;
    private String contactPerson;
    private String contactPhone;
    private String status;
    private String tenantId;
    @TableLogic
    private String delFlag;
    private String remark;

    /** 接口授权API编码列表不落库 */
    @TableField(exist = false)
    private List<String> apiCodes;
}

四、前端代码结构

4.1 目录结构

frontend/src/
├── api/pangu/
│   └── application.js                  # API接口定义
└── views/application/
    ├── index.vue                       # 应用列表页面
    └── components/
        ├── AppDialog.vue               # 新增/编辑弹窗
        └── SecretDialog.vue            # 密钥展示弹窗

4.2 API 接口 (application.js)

import request from '@/utils/request'

// 获取应用列表
export function getApplicationList(params) {
  return request({ url: '/business/application/list', method: 'get', params })
}

// 新增应用
export function addApplication(data) {
  return request({ url: '/business/application', method: 'post', data })
}

// 修改应用
export function updateApplication(data) {
  return request({ url: '/business/application', method: 'put', data })
}

// 删除应用
export function deleteApplication(appId) {
  return request({ url: `/business/application/${appId}`, method: 'delete' })
}

// 重置应用密钥
export function resetAppSecret(appId) {
  return request({ url: `/business/application/resetSecret/${appId}`, method: 'put' })
}

// 获取接口授权选项列表
export function getApiAuthOptions() {
  return request({ url: '/business/application/apiList', method: 'get' })
}

4.3 页面组件

列表页面 (index.vue)

  • 搜索条件:应用名称、应用编码、状态
  • 列表字段:应用名称、应用编码、授权接口、状态、创建时间、创建人
  • 操作按钮:新增、编辑、重置密钥、删除

新增/编辑弹窗 (AppDialog.vue)

  • 表单字段:应用名称、应用描述、联系人、联系电话、状态、接口授权
  • 接口授权:多选框组,从 API 字典加载

五、业务流程

5.1 新增应用流程

┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐
│ 填写表单 │───>│ 提交保存 │───>│ 生成编码 │───>│ 生成密钥 │
└──────────┘    └──────────┘    └──────────┘    └──────────┘
                                     │               │
                                     v               v
                              ┌──────────────────────────┐
                              │   保存应用 + 接口授权    │
                              └──────────────────────────┘

5.2 第三方调用接口流程

┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐
│ 携带凭证 │───>│ 拦截校验 │───>│ 权限检查 │───>│ 执行业务 │
└──────────┘    └──────────┘    └──────────┘    └──────────┘
     │               │               │
     │               v               v
     │         校验AppCode      校验该应用
     │         和AppSecret      是否有权限
     │                          访问该接口
     v
  请求头携带:
  X-App-Code
  X-App-Secret
  X-Timestamp
  X-Sign

六、文件清单

6.1 后端文件

文件路径 说明
pangu-business/src/.../application/controller/PgApplicationController.java 应用管理控制器
pangu-business/src/.../application/domain/PgApplication.java 第三方应用实体
pangu-business/src/.../application/domain/PgApiDict.java API字典实体
pangu-business/src/.../application/domain/PgAppApi.java 应用API授权实体
pangu-business/src/.../application/mapper/PgApplicationMapper.java 应用Mapper
pangu-business/src/.../application/mapper/PgApiDictMapper.java API字典Mapper
pangu-business/src/.../application/mapper/PgAppApiMapper.java 应用API授权Mapper
pangu-business/src/.../application/service/IPgApplicationService.java 应用服务接口
pangu-business/src/.../application/service/IPgApiDictService.java API字典服务接口
pangu-business/src/.../application/service/impl/PgApplicationServiceImpl.java 应用服务实现
pangu-business/src/.../application/service/impl/PgApiDictServiceImpl.java API字典服务实现

6.2 前端文件

文件路径 说明
frontend/src/api/pangu/application.js API接口定义
frontend/src/views/application/index.vue 应用列表页面
frontend/src/views/application/components/AppDialog.vue 新增/编辑弹窗
frontend/src/views/application/components/SecretDialog.vue 密钥展示弹窗

6.3 SQL 文件

文件路径 说明
pangu-business/sql/pangu_tables.sql 表结构包含pg_application、pg_api_dict、pg_app_api
pangu-business/sql/pangu_menu.sql 菜单数据
pangu-business/sql/open_api_dict_data.sql API字典初始数据

文档版本v1.0
更新日期2026-02-04
作者pangu