代码修改

This commit is contained in:
liuhanqing
2026-04-10 10:23:34 +08:00
parent f76c277d79
commit 393540ae28
97 changed files with 5982 additions and 3479 deletions

View File

@@ -0,0 +1,61 @@
package com.ruoyi.license.config;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.ruoyi.framework.config.properties.PermitAllUrlProperties;
import com.ruoyi.license.interceptor.LicenseInterceptor;
/**
* 授权模块配置
*
* @author ruoyi
*/
@Configuration
public class LicenseConfig implements WebMvcConfigurer
{
@Autowired
private LicenseInterceptor licenseInterceptor;
@Autowired
private PermitAllUrlProperties permitAllUrl;
@Value("${license.enabled:false}")
private boolean licenseEnabled;
private static final List<String> BASE_EXCLUDE = Arrays.asList(
"/login",
"/logout",
"/register",
"/captchaImage",
"/system/license/active",
"/swagger-ui.html",
"/swagger-resources/**",
"/webjars/**",
"/*/api-docs",
"/druid/**",
"/*.html",
"/**/*.html",
"/**/*.css",
"/**/*.js",
"/profile/**"
);
@Override
public void addInterceptors(InterceptorRegistry registry)
{
if (licenseEnabled)
{
List<String> excludeList = new ArrayList<>(BASE_EXCLUDE);
excludeList.addAll(permitAllUrl.getUrls());
registry.addInterceptor(licenseInterceptor)
.addPathPatterns("/**")
.excludePathPatterns(excludeList);
}
}
}

View File

@@ -0,0 +1,105 @@
package com.ruoyi.license.domain;
import com.ruoyi.common.core.domain.BaseEntity;
import java.util.Date;
/**
* 系统授权码对象 sys_license
*
* @author ruoyi
*/
public class SysLicense extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 授权ID */
private Long licenseId;
/** 授权码 */
private String licenseCode;
/** 授权开始时间 */
private Date startTime;
/** 授权结束时间 */
private Date expireTime;
/** 授权状态(0未激活 1已激活 2已过期) */
private String status;
/** 激活时间 */
private Date activeTime;
/** 激活人 */
private String activeBy;
public Long getLicenseId()
{
return licenseId;
}
public void setLicenseId(Long licenseId)
{
this.licenseId = licenseId;
}
public String getLicenseCode()
{
return licenseCode;
}
public void setLicenseCode(String licenseCode)
{
this.licenseCode = licenseCode;
}
public Date getStartTime()
{
return startTime;
}
public void setStartTime(Date startTime)
{
this.startTime = startTime;
}
public Date getExpireTime()
{
return expireTime;
}
public void setExpireTime(Date expireTime)
{
this.expireTime = expireTime;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
public Date getActiveTime()
{
return activeTime;
}
public void setActiveTime(Date activeTime)
{
this.activeTime = activeTime;
}
public String getActiveBy()
{
return activeBy;
}
public void setActiveBy(String activeBy)
{
this.activeBy = activeBy;
}
}

View File

@@ -0,0 +1,48 @@
package com.ruoyi.license.interceptor;
import java.io.PrintWriter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import com.ruoyi.license.service.ISysLicenseService;
/**
* 授权拦截器
*
* @author ruoyi
*/
@Component
public class LicenseInterceptor implements HandlerInterceptor
{
@Autowired
private ISysLicenseService licenseService;
@Value("${license.enabled:false}")
private boolean licenseEnabled;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
{
if (!licenseEnabled)
{
return true;
}
if (!licenseService.checkLicenseValid())
{
response.setStatus(HttpServletResponse.SC_OK);
response.setContentType("application/json;charset=UTF-8");
PrintWriter writer = response.getWriter();
writer.write("{\"code\":500,\"msg\":\"\u7cfb\u7edf\u6388\u6743\u5df2\u8fc7\u671f\uff0c\u8bf7\u8054\u7cfb\u7ba1\u7406\u5458\u6fc0\u6d3b\u6388\u6743\u7801\"}");
writer.flush();
return false;
}
return true;
}
}

View File

