first commit

This commit is contained in:
2024-10-02 00:57:17 +08:00
commit 6773f86bc5
312 changed files with 19169 additions and 0 deletions

View File

@@ -0,0 +1,53 @@
package model
import (
"context"
"fmt"
"github.com/zeromicro/go-zero/core/stores/cache"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/zeromicro/go-zero/core/stringx"
"strings"
)
var _ ProductsModel = (*customProductsModel)(nil)
var productsRowsWithoutContent = strings.Join(stringx.Remove(productsFieldNames, "`ProductContent`"), ",")
type (
// ProductsModel is an interface to be customized, add more methods here,
// and implement the added methods in customProductsModel.
ProductsModel interface {
productsModel
FindProductsList(ctx context.Context, page, pageSize int64) ([]*Products, int64, error)
}
customProductsModel struct {
*defaultProductsModel
}
)
// NewProductsModel returns a model for the database table.
func NewProductsModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) ProductsModel {
return &customProductsModel{
defaultProductsModel: newProductsModel(conn, c, opts...),
}
}
func (m *defaultProductsModel) FindProductsList(ctx context.Context, page, pageSize int64) ([]*Products, int64, error) {
offset := (page - 1) * pageSize
var products []*Products
query := fmt.Sprintf("SELECT %s FROM %s ORDER BY created_at DESC LIMIT ?,?", productsRowsWithoutContent, m.table)
err := m.QueryRowsNoCacheCtx(ctx, &products, query, offset, pageSize)
if err != nil {
return nil, 0, err
}
// 查询总数量
var total int64
countQuery := fmt.Sprintf("SELECT COUNT(*) FROM %s", m.table)
err = m.QueryRowNoCacheCtx(ctx, &total, countQuery)
if err != nil {
return nil, 0, err
}
return products, total, nil
}

View File

