package dao import ( "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 ( usersFieldNames = builder.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`"), "=?,") + "=?" cacheIdataUsersIdPrefix = "cache:idata:users:id:" cacheIdataUsersOpenidPrefix = "cache:idata:users:openid:" cacheIdataUsersPhonePrefix = "cache:idata:users:phone:" cacheIdataUsersUidPrefix = "cache:idata: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) { idataUsersPhoneKey := fmt.Sprintf("%s%v", cacheIdataUsersPhonePrefix, data.Phone) idataUsersUidKey := fmt.Sprintf("%s%v", cacheIdataUsersUidPrefix, data.Uid) idataUsersIdKey := fmt.Sprintf("%s%v", cacheIdataUsersIdPrefix, data.Id) idataUsersOpenidKey := fmt.Sprintf("%s%v", cacheIdataUsersOpenidPrefix, data.Openid) 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) }, idataUsersIdKey, idataUsersOpenidKey, idataUsersPhoneKey, idataUsersUidKey) return ret, err } func (m *defaultUsersModel) FindOne(id int64) (*Users, error) { idataUsersIdKey := fmt.Sprintf("%s%v", cacheIdataUsersIdPrefix, id) var resp Users err := m.QueryRow(&resp, idataUsersIdKey, 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) { idataUsersOpenidKey := fmt.Sprintf("%s%v", cacheIdataUsersOpenidPrefix, openid) var resp Users err := m.QueryRowIndex(&resp, idataUsersOpenidKey, 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) { idataUsersPhoneKey := fmt.Sprintf("%s%v", cacheIdataUsersPhonePrefix, phone) var resp Users err := m.QueryRowIndex(&resp, idataUsersPhoneKey, 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) { idataUsersUidKey := fmt.Sprintf("%s%v", cacheIdataUsersUidPrefix, uid) var resp Users err := m.QueryRowIndex(&resp, idataUsersUidKey, 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 { idataUsersUidKey := fmt.Sprintf("%s%v", cacheIdataUsersUidPrefix, data.Uid) idataUsersIdKey := fmt.Sprintf("%s%v", cacheIdataUsersIdPrefix, data.Id) idataUsersOpenidKey := fmt.Sprintf("%s%v", cacheIdataUsersOpenidPrefix, data.Openid) idataUsersPhoneKey := fmt.Sprintf("%s%v", cacheIdataUsersPhonePrefix, data.Phone) _, 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) }, idataUsersIdKey, idataUsersOpenidKey, idataUsersPhoneKey, idataUsersUidKey) return err } func (m *defaultUsersModel) Delete(id int64) error { data, err := m.FindOne(id) if err != nil { return err } idataUsersIdKey := fmt.Sprintf("%s%v", cacheIdataUsersIdPrefix, id) idataUsersOpenidKey := fmt.Sprintf("%s%v", cacheIdataUsersOpenidPrefix, data.Openid) idataUsersPhoneKey := fmt.Sprintf("%s%v", cacheIdataUsersPhonePrefix, data.Phone) idataUsersUidKey := fmt.Sprintf("%s%v", cacheIdataUsersUidPrefix, 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) }, idataUsersUidKey, idataUsersIdKey, idataUsersOpenidKey, idataUsersPhoneKey) return err } func (m *defaultUsersModel) formatPrimary(primary interface{}) string { return fmt.Sprintf("%s%v", cacheIdataUsersIdPrefix, 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) }