@@ -0,0 +1,67 @@
package com.ruoyi.license.mapper;
import com.ruoyi.license.domain.SysLicense;
import java.util.List;
/**
* 授权码Mapper接口
*
* @author ruoyi
*/
public interface SysLicenseMapper
{
/**
* 查询授权码
*
* @param licenseId 授权码ID
* @return 授权码
*/
public SysLicense selectSysLicenseById(Long licenseId);
/**
* 查询授权码列表
*
* @param sysLicense 授权码
* @return 授权码集合
*/
public List<SysLicense> selectSysLicenseList(SysLicense sysLicense);
/**
* 查询当前有效的授权码
*
* @return 授权码
*/
public SysLicense selectActiveLicense();
/**
* 新增授权码
*
* @param sysLicense 授权码
* @return 结果
*/
public int insertSysLicense(SysLicense sysLicense);
/**
* 修改授权码
*
* @param sysLicense 授权码
* @return 结果
*/
public int updateSysLicense(SysLicense sysLicense);
/**
* 删除授权码
*
* @param licenseId 授权码ID
* @return 结果
*/
public int deleteSysLicenseById(Long licenseId);
/**
* 批量删除授权码
*
* @param licenseIds 需要删除的数据ID
* @return 结果
*/
public int deleteSysLicenseByIds(String[] licenseIds);
}

View File

@@ -0,0 +1,87 @@
package com.ruoyi.license.service;
import com.ruoyi.license.domain.SysLicense;
import java.util.List;
/**
* 授权码Service接口
*
* @author ruoyi
*/
public interface ISysLicenseService
{
/**
* 查询授权码
*
* @param licenseId 授权码ID
* @return 授权码
*/
public SysLicense selectSysLicenseById(Long licenseId);
/**
* 查询授权码列表
*
* @param sysLicense 授权码
* @return 授权码集合
*/
public List<SysLicense> selectSysLicenseList(SysLicense sysLicense);
/**
* 新增授权码
*
* @param sysLicense 授权码
* @return 结果
*/
public int insertSysLicense(SysLicense sysLicense);
/**
* 修改授权码
*
* @param sysLicense 授权码
* @return 结果
*/
public int updateSysLicense(SysLicense sysLicense);
/**
* 批量删除授权码
*
* @param ids 需要删除的数据ID
* @return 结果
*/
public int deleteSysLicenseByIds(String ids);
/**
* 删除授权码信息
*
* @param licenseId 授权码ID
* @return 结果
*/
public int deleteSysLicenseById(Long licenseId);
/**
* 激活授权码
*
* @param licenseCode 授权码
* @return 结果
*/
public int activeLicense(String licenseCode);
/**
* 检查授权是否有效
*
* @return true有效 false无效
*/
public boolean checkLicenseValid();
/**
* 获取当前有效授权信息
*
* @return 授权信息
*/
public SysLicense getActiveLicense();
/**
* 更新过期授权码状态
*/
public void updateExpiredLicenses();
}

View File

