小程序开发-服务端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

5.5 KiB

网站信息接口重新设计说明

🎯 重新设计目标

基于新的 LocalDateTime 时间格式,重新设计 getSiteInfo 接口,提高代码质量、可维护性和性能。

🔧 主要改进

1. 接口结构优化

原始接口问题

  • 所有逻辑都在一个方法中,代码冗长
  • 缓存逻辑被注释掉,没有发挥作用
  • 错误处理不够完善
  • 时间计算逻辑复杂且不易理解

重新设计后

  • 模块化设计:将复杂逻辑拆分为多个专门的方法
  • 清晰的职责分离:每个方法只负责一个特定功能
  • 完善的错误处理:添加了异常捕获和日志记录
  • 改进的缓存机制:修复并优化了缓存逻辑

2. 方法拆分

核心方法

public ApiResult<CmsWebsite> getSiteInfo()

主接口方法,负责流程控制和参数验证。

辅助方法

  1. getCachedWebsiteInfo() - 缓存获取
  2. getWebsiteFromDatabase() - 数据库查询
  3. buildCompleteWebsiteInfo() - 构建完整信息
  4. cacheWebsiteInfo() - 缓存存储
  5. calculateExpirationInfo() - 过期信息计算
  6. setWebsiteConfig() - 配置信息设置
  7. setServerTimeInfo() - 服务器时间设置
  8. buildServerTimeWithLocalDateTime() - 新的时间构建方法

3. LocalDateTime 适配

过期时间计算优化

// 原始方式(复杂且不直观)
website.setSoon(website.getExpirationTime().minusDays(30).compareTo(now));
website.setExpired(website.getExpirationTime().compareTo(now));
website.setExpiredDays(java.time.temporal.ChronoUnit.DAYS.between(now, website.getExpirationTime()));

// 重新设计后(清晰且易理解)
LocalDateTime thirtyDaysLater = now.plusDays(30);
website.setSoon(expirationTime.isBefore(thirtyDaysLater) ? 1 : 0);
website.setExpired(expirationTime.isBefore(now) ? -1 : 1);
long daysBetween = ChronoUnit.DAYS.between(now, expirationTime);
website.setExpiredDays(daysBetween);

服务器时间信息增强

// 新增更丰富的时间信息
serverTime.put("now", now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
serverTime.put("timestamp", System.currentTimeMillis());
serverTime.put("weekName", today.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.CHINA));
serverTime.put("monthName", today.getMonth().getDisplayName(TextStyle.FULL, Locale.CHINA));
serverTime.put("monthStart", firstDayOfMonth.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
serverTime.put("monthEnd", lastDayOfMonth.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));

4. 错误处理和日志

缓存异常处理

private CmsWebsite getCachedWebsiteInfo(String cacheKey) {
    try {
        String siteInfo = redisUtil.get(cacheKey);
        if (StrUtil.isNotBlank(siteInfo)) {
            return JSONUtil.parseObject(siteInfo, CmsWebsite.class);
        }
    } catch (Exception e) {
        log.warn("从缓存解析网站信息失败: {}", e.getMessage());
    }
    return null;
}

详细的日志记录

log.info("获取网站信息成功,网站ID: {}, 租户ID: {}", website.getWebsiteId(), tenantId);
log.debug("网站过期信息计算完成 - 即将过期: {}, 是否过期: {}, 剩余天数: {}", 
    website.getSoon(), website.getExpired(), website.getExpiredDays());

5. 性能优化

缓存机制改进

  • 修复缓存读取:原来被注释的缓存读取逻辑已修复
  • 异常安全:缓存操作失败不影响主流程
  • 合理的缓存时间:1天的缓存时间平衡了性能和数据新鲜度

数据库查询优化

  • 精确查询:使用 LambdaQueryWrapper 提高查询效率
  • 限制结果集:使用 limit 1 避免不必要的数据传输

🎯 接口响应增强

服务器时间信息更丰富

{
  "serverTime": {
    "now": "2025-01-12 14:30:45",
    "timestamp": 1705045845000,
    "today": "2025-01-12",
    "tomorrow": "2025-01-13",
    "afterDay": "2025-01-14",
    "week": 7,
    "weekName": "星期日",
    "nextWeek": "2025-01-19",
    "month": 1,
    "monthName": "一月",
    "year": 2025,
    "monthStart": "2025-01-01",
    "monthEnd": "2025-01-31"
  }
}

过期信息更准确

  • 即将过期判断:基于30天内过期的逻辑
  • 过期状态:-1(已过期) / 1(未过期)
  • 剩余天数:正数表示剩余天数,负数表示已过期天数

优势总结

1. 代码质量

  • 可读性:方法职责单一,逻辑清晰
  • 可维护性:模块化设计,易于修改和扩展
  • 可测试性:每个方法都可以独立测试

2. 性能提升

  • 缓存机制:有效减少数据库查询
  • 异常处理:避免因异常导致的性能问题
  • 精确查询:减少不必要的数据传输

3. 功能增强

  • 更丰富的时间信息:提供更多有用的时间数据
  • 更准确的过期计算:基于 LocalDateTime 的精确计算
  • 更好的错误处理:完善的异常处理和日志记录

4. LocalDateTime 适配

  • 完全兼容:与新的时间格式完美配合
  • 类型安全:避免了类型转换的问题
  • 性能优化:使用现代 Java 时间 API

🚀 使用建议

  1. 测试验证:重启应用后测试接口功能
  2. 监控日志:观察缓存命中率和错误日志
  3. 性能监控:对比重构前后的响应时间
  4. 功能验证:确认过期时间计算的准确性

这次重新设计不仅解决了 LocalDateTime 兼容性问题,还显著提升了代码质量和系统性能。