Files
smartmate/backend/middleware/cache_deleter.go
LoveLosita dad1eade93 Version: 0.3.2.dev.260214
feat:  新增获取当前正在进行的任务接口并完成测试

- 若当前为上课时间,返回当前任务 📚
- 若当前为下课/空闲时间,返回下一个任务 ➡️
- 若存在嵌入任务,支持嵌套返回结构 🧩
- 接口已测试通过 🧪

docs: 📝 小幅更新 README

fix: 🐛 修复获取最近已完成任务列表接口的遗漏问题

- 修复无法获取嵌入在课程中的任务问题 🔧

fix: 🐛 修复删除日程接口的字段遗漏问题

- 若删除的是单独任务块,补充删除 task_item 表的 embedded_time 字段
- 避免数据残留与状态异常 
2026-02-14 21:46:02 +08:00

105 lines
3.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package middleware
import (
"context"
"log"
"reflect"
"github.com/LoveLosita/smartflow/backend/dao"
"github.com/LoveLosita/smartflow/backend/model"
"gorm.io/gorm"
)
type GormCachePlugin struct {
cacheDAO *dao.CacheDAO
}
func NewGormCachePlugin(dao *dao.CacheDAO) *GormCachePlugin {
return &GormCachePlugin{
cacheDAO: dao,
}
}
// Name 插件名称
func (p *GormCachePlugin) Name() string {
return "GormCachePlugin"
}
// Initialize 注册 GORM 钩子
func (p *GormCachePlugin) Initialize(db *gorm.DB) error {
// 在增、删、改成功后,统一触发清理逻辑
_ = db.Callback().Create().After("gorm:create").Register("clear_related_cache_after_create", p.afterWrite)
_ = db.Callback().Update().After("gorm:update").Register("clear_related_cache_after_update", p.afterWrite)
_ = db.Callback().Delete().After("gorm:delete").Register("clear_related_cache_after_delete", p.afterWrite)
return nil
}
func (p *GormCachePlugin) afterWrite(db *gorm.DB) {
if db.Error != nil || db.Statement.Schema == nil {
return
}
// 获取 Model 的真实值(剥掉所有指针)
val := reflect.Indirect(reflect.ValueOf(db.Statement.Model))
// 如果是切片,拿切片里元素的类型
if val.Kind() == reflect.Slice {
if val.Len() > 0 {
p.dispatchCacheLogic(val.Index(0).Interface(), db)
}
} else {
p.dispatchCacheLogic(val.Interface(), db)
}
}
// 根据不同的 Model 类型,调用不同的缓存失效逻辑
func (p *GormCachePlugin) dispatchCacheLogic(modelObj interface{}, db *gorm.DB) {
switch m := modelObj.(type) {
case model.Schedule:
// 无论传的是 &s, s, 还是 &[]s剥开后都是 model.Schedule
p.invalidScheduleCache(m.UserID, m.Week)
case model.TaskClass:
p.invalidTaskClassCache(*m.UserID)
case model.Task:
p.invalidTaskCache(m.UserID)
default:
// 只有真正没定义的模型才会到这里
log.Printf("[GORM-Cache] No logic defined for model: %T", modelObj)
}
}
func (p *GormCachePlugin) invalidScheduleCache(userID int, week int) {
if userID == 0 || week == 0 {
return
}
// 3. 异步执行,不阻塞主业务事务
go func() {
// 这里调用你的 CacheDAO 删缓存
_ = p.cacheDAO.DeleteUserWeeklyScheduleFromCache(context.Background(), userID, week)
_ = p.cacheDAO.DeleteUserTodayScheduleFromCache(context.Background(), userID) // 同时删当天日程的缓存,确保数据一致
_ = p.cacheDAO.DeleteUserRecentCompletedSchedulesFromCache(context.Background(), userID) // 同时删最近完成日程的缓存,确保数据一致
_ = p.cacheDAO.DeleteUserOngoingScheduleFromCache(context.Background(), userID) // 同时删正在进行日程的缓存,确保数据一致
log.Printf("[GORM-Cache] Invalidated cache for user %d, week %d", userID, week)
}()
}
func (p *GormCachePlugin) invalidTaskClassCache(userID int) {
if userID == 0 {
return
}
go func() {
_ = p.cacheDAO.DeleteTaskClassList(context.Background(), userID)
log.Printf("[GORM-Cache] Invalidated task class list cache for user %d", userID)
}()
}
func (p *GormCachePlugin) invalidTaskCache(userID int) {
if userID == 0 {
return
}
go func() {
_ = p.cacheDAO.DeleteUserTasksFromCache(context.Background(), userID)
log.Printf("[GORM-Cache] Invalidated task list cache for user %d", userID)
}()
}