@@ -0,0 +1,266 @@
package com.ruoyi.license.service.impl;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.license.domain.SysLicense;
import com.ruoyi.license.mapper.SysLicenseMapper;
import com.ruoyi.license.service.ISysLicenseService;
import com.ruoyi.license.util.LicenseUtils;
/**
* 授权码Service业务层处理
*
* @author ruoyi
*/
@Service
public class SysLicenseServiceImpl implements ISysLicenseService
{
@Autowired
private SysLicenseMapper sysLicenseMapper;
@Autowired
private com.ruoyi.system.mapper.SysConfigMapper sysConfigMapper;
@org.springframework.beans.factory.annotation.Value("${license.enabled:false}")
private boolean licenseEnabled;
/**
* 查询授权码
*
* @param licenseId 授权码ID
* @return 授权码
*/
@Override
public SysLicense selectSysLicenseById(Long licenseId)
{
return sysLicenseMapper.selectSysLicenseById(licenseId);
}
/**
* 查询授权码列表
*
* @param sysLicense 授权码
* @return 授权码
*/
@Override
public List<SysLicense> selectSysLicenseList(SysLicense sysLicense)
{
return sysLicenseMapper.selectSysLicenseList(sysLicense);
}
/**
* 新增授权码
*
* @param sysLicense 授权码
* @return 结果
*/
@Override
public int insertSysLicense(SysLicense sysLicense)
{
sysLicense.setCreateTime(new Date());
return sysLicenseMapper.insertSysLicense(sysLicense);
}
/**
* 修改授权码
*
* @param sysLicense 授权码
* @return 结果
*/
@Override
public int updateSysLicense(SysLicense sysLicense)
{
sysLicense.setUpdateTime(new Date());
return sysLicenseMapper.updateSysLicense(sysLicense);
}
/**
* 删除授权码对象
*
* @param ids 需要删除的数据ID
* @return 结果
*/
@Override
public int deleteSysLicenseByIds(String ids)
{
return sysLicenseMapper.deleteSysLicenseByIds(Convert.toStrArray(ids));
}
/**
* 删除授权码信息
*
* @param licenseId 授权码ID
* @return 结果
*/
@Override
public int deleteSysLicenseById(Long licenseId)
{
return sysLicenseMapper.deleteSysLicenseById(licenseId);
}
/**
* 激活授权码
*
* @param licenseCode 授权码
* @return 结果
*/
@Override
public int activeLicense(String licenseCode)
{
if (StringUtils.isEmpty(licenseCode))
{
return 0;
}
// 验证授权码格式
if (!LicenseUtils.validateFormat(licenseCode))
{
return 0;
}
try
{
// 从配置表获取项目编号
String projectNo = sysConfigMapper.selectConfigByKey("fortucky.project.no");
if (StringUtils.isEmpty(projectNo))
{
return 0;
}
// 解析授权码
long expireTime = LicenseUtils.parseLicense(licenseCode, projectNo);
if (expireTime == 0)
{
return 0;
}
Date now = new Date();
Date startTime = now;
Date expireDate = new Date(expireTime);
// 验证是否已过期
if (expireDate.before(now))
{
return 0;
}
// 创建授权记录
SysLicense license = new SysLicense();
license.setLicenseCode(licenseCode);
license.setStartTime(startTime);
license.setExpireTime(expireDate);
license.setStatus("1");
license.setActiveTime(now);
license.setCreateTime(now);
return sysLicenseMapper.insertSysLicense(license);
}
catch (Exception e)
{
return 0;
}
}
/**
* 检查授权是否有效
*
* @return true有效 false无效
*/
@Override
public boolean checkLicenseValid()
{
// 如果授权码功能未启用,直接返回true
if (!licenseEnabled)
{
return true;
}
SysLicense license = sysLicenseMapper.selectActiveLicense();
if (license == null)
{
System.out.println("[授权检查] 没有找到激活的授权码");
return false;
}
// 从配置表获取项目编号
String projectNo = sysConfigMapper.selectConfigByKey("fortucky.project.no");
if (StringUtils.isEmpty(projectNo))
{
System.out.println("[授权检查] 项目编号未配置");
return false;
}
System.out.println("[授权检查] 授权码: " + license.getLicenseCode());
System.out.println("[授权检查] 项目编号: " + projectNo);
// 从授权码解析过期时间
long expireTime = LicenseUtils.parseLicense(license.getLicenseCode(), projectNo);
if (expireTime == 0)
{
System.out.println("[授权检查] 授权码解析失败");
return false;
}
Date now = new Date();
System.out.println("[授权检查] 当前时间: " + now.getTime());
System.out.println("[授权检查] 过期时间: " + expireTime);
if (expireTime < now.getTime())
{
System.out.println("[授权检查] 授权已过期");
// 更新为过期状态
license.setStatus("2");
sysLicenseMapper.updateSysLicense(license);
return false;
}
return true;
}
/**
* 获取当前有效授权信息
*
* @return 授权信息
*/
@Override
public SysLicense getActiveLicense()
{
return sysLicenseMapper.selectActiveLicense();
}
/**
* 更新过期授权码状态
*/
@Override
public void updateExpiredLicenses()
{
SysLicense query = new SysLicense();
query.setStatus("1");
List<SysLicense> licenses = sysLicenseMapper.selectSysLicenseList(query);
// 从配置表获取项目编号
String projectNo = sysConfigMapper.selectConfigByKey("fortucky.project.no");
if (StringUtils.isEmpty(projectNo))
{
return;
}
Date now = new Date();
for (SysLicense license : licenses)
{
// 从授权码解析过期时间
long expireTime = LicenseUtils.parseLicense(license.getLicenseCode(), projectNo);
if (expireTime > 0 && expireTime < now.getTime())
{
license.setStatus("2");
license.setUpdateTime(now);
sysLicenseMapper.updateSysLicense(license);
}
}
}
}