@@ -0,0 +1,153 @@
// Code generated by goctl. DO NOT EDIT.
// versions:
// goctl version: 1.7.2
package model
import (
"context"
"database/sql"
"fmt"
"strings"
"time"
"github.com/zeromicro/go-zero/core/stores/builder"
"github.com/zeromicro/go-zero/core/stores/cache"
"github.com/zeromicro/go-zero/core/stores/sqlc"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/zeromicro/go-zero/core/stringx"
)
var (
productsFieldNames = builder.RawFieldNames(&Products{})
productsRows = strings.Join(productsFieldNames, ",")
productsRowsExpectAutoSet = strings.Join(stringx.Remove(productsFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
productsRowsWithPlaceHolder = strings.Join(stringx.Remove(productsFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?"
cacheProductsIdPrefix = "cache:products:id:"
cacheProductsProductCodePrefix = "cache:products:productCode:"
)
type (
productsModel interface {
Insert(ctx context.Context, data *Products) (sql.Result, error)
FindOne(ctx context.Context, id int64) (*Products, error)
FindOneByProductCode(ctx context.Context, productCode string) (*Products, error)
Update(ctx context.Context, data *Products) error
Delete(ctx context.Context, id int64) error
}
defaultProductsModel struct {
sqlc.CachedConn
table string
}
Products struct {
Id int64 `db:"id"` // 产品ID
ProductName string `db:"product_name"` // 产品名称
ProductCode string `db:"product_code"` // 产品编号
ProductDescription sql.NullString `db:"product_description"` // 产品简介
ProductContent sql.NullString `db:"product_content"` // 产品内容
ProductGroup string `db:"product_group"` // 产品分类
ProductPrice float64 `db:"product_price"` // 产品价格
CreatedAt time.Time `db:"created_at"` // 创建时间
UpdatedAt time.Time `db:"updated_at"` // 更新时间
}
)
func newProductsModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) *defaultProductsModel {
return &defaultProductsModel{
CachedConn: sqlc.NewConn(conn, c, opts...),
table: "`products`",
}
}
func (m *defaultProductsModel) Delete(ctx context.Context, id int64) error {
data, err := m.FindOne(ctx, id)
if err != nil {
return err
}
productsIdKey := fmt.Sprintf("%s%v", cacheProductsIdPrefix, id)
productsProductCodeKey := fmt.Sprintf("%s%v", cacheProductsProductCodePrefix, data.ProductCode)
_, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
query := fmt.Sprintf("delete from %s where `id` = ?", m.table)
return conn.ExecCtx(ctx, query, id)
}, productsIdKey, productsProductCodeKey)
return err
}
func (m *defaultProductsModel) FindOne(ctx context.Context, id int64) (*Products, error) {
productsIdKey := fmt.Sprintf("%s%v", cacheProductsIdPrefix, id)
var resp Products
err := m.QueryRowCtx(ctx, &resp, productsIdKey, func(ctx context.Context, conn sqlx.SqlConn, v any) error {
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", productsRows, m.table)
return conn.QueryRowCtx(ctx, v, query, id)
})
switch err {
case nil:
return &resp, nil
case sqlc.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultProductsModel) FindOneByProductCode(ctx context.Context, productCode string) (*Products, error) {
productsProductCodeKey := fmt.Sprintf("%s%v", cacheProductsProductCodePrefix, productCode)
var resp Products
err := m.QueryRowIndexCtx(ctx, &resp, productsProductCodeKey, m.formatPrimary, func(ctx context.Context, conn sqlx.SqlConn, v any) (i any, e error) {
query := fmt.Sprintf("select %s from %s where `product_code` = ? limit 1", productsRows, m.table)
if err := conn.QueryRowCtx(ctx, &resp, query, productCode); err != nil {
return nil, err
}
return resp.Id, nil
}, m.queryPrimary)
switch err {
case nil:
return &resp, nil
case sqlc.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultProductsModel) Insert(ctx context.Context, data *Products) (sql.Result, error) {
productsIdKey := fmt.Sprintf("%s%v", cacheProductsIdPrefix, data.Id)
productsProductCodeKey := fmt.Sprintf("%s%v", cacheProductsProductCodePrefix, data.ProductCode)
ret, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?)", m.table, productsRowsExpectAutoSet)
return conn.ExecCtx(ctx, query, data.ProductName, data.ProductCode, data.ProductDescription, data.ProductContent, data.ProductGroup, data.ProductPrice)
}, productsIdKey, productsProductCodeKey)
return ret, err
}
func (m *defaultProductsModel) Update(ctx context.Context, newData *Products) error {
data, err := m.FindOne(ctx, newData.Id)
if err != nil {
return err
}
productsIdKey := fmt.Sprintf("%s%v", cacheProductsIdPrefix, data.Id)
productsProductCodeKey := fmt.Sprintf("%s%v", cacheProductsProductCodePrefix, data.ProductCode)
_, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, productsRowsWithPlaceHolder)
return conn.ExecCtx(ctx, query, newData.ProductName, newData.ProductCode, newData.ProductDescription, newData.ProductContent, newData.ProductGroup, newData.ProductPrice, newData.Id)
}, productsIdKey, productsProductCodeKey)
return err
}
func (m *defaultProductsModel) formatPrimary(primary any) string {
return fmt.Sprintf("%s%v", cacheProductsIdPrefix, primary)
}
func (m *defaultProductsModel) queryPrimary(ctx context.Context, conn sqlx.SqlConn, v, primary any) error {
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", productsRows, m.table)
return conn.QueryRowCtx(ctx, v, query, primary)
}
func (m *defaultProductsModel) tableName() string {
return m.table
}

View File

@@ -0,0 +1,27 @@
package model
import (
"github.com/zeromicro/go-zero/core/stores/cache"
"github.com/zeromicro/go-zero/core/stores/sqlx"
)
var _ SecretsModel = (*customSecretsModel)(nil)
type (
// SecretsModel is an interface to be customized, add more methods here,
// and implement the added methods in customSecretsModel.
SecretsModel interface {
secretsModel
}
customSecretsModel struct {
*defaultSecretsModel
}
)
// NewSecretsModel returns a model for the database table.
func NewSecretsModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) SecretsModel {
return &customSecretsModel{
defaultSecretsModel: newSecretsModel(conn, c, opts...),
}
}

