14 KiB
14 KiB
MES系统授权续费功能 - 任务文档
版本: v2.0.008
作者: 周启威
日期: 2026-03-12
状态: 开发完成
功能概述
实现MES系统授权到期提醒和续费管理功能,包括:
- 首页弹窗提醒(剩余天数/已过期天数)
- 首页顶部到期时间显示(版本说明左侧)
- 到期后限制普通用户访问业务模块
- 管理员续费操作和历史记录管理
- 联系方式管理(邮箱+电话)
已完成工作
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+ XMLSysLicenseRenewalMapper.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. 续费操作
- 管理员填写企业名称、续费到期时间、备注
- 点击确认续费后:
- 自动记录续费前的到期时间
- 更新系统全局到期时间
- 插入续费历史记录
- 自动记录操作人和操作时间
- 刷新历史记录表格
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 中添加:
{
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 中添加:
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.javames-system/src/main/java/cn/sourceplan/system/domain/SysLicenseRenewal.javames-system/src/main/java/cn/sourceplan/system/mapper/SysLicenseConfigMapper.javames-system/src/main/java/cn/sourceplan/system/mapper/SysLicenseRenewalMapper.javames-system/src/main/resources/mapper/system/SysLicenseConfigMapper.xmlmes-system/src/main/resources/mapper/system/SysLicenseRenewalMapper.xmlmes-system/src/main/java/cn/sourceplan/system/service/ISysLicenseService.javames-system/src/main/java/cn/sourceplan/system/service/impl/SysLicenseServiceImpl.javames-admin/src/main/java/cn/sourceplan/web/controller/system/SysLicenseController.java
前端文件
mes-ui/src/api/system/license.jsmes-ui/src/components/LicenseExpireDialog/index.vuemes-ui/src/components/LicenseExpireInfo/index.vuemes-ui/src/views/system/license/renewal.vuemes-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接收JSONPUT /system/license/expire改用 JSON bodyPUT /system/license/contact改用 JSON body- 前后端交互更规范,便于后续扩展
4. 数据查询优化
- ✅ SQL排序保证:Mapper XML 添加
ORDER BY operate_time DESC- 确保续费记录始终按时间倒序显示
- 不依赖数据库默认顺序,提高可靠性
5. 信息展示增强
- ✅ 智能Tooltip:首页到期时间显示增强
- 鼠标悬停显示详细续费信息
- 包含:下次到期时间、剩余天数、上次续费时间、联系方式
- 类似版本说明的交互方式,用户体验一致
6. 弹窗提醒优化
- ✅ 今日不再提示功能:智能提醒策略
- 剩余 > 5天:用户可选择"今日不再提示",避免频繁打扰
- 剩余 ≤ 5天:强制提醒,确保临近到期不会被忽略
- 已过期:强制提醒,确保过期状态得到重视
- 使用 sessionStorage 存储忽略状态,关闭浏览器后重置
- 平衡用户体验和提醒效果,既不过度打扰,又不遗漏重要提醒
7. 路由拦截策略优化
- ✅ 黑名单拦截模式:从白名单改为黑名单
- 仅拦截核心业务模块(生产、仓库、质量、销售、采购、能源、安全、财务)
- 允许访问系统管理、授权管理等非业务模块
- 避免过度限制,提升用户体验
8. 弹窗UI现代化
- ✅ 视觉设计优化:现代化UI风格
- 大图标 + 渐变背景 + 动画效果
- 根据状态变色(橙色警告/红色过期)
- 卡片式布局,信息层次清晰
- 圆角设计,阴影效果,视觉更友好
注意事项
- 时区问题:确保前后端时间格式一致,使用
yyyy-MM-dd HH:mm:ss格式 - 权限校验:所有管理员操作接口必须添加
@PreAuthorize("@ss.hasRole('admin')")注解 - 事务管理:续费操作涉及两张表,已使用
@Transactional保证事务一致性 - 日志记录:所有授权相关操作已添加
@Log注解记录操作日志 - 弹窗提醒:每次进入系统都会显示到期提醒弹窗,确保用户不会错过续费
- 自动记录:续费操作会自动记录续费前到期时间,无需手动填写
设计原则
✅ 轻量化 - 仅2张表,6个接口,3个前端组件
✅ 简洁高效 - 无复杂依赖,无授权密钥验证
✅ 权限分离 - 管理员全权限,普通用户受限
✅ 用户友好 - 弹窗可关闭,首页显示直观
✅ 可维护性 - 代码简洁,逻辑清晰
开发状态
✅ 开发完成 - 2026-03-13
所有功能已实现并集成完毕:
- ✅ 后端接口和数据库
- ✅ 前端组件和页面
- ✅ 首页弹窗和导航栏显示
- ✅ 路由守卫和权限控制
- ✅ 样式优化(下拉菜单格式)
测试要点:
- 登录后首页是否显示授权到期弹窗(剩余≤30天或已过期)
- 导航栏"授权信息"下拉菜单是否显示正确
- 普通用户在授权过期后访问业务模块是否被拦截
- 管理员是否可以正常续费
- 续费后授权信息是否实时更新
排除范围
以下功能不在本次需求范围内:
- ❌ 授权密钥验证
- ❌ 趋势分析
- ❌ 邮件通知
- ❌ 系统消息推送
- ❌ 模块粒度授权控制
- ❌ 多租户支持
- ❌ 自动续费
- ❌ 在线支付