View File

@@ -0,0 +1,47 @@
package com.ruoyi.license.task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.license.service.ISysLicenseService;
/**
* 授权检查定时任务
*
* @author ruoyi
*/
@Component
public class LicenseCheckTask
{
@Autowired
private ISysLicenseService licenseService;
@Autowired
private RedisCache redisCache;
@Value("${license.enabled:false}")
private boolean licenseEnabled;
/**
* 每5分钟检查一次授权状态
*/
@Scheduled(cron = "0 */5 * * * ?")
public void checkLicense()
{
if (!licenseEnabled)
{
return;
}
if (!licenseService.checkLicenseValid())
{
// 授权无效,删除 Redis 中所有登录 token,强制踢出所有在线用户
redisCache.deleteObject(redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*"));
}
licenseService.updateExpiredLicenses();
}
}

View File

@@ -0,0 +1,127 @@
package com.ruoyi.license.util;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
/**
* 授权码生成工具(独立运行)
*
* @author ruoyi
*/
public class LicenseGenerator
{
public static void main(String[] args)
{
Scanner scanner = new Scanner(System.in);
System.out.println("========================================");
System.out.println(" RuoYi 授权码生成工具");
System.out.println("========================================");
System.out.println();
try
{
// 选择授权类型
System.out.println("请选择授权类型:");
System.out.println("1. 5分钟测试");
System.out.println("2. 1个月授权");
System.out.println("3. 3个月授权");
System.out.println("4. 1年授权");
System.out.println("5. 5年授权");
System.out.println("6. 长期授权");
System.out.print("请输入选项(1-6): ");
String typeChoice = scanner.nextLine().trim();
String type;
String typeDesc;
long expireTime;
switch (typeChoice)
{
case "1":
type = LicenseUtils.TYPE_TEST;
typeDesc = "5分钟测试";
expireTime = System.currentTimeMillis() + 5 * 60 * 1000L;
break;
case "2":
type = LicenseUtils.TYPE_MONTH;
typeDesc = "1个月授权";
expireTime = System.currentTimeMillis() + 30L * 24 * 60 * 60 * 1000;
break;
case "3":
type = LicenseUtils.TYPE_THREE;
typeDesc = "3个月授权";
expireTime = System.currentTimeMillis() + 90L * 24 * 60 * 60 * 1000;
break;
case "4":
type = LicenseUtils.TYPE_YEAR;
typeDesc = "1年授权";
expireTime = System.currentTimeMillis() + 365L * 24 * 60 * 60 * 1000;
break;
case "5":
type = LicenseUtils.TYPE_FIVE;
typeDesc = "5年授权";
expireTime = System.currentTimeMillis() + 5 * 365L * 24 * 60 * 60 * 1000;
break;
case "6":
type = LicenseUtils.TYPE_FOREVER;
typeDesc = "长期授权";
expireTime = System.currentTimeMillis() + 100 * 365L * 24 * 60 * 60 * 1000;
break;
default:
System.out.println("错误:无效的选项");
return;
}
// 输入项目编号
System.out.print("请输入项目编号: ");
String projectNo = scanner.nextLine().trim();
if (projectNo.isEmpty())
{
System.out.println("错误:项目编号不能为空");
return;
}
// 生成授权码
String licenseCode = LicenseUtils.generateLicense(type, projectNo);
if (licenseCode == null)
{
System.out.println("错误:授权码生成失败");
return;
}
// 格式化日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date now = new Date();
Date expire = new Date(expireTime);
System.out.println();
System.out.println("========================================");
System.out.println("授权码生成成功!");
System.out.println("========================================");
System.out.println("授权类型: " + typeDesc);
System.out.println("项目编号: " + projectNo);
System.out.println("当前时间: " + sdf.format(now));
System.out.println("过期时间: " + sdf.format(expire));
System.out.println("----------------------------------------");
System.out.println("授权码:");
System.out.println(licenseCode);
System.out.println("========================================");
System.out.println();
System.out.println("请妥善保管授权码,在系统中激活后即可使用。");
System.out.println("注意:系统配置中的项目编号必须与此处一致才能激活。");
}
catch (Exception e)
{
System.out.println("错误:" + e.getMessage());
e.printStackTrace();
}
finally
{
scanner.close();
}
}
}

View File

@@ -0,0 +1,90 @@
package com.ruoyi.license.util;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 授权码测试工具
*
* @author ruoyi
*/
public class LicenseTest
{
public static void main(String[] args)
{
System.out.println("========================================");
System.out.println(" 授权码功能测试");
System.out.println("========================================");
System.out.println();
String projectNo = "FT541";
// 测试1:生成各类型授权码
System.out.println("【测试1】生成各类型授权码");
String testCode = LicenseUtils.generateLicense(LicenseUtils.TYPE_TEST, projectNo);
String yearCode = LicenseUtils.generateLicense(LicenseUtils.TYPE_YEAR, projectNo);
String fiveCode = LicenseUtils.generateLicense(LicenseUtils.TYPE_FIVE, projectNo);
String foreverCode = LicenseUtils.generateLicense(LicenseUtils.TYPE_FOREVER, projectNo);
System.out.println("5分钟测试: " + testCode);
System.out.println("1年授权: " + yearCode);
System.out.println("5年授权: " + fiveCode);
System.out.println("长期授权: " + foreverCode);
System.out.println("结果: ✓ 通过");
System.out.println();
// 测试2:验证授权码格式
System.out.println("【测试2】验证授权码格式");
boolean isValid = LicenseUtils.validateFormat(yearCode);
System.out.println("格式验证: " + (isValid ? "✓ 通过" : "✗ 失败"));
System.out.println();
// 测试3:解析授权码
System.out.println("【测试3】解析授权码");
long expireTime = LicenseUtils.parseLicense(yearCode, projectNo);
if (expireTime > 0)
{
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date expire = new Date(expireTime);
System.out.println("过期时间: " + sdf.format(expire));
System.out.println("结果: ✓ 通过");
}
else
{
System.out.println("结果: ✗ 失败");
}
System.out.println();
// 测试4:项目编号验证
System.out.println("【测试4】项目编号验证");
long validResult = LicenseUtils.parseLicense(yearCode, projectNo);
long invalidResult = LicenseUtils.parseLicense(yearCode, "WRONG001");
System.out.println("正确项目编号: " + (validResult > 0 ? "✓ 通过" : "✗ 失败"));
System.out.println("错误项目编号: " + (invalidResult == 0 ? "✓ 通过(正确拒绝)" : "✗ 失败"));
System.out.println();
// 测试5:授权码格式展示
System.out.println("【测试5】授权码格式展示");
System.out.println("授权码: " + yearCode);
String[] parts = yearCode.split("_");
if (parts.length == 5)
{
System.out.println("前缀: " + parts[0]);
System.out.println("类型: " + parts[1] + " (" + LicenseUtils.getTypeDesc(parts[1]) + ")");
System.out.println("项目编号: " + parts[2]);
System.out.println("加密时间: " + parts[3]);
System.out.println("校验码: " + parts[4]);
System.out.println("结果: ✓ 通过");
}
else
{
System.out.println("结果: ✗ 失败");
}
System.out.println();
System.out.println("========================================");
System.out.println("测试完成!");
System.out.println("========================================");
}
}

View File

@@ -0,0 +1,275 @@
package com.ruoyi.license.util;
import java.util.Base64;
import java.util.Date;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
/**
* 授权码工具类
* 格式: FORTUCKY_授权类型_项目编号_加密时间_校验码
*
* @author ruoyi
*/
public class LicenseUtils
{
// 密钥(16位)
private static final String SECRET_KEY = "RuoYiLicense2024";
// 授权类型
public static final String TYPE_TEST = "TEST"; // 5分钟测试
public static final String TYPE_MONTH = "MONTH"; // 1个月
public static final String TYPE_THREE = "THREE"; // 3个月
public static final String TYPE_YEAR = "YEAR"; // 1年
public static final String TYPE_FIVE = "FIVE"; // 5年
public static final String TYPE_FOREVER = "FOREVER"; // 长期
/**
* 生成授权码
*
* @param type 授权类型
* @param projectNo 项目编号
* @return 授权码
*/
public static String generateLicense(String type, String projectNo)
{
try
{
long expireTime = calculateExpireTime(type);
if (expireTime == 0)
{
return null;
}
// 加密过期时间
String encryptedTime = encrypt(String.valueOf(expireTime));
if (encryptedTime == null)
{
return null;
}
// 生成校验码(取加密时间的前8位MD5)
String checkCode = generateCheckCode(type, projectNo, encryptedTime);
// 拼接授权码: FORTUCKY_类型_项目编号_加密时间_校验码
return "FORTUCKY_" + type + "_" + projectNo + "_" + encryptedTime + "_" + checkCode;
}
catch (Exception e)
{
return null;
}
}
/**
* 验证授权码格式
*
* @param licenseCode 授权码
* @return true有效 false无效
*/
public static boolean validateFormat(String licenseCode)
{
if (licenseCode == null || licenseCode.trim().isEmpty())
{
return false;
}
String[] parts = licenseCode.split("_");
if (parts.length != 5)
{
return false;
}
if (!"FORTUCKY".equals(parts[0]))
{
return false;
}
// 验证授权类型
String type = parts[1];
if (!TYPE_TEST.equals(type) && !TYPE_MONTH.equals(type) && !TYPE_THREE.equals(type) &&
!TYPE_YEAR.equals(type) && !TYPE_FIVE.equals(type) && !TYPE_FOREVER.equals(type))
{
return false;
}
return true;
}
/**
* 解析授权码
*
* @param licenseCode 授权码
* @param projectNo 系统项目编号
* @return 过期时间戳,0表示解析失败
*/
public static long parseLicense(String licenseCode, String projectNo)
{
try
{
if (!validateFormat(licenseCode))
{
return 0;
}
String[] parts = licenseCode.split("_");
String type = parts[1];
String codeProjectNo = parts[2];
String encryptedTime = parts[3];
String checkCode = parts[4];
// 验证项目编号
if (!codeProjectNo.equals(projectNo))
{
return 0;
}
// 验证校验码
String expectedCheckCode = generateCheckCode(type, codeProjectNo, encryptedTime);
if (!checkCode.equals(expectedCheckCode))
{
return 0;
}
// 解密时间
String decrypted = decrypt(encryptedTime);
if (decrypted == null)
{
return 0;
}
return Long.parseLong(decrypted);
}
catch (Exception e)
{
return 0;
}
}
/**
* 获取授权类型描述
*
* @param type 授权类型
* @return 描述
*/
public static String getTypeDesc(String type)
{
switch (type)
{
case TYPE_TEST: return "5分钟测试";
case TYPE_MONTH: return "1个月授权";
case TYPE_THREE: return "3个月授权";
case TYPE_YEAR: return "1年授权";
case TYPE_FIVE: return "5年授权";
case TYPE_FOREVER: return "长期授权";
default: return "未知";
}
}
/**
* 计算过期时间
*
* @param type 授权类型
* @return 过期时间戳
*/
private static long calculateExpireTime(String type)
{
long now = System.currentTimeMillis();
switch (type)
{
case TYPE_TEST:
return now + 5 * 60 * 1000L; // 5分钟
case TYPE_MONTH:
return now + 30L * 24 * 60 * 60 * 1000; // 1个月
case TYPE_THREE:
return now + 90L * 24 * 60 * 60 * 1000; // 3个月
case TYPE_YEAR:
return now + 365L * 24 * 60 * 60 * 1000; // 1年
case TYPE_FIVE:
return now + 5 * 365L * 24 * 60 * 60 * 1000; // 5年
case TYPE_FOREVER:
return now + 100 * 365L * 24 * 60 * 60 * 1000; // 100年(视为长期)
default:
return 0;
}
}
/**
* 生成校验码
*
* @param type 授权类型
* @param projectNo 项目编号
* @param encryptedTime 加密时间
* @return 校验码
*/
private static String generateCheckCode(String type, String projectNo, String encryptedTime)
{
try
{
String data = type + projectNo + encryptedTime;
java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
byte[] hash = md.digest(data.getBytes("UTF-8"));
StringBuilder sb = new StringBuilder();
for (int i = 0; i < Math.min(4, hash.length); i++)
{
sb.append(String.format("%02x", hash[i]));
}
return sb.toString().toUpperCase();
}
catch (Exception e)
{
return "00000000";
}
}
/**
* 加密
*
* @param data 原始数据
* @return 加密后的数据
*/
private static String encrypt(String data)
{
try
{
SecretKeySpec key = new SecretKeySpec(SECRET_KEY.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] encrypted = cipher.doFinal(data.getBytes("UTF-8"));
return Base64.getEncoder().encodeToString(encrypted).replace("+", "-").replace("/", ".").replace("=", "");
}
catch (Exception e)
{
return null;
}
}
/**
* 解密
*
* @param encryptedData 加密数据
* @return 解密后的数据
*/
private static String decrypt(String encryptedData)
{
try
{
String base64Data = encryptedData.replace("-", "+").replace(".", "/");
int padding = (4 - base64Data.length() % 4) % 4;
for (int i = 0; i < padding; i++)
{
base64Data += "=";
}
SecretKeySpec key = new SecretKeySpec(SECRET_KEY.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(base64Data));
return new String(decrypted, "UTF-8");
}
catch (Exception e)
{
return null;
}
}
}

View File

@@ -0,0 +1,108 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.license.mapper.SysLicenseMapper">
<resultMap type="com.ruoyi.license.domain.SysLicense" id="SysLicenseResult">
<result property="licenseId" column="license_id" />
<result property="licenseCode" column="license_code" />
<result property="startTime" column="start_time" />
<result property="expireTime" column="expire_time" />
<result property="status" column="status" />
<result property="activeTime" column="active_time" />
<result property="activeBy" column="active_by" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
<result property="remark" column="remark" />
</resultMap>
<sql id="selectSysLicenseVo">
select license_id, license_code, start_time, expire_time, status, active_time, active_by, create_by, create_time, update_by, update_time, remark from sys_license
</sql>
<select id="selectSysLicenseList" parameterType="com.ruoyi.license.domain.SysLicense" resultMap="SysLicenseResult">
<include refid="selectSysLicenseVo"/>
<where>
<if test="licenseCode != null and licenseCode != ''"> and license_code = #{licenseCode}</if>
<if test="startTime != null "> and start_time = #{startTime}</if>
<if test="expireTime != null "> and expire_time = #{expireTime}</if>
<if test="status != null and status != ''"> and status = #{status}</if>
</where>
order by create_time desc
</select>
<select id="selectSysLicenseById" parameterType="Long" resultMap="SysLicenseResult">
<include refid="selectSysLicenseVo"/>
where license_id = #{licenseId}
</select>
<select id="selectActiveLicense" resultMap="SysLicenseResult">
<include refid="selectSysLicenseVo"/>
where status = '1'
order by create_time desc
OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY
</select>
<insert id="insertSysLicense" parameterType="com.ruoyi.license.domain.SysLicense" useGeneratedKeys="true" keyProperty="licenseId">
insert into sys_license
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="licenseCode != null and licenseCode != ''">license_code,</if>
<if test="startTime != null">start_time,</if>
<if test="expireTime != null">expire_time,</if>
<if test="status != null and status != ''">status,</if>
<if test="activeTime != null">active_time,</if>
<if test="activeBy != null">active_by,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
<if test="remark != null">remark,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="licenseCode != null and licenseCode != ''">#{licenseCode},</if>
<if test="startTime != null">#{startTime},</if>
<if test="expireTime != null">#{expireTime},</if>
<if test="status != null and status != ''">#{status},</if>
<if test="activeTime != null">#{activeTime},</if>
<if test="activeBy != null">#{activeBy},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="remark != null">#{remark},</if>
</trim>
</insert>
<update id="updateSysLicense" parameterType="com.ruoyi.license.domain.SysLicense">
update sys_license
<trim prefix="SET" suffixOverrides=",">
<if test="licenseCode != null and licenseCode != ''">license_code = #{licenseCode},</if>
<if test="startTime != null">start_time = #{startTime},</if>
<if test="expireTime != null">expire_time = #{expireTime},</if>
<if test="status != null and status != ''">status = #{status},</if>
<if test="activeTime != null">active_time = #{activeTime},</if>
<if test="activeBy != null">active_by = #{activeBy},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="remark != null">remark = #{remark},</if>
</trim>
where license_id = #{licenseId}
</update>
<delete id="deleteSysLicenseById" parameterType="Long">
delete from sys_license where license_id = #{licenseId}
</delete>
<delete id="deleteSysLicenseByIds" parameterType="String">
delete from sys_license where license_id in
<foreach item="licenseId" collection="array" open="(" separator="," close=")">
#{licenseId}
</foreach>
</delete>
</mapper>