View File

@@ -0,0 +1,175 @@
// Code generated by goctl. DO NOT EDIT.
// versions:
// goctl version: 1.7.2
package model
import (
"context"
"database/sql"
"fmt"
"strings"
"time"
"github.com/zeromicro/go-zero/core/stores/builder"
"github.com/zeromicro/go-zero/core/stores/cache"
"github.com/zeromicro/go-zero/core/stores/sqlc"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/zeromicro/go-zero/core/stringx"
)
var (
secretsFieldNames = builder.RawFieldNames(&Secrets{})
secretsRows = strings.Join(secretsFieldNames, ",")
secretsRowsExpectAutoSet = strings.Join(stringx.Remove(secretsFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
secretsRowsWithPlaceHolder = strings.Join(stringx.Remove(secretsFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?"
cacheSecretsIdPrefix = "cache:secrets:id:"
cacheSecretsSecretIdPrefix = "cache:secrets:secretId:"
cacheSecretsUserIdPrefix = "cache:secrets:userId:"
)
type (
secretsModel interface {
Insert(ctx context.Context, data *Secrets) (sql.Result, error)
FindOne(ctx context.Context, id int64) (*Secrets, error)
FindOneBySecretId(ctx context.Context, secretId string) (*Secrets, error)
FindOneByUserId(ctx context.Context, userId int64) (*Secrets, error)
Update(ctx context.Context, data *Secrets) error
Delete(ctx context.Context, id int64) error
}
defaultSecretsModel struct {
sqlc.CachedConn
table string
}
Secrets struct {
Id int64 `db:"id"` // 密钥ID
UserId int64 `db:"user_id"` // 用户ID
SecretId string `db:"secret_id"` // 密钥ID
AesKey string `db:"aes_key"` // AES 128位密钥
CreatedAt time.Time `db:"created_at"` // 创建时间
UpdatedAt time.Time `db:"updated_at"` // 更新时间
}
)
func newSecretsModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) *defaultSecretsModel {
return &defaultSecretsModel{
CachedConn: sqlc.NewConn(conn, c, opts...),
table: "`secrets`",
}
}
func (m *defaultSecretsModel) Delete(ctx context.Context, id int64) error {
data, err := m.FindOne(ctx, id)
if err != nil {
return err
}
secretsIdKey := fmt.Sprintf("%s%v", cacheSecretsIdPrefix, id)
secretsSecretIdKey := fmt.Sprintf("%s%v", cacheSecretsSecretIdPrefix, data.SecretId)
secretsUserIdKey := fmt.Sprintf("%s%v", cacheSecretsUserIdPrefix, data.UserId)
_, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
query := fmt.Sprintf("delete from %s where `id` = ?", m.table)
return conn.ExecCtx(ctx, query, id)
}, secretsIdKey, secretsSecretIdKey, secretsUserIdKey)
return err
}
func (m *defaultSecretsModel) FindOne(ctx context.Context, id int64) (*Secrets, error) {
secretsIdKey := fmt.Sprintf("%s%v", cacheSecretsIdPrefix, id)
var resp Secrets
err := m.QueryRowCtx(ctx, &resp, secretsIdKey, func(ctx context.Context, conn sqlx.SqlConn, v any) error {
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", secretsRows, m.table)
return conn.QueryRowCtx(ctx, v, query, id)
})
switch err {
case nil:
return &resp, nil
case sqlc.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultSecretsModel) FindOneBySecretId(ctx context.Context, secretId string) (*Secrets, error) {
secretsSecretIdKey := fmt.Sprintf("%s%v", cacheSecretsSecretIdPrefix, secretId)
var resp Secrets
err := m.QueryRowIndexCtx(ctx, &resp, secretsSecretIdKey, m.formatPrimary, func(ctx context.Context, conn sqlx.SqlConn, v any) (i any, e error) {
query := fmt.Sprintf("select %s from %s where `secret_id` = ? limit 1", secretsRows, m.table)
if err := conn.QueryRowCtx(ctx, &resp, query, secretId); err != nil {
return nil, err
}
return resp.Id, nil
}, m.queryPrimary)
switch err {
case nil:
return &resp, nil
case sqlc.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultSecretsModel) FindOneByUserId(ctx context.Context, userId int64) (*Secrets, error) {
secretsUserIdKey := fmt.Sprintf("%s%v", cacheSecretsUserIdPrefix, userId)
var resp Secrets
err := m.QueryRowIndexCtx(ctx, &resp, secretsUserIdKey, m.formatPrimary, func(ctx context.Context, conn sqlx.SqlConn, v any) (i any, e error) {
query := fmt.Sprintf("select %s from %s where `user_id` = ? limit 1", secretsRows, m.table)
if err := conn.QueryRowCtx(ctx, &resp, query, userId); err != nil {
return nil, err
}
return resp.Id, nil
}, m.queryPrimary)
switch err {
case nil:
return &resp, nil
case sqlc.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultSecretsModel) Insert(ctx context.Context, data *Secrets) (sql.Result, error) {
secretsIdKey := fmt.Sprintf("%s%v", cacheSecretsIdPrefix, data.Id)
secretsSecretIdKey := fmt.Sprintf("%s%v", cacheSecretsSecretIdPrefix, data.SecretId)
secretsUserIdKey := fmt.Sprintf("%s%v", cacheSecretsUserIdPrefix, data.UserId)
ret, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?)", m.table, secretsRowsExpectAutoSet)
return conn.ExecCtx(ctx, query, data.UserId, data.SecretId, data.AesKey)
}, secretsIdKey, secretsSecretIdKey, secretsUserIdKey)
return ret, err
}
func (m *defaultSecretsModel) Update(ctx context.Context, newData *Secrets) error {
data, err := m.FindOne(ctx, newData.Id)
if err != nil {
return err
}
secretsIdKey := fmt.Sprintf("%s%v", cacheSecretsIdPrefix, data.Id)
secretsSecretIdKey := fmt.Sprintf("%s%v", cacheSecretsSecretIdPrefix, data.SecretId)
secretsUserIdKey := fmt.Sprintf("%s%v", cacheSecretsUserIdPrefix, data.UserId)
_, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, secretsRowsWithPlaceHolder)
return conn.ExecCtx(ctx, query, newData.UserId, newData.SecretId, newData.AesKey, newData.Id)
}, secretsIdKey, secretsSecretIdKey, secretsUserIdKey)
return err
}
func (m *defaultSecretsModel) formatPrimary(primary any) string {
return fmt.Sprintf("%s%v", cacheSecretsIdPrefix, primary)
}
func (m *defaultSecretsModel) queryPrimary(ctx context.Context, conn sqlx.SqlConn, v, primary any) error {
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", secretsRows, m.table)
return conn.QueryRowCtx(ctx, v, query, primary)
}
func (m *defaultSecretsModel) tableName() string {
return m.table
}

