diff --git a/continew-admin-common/pom.xml b/continew-admin-common/pom.xml index 1790fca4..99b4d196 100644 --- a/continew-admin-common/pom.xml +++ b/continew-admin-common/pom.xml @@ -81,10 +81,10 @@ continew-starter-data-mybatis-plus - + top.charles7c.continew - continew-starter-cache-springcache + continew-starter-cache-jetcache diff --git a/continew-admin-common/src/main/java/top/charles7c/continew/admin/common/constant/CacheConstants.java b/continew-admin-common/src/main/java/top/charles7c/continew/admin/common/constant/CacheConstants.java index 77ed9bef..a6c1e58b 100644 --- a/continew-admin-common/src/main/java/top/charles7c/continew/admin/common/constant/CacheConstants.java +++ b/continew-admin-common/src/main/java/top/charles7c/continew/admin/common/constant/CacheConstants.java @@ -18,6 +18,7 @@ package top.charles7c.continew.admin.common.constant; import lombok.AccessLevel; import lombok.NoArgsConstructor; +import top.charles7c.continew.starter.core.constant.StringConstants; /** * 缓存相关常量 @@ -28,6 +29,11 @@ import lombok.NoArgsConstructor; @NoArgsConstructor(access = AccessLevel.PRIVATE) public class CacheConstants { + /** + * 分隔符 + */ + public static final String DELIMITER = StringConstants.COLON; + /** * 登录用户键 */ @@ -36,35 +42,35 @@ public class CacheConstants { /** * 验证码键前缀 */ - public static final String CAPTCHA_KEY_PREFIX = "CAPTCHA"; + public static final String CAPTCHA_KEY_PREFIX = "CAPTCHA" + DELIMITER; /** * 限流键前缀 */ - public static final String LIMIT_KEY_PREFIX = "LIMIT"; + public static final String LIMIT_KEY_PREFIX = "LIMIT" + DELIMITER; /** * 用户缓存键前缀 */ - public static final String USER_KEY_PREFIX = "USER"; + public static final String USER_KEY_PREFIX = "USER" + DELIMITER; /** * 菜单缓存键前缀 */ - public static final String MENU_KEY_PREFIX = "MENU"; + public static final String MENU_KEY_PREFIX = "MENU" + DELIMITER; /** * 字典缓存键前缀 */ - public static final String DICT_KEY_PREFIX = "DICT"; + public static final String DICT_KEY_PREFIX = "DICT" + DELIMITER; /** * 参数缓存键前缀 */ - public static final String OPTION_KEY_PREFIX = "OPTION"; + public static final String OPTION_KEY_PREFIX = "OPTION" + DELIMITER; /** * 仪表盘缓存键前缀 */ - public static final String DASHBOARD_KEY_PREFIX = "DASHBOARD"; + public static final String DASHBOARD_KEY_PREFIX = "DASHBOARD" + DELIMITER; } diff --git a/continew-admin-monitor/src/main/java/top/charles7c/continew/admin/monitor/service/impl/DashboardServiceImpl.java b/continew-admin-monitor/src/main/java/top/charles7c/continew/admin/monitor/service/impl/DashboardServiceImpl.java index 55c1edee..d47b287d 100644 --- a/continew-admin-monitor/src/main/java/top/charles7c/continew/admin/monitor/service/impl/DashboardServiceImpl.java +++ b/continew-admin-monitor/src/main/java/top/charles7c/continew/admin/monitor/service/impl/DashboardServiceImpl.java @@ -16,19 +16,14 @@ package top.charles7c.continew.admin.monitor.service.impl; -import java.math.BigDecimal; -import java.util.List; -import java.util.Map; - -import lombok.RequiredArgsConstructor; - -import org.springframework.cache.annotation.CacheConfig; -import org.springframework.cache.annotation.Cacheable; -import org.springframework.stereotype.Service; - import cn.hutool.core.convert.Convert; import cn.hutool.core.util.NumberUtil; - +import com.alicp.jetcache.anno.CachePenetrationProtect; +import com.alicp.jetcache.anno.CacheRefresh; +import com.alicp.jetcache.anno.CacheType; +import com.alicp.jetcache.anno.Cached; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; import top.charles7c.continew.admin.common.constant.CacheConstants; import top.charles7c.continew.admin.monitor.model.resp.DashboardAccessTrendResp; import top.charles7c.continew.admin.monitor.model.resp.DashboardGeoDistributionResp; @@ -39,6 +34,10 @@ import top.charles7c.continew.admin.monitor.service.LogService; import top.charles7c.continew.admin.system.model.resp.DashboardAnnouncementResp; import top.charles7c.continew.admin.system.service.AnnouncementService; +import java.math.BigDecimal; +import java.util.List; +import java.util.Map; + /** * 仪表盘业务实现 * @@ -47,7 +46,6 @@ import top.charles7c.continew.admin.system.service.AnnouncementService; */ @Service @RequiredArgsConstructor -@CacheConfig(cacheNames = CacheConstants.DASHBOARD_KEY_PREFIX) public class DashboardServiceImpl implements DashboardService { private final LogService logService; @@ -67,7 +65,9 @@ public class DashboardServiceImpl implements DashboardService { } @Override - @Cacheable(key = "#days") + @CachePenetrationProtect + @CacheRefresh(refresh = 7200) + @Cached(key = "#days", cacheType = CacheType.BOTH, name = CacheConstants.DASHBOARD_KEY_PREFIX) public List listAccessTrend(Integer days) { return logService.listDashboardAccessTrend(days); } diff --git a/continew-admin-system/src/main/java/top/charles7c/continew/admin/system/service/impl/DictItemServiceImpl.java b/continew-admin-system/src/main/java/top/charles7c/continew/admin/system/service/impl/DictItemServiceImpl.java index 821ddea4..2ebb2d5b 100644 --- a/continew-admin-system/src/main/java/top/charles7c/continew/admin/system/service/impl/DictItemServiceImpl.java +++ b/continew-admin-system/src/main/java/top/charles7c/continew/admin/system/service/impl/DictItemServiceImpl.java @@ -17,10 +17,7 @@ package top.charles7c.continew.admin.system.service.impl; import lombok.RequiredArgsConstructor; -import org.springframework.cache.annotation.CacheConfig; -import org.springframework.cache.annotation.CacheEvict; import org.springframework.stereotype.Service; -import top.charles7c.continew.admin.common.constant.CacheConstants; import top.charles7c.continew.admin.common.model.resp.LabelValueResp; import top.charles7c.continew.admin.system.mapper.DictItemMapper; import top.charles7c.continew.admin.system.model.entity.DictItemDO; @@ -43,11 +40,9 @@ import java.util.List; */ @Service @RequiredArgsConstructor -@CacheConfig(cacheNames = CacheConstants.DICT_KEY_PREFIX) public class DictItemServiceImpl extends BaseServiceImpl implements DictItemService { @Override - @CacheEvict(allEntries = true) public Long add(DictItemReq req) { String value = req.getValue(); CheckUtils.throwIf(this.isValueExists(value, null, req.getDictId()), "新增失败,字典值 [{}] 已存在", value); @@ -55,7 +50,7 @@ public class DictItemServiceImpl extends BaseServiceImpl dictIds) { baseMapper.lambdaUpdate().in(DictItemDO::getDictId, dictIds).remove(); } diff --git a/continew-admin-system/src/main/java/top/charles7c/continew/admin/system/service/impl/MenuServiceImpl.java b/continew-admin-system/src/main/java/top/charles7c/continew/admin/system/service/impl/MenuServiceImpl.java index 9359a906..9f37fb37 100644 --- a/continew-admin-system/src/main/java/top/charles7c/continew/admin/system/service/impl/MenuServiceImpl.java +++ b/continew-admin-system/src/main/java/top/charles7c/continew/admin/system/service/impl/MenuServiceImpl.java @@ -16,18 +16,12 @@ package top.charles7c.continew.admin.system.service.impl; -import java.util.*; - +import cn.hutool.core.bean.BeanUtil; +import com.alicp.jetcache.anno.CacheInvalidate; +import com.alicp.jetcache.anno.Cached; import lombok.RequiredArgsConstructor; - -import org.springframework.cache.annotation.CacheConfig; -import org.springframework.cache.annotation.CacheEvict; -import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; - -import cn.hutool.core.bean.BeanUtil; - import top.charles7c.continew.admin.common.constant.CacheConstants; import top.charles7c.continew.admin.common.enums.DisEnableStatusEnum; import top.charles7c.continew.admin.system.mapper.MenuMapper; @@ -39,6 +33,9 @@ import top.charles7c.continew.admin.system.service.MenuService; import top.charles7c.continew.starter.core.util.validate.CheckUtils; import top.charles7c.continew.starter.extension.crud.base.BaseServiceImpl; +import java.util.List; +import java.util.Set; + /** * 菜单业务实现 * @@ -47,11 +44,10 @@ import top.charles7c.continew.starter.extension.crud.base.BaseServiceImpl; */ @Service @RequiredArgsConstructor -@CacheConfig(cacheNames = CacheConstants.MENU_KEY_PREFIX) public class MenuServiceImpl extends BaseServiceImpl implements MenuService { @Override - @CacheEvict(allEntries = true) + @CacheInvalidate(key = "'ALL'", name = CacheConstants.MENU_KEY_PREFIX) public Long add(MenuReq req) { String title = req.getTitle(); CheckUtils.throwIf(this.isNameExists(title, req.getParentId(), null), "新增失败,[{}] 已存在", title); @@ -60,7 +56,7 @@ public class MenuServiceImpl extends BaseServiceImpl ids) { baseMapper.lambdaUpdate().in(MenuDO::getParentId, ids).remove(); @@ -81,7 +77,7 @@ public class MenuServiceImpl extends BaseServiceImpl listByRoleCode(String roleCode) { List menuList = baseMapper.selectListByRoleCode(roleCode); List list = BeanUtil.copyToList(menuList, MenuResp.class); @@ -90,7 +86,7 @@ public class MenuServiceImpl extends BaseServiceImpl list() { MenuQuery menuQuery = new MenuQuery(); menuQuery.setStatus(DisEnableStatusEnum.ENABLE.getValue()); diff --git a/continew-admin-system/src/main/java/top/charles7c/continew/admin/system/service/impl/OptionServiceImpl.java b/continew-admin-system/src/main/java/top/charles7c/continew/admin/system/service/impl/OptionServiceImpl.java index 4abc27ce..bb9902bc 100644 --- a/continew-admin-system/src/main/java/top/charles7c/continew/admin/system/service/impl/OptionServiceImpl.java +++ b/continew-admin-system/src/main/java/top/charles7c/continew/admin/system/service/impl/OptionServiceImpl.java @@ -16,16 +16,10 @@ package top.charles7c.continew.admin.system.service.impl; -import java.util.List; - -import lombok.RequiredArgsConstructor; - -import org.springframework.cache.annotation.CacheConfig; -import org.springframework.cache.annotation.CacheEvict; -import org.springframework.stereotype.Service; - import cn.hutool.core.bean.BeanUtil; - +import com.alicp.jetcache.anno.CacheInvalidate; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; import top.charles7c.continew.admin.common.constant.CacheConstants; import top.charles7c.continew.admin.system.mapper.OptionMapper; import top.charles7c.continew.admin.system.model.entity.OptionDO; @@ -36,6 +30,8 @@ import top.charles7c.continew.admin.system.model.resp.OptionResp; import top.charles7c.continew.admin.system.service.OptionService; import top.charles7c.continew.starter.data.mybatis.plus.query.QueryHelper; +import java.util.List; + /** * 参数业务实现 * @@ -44,7 +40,6 @@ import top.charles7c.continew.starter.data.mybatis.plus.query.QueryHelper; */ @Service @RequiredArgsConstructor -@CacheConfig(cacheNames = CacheConstants.OPTION_KEY_PREFIX) public class OptionServiceImpl implements OptionService { private final OptionMapper baseMapper; @@ -55,13 +50,13 @@ public class OptionServiceImpl implements OptionService { } @Override - @CacheEvict(allEntries = true) + // @CacheInvalidate(key = "#req.code", name = CacheConstants.OPTION_KEY_PREFIX, multi = true) public void update(List req) { baseMapper.updateBatchById(BeanUtil.copyToList(req, OptionDO.class)); } @Override - @CacheEvict(allEntries = true) + @CacheInvalidate(key = "#req.code", name = CacheConstants.OPTION_KEY_PREFIX, multi = true) public void resetValue(OptionResetValueReq req) { baseMapper.lambdaUpdate().set(OptionDO::getValue, null).in(OptionDO::getCode, req.getCode()).update(); } diff --git a/continew-admin-system/src/main/java/top/charles7c/continew/admin/system/service/impl/RoleServiceImpl.java b/continew-admin-system/src/main/java/top/charles7c/continew/admin/system/service/impl/RoleServiceImpl.java index 4f4f5e04..6b9308c5 100644 --- a/continew-admin-system/src/main/java/top/charles7c/continew/admin/system/service/impl/RoleServiceImpl.java +++ b/continew-admin-system/src/main/java/top/charles7c/continew/admin/system/service/impl/RoleServiceImpl.java @@ -19,8 +19,8 @@ package top.charles7c.continew.admin.system.service.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; +import com.alicp.jetcache.anno.CacheInvalidate; import lombok.RequiredArgsConstructor; -import org.springframework.cache.annotation.CacheEvict; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import top.charles7c.continew.admin.auth.service.OnlineUserService; @@ -78,7 +78,7 @@ public class RoleServiceImpl extends BaseServiceImpl implements UserService, CommonUserService { @Resource @@ -264,7 +263,7 @@ public class UserServiceImpl extends BaseServiceImpl accountLogin(@Validated @RequestBody AccountLoginReq loginReq) { - String captchaKey = RedisUtils.formatKey(CacheConstants.CAPTCHA_KEY_PREFIX, loginReq.getUuid()); + String captchaKey = CacheConstants.CAPTCHA_KEY_PREFIX + loginReq.getUuid(); String captcha = RedisUtils.get(captchaKey); ValidationUtils.throwIfBlank(captcha, "验证码已失效"); RedisUtils.delete(captchaKey); @@ -84,7 +84,7 @@ public class AuthController { @PostMapping("/email") public R emailLogin(@Validated @RequestBody EmailLoginReq loginReq) { String email = loginReq.getEmail(); - String captchaKey = RedisUtils.formatKey(CacheConstants.CAPTCHA_KEY_PREFIX, email); + String captchaKey = CacheConstants.CAPTCHA_KEY_PREFIX + email; String captcha = RedisUtils.get(captchaKey); ValidationUtils.throwIfBlank(captcha, "验证码已失效"); ValidationUtils.throwIfNotEqualIgnoreCase(loginReq.getCaptcha(), captcha, "验证码错误"); @@ -98,7 +98,7 @@ public class AuthController { @PostMapping("/phone") public R phoneLogin(@Validated @RequestBody PhoneLoginReq loginReq) { String phone = loginReq.getPhone(); - String captchaKey = RedisUtils.formatKey(CacheConstants.CAPTCHA_KEY_PREFIX, phone); + String captchaKey = CacheConstants.CAPTCHA_KEY_PREFIX + phone; String captcha = RedisUtils.get(captchaKey); ValidationUtils.throwIfBlank(captcha, "验证码已失效"); ValidationUtils.throwIfNotEqualIgnoreCase(loginReq.getCaptcha(), captcha, "验证码错误"); diff --git a/continew-admin-webapi/src/main/java/top/charles7c/continew/admin/webapi/common/CaptchaController.java b/continew-admin-webapi/src/main/java/top/charles7c/continew/admin/webapi/common/CaptchaController.java index 6d1fea37..843e1cdd 100644 --- a/continew-admin-webapi/src/main/java/top/charles7c/continew/admin/webapi/common/CaptchaController.java +++ b/continew-admin-webapi/src/main/java/top/charles7c/continew/admin/webapi/common/CaptchaController.java @@ -16,20 +16,24 @@ package top.charles7c.continew.admin.webapi.common; -import java.time.Duration; -import java.util.LinkedHashMap; -import java.util.Map; - +import cn.dev33.satoken.annotation.SaIgnore; +import cn.hutool.core.lang.Dict; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.RandomUtil; +import cn.hutool.extra.servlet.JakartaServletUtil; +import com.anji.captcha.model.common.RepCodeEnum; +import com.anji.captcha.model.common.ResponseModel; +import com.anji.captcha.model.vo.CaptchaVO; +import com.anji.captcha.service.CaptchaService; +import com.wf.captcha.base.Captcha; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.mail.MessagingException; import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.Pattern; - import lombok.RequiredArgsConstructor; - -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; - import org.dromara.sms4j.api.SmsBlend; import org.dromara.sms4j.api.entity.SmsResponse; import org.dromara.sms4j.comm.constant.SupplierConstant; @@ -38,20 +42,6 @@ import org.redisson.api.RateType; import org.springframework.http.HttpHeaders; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; - -import com.anji.captcha.model.common.RepCodeEnum; -import com.anji.captcha.model.common.ResponseModel; -import com.anji.captcha.model.vo.CaptchaVO; -import com.anji.captcha.service.CaptchaService; -import com.wf.captcha.base.Captcha; - -import cn.dev33.satoken.annotation.SaIgnore; -import cn.hutool.core.lang.Dict; -import cn.hutool.core.map.MapUtil; -import cn.hutool.core.util.IdUtil; -import cn.hutool.core.util.RandomUtil; -import cn.hutool.extra.servlet.JakartaServletUtil; - import top.charles7c.continew.admin.common.config.properties.CaptchaProperties; import top.charles7c.continew.admin.common.constant.CacheConstants; import top.charles7c.continew.admin.common.constant.RegexConstants; @@ -66,6 +56,10 @@ import top.charles7c.continew.starter.extension.crud.model.resp.R; import top.charles7c.continew.starter.log.common.annotation.Log; import top.charles7c.continew.starter.messaging.mail.util.MailUtils; +import java.time.Duration; +import java.util.LinkedHashMap; +import java.util.Map; + /** * 验证码 API * @@ -106,7 +100,7 @@ public class CaptchaController { public R getImageCaptcha() { Captcha captcha = graphicCaptchaProperties.getCaptcha(); String uuid = IdUtil.fastUUID(); - String captchaKey = RedisUtils.formatKey(CacheConstants.CAPTCHA_KEY_PREFIX, uuid); + String captchaKey = CacheConstants.CAPTCHA_KEY_PREFIX + uuid; RedisUtils.set(captchaKey, captcha.text(), Duration.ofMinutes(captchaProperties.getExpirationInMinutes())); return R.ok(CaptchaResp.builder().uuid(uuid).img(captcha.toBase64()).build()); } @@ -116,7 +110,7 @@ public class CaptchaController { public R getMailCaptcha(@NotBlank(message = "邮箱不能为空") @Pattern(regexp = RegexConstants.EMAIL, message = "邮箱格式错误") String email) throws MessagingException { String limitKeyPrefix = CacheConstants.LIMIT_KEY_PREFIX; String captchaKeyPrefix = CacheConstants.CAPTCHA_KEY_PREFIX; - String limitCaptchaKey = RedisUtils.formatKey(limitKeyPrefix, captchaKeyPrefix, email); + String limitCaptchaKey = limitKeyPrefix + captchaKeyPrefix + email; long limitTimeInMillisecond = RedisUtils.getTimeToLive(limitCaptchaKey); CheckUtils.throwIf(limitTimeInMillisecond > 0, "发送验证码过于频繁,请您 {}s 后再试", limitTimeInMillisecond / 1000); // 生成验证码 @@ -129,7 +123,7 @@ public class CaptchaController { .set("expiration", expirationInMinutes)); MailUtils.sendHtml(email, String.format("【%s】邮箱验证码", projectProperties.getName()), content); // 保存验证码 - String captchaKey = RedisUtils.formatKey(captchaKeyPrefix, email); + String captchaKey = captchaKeyPrefix + email; RedisUtils.set(captchaKey, captcha, Duration.ofMinutes(expirationInMinutes)); RedisUtils.set(limitCaptchaKey, captcha, Duration.ofSeconds(captchaMail.getLimitInSeconds())); return R.ok(String.format("发送成功,验证码有效期 %s 分钟", expirationInMinutes)); @@ -148,21 +142,21 @@ public class CaptchaController { String templateId = captchaSms.getTemplateId(); String limitKeyPrefix = CacheConstants.LIMIT_KEY_PREFIX; String captchaKeyPrefix = CacheConstants.CAPTCHA_KEY_PREFIX; - String limitTemplateKeyPrefix = RedisUtils.formatKey(limitKeyPrefix, captchaKeyPrefix); + String limitTemplateKeyPrefix = limitKeyPrefix + captchaKeyPrefix; // 限制短信发送频率 // 1.同一号码同一短信模板,1分钟2条,1小时8条,24小时20条,e.g. LIMIT:CAPTCHA:XXX:188xxxxx:1 CheckUtils.throwIf(!RedisUtils.rateLimit(RedisUtils - .formatKey(limitTemplateKeyPrefix, "MIN", phone, templateId), RateType.OVERALL, 2, 60), "验证码发送过于频繁,请稍后后再试"); + .formatKey(limitTemplateKeyPrefix + "MIN", phone, templateId), RateType.OVERALL, 2, 60), "验证码发送过于频繁,请稍后后再试"); CheckUtils.throwIf(!RedisUtils.rateLimit(RedisUtils - .formatKey(limitTemplateKeyPrefix, "HOUR", phone, templateId), RateType.OVERALL, 8, 60 * 60), "验证码发送过于频繁,请稍后后再试"); + .formatKey(limitTemplateKeyPrefix + "HOUR", phone, templateId), RateType.OVERALL, 8, 60 * 60), "验证码发送过于频繁,请稍后后再试"); CheckUtils.throwIf(!RedisUtils.rateLimit(RedisUtils - .formatKey(limitTemplateKeyPrefix, "DAY", phone, templateId), RateType.OVERALL, 20, 60 * 60 * 24), "验证码发送过于频繁,请稍后后再试"); + .formatKey(limitTemplateKeyPrefix + "DAY", phone, templateId), RateType.OVERALL, 20, 60 * 60 * 24), "验证码发送过于频繁,请稍后后再试"); // 2.同一号码所有短信模板 24 小时 100 条,e.g. LIMIT:CAPTCHA:188xxxxx - String limitPhoneKey = RedisUtils.formatKey(limitKeyPrefix, captchaKeyPrefix, phone); + String limitPhoneKey = limitKeyPrefix + captchaKeyPrefix + phone; CheckUtils.throwIf(!RedisUtils .rateLimit(limitPhoneKey, RateType.OVERALL, 100, 60 * 60 * 24), "验证码发送过于频繁,请稍后后再试"); // 3.同一 IP 每分钟限制发送 30 条,e.g. LIMIT:CAPTCHA:PHONE:1xx.1xx.1xx.1xx - String limitIpKey = RedisUtils.formatKey(limitKeyPrefix, captchaKeyPrefix, "PHONE", JakartaServletUtil + String limitIpKey = RedisUtils.formatKey(limitKeyPrefix + captchaKeyPrefix + "PHONE", JakartaServletUtil .getClientIP(request)); CheckUtils.throwIf(!RedisUtils.rateLimit(limitIpKey, RateType.OVERALL, 30, 60), "验证码发送过于频繁,请稍后后再试"); // 生成验证码 @@ -177,7 +171,7 @@ public class CaptchaController { .getTemplateId(), (LinkedHashMap)messageMap); CheckUtils.throwIf(!smsResponse.isSuccess(), "验证码发送失败"); // 保存验证码 - String captchaKey = RedisUtils.formatKey(captchaKeyPrefix, phone); + String captchaKey = captchaKeyPrefix + phone; RedisUtils.set(captchaKey, captcha, Duration.ofMinutes(expirationInMinutes)); return R.ok(String.format("发送成功,验证码有效期 %s 分钟", expirationInMinutes)); } diff --git a/continew-admin-webapi/src/main/java/top/charles7c/continew/admin/webapi/common/CommonController.java b/continew-admin-webapi/src/main/java/top/charles7c/continew/admin/webapi/common/CommonController.java index 99bf7acb..ad7e9074 100644 --- a/continew-admin-webapi/src/main/java/top/charles7c/continew/admin/webapi/common/CommonController.java +++ b/continew-admin-webapi/src/main/java/top/charles7c/continew/admin/webapi/common/CommonController.java @@ -20,6 +20,7 @@ import cn.dev33.satoken.annotation.SaIgnore; import cn.hutool.core.lang.tree.Tree; import cn.hutool.core.util.ClassUtil; import cn.hutool.core.util.StrUtil; +import com.alicp.jetcache.anno.Cached; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.enums.ParameterIn; @@ -27,7 +28,6 @@ import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; import org.dromara.x.file.storage.core.FileInfo; -import org.springframework.cache.annotation.Cacheable; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; @@ -103,7 +103,7 @@ public class CommonController { @Operation(summary = "查询字典", description = "查询字典列表") @Parameter(name = "code", description = "字典编码", example = "announcement_type", in = ParameterIn.PATH) @GetMapping("/dict/{code}") - @Cacheable(key = "#code", cacheNames = CacheConstants.DICT_KEY_PREFIX) + @Cached(key = "#code", name = CacheConstants.DICT_KEY_PREFIX) public R> listDict(@PathVariable String code) { Optional> enumClass = this.getEnumClassByName(code); return R.ok(enumClass.map(this::listEnumDict).orElseGet(() -> dictItemService.listByDictCode(code))); @@ -112,7 +112,7 @@ public class CommonController { @SaIgnore @Operation(summary = "查询参数", description = "查询参数") @GetMapping("/option") - @Cacheable(cacheNames = CacheConstants.OPTION_KEY_PREFIX) + @Cached(name = CacheConstants.OPTION_KEY_PREFIX) public R> listOption(@Validated OptionQuery query) { return R.ok(optionService.list(query) .stream() diff --git a/continew-admin-webapi/src/main/java/top/charles7c/continew/admin/webapi/system/UserCenterController.java b/continew-admin-webapi/src/main/java/top/charles7c/continew/admin/webapi/system/UserCenterController.java index 7ba5b148..ca6bf221 100644 --- a/continew-admin-webapi/src/main/java/top/charles7c/continew/admin/webapi/system/UserCenterController.java +++ b/continew-admin-webapi/src/main/java/top/charles7c/continew/admin/webapi/system/UserCenterController.java @@ -113,7 +113,7 @@ public class UserCenterController { String rawCurrentPassword = ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(updateReq .getCurrentPassword())); ValidationUtils.throwIfBlank(rawCurrentPassword, "当前密码解密失败"); - String captchaKey = RedisUtils.formatKey(CacheConstants.CAPTCHA_KEY_PREFIX, updateReq.getNewPhone()); + String captchaKey = CacheConstants.CAPTCHA_KEY_PREFIX + updateReq.getNewPhone(); String captcha = RedisUtils.get(captchaKey); ValidationUtils.throwIfBlank(captcha, "验证码已失效"); ValidationUtils.throwIfNotEqualIgnoreCase(updateReq.getCaptcha(), captcha, "验证码错误"); @@ -128,7 +128,7 @@ public class UserCenterController { String rawCurrentPassword = ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(updateReq .getCurrentPassword())); ValidationUtils.throwIfBlank(rawCurrentPassword, "当前密码解密失败"); - String captchaKey = RedisUtils.formatKey(CacheConstants.CAPTCHA_KEY_PREFIX, updateReq.getNewEmail()); + String captchaKey = CacheConstants.CAPTCHA_KEY_PREFIX + updateReq.getNewEmail(); String captcha = RedisUtils.get(captchaKey); ValidationUtils.throwIfBlank(captcha, "验证码已失效"); ValidationUtils.throwIfNotEqualIgnoreCase(updateReq.getCaptcha(), captcha, "验证码错误"); diff --git a/continew-admin-webapi/src/main/resources/config/application-dev.yml b/continew-admin-webapi/src/main/resources/config/application-dev.yml index d377d860..b87543c3 100644 --- a/continew-admin-webapi/src/main/resources/config/application-dev.yml +++ b/continew-admin-webapi/src/main/resources/config/application-dev.yml @@ -56,30 +56,54 @@ spring.liquibase: change-log: classpath:/db/changelog/db.changelog-master.yaml --- ### 缓存配置 -spring: - ## Spring Cache 配置 - cache: - type: REDIS - data: - ## Redis 配置(单机版) - redis: - # 地址 - host: ${REDIS_HOST:127.0.0.1} - # 端口(默认 6379) - port: ${REDIS_PORT:6379} - # 密码(未设置密码时可为空或注释掉) - password: ${REDIS_PWD:123456} - # 数据库索引 - database: ${REDIS_DB:0} - # 连接超时时间 - timeout: 10s - # 是否开启 SSL - ssl: - enabled: false - # Redisson 配置 - redisson: - enabled: true - mode: SINGLE +spring.data: + ## Redis 配置(单机模式) + redis: + # 地址 + host: ${REDIS_HOST:127.0.0.1} + # 端口(默认 6379) + port: ${REDIS_PORT:6379} + # 密码(未设置密码时可为空或注释掉) + password: ${REDIS_PWD:123456} + # 数据库索引 + database: ${REDIS_DB:0} + # 连接超时时间 + timeout: 10s + # 是否开启 SSL + ssl: + enabled: false + ## Redisson 配置 + redisson: + enabled: true + mode: SINGLE +## JetCache 配置 +jetcache: + ## 本地/进程级/一级缓存配置 + local: + default: + # 缓存类型 + type: caffeine + # key 转换器的全局配置 + keyConvertor: jackson + # 以毫秒为单位指定超时时间的全局配置 + expireAfterWriteInMillis: 7200000 + # 每个缓存实例的最大元素的全局配置,仅 local 类型的缓存需要指定 + limit: 1000 + ## 远程/分布式/二级缓存配置 + remote: + default: + # 缓存类型 + type: redisson + # key 转换器的全局配置(用于将复杂的 KEY 类型转换为缓存实现可以接受的类型) + keyConvertor: jackson + # 以毫秒为单位指定超时时间的全局配置 + expireAfterWriteInMillis: 7200000 + # 2.7+ 支持两级缓存更新以后失效其他 JVM 中的 local cache,但多个服务共用 Redis 同一个 channel 可能会造成广播风暴,需要在这里指定channel。 + # 你可以决定多个不同的服务是否共用同一个 channel,如果没有指定则不开启。 + broadcastChannel: ${spring.application.name} + # 序列化器的全局配置,仅 remote 类型的缓存需要指定 + valueEncoder: java + valueDecoder: java --- ### 验证码配置 continew-starter.captcha: diff --git a/continew-admin-webapi/src/main/resources/config/application-prod.yml b/continew-admin-webapi/src/main/resources/config/application-prod.yml index 0396bb3d..d9fc8e5d 100644 --- a/continew-admin-webapi/src/main/resources/config/application-prod.yml +++ b/continew-admin-webapi/src/main/resources/config/application-prod.yml @@ -58,30 +58,54 @@ spring.liquibase: change-log: classpath:/db/changelog/db.changelog-master.yaml --- ### 缓存配置 -spring: - ## Spring Cache 配置 - cache: - type: REDIS - data: - ## Redis 配置(单机版) - redis: - # 地址 - host: ${REDIS_HOST:127.0.0.1} - # 端口(默认 6379) - port: ${REDIS_PORT:6379} - # 密码(未设置密码时可为空或注释掉) - password: ${REDIS_PWD:123456} - # 数据库索引 - database: ${REDIS_DB:0} - # 连接超时时间 - timeout: 10s - # 是否开启 SSL - ssl: - enabled: false - # Redisson 配置 - redisson: - enabled: true - mode: SINGLE +spring.data: + ## Redis 配置(单机模式) + redis: + # 地址 + host: ${REDIS_HOST:127.0.0.1} + # 端口(默认 6379) + port: ${REDIS_PORT:6379} + # 密码(未设置密码时可为空或注释掉) + password: ${REDIS_PWD:123456} + # 数据库索引 + database: ${REDIS_DB:0} + # 连接超时时间 + timeout: 10s + # 是否开启 SSL + ssl: + enabled: false + ## Redisson 配置 + redisson: + enabled: true + mode: SINGLE +## JetCache 配置 +jetcache: + ## 本地/进程级/一级缓存配置 + local: + default: + # 缓存类型 + type: caffeine + # key 转换器的全局配置 + keyConvertor: jackson + # 以毫秒为单位指定超时时间的全局配置 + expireAfterWriteInMillis: 7200000 + # 每个缓存实例的最大元素的全局配置,仅 local 类型的缓存需要指定 + limit: 1000 + ## 远程/分布式/二级缓存配置 + remote: + default: + # 缓存类型 + type: redisson + # key 转换器的全局配置(用于将复杂的 KEY 类型转换为缓存实现可以接受的类型) + keyConvertor: jackson + # 以毫秒为单位指定超时时间的全局配置 + expireAfterWriteInMillis: 7200000 + # 2.7+ 支持两级缓存更新以后失效其他 JVM 中的 local cache,但多个服务共用 Redis 同一个 channel 可能会造成广播风暴,需要在这里指定channel。 + # 你可以决定多个不同的服务是否共用同一个 channel,如果没有指定则不开启。 + broadcastChannel: ${spring.application.name} + # 序列化器的全局配置,仅 remote 类型的缓存需要指定 + valueEncoder: java + valueDecoder: java --- ### 验证码配置 continew-starter.captcha: