package dao import ( "database/sql" "fmt" "strings" "time" "github.com/tal-tech/go-zero/core/stores/cache" "github.com/tal-tech/go-zero/core/stores/sqlc" "github.com/tal-tech/go-zero/core/stores/sqlx" "github.com/tal-tech/go-zero/core/stringx" "github.com/tal-tech/go-zero/tools/goctl/model/sql/builderx" ) var ( usersFieldNames = builderx.RawFieldNames(&Users{}) usersRows = strings.Join(usersFieldNames, ",") usersRowsExpectAutoSet = strings.Join(stringx.Remove(usersFieldNames, "`id`", "`create_time`", "`update_time`"), ",") usersRowsWithPlaceHolder = strings.Join(stringx.Remove(usersFieldNames, "`id`", "`create_time`", "`update_time`"), "=?,") + "=?" cacheUsersIdPrefix = "cache#users#id#" cacheUsersOpenidPrefix = "cache#users#openid#" cacheUsersPhonePrefix = "cache#users#phone#" cacheUsersUidPrefix = "cache#users#uid#" ) type ( UsersModel interface { Insert(data Users) (sql.Result, error) FindOne(id int64) (*Users, error) FindOneByOpenid(openid string) (*Users, error) FindOneByPhone(phone string) (*Users, error) FindOneByUid(uid string) (*Users, error) Update(data Users) error Delete(id int64) error } defaultUsersModel struct { sqlc.CachedConn table string } Users struct { Id int64 `db:"id"` Uid string `db:"uid"` // 用户ID Openid string `db:"openid"` // 微信openid Secret string `db:"secret"` // secret Phone string `db:"phone"` // 手机号 Password string `db:"password"` // 密码 Avatar string `db:"avatar"` // 头像url Name string `db:"name"` // 昵称 Gender int64 `db:"gender"` // 性别 Score int64 `db:"score"` // 金币数量 Vip int64 `db:"vip"` // VIP等级 VipExpireTime int64 `db:"vip_expire_time"` // VIP到期时间戳 ApiOpened int64 `db:"api_opened"` // Api开通情况 CreateTime time.Time `db:"create_time"` UpdateTime time.Time `db:"update_time"` } ) func NewUsersModel(conn sqlx.SqlConn, c cache.CacheConf) UsersModel { return &defaultUsersModel{ CachedConn: sqlc.NewConn(conn, c), table: "`users`", } } func (m *defaultUsersModel) Insert(data Users) (sql.Result, error) { usersUidKey := fmt.Sprintf("%s%v", cacheUsersUidPrefix, data.Uid) usersOpenidKey := fmt.Sprintf("%s%v", cacheUsersOpenidPrefix, data.Openid) usersPhoneKey := fmt.Sprintf("%s%v", cacheUsersPhonePrefix, data.Phone) ret, err := m.Exec(func(conn sqlx.SqlConn) (result sql.Result, err error) { query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, usersRowsExpectAutoSet) return conn.Exec(query, data.Uid, data.Openid, data.Secret, data.Phone, data.Password, data.Avatar, data.Name, data.Gender, data.Score, data.Vip, data.VipExpireTime, data.ApiOpened) }, usersOpenidKey, usersPhoneKey, usersUidKey) return ret, err } func (m *defaultUsersModel) FindOne(id int64) (*Users, error) { usersIdKey := fmt.Sprintf("%s%v", cacheUsersIdPrefix, id) var resp Users err := m.QueryRow(&resp, usersIdKey, func(conn sqlx.SqlConn, v interface{}) error { query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", usersRows, m.table) return conn.QueryRow(v, query, id) }) switch err { case nil: return &resp, nil case sqlc.ErrNotFound: return nil, ErrNotFound default: return nil, err } } func (m *defaultUsersModel) FindOneByOpenid(openid string) (*Users, error) { usersOpenidKey := fmt.Sprintf("%s%v", cacheUsersOpenidPrefix, openid) var resp Users err := m.QueryRowIndex(&resp, usersOpenidKey, m.formatPrimary, func(conn sqlx.SqlConn, v interface{}) (i interface{}, e error) { query := fmt.Sprintf("select %s from %s where `openid` = ? limit 1", usersRows, m.table) if err := conn.QueryRow(&resp, query, openid); 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 *defaultUsersModel) FindOneByPhone(phone string) (*Users, error) { usersPhoneKey := fmt.Sprintf("%s%v", cacheUsersPhonePrefix, phone) var resp Users err := m.QueryRowIndex(&resp, usersPhoneKey, m.formatPrimary, func(conn sqlx.SqlConn, v interface{}) (i interface{}, e error) { query := fmt.Sprintf("select %s from %s where `phone` = ? limit 1", usersRows, m.table) if err := conn.QueryRow(&resp, query, phone); 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 *defaultUsersModel) FindOneByUid(uid string) (*Users, error) { usersUidKey := fmt.Sprintf("%s%v", cacheUsersUidPrefix, uid) var resp Users err := m.QueryRowIndex(&resp, usersUidKey, m.formatPrimary, func(conn sqlx.SqlConn, v interface{}) (i interface{}, e error) { query := fmt.Sprintf("select %s from %s where `uid` = ? limit 1", usersRows, m.table) if err := conn.QueryRow(&resp, query, uid); 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 *defaultUsersModel) Update(data Users) error { usersOpenidKey := fmt.Sprintf("%s%v", cacheUsersOpenidPrefix, data.Openid) usersPhoneKey := fmt.Sprintf("%s%v", cacheUsersPhonePrefix, data.Phone) usersUidKey := fmt.Sprintf("%s%v", cacheUsersUidPrefix, data.Uid) usersIdKey := fmt.Sprintf("%s%v", cacheUsersIdPrefix, data.Id) _, err := m.Exec(func(conn sqlx.SqlConn) (result sql.Result, err error) { query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, usersRowsWithPlaceHolder) return conn.Exec(query, data.Uid, data.Openid, data.Secret, data.Phone, data.Password, data.Avatar, data.Name, data.Gender, data.Score, data.Vip, data.VipExpireTime, data.ApiOpened, data.Id) }, usersPhoneKey, usersUidKey, usersIdKey, usersOpenidKey) return err } func (m *defaultUsersModel) Delete(id int64) error { data, err := m.FindOne(id) if err != nil { return err } usersIdKey := fmt.Sprintf("%s%v", cacheUsersIdPrefix, id) usersOpenidKey := fmt.Sprintf("%s%v", cacheUsersOpenidPrefix, data.Openid) usersPhoneKey := fmt.Sprintf("%s%v", cacheUsersPhonePrefix, data.Phone) usersUidKey := fmt.Sprintf("%s%v", cacheUsersUidPrefix, data.Uid) _, err = m.Exec(func(conn sqlx.SqlConn) (result sql.Result, err error) { query := fmt.Sprintf("delete from %s where `id` = ?", m.table) return conn.Exec(query, id) }, usersUidKey, usersIdKey, usersOpenidKey, usersPhoneKey) return err } func (m *defaultUsersModel) formatPrimary(primary interface{}) string { return fmt.Sprintf("%s%v", cacheUsersIdPrefix, primary) } func (m *defaultUsersModel) queryPrimary(conn sqlx.SqlConn, v, primary interface{}) error { query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", usersRows, m.table) return conn.QueryRow(v, query, primary) }