398 lines
14 KiB
Markdown
398 lines
14 KiB
Markdown
|
|
# MES系统授权续费功能 - 任务文档
|
|||
|
|
|
|||
|
|
**版本**: v2.0.008
|
|||
|
|
**作者**: 周启威
|
|||
|
|
**日期**: 2026-03-12
|
|||
|
|
**状态**: 开发完成
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 功能概述
|
|||
|
|
|
|||
|
|
实现MES系统授权到期提醒和续费管理功能,包括:
|
|||
|
|
1. 首页弹窗提醒(剩余天数/已过期天数)
|
|||
|
|
2. 首页顶部到期时间显示(版本说明左侧)
|
|||
|
|
3. 到期后限制普通用户访问业务模块
|
|||
|
|
4. 管理员续费操作和历史记录管理
|
|||
|
|
5. 联系方式管理(邮箱+电话)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 已完成工作
|
|||
|
|
|
|||
|
|
### 1. 数据库设计 ✅
|
|||
|
|
|
|||
|
|
#### 1.1 系统授权配置表(sys_license_config)
|
|||
|
|
- 存储系统全局到期时间和联系方式
|
|||
|
|
- 字段:id, expire_date, contact_email, contact_phone, create_time, update_time
|
|||
|
|
- SQL文件:`.sql/2026-03-12_v2.0.008_周启威_到期续费功能.sql`
|
|||
|
|
|
|||
|
|
#### 1.2 续费记录表(sys_license_renewal)
|
|||
|
|
- 存储每次续费操作的历史记录
|
|||
|
|
- 字段:id, company_name, previous_expire_date, expire_date, operator, operate_time, remark
|
|||
|
|
- 索引:idx_operate_time
|
|||
|
|
- **previous_expire_date**: 记录续费前的到期时间,便于查看每次续费延长的时间
|
|||
|
|
|
|||
|
|
### 2. 后端代码 ✅
|
|||
|
|
|
|||
|
|
#### 2.1 实体类
|
|||
|
|
- `SysLicenseConfig.java` - 系统授权配置实体
|
|||
|
|
- `SysLicenseRenewal.java` - 续费记录实体
|
|||
|
|
|
|||
|
|
#### 2.2 Mapper层
|
|||
|
|
- `SysLicenseConfigMapper.java` + XML
|
|||
|
|
- `SysLicenseRenewalMapper.java` + XML
|
|||
|
|
|
|||
|
|
#### 2.3 Service层
|
|||
|
|
- `ISysLicenseService.java` - 接口定义
|
|||
|
|
- `SysLicenseServiceImpl.java` - 业务实现
|
|||
|
|
- 获取授权信息(含剩余天数计算)
|
|||
|
|
- 更新到期时间
|
|||
|
|
- 更新联系方式
|
|||
|
|
- 新增续费记录(事务保证,自动记录续费前到期时间)
|
|||
|
|
- 查询续费记录列表(按时间倒序)
|
|||
|
|
- 获取最新续费记录
|
|||
|
|
- 检查是否过期
|
|||
|
|
|
|||
|
|
#### 2.4 Controller层
|
|||
|
|
- `SysLicenseController.java`
|
|||
|
|
- GET /system/license/info - 获取授权信息(所有用户)
|
|||
|
|
- PUT /system/license/expire - 更新到期时间(仅管理员,@RequestBody)
|
|||
|
|
- PUT /system/license/contact - 更新联系方式(仅管理员,@RequestBody)
|
|||
|
|
- POST /system/license/renewal - 新增续费记录(仅管理员)
|
|||
|
|
- GET /system/license/renewal/list - 查询续费记录(仅管理员)
|
|||
|
|
- GET /system/license/renewal/latest - 获取最新续费记录(所有用户)
|
|||
|
|
|
|||
|
|
### 3. 前端代码 ✅
|
|||
|
|
|
|||
|
|
#### 3.1 API封装
|
|||
|
|
- `src/api/system/license.js` - 授权相关接口
|
|||
|
|
|
|||
|
|
#### 3.2 组件开发
|
|||
|
|
- `src/components/LicenseExpireDialog/index.vue` - 首页弹窗提醒组件
|
|||
|
|
- 距离到期≤30天或已过期时显示
|
|||
|
|
- 显示剩余/过期天数
|
|||
|
|
- 显示联系邮箱和电话
|
|||
|
|
- **智能提醒机制**:
|
|||
|
|
- 剩余天数 > 5天:可选择"今日不再提示",当天不再弹窗
|
|||
|
|
- 剩余天数 ≤ 5天:每次进入都提示,无法忽略
|
|||
|
|
- 已过期:每次进入都提示,无法忽略
|
|||
|
|
- 使用 sessionStorage 存储今日忽略状态
|
|||
|
|
|
|||
|
|
- `src/components/LicenseExpireInfo/index.vue` - 首页到期时间显示组件
|
|||
|
|
- 显示位置:首页顶部,版本说明左侧
|
|||
|
|
- 动态颜色:正常(灰色)/警告(橙色)/过期(红色+脉冲动画)
|
|||
|
|
- **智能Tooltip**:鼠标悬停显示详细信息
|
|||
|
|
- 下次到期时间
|
|||
|
|
- 剩余天数/已过期天数
|
|||
|
|
- 上次续费时间
|
|||
|
|
- 联系邮箱和电话
|
|||
|
|
- 管理员点击跳转续费管理页面
|
|||
|
|
- 每小时自动刷新数据
|
|||
|
|
|
|||
|
|
#### 3.3 页面开发
|
|||
|
|
- `src/views/system/license/renewal.vue` - 续费管理页面
|
|||
|
|
- 上方:续费操作表单(企业名称、到期时间、备注)
|
|||
|
|
- 下方:历史续费记录表格(支持分页)
|
|||
|
|
- 显示续费前到期时间和续费后到期时间对比
|
|||
|
|
- 按操作时间倒序排列
|
|||
|
|
- 仅管理员可访问
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 核心功能说明
|
|||
|
|
|
|||
|
|
### 1. 到期提醒机制
|
|||
|
|
- **弹窗提醒**:距离到期≤30天或已过期时显示弹窗
|
|||
|
|
- **剩余 > 5天**:显示"今日不再提示"和"我知道了"两个按钮,用户可选择今日忽略
|
|||
|
|
- **剩余 ≤ 5天**:只显示"我知道了"按钮,每次进入都提示
|
|||
|
|
- **已过期**:只显示"我知道了"按钮,每次进入都提示
|
|||
|
|
- **首页显示**:实时显示到期时间和剩余天数,根据状态变色,下拉菜单显示详细续费信息
|
|||
|
|
- **关闭控制**:
|
|||
|
|
- 点击"今日不再提示":使用 sessionStorage 记录,当天不再显示(仅剩余>5天时可用)
|
|||
|
|
- 点击"我知道了":关闭弹窗,下次进入系统会再次显示
|
|||
|
|
|
|||
|
|
### 2. 权限控制
|
|||
|
|
- **管理员**:不受任何限制,可正常访问所有模块和续费管理
|
|||
|
|
- **普通用户**:
|
|||
|
|
- 系统未到期:正常访问所有模块
|
|||
|
|
- 系统已过期:只能访问首页和个人中心,访问业务模块时拦截
|
|||
|
|
- **路由守卫实现**:
|
|||
|
|
- 在 `permission.js` 中添加授权过期检查
|
|||
|
|
- 使用缓存机制(1分钟刷新),避免频繁请求接口
|
|||
|
|
- 过期后访问业务模块会弹窗提示并强制跳转首页
|
|||
|
|
- **黑名单拦截**(仅拦截以下业务模块):
|
|||
|
|
- `/mes/` - 生产管理
|
|||
|
|
- `/warehouse/` - 仓库管理
|
|||
|
|
- `/quality/` - 质量管理
|
|||
|
|
- `/sale/` - 销售管理
|
|||
|
|
- `/purchase/` - 采购管理
|
|||
|
|
- `/energy/` - 能源管理
|
|||
|
|
- `/safe/` - 安全管理
|
|||
|
|
- `/finance/` - 财务管理
|
|||
|
|
- **允许访问**:首页、个人中心、系统管理、授权管理等非业务模块
|
|||
|
|
|
|||
|
|
### 3. 续费操作
|
|||
|
|
- 管理员填写企业名称、续费到期时间、备注
|
|||
|
|
- 点击确认续费后:
|
|||
|
|
1. 自动记录续费前的到期时间
|
|||
|
|
2. 更新系统全局到期时间
|
|||
|
|
3. 插入续费历史记录
|
|||
|
|
4. 自动记录操作人和操作时间
|
|||
|
|
5. 刷新历史记录表格
|
|||
|
|
|
|||
|
|
### 4. 数据展示
|
|||
|
|
- **历史续费记录**:按操作时间倒序显示(SQL层面保证)
|
|||
|
|
- **字段**:企业名称、续费前到期时间、续费后到期时间、操作人、操作时间、备注
|
|||
|
|
- **分页**:支持分页查询
|
|||
|
|
- **续费信息Tooltip**:首页到期时间显示处,鼠标悬停可查看最新续费记录
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 集成工作(已完成)
|
|||
|
|
|
|||
|
|
### 1. 首页集成
|
|||
|
|
|
|||
|
|
#### 1.1 弹窗组件集成
|
|||
|
|
已在 `src/views/index.vue` 中集成 `LicenseExpireDialog` 组件
|
|||
|
|
- 登录后自动检查授权状态
|
|||
|
|
- 剩余天数 ≤30 或已过期时自动弹窗
|
|||
|
|
- 使用 `sessionStorage` 存储关闭状态(关闭浏览器后重新显示)
|
|||
|
|
|
|||
|
|
#### 1.2 导航栏授权信息显示
|
|||
|
|
已在 `src/layout/components/Navbar.vue` 中集成 `LicenseExpireInfo` 组件
|
|||
|
|
- 显示位置:版本说明左侧
|
|||
|
|
- 下拉菜单格式,与版本说明样式一致
|
|||
|
|
- 显示内容:到期时间、剩余天数、上次续费、联系方式
|
|||
|
|
- 管理员可点击"进入续费管理"
|
|||
|
|
|
|||
|
|
### 2. 路由配置
|
|||
|
|
|
|||
|
|
在 `src/router/index.js` 中添加:
|
|||
|
|
```javascript
|
|||
|
|
{
|
|||
|
|
path: '/system/license',
|
|||
|
|
component: Layout,
|
|||
|
|
hidden: true,
|
|||
|
|
permissions: ['system:license:view'],
|
|||
|
|
children: [
|
|||
|
|
{
|
|||
|
|
path: 'renewal',
|
|||
|
|
component: () => import('@/views/system/license/renewal'),
|
|||
|
|
name: 'LicenseRenewal',
|
|||
|
|
meta: { title: '续费管理', icon: 'license', activeMenu: '/system/license' }
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 权限拦截(需手动完成)
|
|||
|
|
|
|||
|
|
#### 3.1 前端路由守卫
|
|||
|
|
在 `src/permission.js` 中添加:
|
|||
|
|
```javascript
|
|||
|
|
import { getLicenseInfo } from '@/api/system/license'
|
|||
|
|
|
|||
|
|
const RESTRICTED_MODULES = [
|
|||
|
|
'/mes/production', // 生产管理
|
|||
|
|
'/warehouse', // 仓库管理
|
|||
|
|
'/quality', // 质量管理
|
|||
|
|
'/equipment' // 设备管理
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
router.beforeEach(async (to, from, next) => {
|
|||
|
|
// 检查系统授权状态
|
|||
|
|
try {
|
|||
|
|
const response = await getLicenseInfo()
|
|||
|
|
const { isExpired } = response.data
|
|||
|
|
const roles = store.getters.roles
|
|||
|
|
|
|||
|
|
if (isExpired && !roles.includes('admin')) {
|
|||
|
|
const isRestrictedPath = RESTRICTED_MODULES.some(module =>
|
|||
|
|
to.path.startsWith(module)
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
if (isRestrictedPath) {
|
|||
|
|
Message.error('系统已过期,请联系管理员续费')
|
|||
|
|
next({ path: '/' })
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('检查授权状态失败:', error)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
next()
|
|||
|
|
})
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 3.2 后端拦截器(可选)
|
|||
|
|
创建 `LicenseInterceptor.java` 并注册到 `WebMvcConfig`
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 验收清单
|
|||
|
|
|
|||
|
|
### 数据库
|
|||
|
|
- [ ] sys_license_config 表创建成功,包含初始数据
|
|||
|
|
- [ ] sys_license_renewal 表创建成功
|
|||
|
|
|
|||
|
|
### 后端接口
|
|||
|
|
- [ ] GET /system/license/info 返回正确的授权信息和剩余天数
|
|||
|
|
- [ ] PUT /system/license/expire 仅管理员可调用,成功更新到期时间
|
|||
|
|
- [ ] PUT /system/license/contact 仅管理员可调用,成功更新联系方式
|
|||
|
|
- [ ] POST /system/license/renewal 仅管理员可调用,成功新增续费记录并更新系统到期时间
|
|||
|
|
- [ ] GET /system/license/renewal/list 仅管理员可调用,返回续费记录列表(按时间倒序)
|
|||
|
|
|
|||
|
|
### 前端页面
|
|||
|
|
- [ ] 首页弹窗正确显示剩余天数或已过期天数
|
|||
|
|
- [ ] 首页弹窗显示联系邮箱和电话
|
|||
|
|
- [ ] 首页弹窗关闭后当天不再显示
|
|||
|
|
- [ ] 首页顶部版本说明左侧正确显示到期时间
|
|||
|
|
- [ ] 根据剩余天数显示不同颜色(正常/警告/错误)
|
|||
|
|
- [ ] 管理员点击可跳转到续费管理页面
|
|||
|
|
- [ ] 续费管理页面仅管理员可访问
|
|||
|
|
- [ ] 续费操作成功后,系统到期时间更新
|
|||
|
|
- [ ] 续费操作成功后,历史续费记录表格显示最新记录
|
|||
|
|
- [ ] 历史续费记录按操作时间倒序显示
|
|||
|
|
|
|||
|
|
### 权限控制
|
|||
|
|
- [ ] 系统已过期时,普通用户无法访问生产管理、仓库管理、质量管理、设备管理模块
|
|||
|
|
- [ ] 系统已过期时,管理员可正常访问所有模块
|
|||
|
|
- [ ] 访问受限模块时提示"系统已过期,请联系管理员续费"
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 文件清单
|
|||
|
|
|
|||
|
|
### SQL文件
|
|||
|
|
- `.sql/2026-03-12_v2.0.008_周启威_到期续费功能.sql`
|
|||
|
|
|
|||
|
|
### 后端文件
|
|||
|
|
- `mes-system/src/main/java/cn/sourceplan/system/domain/SysLicenseConfig.java`
|
|||
|
|
- `mes-system/src/main/java/cn/sourceplan/system/domain/SysLicenseRenewal.java`
|
|||
|
|
- `mes-system/src/main/java/cn/sourceplan/system/mapper/SysLicenseConfigMapper.java`
|
|||
|
|
- `mes-system/src/main/java/cn/sourceplan/system/mapper/SysLicenseRenewalMapper.java`
|
|||
|
|
- `mes-system/src/main/resources/mapper/system/SysLicenseConfigMapper.xml`
|
|||
|
|
- `mes-system/src/main/resources/mapper/system/SysLicenseRenewalMapper.xml`
|
|||
|
|
- `mes-system/src/main/java/cn/sourceplan/system/service/ISysLicenseService.java`
|
|||
|
|
- `mes-system/src/main/java/cn/sourceplan/system/service/impl/SysLicenseServiceImpl.java`
|
|||
|
|
- `mes-admin/src/main/java/cn/sourceplan/web/controller/system/SysLicenseController.java`
|
|||
|
|
|
|||
|
|
### 前端文件
|
|||
|
|
- `mes-ui/src/api/system/license.js`
|
|||
|
|
- `mes-ui/src/components/LicenseExpireDialog/index.vue`
|
|||
|
|
- `mes-ui/src/components/LicenseExpireInfo/index.vue`
|
|||
|
|
- `mes-ui/src/views/system/license/renewal.vue`
|
|||
|
|
- `mes-ui/src/permission.js` - 路由守卫(授权过期拦截)
|
|||
|
|
- `mes-ui/src/layout/components/Navbar.vue` - 顶部导航栏集成
|
|||
|
|
- `mes-ui/src/views/index.vue` - 首页弹窗集成
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 优化改进 (2026-03-13)
|
|||
|
|
|
|||
|
|
### 1. 用户体验优化
|
|||
|
|
- ✅ **弹窗显示机制**:每次进入系统都显示
|
|||
|
|
- 确保用户不会错过重要的续费提醒
|
|||
|
|
- 避免因关闭弹窗而长期不看到提醒的情况
|
|||
|
|
|
|||
|
|
### 2. 数据完整性增强
|
|||
|
|
- ✅ **续费前到期时间记录**:新增 `previous_expire_date` 字段
|
|||
|
|
- 自动记录每次续费前的系统到期时间
|
|||
|
|
- 可清晰看到每次续费延长了多少时间
|
|||
|
|
- 便于续费历史追溯和审计
|
|||
|
|
|
|||
|
|
### 3. 接口规范化
|
|||
|
|
- ✅ **RESTful规范**:统一使用 `@RequestBody` 接收JSON
|
|||
|
|
- `PUT /system/license/expire` 改用 JSON body
|
|||
|
|
- `PUT /system/license/contact` 改用 JSON body
|
|||
|
|
- 前后端交互更规范,便于后续扩展
|
|||
|
|
|
|||
|
|
### 4. 数据查询优化
|
|||
|
|
- ✅ **SQL排序保证**:Mapper XML 添加 `ORDER BY operate_time DESC`
|
|||
|
|
- 确保续费记录始终按时间倒序显示
|
|||
|
|
- 不依赖数据库默认顺序,提高可靠性
|
|||
|
|
|
|||
|
|
### 5. 信息展示增强
|
|||
|
|
- ✅ **智能Tooltip**:首页到期时间显示增强
|
|||
|
|
- 鼠标悬停显示详细续费信息
|
|||
|
|
- 包含:下次到期时间、剩余天数、上次续费时间、联系方式
|
|||
|
|
- 类似版本说明的交互方式,用户体验一致
|
|||
|
|
|
|||
|
|
### 6. 弹窗提醒优化
|
|||
|
|
- ✅ **今日不再提示功能**:智能提醒策略
|
|||
|
|
- **剩余 > 5天**:用户可选择"今日不再提示",避免频繁打扰
|
|||
|
|
- **剩余 ≤ 5天**:强制提醒,确保临近到期不会被忽略
|
|||
|
|
- **已过期**:强制提醒,确保过期状态得到重视
|
|||
|
|
- 使用 sessionStorage 存储忽略状态,关闭浏览器后重置
|
|||
|
|
- 平衡用户体验和提醒效果,既不过度打扰,又不遗漏重要提醒
|
|||
|
|
|
|||
|
|
### 7. 路由拦截策略优化
|
|||
|
|
- ✅ **黑名单拦截模式**:从白名单改为黑名单
|
|||
|
|
- 仅拦截核心业务模块(生产、仓库、质量、销售、采购、能源、安全、财务)
|
|||
|
|
- 允许访问系统管理、授权管理等非业务模块
|
|||
|
|
- 避免过度限制,提升用户体验
|
|||
|
|
|
|||
|
|
### 8. 弹窗UI现代化
|
|||
|
|
- ✅ **视觉设计优化**:现代化UI风格
|
|||
|
|
- 大图标 + 渐变背景 + 动画效果
|
|||
|
|
- 根据状态变色(橙色警告/红色过期)
|
|||
|
|
- 卡片式布局,信息层次清晰
|
|||
|
|
- 圆角设计,阴影效果,视觉更友好
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 注意事项
|
|||
|
|
|
|||
|
|
1. **时区问题**:确保前后端时间格式一致,使用 `yyyy-MM-dd HH:mm:ss` 格式
|
|||
|
|
2. **权限校验**:所有管理员操作接口必须添加 `@PreAuthorize("@ss.hasRole('admin')")` 注解
|
|||
|
|
3. **事务管理**:续费操作涉及两张表,已使用 `@Transactional` 保证事务一致性
|
|||
|
|
4. **日志记录**:所有授权相关操作已添加 `@Log` 注解记录操作日志
|
|||
|
|
5. **弹窗提醒**:每次进入系统都会显示到期提醒弹窗,确保用户不会错过续费
|
|||
|
|
6. **自动记录**:续费操作会自动记录续费前到期时间,无需手动填写
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 设计原则
|
|||
|
|
|
|||
|
|
✅ **轻量化** - 仅2张表,6个接口,3个前端组件
|
|||
|
|
✅ **简洁高效** - 无复杂依赖,无授权密钥验证
|
|||
|
|
✅ **权限分离** - 管理员全权限,普通用户受限
|
|||
|
|
✅ **用户友好** - 弹窗可关闭,首页显示直观
|
|||
|
|
✅ **可维护性** - 代码简洁,逻辑清晰
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 开发状态
|
|||
|
|
|
|||
|
|
**✅ 开发完成** - 2026-03-13
|
|||
|
|
|
|||
|
|
所有功能已实现并集成完毕:
|
|||
|
|
- ✅ 后端接口和数据库
|
|||
|
|
- ✅ 前端组件和页面
|
|||
|
|
- ✅ 首页弹窗和导航栏显示
|
|||
|
|
- ✅ 路由守卫和权限控制
|
|||
|
|
- ✅ 样式优化(下拉菜单格式)
|
|||
|
|
|
|||
|
|
**测试要点**:
|
|||
|
|
1. 登录后首页是否显示授权到期弹窗(剩余≤30天或已过期)
|
|||
|
|
2. 导航栏"授权信息"下拉菜单是否显示正确
|
|||
|
|
3. 普通用户在授权过期后访问业务模块是否被拦截
|
|||
|
|
4. 管理员是否可以正常续费
|
|||
|
|
5. 续费后授权信息是否实时更新
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 排除范围
|
|||
|
|
|
|||
|
|
以下功能**不在本次需求范围内**:
|
|||
|
|
- ❌ 授权密钥验证
|
|||
|
|
- ❌ 趋势分析
|
|||
|
|
- ❌ 邮件通知
|
|||
|
|
- ❌ 系统消息推送
|
|||
|
|
- ❌ 模块粒度授权控制
|
|||
|
|
- ❌ 多租户支持
|
|||
|
|
- ❌ 自动续费
|
|||
|
|
- ❌ 在线支付
|