View File

@@ -0,0 +1,154 @@
package model
import (
"context"
"database/sql"
"fmt"
"github.com/zeromicro/go-zero/core/stores/cache"
"github.com/zeromicro/go-zero/core/stores/redis"
"github.com/zeromicro/go-zero/core/stores/sqlc"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"time"
)
var _ UserProductsModel = (*customUserProductsModel)(nil)
type UserProductItem struct {
Id int64 `db:"id"`
UserId int64 `db:"user_id"`
ProductId int64 `db:"product_id"`
ProductName string `db:"product_name"`
ProductCode string `db:"product_code"`
ProductDescription sql.NullString `db:"product_description"`
ProductGroup string `db:"product_group"`
ProductPrice float64 `db:"product_price"`
CreatedAt time.Time `db:"created_at"`
UpdatedAt time.Time `db:"updated_at"`
}
type (
// UserProductsModel is an interface to be customized, add more methods here,
// and implement the added methods in customUserProductsModel.
UserProductsModel interface {
userProductsModel
FindUserProductsList(ctx context.Context, userId, page, pageSize int64) ([]*UserProductItem, int64, error)
FindOneUserProduct(ctx context.Context, userId, productId int64) (*UserProducts, error)
FindMatchUserProductCode(ctx context.Context, userId int64, productCode string) (bool, error)
}
customUserProductsModel struct {
*defaultUserProductsModel
rds *redis.Redis
}
)
// NewUserProductsModel returns a model for the database table.
func NewUserProductsModel(rds *redis.Redis, conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) UserProductsModel {
return &customUserProductsModel{
rds: rds,
defaultUserProductsModel: newUserProductsModel(conn, c, opts...),
}
}
func (m *defaultUserProductsModel) FindUserProductsList(ctx context.Context, userId, page, pageSize int64) ([]*UserProductItem, int64, error) {
offset := (page - 1) * pageSize
var userProducts []*UserProductItem
// SQL查询语句手动选择需要的products字段
query := `
SELECT
up.id AS user_product_id,
up.user_id,
p.id AS product_id,
p.product_name,
p.product_code,
COALESCE(p.product_description, '') AS product_description,
p.product_group,
p.product_price,
up.created_at,
up.updated_at
FROM user_products up
JOIN products p ON up.product_id = p.id
WHERE up.user_id = ?
ORDER BY up.created_at DESC
LIMIT ?, ?`
// 执行查询
err := m.QueryRowsNoCacheCtx(ctx, &userProducts, query, userId, offset, pageSize)
if err != nil {
return nil, 0, err
}
// 查询总数量
var total int64
countQuery := "SELECT COUNT(*) FROM user_products WHERE user_id = ?"
err = m.QueryRowNoCacheCtx(ctx, &total, countQuery, userId)
if err != nil {
return nil, 0, err
}
return userProducts, total, nil
}
func (m *customUserProductsModel) FindOneUserProduct(ctx context.Context, userId, productId int64) (*UserProducts, error) {
// 定义 Redis 缓存 Set 键
redisKey := fmt.Sprintf("user_products:%d", userId)
// 检查 Redis Set 中是否存在用户与产品的关联
isMember, err := m.rds.SismemberCtx(ctx, redisKey, productId)
if err == nil && isMember {
// 如果 Redis Set 中存在,返回空,因为不需要重复查询
return nil, nil
}
var userProduct UserProducts
query := fmt.Sprintf("SELECT %s FROM %s WHERE `user_id` = ? AND `product_id` = ? LIMIT 1", userProductsRows, m.table)
err = m.QueryRowNoCacheCtx(ctx, &userProduct, query, userId, productId)
switch err {
case nil:
// 将用户产品的关联写入 Redis Set
_, err = m.rds.SaddCtx(ctx, redisKey, productId)
if err != nil {
return nil, err
}
return &userProduct, nil
case sqlc.ErrNotFound:
// 返回未找到的错误
return nil, ErrNotFound
default:
// 其他错误
return nil, err
}
}
func (m *customUserProductsModel) FindMatchUserProductCode(ctx context.Context, userId int64, productCode string) (bool, error) {
// 定义 Redis 缓存 Set 键
redisKey := fmt.Sprintf("user_products:%d", userId)
// 1. 检查 Redis Set 中是否存在用户与产品的关联
isMember, err := m.rds.SismemberCtx(ctx, redisKey, productCode)
if err == nil && isMember {
// 如果 Redis Set 中存在,表示关联已存在,返回 true
return true, nil
}
// 2. 如果 Redis 中没有匹配,则查询数据库
query := `
SELECT COUNT(*)
FROM user_products up
JOIN products p ON up.product_id = p.id
WHERE up.user_id = ? AND p.product_code = ?`
var count int
err = m.QueryRowNoCacheCtx(ctx, &count, query, userId, productCode)
if err != nil {
// 如果数据库查询出错,返回错误
return false, err
}
// 3. 如果数据库查询成功且有记录,更新 Redis Set 并返回 true
if count > 0 {
_, redisErr := m.rds.SaddCtx(ctx, redisKey, productCode)
if redisErr != nil {
return false, redisErr // Redis 更新失败
}
return true, nil
}
// 4. 如果没有找到匹配的关联,返回 false
return false, nil
}

