package front import ( "encoding/json" "errors" "fmt" "github.com/gin-gonic/gin" "github.com/go-redis/redis" "gorm.io/gorm" "sync" "worktest/pkg/controller" "worktest/pkg/model" "worktest/pkg/redistab" ) type ListReq struct { Title string `json:"'title'"` UserId uint `json:"'userId'"` } type DetailReq struct { ID uint UserId uint `json:"'userId'"` } var synMysqlToRedisLock sync.RWMutex func MysqlList(c *gin.Context) { var req ListReq if err := c.ShouldBind(&req); err != nil { controller.Error(c, err.Error()) return } var list []*model.Product model.DB.Model(&model.Product{}).Find(&list) fmt.Println("2--------", redistab.RedisClient) controller.Success(c, list) return } func RedisBuy(c *gin.Context) { var req DetailReq if err := c.ShouldBind(&req); err != nil { controller.Error(c, err.Error()) return } var list []*model.Product model.DB.Model(&model.Product{}).Find(&list) err := model.DB.Transaction(func(tx *gorm.DB) error { var obj *model.Product if err := model.DB.Model(&model.Product{}).First(&obj, req.ID).Error; err != nil { return err } if obj.StockSize <= 0 { return errors.New("库存不足") } //生成订单 productOrder := &model.ProductOrder{ ProductID: req.ID, UserId: req.UserId, } if err := model.DB.Model(&model.ProductOrder{}).Create(&productOrder).Error; err != nil { return err } //扣除库存 model.DB.Model(&model.Product{}).Where(&model.Product{ID: req.ID}).UpdateColumn("stock_size", gorm.Expr("stock_size - 1")) return nil }) if err != nil { controller.Error(c, err.Error()) return } fmt.Println("2--------", redistab.RedisClient) controller.Success(c, list) return } func MysqlBuy(c *gin.Context) { var req DetailReq if err := c.ShouldBind(&req); err != nil { controller.Error(c, err.Error()) return } var list []*model.Product model.DB.Model(&model.Product{}).Find(&list) err := model.DB.Transaction(func(tx *gorm.DB) error { var obj *model.Product if err := model.DB.Model(&model.Product{}).First(&obj, req.ID).Error; err != nil { return err } if obj.StockSize <= 0 { return errors.New("库存不足") } //生成订单 productOrder := &model.ProductOrder{ ProductID: req.ID, UserId: req.UserId, } if err := model.DB.Model(&model.ProductOrder{}).Create(&productOrder).Error; err != nil { return err } //扣除库存 model.DB.Model(&model.Product{}).Where(&model.Product{ID: req.ID}).UpdateColumn("stock_size", gorm.Expr("stock_size - 1")) return nil }) if err != nil { controller.Error(c, err.Error()) return } fmt.Println("2--------", redistab.RedisClient) controller.Success(c, list) return } func RedisList(c *gin.Context) { var req ListReq if err := c.ShouldBind(&req); err != nil { controller.Error(c, err.Error()) return } var list []*model.Product model.DB.Model(&model.Product{}).Find(&list) fmt.Println("2--------", redistab.RedisClient) controller.Success(c, list) //统计人获取的次数 return } func MysqlDetail(c *gin.Context) { var req DetailReq if err := c.ShouldBind(&req); err != nil { controller.Error(c, err.Error()) return } var productObj *model.Product if err := model.DB.Model(&model.Product{}).First(&productObj, req.ID).Error; err != nil { controller.Error(c, err.Error()) return } controller.Success(c, productObj) return } func RedisDetail(c *gin.Context) { var productObj *model.Product var req DetailReq if err := c.ShouldBind(&req); err != nil { controller.Error(c, err.Error()) return } v, err := redistab.RedisClient.Get(redistab.GetProductDetail(req.ID)).Result() //无缓存 则去mysql同步数据 if err != nil { var tempObj *model.Product if err := model.DB.Model(&model.Product{}).First(&tempObj, req.ID).Error; err != nil { controller.Error(c, err.Error()) return } b, err := json.Marshal(tempObj) if err != nil { controller.Error(c, err.Error()) return } v, err = redistab.RedisClient.Set(redistab.GetProductDetail(req.ID), string(b), 0).Result() fmt.Println("1---------", v, err) if err != nil { controller.Error(c, err.Error()) return } v, _ = redistab.RedisClient.Get(redistab.GetProductDetail(req.ID)).Result() } err = json.Unmarshal([]byte(v), &productObj) if err != nil { controller.Error(c, err.Error()) return } controller.Success(c, productObj) return } func RedisDetailLock(c *gin.Context) { var productObj *model.Product var req DetailReq if err := c.ShouldBind(&req); err != nil { controller.Error(c, err.Error()) return } v, err := redistab.RedisClient.Get(redistab.GetProductDetail(req.ID)).Result() //无缓存 则去mysql同步数据 if err != nil { synMysqlToRedisLock.Lock() defer synMysqlToRedisLock.Lock() var tempObj *model.Product if err := model.DB.Model(&model.Product{}).First(&tempObj, req.ID).Error; err != nil { controller.Error(c, err.Error()) return } b, err := json.Marshal(tempObj) if err != nil { controller.Error(c, err.Error()) return } v, err = redistab.RedisClient.Set(redistab.GetProductDetail(req.ID), string(b), 0).Result() fmt.Println("1---------", v, err) if err != nil { controller.Error(c, err.Error()) return } v, _ = redistab.RedisClient.Get(redistab.GetProductDetail(req.ID)).Result() } err = json.Unmarshal([]byte(v), &productObj) if err != nil { controller.Error(c, err.Error()) return } controller.Success(c, productObj) return } func RedisDetailBitMap(c *gin.Context) { var productObj *model.Product var req DetailReq if err := c.ShouldBind(&req); err != nil { controller.Error(c, err.Error()) return } v, err := redistab.RedisClient.Get(redistab.GetProductDetail(req.ID)).Result() //bitmap bit, err := redistab.RedisClient.GetBit(redistab.GetProductBitMap(), int64(req.ID)).Result() fmt.Println("2----------", bit, err) if bit == 0 { //不存在 controller.Error(c, "非法数据") return } //无缓存 则去mysql同步数据 if err != nil { synMysqlToRedisLock.Lock() defer synMysqlToRedisLock.Lock() var tempObj *model.Product if err := model.DB.Model(&model.Product{}).First(&tempObj, req.ID).Error; err != nil { controller.Error(c, err.Error()) return } b, err := json.Marshal(tempObj) if err != nil { controller.Error(c, err.Error()) return } v, err = redistab.RedisClient.Set(redistab.GetProductDetail(req.ID), string(b), 0).Result() fmt.Println("1---------", v, err) if err != nil { controller.Error(c, err.Error()) return } v, _ = redistab.RedisClient.Get(redistab.GetProductDetail(req.ID)).Result() } err = json.Unmarshal([]byte(v), &productObj) if err != nil { controller.Error(c, err.Error()) return } //增加统计,增加去重统计 该商品的DAU _, _ = redistab.RedisClient.PFAdd(redistab.GetProductDetailLogCount(req.ID)).Result() controller.Success(c, productObj) return } func RedisCountProduct(c *gin.Context) { var req DetailReq if err := c.ShouldBind(&req); err != nil { controller.Error(c, err.Error()) return } //增加统计,增加去重统计 该商品的DAU _ = &redis.BitCount{ Start: 1, End: 1, } b, _ := redistab.RedisClient.BitCount(redistab.GetProductBitMap(), nil).Result() controller.Success(c, b) return } func RedisDetailBitMapCount(c *gin.Context) { var productObj *model.Product var req DetailReq if err := c.ShouldBind(&req); err != nil { controller.Error(c, err.Error()) return } v, err := redistab.RedisClient.Get(redistab.GetProductDetail(req.ID)).Result() //bitmap bit, err := redistab.RedisClient.GetBit(redistab.GetProductBitMap(), int64(req.ID)).Result() fmt.Println("2----------", bit, err) if bit == 0 { //不存在 controller.Error(c, "非法数据") return } //无缓存 则去mysql同步数据 if err != nil { synMysqlToRedisLock.Lock() defer synMysqlToRedisLock.Lock() var tempObj *model.Product if err := model.DB.Model(&model.Product{}).First(&tempObj, req.ID).Error; err != nil { controller.Error(c, err.Error()) return } b, err := json.Marshal(tempObj) if err != nil { controller.Error(c, err.Error()) return } v, err = redistab.RedisClient.Set(redistab.GetProductDetail(req.ID), string(b), 0).Result() fmt.Println("1---------", v, err) if err != nil { controller.Error(c, err.Error()) return } v, _ = redistab.RedisClient.Get(redistab.GetProductDetail(req.ID)).Result() } err = json.Unmarshal([]byte(v), &productObj) if err != nil { controller.Error(c, err.Error()) return } //增加统计,增加去重统计 该商品的DAU _, _ = redistab.RedisClient.PFAdd(redistab.GetProductDetailLogCount(req.ID)).Result() controller.Success(c, productObj) return }