1230 lines
49 KiB
Markdown
1230 lines
49 KiB
Markdown
# 盘古用户平台 - 应用管理模块技术方案
|
||
|
||
---
|
||
|
||
| 文档信息 | 内容 |
|
||
|---------|------|
|
||
| **文档版本** | V1.0 |
|
||
| **项目名称** | 盘古用户平台(Pangu User Platform) |
|
||
| **模块名称** | 应用管理模块 |
|
||
| **编写团队 | pangu |
|
||
| **创建日期** | 2026-01-31 |
|
||
| **审核状态** | 待评审 |
|
||
|
||
---
|
||
|
||
## 修订记录
|
||
|
||
| 版本 | 日期 | 修订人 | 修订内容 |
|
||
|------|------|--------|----------|
|
||
| V1.0 | 2026-01-31 | pangu | 初稿 |
|
||
|
||
---
|
||
|
||
## 目录
|
||
|
||
1. [模块概述](#1-模块概述)
|
||
2. [需求分析](#2-需求分析)
|
||
3. [系统设计](#3-系统设计)
|
||
4. [前端技术方案](#4-前端技术方案)
|
||
5. [后端技术方案](#5-后端技术方案)
|
||
6. [数据库设计](#6-数据库设计)
|
||
7. [接口设计](#7-接口设计)
|
||
8. [开发计划](#8-开发计划)
|
||
9. [测试方案](#9-测试方案)
|
||
10. [风险评估](#10-风险评估)
|
||
|
||
---
|
||
|
||
## 1. 模块概述
|
||
|
||
### 1.1 模块定位
|
||
|
||
应用管理模块是盘古用户平台的核心模块之一,负责管理接入平台的第三方应用,控制API接口访问权限。通过该模块,超级管理员可以创建应用、分配接口权限、管理应用密钥,实现对外开放API的安全访问控制。
|
||
|
||
### 1.2 核心价值
|
||
|
||
| 价值点 | 描述 |
|
||
|--------|------|
|
||
| **统一接入管理** | 对所有第三方应用进行统一注册和管理 |
|
||
| **细粒度权限控制** | 精确控制每个应用可访问的API接口 |
|
||
| **安全认证机制** | 通过AppId+AppSecret签名机制保障接口安全 |
|
||
| **密钥生命周期管理** | 支持密钥重置,确保安全风险可控 |
|
||
|
||
### 1.3 模块边界
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ 应用管理模块 │
|
||
├─────────────────────────────────────────────────────────────┤
|
||
│ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │
|
||
│ │ 应用CRUD │ │ 接口授权 │ │ 密钥管理 │ │
|
||
│ │ - 新增应用 │ │ - 接口勾选 │ │ - 自动生成 │ │
|
||
│ │ - 编辑应用 │ │ - 权限存储 │ │ - 重置密钥 │ │
|
||
│ │ - 删除应用 │ │ - 权限校验 │ │ - 安全提示 │ │
|
||
│ │ - 查询列表 │ │ │ │ │ │
|
||
│ └───────────────┘ └───────────────┘ └───────────────┘ │
|
||
│ │ │
|
||
│ ▼ │
|
||
│ ┌───────────────┐ │
|
||
│ │ 开放API网关 │ │
|
||
│ │ - 签名验证 │ │
|
||
│ │ - 权限校验 │ │
|
||
│ │ - 请求转发 │ │
|
||
│ └───────────────┘ │
|
||
└─────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 2. 需求分析
|
||
|
||
### 2.1 功能需求
|
||
|
||
#### 2.1.1 功能清单
|
||
|
||
| 功能编号 | 功能名称 | 功能描述 | 优先级 | 状态 |
|
||
|---------|---------|---------|:------:|:----:|
|
||
| APP-001 | 应用列表查询 | 按应用名称、编码、状态筛选查询 | P0 | 待开发 |
|
||
| APP-002 | 新增应用 | 创建新应用,自动生成应用编码和密钥 | P0 | 待开发 |
|
||
| APP-003 | 编辑应用 | 修改应用信息和接口授权 | P0 | 待开发 |
|
||
| APP-004 | 删除应用 | 删除应用及其授权信息 | P1 | 待开发 |
|
||
| APP-005 | 重置密钥 | 重新生成应用密钥 | P0 | 待开发 |
|
||
| APP-006 | 接口授权 | 配置应用可访问的API接口 | P0 | 待开发 |
|
||
| APP-007 | 禁用/启用应用 | 控制应用访问权限 | P0 | 待开发 |
|
||
|
||
#### 2.1.2 业务规则
|
||
|
||
| 规则编号 | 规则描述 | 验证方式 |
|
||
|---------|---------|---------|
|
||
| APP-R01 | 应用编码由系统自动生成,格式:YY + 6位数字序号 | 后端生成 |
|
||
| APP-R02 | 应用密钥由系统自动生成,32位随机字符串 | 后端生成 |
|
||
| APP-R03 | 重置密钥后,旧密钥立即失效 | 后端处理 |
|
||
| APP-R04 | 重置密钥后需弹窗显示新密钥并提供复制功能 | 前端展示 |
|
||
| APP-R05 | 删除应用需popconfirm二次确认 | 前端交互 |
|
||
| APP-R06 | 禁用应用后,该应用无法调用任何API接口 | 后端拦截 |
|
||
| APP-R07 | 接口授权采用勾选方式,可多选 | 前端交互 |
|
||
| APP-R08 | 应用名称不能重复 | 后端校验 |
|
||
|
||
### 2.2 非功能需求
|
||
|
||
| 需求类型 | 需求描述 | 指标 |
|
||
|---------|---------|------|
|
||
| **性能** | 应用列表查询响应时间 | ≤ 500ms |
|
||
| **性能** | 接口授权校验响应时间 | ≤ 50ms |
|
||
| **安全** | 密钥加密存储 | AES加密 |
|
||
| **安全** | 接口签名验证 | MD5签名 |
|
||
| **安全** | 防重放攻击 | 时间戳校验(5分钟内有效) |
|
||
| **可用性** | 权限变更实时生效 | 无需重启服务 |
|
||
|
||
### 2.3 用户角色
|
||
|
||
| 角色 | 权限范围 |
|
||
|------|---------|
|
||
| **超级管理员** | 可查看所有应用,可新增/编辑/删除应用,可进行接口授权,可重置密钥 |
|
||
| **分公司用户** | 无权限 |
|
||
| **学校用户** | 无权限 |
|
||
|
||
---
|
||
|
||
## 3. 系统设计
|
||
|
||
### 3.1 整体架构
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────────┐
|
||
│ 前端层 │
|
||
│ ┌─────────────────────────────────────────────────────────────┐ │
|
||
│ │ 应用管理页面 (Vue 3 + Element Plus) │ │
|
||
│ │ - 列表页 (index.vue) │ │
|
||
│ │ - 新增/编辑弹窗 (AppDialog.vue) │ │
|
||
│ │ - 密钥展示弹窗 (SecretDialog.vue) │ │
|
||
│ └─────────────────────────────────────────────────────────────┘ │
|
||
└────────────────────────────────┬────────────────────────────────────┘
|
||
│ HTTP/HTTPS
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────────────┐
|
||
│ 后端服务层 │
|
||
│ ┌─────────────────────────────────────────────────────────────┐ │
|
||
│ │ 应用管理服务 (Spring Boot) │ │
|
||
│ │ - ApplicationController │ │
|
||
│ │ - ApplicationService │ │
|
||
│ │ - ApplicationMapper │ │
|
||
│ └─────────────────────────────────────────────────────────────┘ │
|
||
│ │
|
||
│ ┌─────────────────────────────────────────────────────────────┐ │
|
||
│ │ 开放API网关 │ │
|
||
│ │ - ApiAuthInterceptor (签名验证) │ │
|
||
│ │ - ApiPermissionFilter (权限校验) │ │
|
||
│ └─────────────────────────────────────────────────────────────┘ │
|
||
└────────────────────────────────┬────────────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────────────┐
|
||
│ 数据层 │
|
||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||
│ │ pg_application│ │ pg_app_api │ │ pg_api_dict │ │
|
||
│ │ 应用表 │ │ 应用接口授权 │ │ 接口字典 │ │
|
||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||
│ │
|
||
│ ┌──────────────┐ │
|
||
│ │ Redis │ ← 缓存应用授权信息,提升验证性能 │
|
||
│ └──────────────┘ │
|
||
└─────────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 3.2 数据流设计
|
||
|
||
#### 3.2.1 应用创建流程
|
||
|
||
```
|
||
┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐
|
||
│ 前端 │ │ Controller │ │ Service │ │ MySQL │
|
||
└─────┬─────┘ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘
|
||
│ │ │ │
|
||
│ POST /api/application │ │
|
||
│──────────────────► │ │
|
||
│ │ │ │
|
||
│ │ insertApplication │
|
||
│ │──────────────────► │
|
||
│ │ │ │
|
||
│ │ │ 1.生成应用编码 │
|
||
│ │ │ 2.生成密钥 │
|
||
│ │ │ 3.加密存储 │
|
||
│ │ │──────────────────►
|
||
│ │ │ │
|
||
│ │ │ 4.保存接口授权 │
|
||
│ │ │──────────────────►
|
||
│ │ │ │
|
||
│ 返回新密钥(仅新增时) │ │
|
||
│◄────────────────── │ │
|
||
│ │ │ │
|
||
```
|
||
|
||
#### 3.2.2 开放API调用流程
|
||
|
||
```
|
||
┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐
|
||
│ 第三方应用 │ │ API网关 │ │ Redis │ │ 业务 │
|
||
└─────┬─────┘ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘
|
||
│ │ │ │
|
||
│ GET /open/xxx │ │ │
|
||
│ Header: X-App-Id, X-Timestamp, X-Sign │
|
||
│──────────────────► │ │
|
||
│ │ │ │
|
||
│ │ 1.验证时间戳 │ │
|
||
│ │ 2.查询应用信息 │ │
|
||
│ │──────────────────► │
|
||
│ │◄────────────────── │
|
||
│ │ │ │
|
||
│ │ 3.验证签名 │ │
|
||
│ │ 4.检查应用状态 │ │
|
||
│ │ 5.检查接口权限 │ │
|
||
│ │ │ │
|
||
│ │ │ 转发请求 │
|
||
│ │─────────────────────────────────────►
|
||
│ │ │ │
|
||
│ 返回业务数据 │ │ │
|
||
│◄──────────────────────────────────────────────────────│
|
||
│ │ │ │
|
||
```
|
||
|
||
---
|
||
|
||
## 4. 前端技术方案
|
||
|
||
### 4.1 技术栈
|
||
|
||
| 技术 | 版本 | 用途 |
|
||
|------|------|------|
|
||
| Vue | 3.x | 前端框架 |
|
||
| Element Plus | 2.x | UI组件库 |
|
||
| Axios | 1.x | HTTP客户端 |
|
||
| Pinia | 2.x | 状态管理 |
|
||
|
||
### 4.2 目录结构
|
||
|
||
```
|
||
pangu-ui/src/
|
||
├── api/
|
||
│ └── application.js # 应用管理API封装
|
||
├── views/
|
||
│ └── application/
|
||
│ ├── index.vue # 应用列表页
|
||
│ └── components/
|
||
│ ├── AppDialog.vue # 新增/编辑弹窗
|
||
│ └── SecretDialog.vue # 密钥展示弹窗
|
||
└── mock/
|
||
└── application.js # Mock数据(开发阶段)
|
||
```
|
||
|
||
### 4.3 页面设计
|
||
|
||
#### 4.3.1 应用列表页 (index.vue)
|
||
|
||
**页面布局**
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ 搜索区域 │
|
||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────┐ ┌────┐ ┌────┐ │
|
||
│ │ 应用名称 │ │ 应用编码 │ │ 状态 ▼ │ │搜索│ │重置│ │
|
||
│ └──────────────┘ └──────────────┘ └──────────┘ └────┘ └────┘ │
|
||
├─────────────────────────────────────────────────────────────────┤
|
||
│ [+ 新增] │
|
||
├─────────────────────────────────────────────────────────────────┤
|
||
│ 表格区域 │
|
||
│ ┌──────┬──────────┬────────────────────┬────────┬──────┬─────┐│
|
||
│ │应用名│ 应用编码 │ 授权接口 │ 状态 │ 创建 │操作 ││
|
||
│ ├──────┼──────────┼────────────────────┼────────┼──────┼─────┤│
|
||
│ │智慧 │ YY000001 │ [学校] [年级] [+3] │ ● 正常 │01-01 │编辑 ││
|
||
│ │校园 │ │ │ │admin │重置 ││
|
||
│ │ │ │ │ │ │删除 ││
|
||
│ └──────┴──────────┴────────────────────┴────────┴──────┴─────┘│
|
||
├─────────────────────────────────────────────────────────────────┤
|
||
│ 共 20 条 [<] 1 2 3 ... [>] │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
**核心代码结构**
|
||
|
||
```vue
|
||
<template>
|
||
<div class="app-container">
|
||
<!-- 搜索区域 -->
|
||
<el-card shadow="never" class="search-wrapper">
|
||
<el-form :model="queryParams" :inline="true">
|
||
<el-form-item label="应用名称">
|
||
<el-input v-model="queryParams.appName" placeholder="请输入" clearable />
|
||
</el-form-item>
|
||
<el-form-item label="应用编码">
|
||
<el-input v-model="queryParams.appCode" placeholder="请输入" clearable />
|
||
</el-form-item>
|
||
<el-form-item label="状态">
|
||
<el-select v-model="queryParams.status" placeholder="全部" clearable>
|
||
<el-option label="正常" value="0" />
|
||
<el-option label="停用" value="1" />
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-button type="primary" @click="handleQuery">搜索</el-button>
|
||
<el-button @click="resetQuery">重置</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
</el-card>
|
||
|
||
<!-- 表格区域 -->
|
||
<el-card shadow="never">
|
||
<el-button type="primary" @click="handleAdd">新增</el-button>
|
||
<el-table :data="tableData" border stripe>
|
||
<el-table-column prop="appName" label="应用名称" />
|
||
<el-table-column prop="appCode" label="应用编码" />
|
||
<el-table-column prop="apis" label="授权接口">
|
||
<template #default="{ row }">
|
||
<el-tag v-for="api in row.apis?.slice(0, 3)" :key="api" size="small">
|
||
{{ api }}
|
||
</el-tag>
|
||
<el-tag v-if="row.apis?.length > 3" type="info">+{{ row.apis.length - 3 }}</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="status" label="状态">
|
||
<template #default="{ row }">
|
||
<el-tag :type="row.status === '0' ? 'success' : 'danger'">
|
||
{{ row.status === '0' ? '正常' : '停用' }}
|
||
</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="createTime" label="创建时间" />
|
||
<el-table-column label="操作" fixed="right">
|
||
<template #default="{ row }">
|
||
<el-button link @click="handleEdit(row)">编辑</el-button>
|
||
<el-button link @click="handleResetSecret(row)">重置密钥</el-button>
|
||
<el-popconfirm title="确定删除?" @confirm="handleDelete(row)">
|
||
<template #reference>
|
||
<el-button link type="danger">删除</el-button>
|
||
</template>
|
||
</el-popconfirm>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
<el-pagination v-model:current-page="queryParams.pageNum" :total="total" />
|
||
</el-card>
|
||
|
||
<!-- 弹窗组件 -->
|
||
<AppDialog ref="appDialogRef" @success="handleQuery" />
|
||
<SecretDialog ref="secretDialogRef" />
|
||
</div>
|
||
</template>
|
||
```
|
||
|
||
#### 4.3.2 新增/编辑弹窗 (AppDialog.vue)
|
||
|
||
**表单布局**
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ 新增应用 / 编辑应用 [X] │
|
||
├─────────────────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ 应用名称* [________________________] │
|
||
│ │
|
||
│ 应用编码 [保存后自动生成___________] (只读) │
|
||
│ │
|
||
│ 应用描述 [________________________] │
|
||
│ [________________________] │
|
||
│ [________________________] │
|
||
│ │
|
||
│ 联系人 [________________________] │
|
||
│ │
|
||
│ 联系电话 [________________________] │
|
||
│ │
|
||
│ 状态 [●] 正常 [○] 停用 │
|
||
│ │
|
||
│ 接口授权 [✓] 查询学生信息 │
|
||
│ [✓] 查询学校信息 │
|
||
│ [✓] 查询年级信息 │
|
||
│ [ ] 查询班级信息 │
|
||
│ [ ] 查询会员信息 │
|
||
│ [ ] 查询区域树 │
|
||
│ │
|
||
├─────────────────────────────────────────────────────────────────┤
|
||
│ [取消] [确定] │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
**表单字段说明**
|
||
|
||
| 字段 | 类型 | 必填 | 校验规则 | 说明 |
|
||
|------|------|:----:|---------|------|
|
||
| appName | 文本 | ✓ | 最大100字符 | 应用名称 |
|
||
| appCode | 文本 | - | 只读 | 系统自动生成 |
|
||
| description | 文本域 | - | 最大500字符 | 应用描述 |
|
||
| contactPerson | 文本 | - | 最大50字符 | 联系人 |
|
||
| contactPhone | 文本 | - | 手机号格式 | 联系电话 |
|
||
| status | 开关 | ✓ | - | 0正常/1停用 |
|
||
| apiCodes | 复选框组 | - | - | 授权的接口编码列表 |
|
||
|
||
#### 4.3.3 密钥展示弹窗 (SecretDialog.vue)
|
||
|
||
**弹窗布局**
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ 应用密钥 [X] │
|
||
├─────────────────────────────────────────────────────────────────┤
|
||
│ ⚠️ 请妥善保管密钥,密钥重置后旧密钥将立即失效 │
|
||
├─────────────────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ 应用名称 AI智慧平台 │
|
||
│ │
|
||
│ 应用编码 YY000001 │
|
||
│ │
|
||
│ 应用密钥 [a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6] [复制] │
|
||
│ │
|
||
├─────────────────────────────────────────────────────────────────┤
|
||
│ [关闭] │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 4.4 API接口封装
|
||
|
||
```javascript
|
||
/**
|
||
* 应用管理API接口
|
||
* @author pangu
|
||
*/
|
||
import request from '@/utils/request'
|
||
|
||
// 获取应用列表
|
||
export function listApplication(params) {
|
||
return request.get('/api/application/list', { params })
|
||
}
|
||
|
||
// 获取应用详情
|
||
export function getApplication(appId) {
|
||
return request.get(`/api/application/${appId}`)
|
||
}
|
||
|
||
// 新增应用
|
||
export function addApplication(data) {
|
||
return request.post('/api/application', data)
|
||
}
|
||
|
||
// 修改应用
|
||
export function updateApplication(data) {
|
||
return request.put('/api/application', data)
|
||
}
|
||
|
||
// 删除应用
|
||
export function deleteApplication(appId) {
|
||
return request.delete(`/api/application/${appId}`)
|
||
}
|
||
|
||
// 重置密钥
|
||
export function resetAppSecret(appId) {
|
||
return request.put(`/api/application/resetSecret/${appId}`)
|
||
}
|
||
|
||
// 获取API接口列表(用于授权选择)
|
||
export function getApiList() {
|
||
return request.get('/api/application/apiList')
|
||
}
|
||
```
|
||
|
||
### 4.5 前端开发规范
|
||
|
||
| 规范项 | 说明 |
|
||
|-------|------|
|
||
| 组件命名 | 大驼峰,如 `AppDialog.vue` |
|
||
| 方法命名 | 小驼峰,如 `handleQuery`、`handleEdit` |
|
||
| 事件处理 | 以 `handle` 开头,如 `handleSubmit` |
|
||
| API请求 | 统一使用 `@/utils/request` 封装 |
|
||
| 表单验证 | 使用 Element Plus 的 Form 组件校验 |
|
||
| 错误处理 | 统一使用 `ElMessage` 提示 |
|
||
|
||
---
|
||
|
||
## 5. 后端技术方案
|
||
|
||
### 5.1 技术栈
|
||
|
||
| 技术 | 版本 | 用途 |
|
||
|------|------|------|
|
||
| Spring Boot | 3.3.x | 应用框架 |
|
||
| Spring Security | 6.x | 安全框架 |
|
||
| MyBatis Plus | 3.5.x | ORM框架 |
|
||
| Redis | 7.x | 缓存 |
|
||
| Hutool | 5.x | 工具库 |
|
||
| JDK | 17+ | 运行环境 |
|
||
|
||
### 5.2 模块结构
|
||
|
||
```
|
||
pangu-admin/
|
||
├── controller/
|
||
│ └── ApplicationController.java # 应用管理控制器
|
||
├── service/
|
||
│ ├── IApplicationService.java # 应用服务接口
|
||
│ └── impl/
|
||
│ └── ApplicationServiceImpl.java
|
||
├── mapper/
|
||
│ ├── ApplicationMapper.java # 应用Mapper
|
||
│ └── AppApiMapper.java # 应用接口授权Mapper
|
||
├── domain/
|
||
│ ├── entity/
|
||
│ │ ├── Application.java # 应用实体
|
||
│ │ ├── AppApi.java # 应用接口授权实体
|
||
│ │ └── ApiDict.java # 接口字典实体
|
||
│ ├── vo/
|
||
│ │ └── ApplicationVO.java # 应用视图对象
|
||
│ └── dto/
|
||
│ └── ApplicationDTO.java # 应用传输对象
|
||
└── util/
|
||
└── SecretGenerator.java # 密钥生成工具
|
||
|
||
pangu-open/
|
||
├── controller/
|
||
│ └── OpenApiController.java # 开放API控制器
|
||
├── interceptor/
|
||
│ └── ApiAuthInterceptor.java # API认证拦截器
|
||
└── service/
|
||
└── ApiAuthService.java # API认证服务
|
||
```
|
||
|
||
### 5.3 核心类设计
|
||
|
||
#### 5.3.1 实体类 (Application.java)
|
||
|
||
```java
|
||
/**
|
||
* 应用实体
|
||
* @author pangu
|
||
*/
|
||
@Data
|
||
@TableName("pg_application")
|
||
public class Application extends BaseEntity {
|
||
|
||
/** 应用ID */
|
||
@TableId(type = IdType.AUTO)
|
||
private Long appId;
|
||
|
||
/** 应用编码 */
|
||
private String appCode;
|
||
|
||
/** 应用名称 */
|
||
private String appName;
|
||
|
||
/** 应用密钥(加密存储) */
|
||
private String appSecret;
|
||
|
||
/** 应用描述 */
|
||
private String appDesc;
|
||
|
||
/** 联系人 */
|
||
private String contactPerson;
|
||
|
||
/** 联系电话 */
|
||
private String contactPhone;
|
||
|
||
/** 状态(0正常 1停用) */
|
||
private String status;
|
||
|
||
/** 删除标志 */
|
||
@TableLogic
|
||
private String delFlag;
|
||
}
|
||
```
|
||
|
||
#### 5.3.2 服务接口 (IApplicationService.java)
|
||
|
||
```java
|
||
/**
|
||
* 应用管理服务接口
|
||
* @author pangu
|
||
*/
|
||
public interface IApplicationService {
|
||
|
||
/**
|
||
* 查询应用列表
|
||
*/
|
||
List<ApplicationVO> selectApplicationList(ApplicationDTO dto);
|
||
|
||
/**
|
||
* 查询应用详情
|
||
*/
|
||
ApplicationVO selectApplicationById(Long appId);
|
||
|
||
/**
|
||
* 新增应用
|
||
* @return 返回应用编码和密钥
|
||
*/
|
||
Map<String, String> insertApplication(ApplicationDTO dto);
|
||
|
||
/**
|
||
* 修改应用
|
||
*/
|
||
int updateApplication(ApplicationDTO dto);
|
||
|
||
/**
|
||
* 删除应用
|
||
*/
|
||
int deleteApplicationById(Long appId);
|
||
|
||
/**
|
||
* 重置密钥
|
||
* @return 返回新密钥
|
||
*/
|
||
String resetAppSecret(Long appId);
|
||
|
||
/**
|
||
* 根据应用编码查询应用信息(用于API认证)
|
||
*/
|
||
Application selectByAppCode(String appCode);
|
||
|
||
/**
|
||
* 检查应用是否有接口权限
|
||
*/
|
||
boolean checkApiPermission(String appCode, String apiPath);
|
||
}
|
||
```
|
||
|
||
#### 5.3.3 控制器 (ApplicationController.java)
|
||
|
||
```java
|
||
/**
|
||
* 应用管理控制器
|
||
* @author pangu
|
||
*/
|
||
@RestController
|
||
@RequestMapping("/api/application")
|
||
@PreAuthorize("hasRole('admin')") // 仅超级管理员可访问
|
||
public class ApplicationController extends BaseController {
|
||
|
||
@Autowired
|
||
private IApplicationService applicationService;
|
||
|
||
/**
|
||
* 查询应用列表
|
||
*/
|
||
@GetMapping("/list")
|
||
public TableDataInfo list(ApplicationDTO dto) {
|
||
startPage();
|
||
List<ApplicationVO> list = applicationService.selectApplicationList(dto);
|
||
return getDataTable(list);
|
||
}
|
||
|
||
/**
|
||
* 获取应用详情
|
||
*/
|
||
@GetMapping("/{appId}")
|
||
public AjaxResult getInfo(@PathVariable Long appId) {
|
||
return AjaxResult.success(applicationService.selectApplicationById(appId));
|
||
}
|
||
|
||
/**
|
||
* 新增应用
|
||
*/
|
||
@PostMapping
|
||
@Log(title = "应用管理", businessType = BusinessType.INSERT)
|
||
public AjaxResult add(@Validated @RequestBody ApplicationDTO dto) {
|
||
Map<String, String> result = applicationService.insertApplication(dto);
|
||
return AjaxResult.success(result);
|
||
}
|
||
|
||
/**
|
||
* 修改应用
|
||
*/
|
||
@PutMapping
|
||
@Log(title = "应用管理", businessType = BusinessType.UPDATE)
|
||
public AjaxResult edit(@Validated @RequestBody ApplicationDTO dto) {
|
||
return toAjax(applicationService.updateApplication(dto));
|
||
}
|
||
|
||
/**
|
||
* 删除应用
|
||
*/
|
||
@DeleteMapping("/{appId}")
|
||
@Log(title = "应用管理", businessType = BusinessType.DELETE)
|
||
public AjaxResult remove(@PathVariable Long appId) {
|
||
return toAjax(applicationService.deleteApplicationById(appId));
|
||
}
|
||
|
||
/**
|
||
* 重置密钥
|
||
*/
|
||
@PutMapping("/resetSecret/{appId}")
|
||
@Log(title = "应用管理", businessType = BusinessType.UPDATE)
|
||
public AjaxResult resetSecret(@PathVariable Long appId) {
|
||
String newSecret = applicationService.resetAppSecret(appId);
|
||
return AjaxResult.success("重置成功", Map.of("appSecret", newSecret));
|
||
}
|
||
|
||
/**
|
||
* 获取API接口列表
|
||
*/
|
||
@GetMapping("/apiList")
|
||
public AjaxResult apiList() {
|
||
return AjaxResult.success(applicationService.selectApiDictList());
|
||
}
|
||
}
|
||
```
|
||
|
||
### 5.4 核心算法
|
||
|
||
#### 5.4.1 应用编码生成
|
||
|
||
```java
|
||
/**
|
||
* 生成应用编码
|
||
* 格式:YY + 6位序号(从000001开始)
|
||
*/
|
||
public String generateAppCode() {
|
||
// 获取当前最大序号
|
||
String maxCode = applicationMapper.selectMaxAppCode();
|
||
int nextSeq = 1;
|
||
if (StringUtils.isNotBlank(maxCode)) {
|
||
nextSeq = Integer.parseInt(maxCode.substring(2)) + 1;
|
||
}
|
||
return String.format("YY%06d", nextSeq);
|
||
}
|
||
```
|
||
|
||
#### 5.4.2 密钥生成
|
||
|
||
```java
|
||
/**
|
||
* 生成32位随机密钥
|
||
*/
|
||
public String generateAppSecret() {
|
||
return RandomUtil.randomString(32);
|
||
}
|
||
```
|
||
|
||
#### 5.4.3 签名验证
|
||
|
||
```java
|
||
/**
|
||
* 验证API请求签名
|
||
*/
|
||
public boolean verifySign(HttpServletRequest request) {
|
||
String appId = request.getHeader("X-App-Id");
|
||
String timestamp = request.getHeader("X-Timestamp");
|
||
String sign = request.getHeader("X-Sign");
|
||
|
||
// 1. 验证时间戳(5分钟内有效)
|
||
long reqTime = Long.parseLong(timestamp);
|
||
if (Math.abs(System.currentTimeMillis() - reqTime) > 5 * 60 * 1000) {
|
||
throw new ApiException("请求已过期");
|
||
}
|
||
|
||
// 2. 获取应用密钥
|
||
Application app = applicationService.selectByAppCode(appId);
|
||
if (app == null || "1".equals(app.getStatus())) {
|
||
throw new ApiException("应用不存在或已禁用");
|
||
}
|
||
|
||
// 3. 构建签名字符串
|
||
String signStr = buildSignString(request, app.getAppSecret());
|
||
|
||
// 4. 验证签名
|
||
String expectedSign = DigestUtils.md5Hex(signStr).toUpperCase();
|
||
return expectedSign.equals(sign);
|
||
}
|
||
|
||
/**
|
||
* 构建签名字符串
|
||
* 将请求参数按ASCII排序后拼接,末尾追加appSecret
|
||
*/
|
||
private String buildSignString(HttpServletRequest request, String appSecret) {
|
||
Map<String, String> params = new TreeMap<>();
|
||
request.getParameterMap().forEach((key, values) -> {
|
||
if (values.length > 0) {
|
||
params.put(key, values[0]);
|
||
}
|
||
});
|
||
|
||
StringBuilder sb = new StringBuilder();
|
||
params.forEach((key, value) -> {
|
||
if (sb.length() > 0) sb.append("&");
|
||
sb.append(key).append("=").append(value);
|
||
});
|
||
sb.append("&appSecret=").append(appSecret);
|
||
|
||
return sb.toString();
|
||
}
|
||
```
|
||
|
||
### 5.5 缓存设计
|
||
|
||
| 缓存KEY | 过期时间 | 说明 |
|
||
|---------|---------|------|
|
||
| `app:info:{appCode}` | 30分钟 | 应用基本信息 |
|
||
| `app:apis:{appCode}` | 30分钟 | 应用授权的接口列表 |
|
||
|
||
```java
|
||
/**
|
||
* 清除应用缓存
|
||
* 在修改、删除、重置密钥时调用
|
||
*/
|
||
public void clearAppCache(String appCode) {
|
||
redisCache.deleteObject("app:info:" + appCode);
|
||
redisCache.deleteObject("app:apis:" + appCode);
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 6. 数据库设计
|
||
|
||
### 6.1 表结构
|
||
|
||
#### 6.1.1 应用表 (pg_application)
|
||
|
||
```sql
|
||
CREATE TABLE `pg_application` (
|
||
`app_id` bigint NOT NULL AUTO_INCREMENT COMMENT '应用ID',
|
||
`app_code` varchar(32) NOT NULL COMMENT '应用编码',
|
||
`app_name` varchar(100) NOT NULL COMMENT '应用名称',
|
||
`app_secret` varchar(64) NOT NULL COMMENT '应用密钥',
|
||
`app_desc` varchar(500) DEFAULT NULL COMMENT '应用描述',
|
||
`contact_person` varchar(50) DEFAULT NULL COMMENT '联系人',
|
||
`contact_phone` varchar(20) DEFAULT NULL COMMENT '联系电话',
|
||
`status` char(1) DEFAULT '0' COMMENT '状态(0正常 1停用)',
|
||
`create_by` varchar(64) DEFAULT '' COMMENT '创建者',
|
||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||
`update_by` varchar(64) DEFAULT '' 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='应用表';
|
||
```
|
||
|
||
#### 6.1.2 应用接口授权表 (pg_app_api)
|
||
|
||
```sql
|
||
CREATE TABLE `pg_app_api` (
|
||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||
`app_id` bigint NOT NULL COMMENT '应用ID',
|
||
`api_code` varchar(100) NOT NULL COMMENT '接口编码',
|
||
`api_name` varchar(100) DEFAULT NULL COMMENT '接口名称',
|
||
`api_path` varchar(200) NOT NULL COMMENT '接口路径',
|
||
`create_by` varchar(64) DEFAULT '' COMMENT '创建者',
|
||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||
PRIMARY KEY (`id`),
|
||
UNIQUE KEY `uk_app_api` (`app_id`, `api_code`),
|
||
KEY `idx_app_id` (`app_id`)
|
||
) ENGINE=InnoDB COMMENT='应用接口授权表';
|
||
```
|
||
|
||
#### 6.1.3 API接口字典表 (pg_api_dict)
|
||
|
||
```sql
|
||
CREATE TABLE `pg_api_dict` (
|
||
`api_id` bigint NOT NULL AUTO_INCREMENT COMMENT '接口ID',
|
||
`api_code` varchar(100) NOT NULL COMMENT '接口编码',
|
||
`api_name` varchar(100) NOT NULL COMMENT '接口名称',
|
||
`api_path` varchar(200) NOT NULL COMMENT '接口路径',
|
||
`api_method` varchar(10) DEFAULT 'GET' COMMENT '请求方法',
|
||
`api_desc` varchar(500) DEFAULT NULL COMMENT '接口描述',
|
||
`order_num` int DEFAULT 0 COMMENT '显示顺序',
|
||
`status` char(1) DEFAULT '0' COMMENT '状态(0正常 1停用)',
|
||
`create_by` varchar(64) DEFAULT '' COMMENT '创建者',
|
||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||
`update_by` varchar(64) DEFAULT '' COMMENT '更新者',
|
||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||
PRIMARY KEY (`api_id`),
|
||
UNIQUE KEY `uk_api_code` (`api_code`)
|
||
) ENGINE=InnoDB COMMENT='API接口字典表';
|
||
```
|
||
|
||
### 6.2 初始化数据
|
||
|
||
```sql
|
||
-- API接口字典数据
|
||
INSERT INTO pg_api_dict (api_id, api_code, api_name, api_path, api_method, api_desc, order_num) VALUES
|
||
(1, 'STUDENT_LIST', '查询学生信息', '/open/student/list', 'GET', '获取学生列表', 1),
|
||
(2, 'SCHOOL_LIST', '查询学校信息', '/open/school/list', 'GET', '获取学校列表', 2),
|
||
(3, 'GRADE_LIST', '查询年级信息', '/open/grade/list', 'GET', '获取年级列表', 3),
|
||
(4, 'CLASS_LIST', '查询班级信息', '/open/class/list', 'GET', '获取班级列表', 4),
|
||
(5, 'MEMBER_LIST', '查询会员信息', '/open/member/list', 'GET', '获取会员列表', 5),
|
||
(6, 'REGION_TREE', '查询区域树', '/open/region/tree', 'GET', '获取区域树形结构', 6);
|
||
|
||
-- 示例应用数据
|
||
INSERT INTO pg_application (app_id, app_code, app_name, app_secret, app_desc, status, create_time) VALUES
|
||
(1, 'YY000001', 'AI智慧平台', 'a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6', 'AI智慧教育平台接入', '0', NOW());
|
||
|
||
-- 示例应用接口授权
|
||
INSERT INTO pg_app_api (id, app_id, api_code, api_name, api_path, create_time) VALUES
|
||
(1, 1, 'SCHOOL_LIST', '查询学校信息', '/open/school/list', NOW()),
|
||
(2, 1, 'GRADE_LIST', '查询年级信息', '/open/grade/list', NOW()),
|
||
(3, 1, 'CLASS_LIST', '查询班级信息', '/open/class/list', NOW());
|
||
```
|
||
|
||
### 6.3 索引设计
|
||
|
||
| 表名 | 索引名 | 索引字段 | 说明 |
|
||
|------|--------|---------|------|
|
||
| pg_application | uk_app_code | app_code | 应用编码唯一 |
|
||
| pg_app_api | uk_app_api | app_id, api_code | 应用接口唯一 |
|
||
| pg_app_api | idx_app_id | app_id | 按应用查询 |
|
||
| pg_api_dict | uk_api_code | api_code | 接口编码唯一 |
|
||
|
||
---
|
||
|
||
## 7. 接口设计
|
||
|
||
### 7.1 管理端接口
|
||
|
||
#### 7.1.1 查询应用列表
|
||
|
||
| 项目 | 内容 |
|
||
|------|------|
|
||
| **接口地址** | `GET /api/application/list` |
|
||
| **请求参数** | appName, appCode, status, pageNum, pageSize |
|
||
| **响应格式** | TableDataInfo(分页格式) |
|
||
|
||
#### 7.1.2 获取应用详情
|
||
|
||
| 项目 | 内容 |
|
||
|------|------|
|
||
| **接口地址** | `GET /api/application/{appId}` |
|
||
| **请求参数** | appId(路径参数) |
|
||
| **响应格式** | AjaxResult |
|
||
|
||
#### 7.1.3 新增应用
|
||
|
||
| 项目 | 内容 |
|
||
|------|------|
|
||
| **接口地址** | `POST /api/application` |
|
||
| **请求体** | ApplicationDTO |
|
||
| **响应格式** | AjaxResult(包含appCode和appSecret) |
|
||
|
||
**请求示例**
|
||
|
||
```json
|
||
{
|
||
"appName": "AI智慧平台",
|
||
"appDesc": "AI教育智慧平台",
|
||
"contactPerson": "张经理",
|
||
"contactPhone": "13812345678",
|
||
"status": "0",
|
||
"apiCodes": ["STUDENT_LIST", "SCHOOL_LIST", "GRADE_LIST"]
|
||
}
|
||
```
|
||
|
||
**响应示例**
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "新增成功",
|
||
"data": {
|
||
"appCode": "YY000002",
|
||
"appSecret": "x1y2z3a4b5c6d7e8f9g0h1i2j3k4l5m6"
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 7.1.4 修改应用
|
||
|
||
| 项目 | 内容 |
|
||
|------|------|
|
||
| **接口地址** | `PUT /api/application` |
|
||
| **请求体** | ApplicationDTO(包含appId) |
|
||
| **响应格式** | AjaxResult |
|
||
|
||
#### 7.1.5 删除应用
|
||
|
||
| 项目 | 内容 |
|
||
|------|------|
|
||
| **接口地址** | `DELETE /api/application/{appId}` |
|
||
| **请求参数** | appId(路径参数) |
|
||
| **响应格式** | AjaxResult |
|
||
|
||
#### 7.1.6 重置密钥
|
||
|
||
| 项目 | 内容 |
|
||
|------|------|
|
||
| **接口地址** | `PUT /api/application/resetSecret/{appId}` |
|
||
| **请求参数** | appId(路径参数) |
|
||
| **响应格式** | AjaxResult(包含新的appSecret) |
|
||
|
||
**响应示例**
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "重置成功",
|
||
"data": {
|
||
"appSecret": "n1e2w3s4e5c6r7e8t9k0e1y2v3a4l5u6"
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 7.1.7 获取API接口列表
|
||
|
||
| 项目 | 内容 |
|
||
|------|------|
|
||
| **接口地址** | `GET /api/application/apiList` |
|
||
| **请求参数** | 无 |
|
||
| **响应格式** | AjaxResult |
|
||
|
||
**响应示例**
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "查询成功",
|
||
"data": [
|
||
{ "apiCode": "STUDENT_LIST", "apiName": "查询学生信息", "apiPath": "/open/student/list" },
|
||
{ "apiCode": "SCHOOL_LIST", "apiName": "查询学校信息", "apiPath": "/open/school/list" },
|
||
{ "apiCode": "GRADE_LIST", "apiName": "查询年级信息", "apiPath": "/open/grade/list" },
|
||
{ "apiCode": "CLASS_LIST", "apiName": "查询班级信息", "apiPath": "/open/class/list" },
|
||
{ "apiCode": "MEMBER_LIST", "apiName": "查询会员信息", "apiPath": "/open/member/list" },
|
||
{ "apiCode": "REGION_TREE", "apiName": "查询区域树", "apiPath": "/open/region/tree" }
|
||
]
|
||
}
|
||
```
|
||
|
||
### 7.2 开放API接口
|
||
|
||
#### 7.2.1 签名规则
|
||
|
||
**请求头**
|
||
|
||
| Header | 必填 | 说明 |
|
||
|--------|:----:|------|
|
||
| X-App-Id | 是 | 应用编码 |
|
||
| X-Timestamp | 是 | 时间戳(毫秒) |
|
||
| X-Sign | 是 | 签名 |
|
||
|
||
**签名算法**
|
||
|
||
```
|
||
1. 将所有请求参数按参数名ASCII升序排序
|
||
2. 拼接成 key1=value1&key2=value2 格式
|
||
3. 末尾追加 &appSecret=xxx
|
||
4. 对整个字符串进行MD5加密(32位大写)
|
||
```
|
||
|
||
**Java签名示例**
|
||
|
||
```java
|
||
public String generateSign(Map<String, String> params, String appSecret) {
|
||
// 1. 参数排序
|
||
Map<String, String> sortedParams = new TreeMap<>(params);
|
||
|
||
// 2. 拼接字符串
|
||
StringBuilder sb = new StringBuilder();
|
||
sortedParams.forEach((key, value) -> {
|
||
if (sb.length() > 0) sb.append("&");
|
||
sb.append(key).append("=").append(value);
|
||
});
|
||
sb.append("&appSecret=").append(appSecret);
|
||
|
||
// 3. MD5加密
|
||
return DigestUtils.md5Hex(sb.toString()).toUpperCase();
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 8. 开发计划
|
||
|
||
### 8.1 阶段划分
|
||
|
||
| 阶段 | 内容 | 交付物 |
|
||
|------|------|--------|
|
||
| **阶段一:设计评审** | 技术方案评审、接口设计评审 | 评审通过的技术方案 |
|
||
| **阶段二:后端开发** | 数据库表创建、后端接口开发 | 可调试的后端API |
|
||
| **阶段三:前端开发** | 前端页面开发、接口联调 | 可运行的前端页面 |
|
||
| **阶段四:联调测试** | 前后端联调、功能测试 | 测试报告 |
|
||
| **阶段五:验收上线** | 用户验收、部署上线 | 上线报告 |
|
||
|
||
### 8.2 开发任务清单
|
||
|
||
#### 8.2.1 后端任务
|
||
|
||
| 序号 | 任务 | 优先级 | 依赖 |
|
||
|:----:|------|:------:|------|
|
||
| 1 | 创建数据库表 | P0 | - |
|
||
| 2 | 实体类和Mapper开发 | P0 | 1 |
|
||
| 3 | Service层开发 | P0 | 2 |
|
||
| 4 | Controller层开发 | P0 | 3 |
|
||
| 5 | 应用编码生成器 | P0 | 3 |
|
||
| 6 | 密钥生成与加密 | P0 | 3 |
|
||
| 7 | API签名验证拦截器 | P0 | 3 |
|
||
| 8 | 缓存处理 | P1 | 7 |
|
||
| 9 | 单元测试 | P1 | 4 |
|
||
|
||
#### 8.2.2 前端任务
|
||
|
||
| 序号 | 任务 | 优先级 | 依赖 |
|
||
|:----:|------|:------:|------|
|
||
| 1 | API接口封装 | P0 | - |
|
||
| 2 | 列表页面开发 | P0 | 1 |
|
||
| 3 | 新增/编辑弹窗开发 | P0 | 1 |
|
||
| 4 | 密钥展示弹窗开发 | P0 | 1 |
|
||
| 5 | Mock数据开发 | P1 | 1 |
|
||
| 6 | 接口联调 | P0 | 后端4 |
|
||
| 7 | 样式优化 | P2 | 6 |
|
||
|
||
### 8.3 里程碑
|
||
|
||
| 里程碑 | 完成标准 |
|
||
|--------|---------|
|
||
| M1 设计完成 | 技术方案通过评审 |
|
||
| M2 后端完成 | 后端接口开发完成,Postman可调试 |
|
||
| M3 前端完成 | 前端页面开发完成,Mock数据可运行 |
|
||
| M4 联调完成 | 前后端联调通过,功能可正常使用 |
|
||
| M5 验收完成 | 用户验收通过,可部署上线 |
|
||
|
||
---
|
||
|
||
## 9. 测试方案
|
||
|
||
### 9.1 测试范围
|
||
|
||
| 测试类型 | 测试内容 |
|
||
|---------|---------|
|
||
| **功能测试** | 应用CRUD、接口授权、密钥重置 |
|
||
| **接口测试** | API签名验证、权限校验 |
|
||
| **性能测试** | 列表查询性能、签名验证性能 |
|
||
| **安全测试** | 密钥加密、防重放攻击 |
|
||
|
||
### 9.2 测试用例
|
||
|
||
#### 9.2.1 功能测试用例
|
||
|
||
| 用例编号 | 用例名称 | 前置条件 | 测试步骤 | 预期结果 |
|
||
|---------|---------|---------|---------|---------|
|
||
| TC-APP-001 | 新增应用 | 已登录超管账号 | 1.点击新增 2.填写表单 3.选择接口 4.提交 | 应用创建成功,显示密钥 |
|
||
| TC-APP-002 | 应用编码自动生成 | 已有应用YY000001 | 新增应用 | 新应用编码为YY000002 |
|
||
| TC-APP-003 | 重置密钥 | 已有应用 | 点击重置密钥 | 弹窗显示新密钥,可复制 |
|
||
| TC-APP-004 | 删除应用 | 已有应用 | 点击删除,确认 | 应用删除成功 |
|
||
| TC-APP-005 | 禁用应用 | 已有应用 | 编辑状态为停用 | 应用无法调用API |
|
||
| TC-APP-006 | 接口授权 | 已有应用 | 勾选部分接口 | 仅授权接口可访问 |
|
||
|
||
#### 9.2.2 接口测试用例
|
||
|
||
| 用例编号 | 用例名称 | 测试步骤 | 预期结果 |
|
||
|---------|---------|---------|---------|
|
||
| TC-API-001 | 签名正确 | 使用正确密钥生成签名 | 请求成功 |
|
||
| TC-API-002 | 签名错误 | 使用错误密钥生成签名 | 返回"签名验证失败" |
|
||
| TC-API-003 | 时间戳过期 | 使用10分钟前的时间戳 | 返回"请求已过期" |
|
||
| TC-API-004 | 应用禁用 | 使用禁用应用的密钥 | 返回"应用已禁用" |
|
||
| TC-API-005 | 无接口权限 | 访问未授权接口 | 返回"无权访问该接口" |
|
||
|
||
### 9.3 验收标准
|
||
|
||
| 验收项 | 验收标准 |
|
||
|-------|---------|
|
||
| 功能完整性 | 所有P0功能用例通过 |
|
||
| 接口安全性 | 签名验证、权限校验正常 |
|
||
| 性能指标 | 列表查询 ≤500ms,签名验证 ≤50ms |
|
||
| 代码质量 | 无严重BUG,代码规范检查通过 |
|
||
|
||
---
|
||
|
||
## 10. 风险评估
|
||
|
||
### 10.1 风险清单
|
||
|
||
| 风险编号 | 风险描述 | 影响程度 | 发生概率 | 应对措施 |
|
||
|---------|---------|:--------:|:--------:|---------|
|
||
| R01 | 密钥泄露 | 高 | 低 | 加密存储,传输加密,操作审计 |
|
||
| R02 | 签名算法被破解 | 高 | 低 | 预留算法升级能力 |
|
||
| R03 | API被恶意调用 | 中 | 中 | 频率限制,IP白名单(预留) |
|
||
| R04 | 权限变更不实时 | 低 | 中 | 使用缓存时设置合理过期时间 |
|
||
|
||
### 10.2 应对方案
|
||
|
||
#### R01 密钥泄露
|
||
|
||
- **预防**:密钥加密存储,只在新增和重置时显示一次
|
||
- **发现**:监控异常调用行为
|
||
- **处置**:支持立即重置密钥使旧密钥失效
|
||
|
||
#### R03 API被恶意调用
|
||
|
||
- **当前**:签名验证 + 时间戳防重放
|
||
- **预留**:接口频率限制(可后续添加)
|
||
- **预留**:IP白名单机制(可后续添加)
|
||
|
||
---
|
||
|
||
## 附录
|
||
|
||
### 附录A:墨刀原型对照
|
||
|
||
| 原型页面 | 对应功能 | 实现状态 |
|
||
|---------|---------|:--------:|
|
||
| 应用管理-列表 | 应用列表查询 | 待开发 |
|
||
| 应用管理-编辑 | 新增/编辑应用、接口授权 | 待开发 |
|
||
|
||
### 附录B:相关文档
|
||
|
||
| 文档名称 | 路径 |
|
||
|---------|------|
|
||
| 需求规格说明书 | docs/01-需求文档/需求规格说明书_v1.0.md |
|
||
| 系统设计文档 | docs/02-系统设计/系统设计文档_v1.0.md |
|
||
| 数据库设计文档 | docs/03-数据库设计/数据库设计文档_v1.0.md |
|
||
| 接口设计文档 | docs/04-接口文档/接口设计文档_v1.0.md |
|
||
|
||
---
|
||
|
||
## 审核签字
|
||
|
||
| 角色 | 姓名 | 日期 | 签字 |
|
||
|-----|------|------|------|
|
||
| 技术负责人 | | | |
|
||
| 前端负责人 | | | |
|
||
| 后端负责人 | | | |
|
||
| 测试负责人 | | | |
|
||
|
||
---
|
||
|
||
*文档结束*
|