View File

@@ -0,0 +1,114 @@
// Code generated by goctl. DO NOT EDIT.
// versions:
// goctl version: 1.7.2
package model
import (
"context"
"database/sql"
"fmt"
"strings"
"time"
"github.com/zeromicro/go-zero/core/stores/builder"
"github.com/zeromicro/go-zero/core/stores/cache"
"github.com/zeromicro/go-zero/core/stores/sqlc"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/zeromicro/go-zero/core/stringx"
)
var (
userProductsFieldNames = builder.RawFieldNames(&UserProducts{})
userProductsRows = strings.Join(userProductsFieldNames, ",")
userProductsRowsExpectAutoSet = strings.Join(stringx.Remove(userProductsFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
userProductsRowsWithPlaceHolder = strings.Join(stringx.Remove(userProductsFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?"
cacheUserProductsIdPrefix = "cache:userProducts:id:"
)
type (
userProductsModel interface {
Insert(ctx context.Context, data *UserProducts) (sql.Result, error)
FindOne(ctx context.Context, id int64) (*UserProducts, error)
Update(ctx context.Context, data *UserProducts) error
Delete(ctx context.Context, id int64) error
}
defaultUserProductsModel struct {
sqlc.CachedConn
table string
}
UserProducts struct {
Id int64 `db:"id"` // 用户产品ID
UserId int64 `db:"user_id"` // 用户ID
ProductId int64 `db:"product_id"` // 产品ID
CreatedAt time.Time `db:"created_at"` // 创建时间
UpdatedAt time.Time `db:"updated_at"` // 更新时间
}
)
func newUserProductsModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) *defaultUserProductsModel {
return &defaultUserProductsModel{
CachedConn: sqlc.NewConn(conn, c, opts...),
table: "`user_products`",
}
}
func (m *defaultUserProductsModel) Delete(ctx context.Context, id int64) error {
userProductsIdKey := fmt.Sprintf("%s%v", cacheUserProductsIdPrefix, id)
_, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
query := fmt.Sprintf("delete from %s where `id` = ?", m.table)
return conn.ExecCtx(ctx, query, id)
}, userProductsIdKey)
return err
}
func (m *defaultUserProductsModel) FindOne(ctx context.Context, id int64) (*UserProducts, error) {
userProductsIdKey := fmt.Sprintf("%s%v", cacheUserProductsIdPrefix, id)
var resp UserProducts
err := m.QueryRowCtx(ctx, &resp, userProductsIdKey, func(ctx context.Context, conn sqlx.SqlConn, v any) error {
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", userProductsRows, m.table)
return conn.QueryRowCtx(ctx, v, query, id)
})
switch err {
case nil:
return &resp, nil
case sqlc.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultUserProductsModel) Insert(ctx context.Context, data *UserProducts) (sql.Result, error) {
userProductsIdKey := fmt.Sprintf("%s%v", cacheUserProductsIdPrefix, data.Id)
ret, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
query := fmt.Sprintf("insert into %s (%s) values (?, ?)", m.table, userProductsRowsExpectAutoSet)
return conn.ExecCtx(ctx, query, data.UserId, data.ProductId)
}, userProductsIdKey)
return ret, err
}
func (m *defaultUserProductsModel) Update(ctx context.Context, data *UserProducts) error {
userProductsIdKey := fmt.Sprintf("%s%v", cacheUserProductsIdPrefix, data.Id)
_, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, userProductsRowsWithPlaceHolder)
return conn.ExecCtx(ctx, query, data.UserId, data.ProductId, data.Id)
}, userProductsIdKey)
return err
}
func (m *defaultUserProductsModel) formatPrimary(primary any) string {
return fmt.Sprintf("%s%v", cacheUserProductsIdPrefix, primary)
}
func (m *defaultUserProductsModel) queryPrimary(ctx context.Context, conn sqlx.SqlConn, v, primary any) error {
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", userProductsRows, m.table)
return conn.QueryRowCtx(ctx, v, query, primary)
}
func (m *defaultUserProductsModel) tableName() string {
return m.table
}

