# 软件项目资源登记平台 — 需求分析与设计方案 ## 一、需求分析 ### 1.1 业务背景 随着企业数字化转型深入,团队在日常运营中会使用大量云资源和服务套餐(云服务器、云数据库、对象存储、域名、SSL 证书、CDN、短信包、邮件包等),这些资源具有以下特点: - **分散管理**:资源由不同人员购买和管理,信息散落在个人手中,缺乏统一视图 - **到期风险**:资源到期如未续费会导致服务中断,影响线上业务 - **归属不清**:资源与项目之间的对应关系不明确,难以进行项目级成本核算 - **成本盲区**:缺乏全局费用统计,无法有效进行成本管控和优化 ### 1.2 目标用户 | 角色 | 描述 | 核心诉求 | | -------- | ---------------------------------------------- | -------------------------------------- | | 管理员 | 系统管理员,拥有全部权限 | 统一管理平台所有资源和用户 | | 普通用户 | 项目负责人/运维人员/开发人员 | 登记和管理自己负责的资源,接收到期提醒 | ### 1.3 功能需求 #### FR-01:用户认证与权限管理 - **FR-01-01**:支持账号密码登录,登录成功后颁发 JWT Token - **FR-01-02**:支持修改个人密码(需验证原密码) - **FR-01-03**:区分管理员和普通用户两级角色 - **FR-01-04**:管理员可管理所有用户(增删改查),普通用户无此权限 #### FR-02:资源管理 - **FR-02-01**:支持资源的增删改查(逻辑删除) - **FR-02-02**:资源信息包含:名称、类型、服务商、账号信息、开通日期、到期日期、费用、计费周期、负责人、状态、备注 - **FR-02-03**:支持按名称、类型、服务商、负责人、状态、到期天数等多维度筛选 - **FR-02-04**:支持分页展示 - **FR-02-05**:支持资源导出为 Excel 文件 - **FR-02-06**:资源状态(使用中/即将到期/已过期/已停用)由系统自动维护 #### FR-03:项目管理 - **FR-03-01**:支持项目的增删改查(逻辑删除) - **FR-03-02**:项目信息包含:名称、负责人、状态、备注 - **FR-03-03**:项目详情页展示关联的资源列表 - **FR-03-04**:支持在项目详情页关联/解除资源 #### FR-04:项目与资源关联 - **FR-04-01**:一个资源可关联多个项目(多对多关系) - **FR-04-02**:在资源表单中可选择关联的项目(多选) - **FR-04-03**:在项目详情页可批量关联资源 #### FR-05:字典管理 - **FR-05-01**:资源类型字典可增删改查,支持自定义排序 - **FR-05-02**:服务商字典可增删改查 - **FR-05-03**:字典变更实时生效,无需重启 #### FR-06:工作台 - **FR-06-01**:展示项目总数、资源总数、即将到期数、已过期数 - **FR-06-02**:展示需要关注的资源列表(即将到期 + 已过期,按到期日期升序) - **FR-06-03**:展示各资源类型的数量分布 #### FR-07:到期提醒 - **FR-07-01**:系统每日定时扫描资源到期状态 - **FR-07-02**:自动刷新资源状态字段(使用中→即将到期→已过期) - **FR-07-03**:分三个阶段发送邮件提醒:提前30天、提前7天、已过期 - **FR-07-04**:同一资源同一阶段只发送一次提醒,避免重复骚扰 - **FR-07-05**:已停用的资源不触发提醒 - **FR-07-06**:提醒天数和 cron 表达式可配置 #### FR-08:费用统计 - **FR-08-01**:按项目维度统计资源数量和总费用 - **FR-08-02**:按资源类型维度统计资源数量和总费用 #### FR-09:操作日志 - **FR-09-01**:记录资源、项目、用户等模块的关键操作(新增/编辑/删除/关联变更) - **FR-09-02**:日志包含操作人、操作模块、操作类型、操作对象、操作详情和时间 - **FR-09-03**:支持分页查看操作日志 ### 1.4 非功能需求 | 类别 | 要求 | | ---------- | ------------------------------------------------------------------------ | | 安全性 | 密码 BCrypt 加密存储;JWT 无状态认证;接口权限控制;CORS 跨域配置 | | 性能 | 列表查询避免 N+1 问题,关联数据批量查询;分页查询减少单次数据量 | | 可用性 | 统一响应格式和错误处理;前端统一拦截提示;表单参数校验 | | 可扩展性 | 资源类型和服务商通过字典表管理,用户可自行扩展,无需修改代码 | | 可维护性 | 前后端分离;分层架构清晰;Lombok 减少样板代码;MyBatis-Plus 简化数据访问 | | 数据完整性 | 关键操作使用事务保证一致性;逻辑删除保留历史数据;唯一约束防止重复 | --- ## 二、系统设计方案 ### 2.1 整体架构设计 采用经典的 **前后端分离** + **分层架构** 设计: ``` ┌─────────────────────────────────────────┐ │ 表现层 (Frontend) │ │ Vue 3 SPA + Element Plus + Pinia │ └─────────────────┬───────────────────────┘ │ REST API (JSON) ┌─────────────────▼───────────────────────┐ │ 接口层 (Controller) │ │ 接收请求 → 参数校验 → 调用 Service │ ├─────────────────────────────────────────┤ │ 业务层 (Service) │ │ 核心业务逻辑、事务管理、VO 组装 │ ├─────────────────────────────────────────┤ │ 持久层 (Mapper) │ │ MyBatis-Plus BaseMapper 自动 CRUD │ ├─────────────────────────────────────────┤ │ 数据层 (MySQL) │ │ 8 张业务表 + 逻辑删除 + 唯一约束 │ └─────────────────────────────────────────┘ ``` **横切关注点**: - 安全认证(JwtAuthenticationFilter) - 全局异常处理(GlobalExceptionHandler) - 操作日志记录(OperationLogService) ### 2.2 认证鉴权设计 ``` 登录流程: 用户 → POST /auth/login {username, password} → Spring Security AuthenticationManager 校验 → 校验通过 → JwtUtil.generateToken(userId, username) → 返回 Token → 校验失败 → 抛出 BadCredentialsException → 全局异常处理返回错误 请求鉴权流程: 请求 → JwtAuthenticationFilter → 从 Authorization 头提取 Bearer Token → JwtUtil.parseToken() 验证有效性 → 从数据库加载用户信息(含角色) → 设置 SecurityContext → SecurityConfig 根据路径规则判断权限 - /auth/login → permitAll - /user/** → hasRole("ADMIN") - 其他 → authenticated ``` **Token 设计**: - 算法:HS256(HMAC-SHA256) - 有效期:24 小时(可配置) - 载荷:userId(自定义 claim)+ username(subject) - 前端存储:localStorage(简单可靠,适合内部系统) ### 2.3 数据模型设计 #### 2.3.1 核心实体关系 ``` Project ──M:N──> Resource │ ProjectResource (中间表) Resource ──N:1──> ResourceType (类型字典) Resource ──N:1──> Provider (服务商字典) Resource ──N:1──> SysUser (负责人) Project ──N:1──> SysUser (负责人) Resource ──1:N──> ExpireNotifyLog (提醒记录) SysUser ──1:N──> OperationLog (操作日志) ``` #### 2.3.2 关键字段设计决策 | 设计决策 | 选择 | 原因 | | ---------------------------- | ---------------- | ----------------------------------------------------- | | 资源状态存储 | 冗余 status 字段 | 避免每次查询都计算到期状态,支持直接按状态筛选和索引 | | 项目-资源关系 | 独立中间表 | 多对多关系的标准实现,支持双向查询 | | 到期提醒防重 | 唯一约束+代码查重 | 数据库层面兜底 + 应用层面先查后插,双重保障 | | 逻辑删除 | deleted 字段 | 保留历史数据,支持数据恢复,MyBatis-Plus @TableLogic 自动过滤 | | 密码存储 | BCrypt | Spring Security 默认方案,自带盐值,安全性高 | | 费用字段 | DECIMAL(12,2) | 精确的货币计算,避免浮点精度问题 | ### 2.4 核心业务流程设计 #### 2.4.1 资源创建/编辑流程 ``` 用户提交表单 → Controller 接收 ResourceDTO(含 projectIds 列表) → Service.saveOrUpdate() → 判断是新增还是编辑 → 保存 Resource 基本信息 → 维护项目关联: 1. 删除该资源的所有旧关联 (DELETE FROM project_resource WHERE resource_id = ?) 2. 遍历 projectIds,逐条插入新关联 → 记录操作日志 → 事务提交 ``` **设计考量**:采用"先删后插"策略维护关联关系,逻辑简单、不易出现脏数据,适合数据量不大的场景。 #### 2.4.2 到期提醒定时任务流程 ``` @Scheduled(cron = "0 0 8 * * ?") → Step 1: refreshExpireStatus() → 查询所有非停用资源 → 根据到期日期计算新状态 → 状态变化时更新数据库 → Step 2: 邮件提醒扫描 → 查询所有有到期日期且非停用的资源 → 遍历每个资源: → 计算距到期天数 → 判断所处阶段(>30天:不提醒 / ≤30天:stage1 / ≤7天:stage2 / <0:stage3) → 查询 expire_notify_log 是否已发送该阶段提醒 → 未发送 → 查询负责人邮箱 → 发送邮件 → 写入日志记录 → 输出发送统计 ``` **邮件策略**: | 阶段 | 条件 | 邮件标题样式 | 发送次数 | | --------- | -------------- | ------------------------------------- | -------- | | stage=1 | 距到期≤30天 | 【资源到期提醒】xxx 将在N天后到期 | 1次 | | stage=2 | 距到期≤7天 | 【紧急】资源 xxx 即将到期,仅剩N天 | 1次 | | stage=3 | 已过期(天数<0) | 【已过期】资源 xxx 已到期,请尽快处理 | 1次 | #### 2.4.3 数据查询与 VO 组装流程 ``` Controller 接收查询参数 → Service 构建 LambdaQueryWrapper → Mapper.selectPage() 分页查询 Resource 实体 → assembleVOList() 批量组装 VO: 1. 收集所有 typeId、providerId、ownerId、resourceId 2. 批量查询 ResourceType → Map 3. 批量查询 Provider → Map 4. 批量查询 SysUser → Map 5. 批量查询 ProjectResource → Map> 6. 批量查询 Project → Map 7. 遍历 Resource 列表,填充 VO 各字段 → 返回 Page ``` **性能考量**:将 N+1 查询转化为 5 次批量查询,极大减少数据库交互次数。 ### 2.5 前端架构设计 #### 2.5.1 目录结构 ``` frontend/src/ ├── api/ # API 接口封装(按业务模块拆分) │ ├── request.js # Axios 实例 + 拦截器 │ ├── auth.js # 登录、用户信息、密码修改 │ ├── dashboard.js │ ├── resource.js │ ├── project.js │ ├── dict.js │ ├── user.js │ └── log.js ├── layout/ # 全局布局组件(侧边栏 + 顶部栏) ├── router/ # 路由配置 + 导航守卫 ├── store/ # Pinia 状态管理(用户状态) ├── views/ # 页面组件(按业务模块组织) │ ├── Dashboard.vue │ ├── Login.vue │ ├── CostStat.vue │ ├── resource/ # 资源管理 │ ├── project/ # 项目管理 │ ├── dict/ # 字典管理 │ └── system/ # 系统管理(用户 + 日志) ├── styles/ # 全局样式变量 └── components/ # 公共组件 ``` #### 2.5.2 组件设计模式 - **页面组件**:每个页面一个 `.vue` 文件,使用 `