View File

@@ -0,0 +1,5 @@
package model
import "github.com/zeromicro/go-zero/core/stores/sqlx"
var ErrNotFound = sqlx.ErrNotFound

View File

@@ -0,0 +1,87 @@
package model
import (
"context"
"fmt"
"github.com/zeromicro/go-zero/core/stores/cache"
"github.com/zeromicro/go-zero/core/stores/redis"
"github.com/zeromicro/go-zero/core/stores/sqlc"
"github.com/zeromicro/go-zero/core/stores/sqlx"
)
var _ WhitelistModel = (*customWhitelistModel)(nil)
type (
// WhitelistModel is an interface to be customized, add more methods here,
// and implement the added methods in customWhitelistModel.
WhitelistModel interface {
whitelistModel
IsIpInWhitelist(ctx context.Context, ip string) (bool, error)
FindWhitelistList(ctx context.Context, userId, page, pageSize int64) ([]*Whitelist, int64, error)
}
customWhitelistModel struct {
*defaultWhitelistModel
rds *redis.Redis
}
)
// NewWhitelistModel returns a model for the database table.
func NewWhitelistModel(rds *redis.Redis, conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) WhitelistModel {
return &customWhitelistModel{
rds: rds,
defaultWhitelistModel: newWhitelistModel(conn, c, opts...),
}
}
func (m *customWhitelistModel) IsIpInWhitelist(ctx context.Context, ip string) (bool, error) {
// 定义 Redis 缓存 Set 键,存储所有白名单 IP
redisKey := "whitelist_ips"
// 1. 检查 Redis Set 中是否有这个 IP
isMember, err := m.rds.SismemberCtx(ctx, redisKey, ip)
if err == nil && isMember {
// 如果 Redis Set 中存在,表示 IP 已在白名单中
return true, nil
}
// 2. 如果 Redis 中没有匹配,查询数据库
query := `SELECT whitelist_ip FROM whitelist WHERE whitelist_ip = ? LIMIT 1`
var dbIp string
err = m.QueryRowNoCacheCtx(ctx, &dbIp, query, ip)
if err != nil {
// 如果数据库查询出错,返回错误
if err == sqlc.ErrNotFound {
return false, nil // 如果没有找到,返回 false
}
return false, err
}
// 3. 如果数据库查询成功,写入 Redis Set并返回 true
_, redisErr := m.rds.SaddCtx(ctx, redisKey, ip)
if redisErr != nil {
return false, redisErr // Redis 更新失败
}
return true, nil
}
func (m *customWhitelistModel) FindWhitelistList(ctx context.Context, userId, page, pageSize int64) ([]*Whitelist, int64, error) {
offset := (page - 1) * pageSize
var whitelist []*Whitelist
query := fmt.Sprintf("SELECT %s FROM %s WHERE user_id = ? ORDER BY created_at DESC LIMIT ?,?", whitelistRows, m.table)
err := m.QueryRowsNoCacheCtx(ctx, &whitelist, query, userId, offset, pageSize)
if err != nil {
return nil, 0, err
}
// 查询总数量
var total int64
countQuery := fmt.Sprintf("SELECT COUNT(*) FROM %s", m.table)
err = m.QueryRowNoCacheCtx(ctx, &total, countQuery)
if err != nil {
return nil, 0, err
}
return whitelist, total, nil
}

View File

@@ -0,0 +1,114 @@
// Code generated by goctl. DO NOT EDIT.
// versions:
// goctl version: 1.7.2
package model
import (
"context"
"database/sql"
"fmt"
"strings"
"time"
"github.com/zeromicro/go-zero/core/stores/builder"
"github.com/zeromicro/go-zero/core/stores/cache"
"github.com/zeromicro/go-zero/core/stores/sqlc"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/zeromicro/go-zero/core/stringx"
)
var (
whitelistFieldNames = builder.RawFieldNames(&Whitelist{})
whitelistRows = strings.Join(whitelistFieldNames, ",")
whitelistRowsExpectAutoSet = strings.Join(stringx.Remove(whitelistFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
whitelistRowsWithPlaceHolder = strings.Join(stringx.Remove(whitelistFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?"
cacheWhitelistIdPrefix = "cache:whitelist:id:"
)
type (
whitelistModel interface {
Insert(ctx context.Context, data *Whitelist) (sql.Result, error)
FindOne(ctx context.Context, id int64) (*Whitelist, error)
Update(ctx context.Context, data *Whitelist) error
Delete(ctx context.Context, id int64) error
}
defaultWhitelistModel struct {
sqlc.CachedConn
table string
}
Whitelist struct {
Id int64 `db:"id"` // 白名单ID
UserId int64 `db:"user_id"` // 用户ID
WhitelistIp string `db:"whitelist_ip"` // 白名单IP
CreatedAt time.Time `db:"created_at"` // 创建时间
UpdatedAt time.Time `db:"updated_at"` // 更新时间
}
)
func newWhitelistModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) *defaultWhitelistModel {
return &defaultWhitelistModel{
CachedConn: sqlc.NewConn(conn, c, opts...),
table: "`whitelist`",
}
}
func (m *defaultWhitelistModel) Delete(ctx context.Context, id int64) error {
whitelistIdKey := fmt.Sprintf("%s%v", cacheWhitelistIdPrefix, id)
_, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
query := fmt.Sprintf("delete from %s where `id` = ?", m.table)
return conn.ExecCtx(ctx, query, id)
}, whitelistIdKey)
return err
}
func (m *defaultWhitelistModel) FindOne(ctx context.Context, id int64) (*Whitelist, error) {
whitelistIdKey := fmt.Sprintf("%s%v", cacheWhitelistIdPrefix, id)
var resp Whitelist
err := m.QueryRowCtx(ctx, &resp, whitelistIdKey, func(ctx context.Context, conn sqlx.SqlConn, v any) error {
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", whitelistRows, m.table)
return conn.QueryRowCtx(ctx, v, query, id)
})
switch err {
case nil:
return &resp, nil
case sqlc.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultWhitelistModel) Insert(ctx context.Context, data *Whitelist) (sql.Result, error) {
whitelistIdKey := fmt.Sprintf("%s%v", cacheWhitelistIdPrefix, data.Id)
ret, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
query := fmt.Sprintf("insert into %s (%s) values (?, ?)", m.table, whitelistRowsExpectAutoSet)
return conn.ExecCtx(ctx, query, data.UserId, data.WhitelistIp)
}, whitelistIdKey)
return ret, err
}
func (m *defaultWhitelistModel) Update(ctx context.Context, data *Whitelist) error {
whitelistIdKey := fmt.Sprintf("%s%v", cacheWhitelistIdPrefix, data.Id)
_, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, whitelistRowsWithPlaceHolder)
return conn.ExecCtx(ctx, query, data.UserId, data.WhitelistIp, data.Id)
}, whitelistIdKey)
return err
}
func (m *defaultWhitelistModel) formatPrimary(primary any) string {
return fmt.Sprintf("%s%v", cacheWhitelistIdPrefix, primary)
}
func (m *defaultWhitelistModel) queryPrimary(ctx context.Context, conn sqlx.SqlConn, v, primary any) error {
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", whitelistRows, m.table)
return conn.QueryRowCtx(ctx, v, query, primary)
}
func (m *defaultWhitelistModel) tableName() string {
return m.table
}