package model import ( "context" "database/sql" "fmt" "strings" "time" "git.i2edu.net/i2/i2-bill-erp/transform" "git.i2edu.net/i2/i2-bill-erp/transformclient" "github.com/xormplus/xorm" "git.i2edu.net/i2/go-zero/core/stores/cache" "git.i2edu.net/i2/go-zero/core/stores/sqlc" "git.i2edu.net/i2/go-zero/core/stores/sqlx" "git.i2edu.net/i2/go-zero/core/stringx" "git.i2edu.net/i2/go-zero/tools/goctl/model/sql/builderx" ) var ( UserFieldNames = builderx.RawFieldNames(&User{}) UserRows = strings.Join(UserFieldNames, ",") UserRowsExpectAutoSet = strings.Join(stringx.Remove(UserFieldNames, "`id`", "`create_time`", "`update_time`"), ",") UserRowsWithPlaceHolder = strings.Join(stringx.Remove(UserFieldNames, "`id`", "`create_time`", "`update_time`"), "=?,") + "=?" cacheUserIdPrefix = "cache:user:id:" cacheUserUsernamePrefix = "cache:user:username:" cacheUserWeiXinOpenIdPrefix = "cache:user:weixin_openid:" ) type ( Cache interface { SetCache(key string, v interface{}) error GetCache(key string, v interface{}) error SetWithExpire(key string, v interface{}, expire time.Duration) error } UserModel interface { Insert(data User) (sql.Result, error) FindOne(id int64) (*User, error) FindOneByUsername(username string) (*User, error) FindOneByWeiXinOpenId(openid string) (*User, error) Update(data User) error Delete(id int64) error CacheStorage() Cache } defaultUserModel struct { sqlc.CachedConn table string } User struct { Mobile string `db:"mobile"` Avatar string `db:"avatar"` WeixinOpenid string `db:"weixin_openid"` Password string `db:"password"` Birthday int64 `db:"birthday"` RegisterTime int64 `db:"register_time"` LastLoginTime int64 `db:"last_login_time"` Nickname string `db:"nickname"` Id int64 `db:"id"` ErpId string `db:"erp_id"` Username string `db:"username"` Gender int64 `db:"gender"` UserLevelId int64 `db:"user_level_id"` RegisterIp string `db:"register_ip"` LastLoginIp string `db:"last_login_ip"` } ) func NewUserModel(conn sqlx.SqlConn, c cache.CacheConf) UserModel { return &defaultUserModel{ CachedConn: sqlc.NewConn(conn, c), table: "`i2bill_user`", } } type UserXorm struct { Mobile string `json:"mobile"` Avatar string `json:"avatar"` WeixinOpenid string `json:"weixin_openid"` Password string `json:"password"` Birthday int64 `json:"birthday"` RegisterTime int64 `json:"register_time"` LastLoginTime int64 `json:"last_login_time"` Nickname string `json:"nickname"` Id int64 `json:"id"` ErpId string `json:"erp_id"` Username string `json:"username"` Gender int64 `json:"gender"` UserLevelId int64 `json:"user_level_id"` RegisterIp string `json:"register_ip"` LastLoginIp string `json:"last_login_ip"` } func (t *UserXorm) TableName() string { return "i2bill_user" } func (m *defaultUserModel) Insert(data User) (sql.Result, error) { userUsernameKey := fmt.Sprintf("%s%v", cacheUserUsernamePrefix, data.Username) ret, err := m.Exec(func(conn sqlx.SqlConn) (result sql.Result, err error) { query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, UserRowsExpectAutoSet) return conn.Exec(query, data.Mobile, data.Avatar, data.WeixinOpenid, data.Password, data.Birthday, data.RegisterTime, data.LastLoginTime, data.Nickname, data.Username, data.Gender, data.UserLevelId, data.RegisterIp, data.LastLoginIp) }, userUsernameKey) return ret, err } func (m *defaultUserModel) FindOne(id int64) (*User, error) { userIdKey := fmt.Sprintf("%s%v", cacheUserIdPrefix, id) var resp User err := m.QueryRow(&resp, userIdKey, func(conn sqlx.SqlConn, v interface{}) error { query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", UserRows, 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 *defaultUserModel) FindOneByWeiXinOpenId(id string) (*User, error) { userIdKey := fmt.Sprintf("%s%v", cacheUserWeiXinOpenIdPrefix, id) var resp User err := m.QueryRow(&resp, userIdKey, func(conn sqlx.SqlConn, v interface{}) error { query := fmt.Sprintf("select %s from %s where `weixin_openid` = ? limit 1", UserRows, 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 *defaultUserModel) FindOneByUsername(username string) (*User, error) { userUsernameKey := fmt.Sprintf("%s%v", cacheUserUsernamePrefix, username) var resp User err := m.QueryRowIndex(&resp, userUsernameKey, m.formatPrimary, func(conn sqlx.SqlConn, v interface{}) (i interface{}, e error) { query := fmt.Sprintf("select %s from %s where `username` = ? limit 1", UserRows, m.table) if err := conn.QueryRow(&resp, query, username); 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 *defaultUserModel) Update(data User) error { userIdKey := fmt.Sprintf("%s%v", cacheUserIdPrefix, data.Id) userUsernameKey := fmt.Sprintf("%s%v", cacheUserUsernamePrefix, data.Username) _, err := m.Exec(func(conn sqlx.SqlConn) (result sql.Result, err error) { query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, UserRowsWithPlaceHolder) return conn.Exec(query, data.Mobile, data.Avatar, data.WeixinOpenid, data.Password, data.Birthday, data.RegisterTime, data.LastLoginTime, data.Nickname, data.Username, data.Gender, data.UserLevelId, data.RegisterIp, data.LastLoginIp, data.Id) }, userIdKey, userUsernameKey) return err } func (m *defaultUserModel) Delete(id int64) error { data, err := m.FindOne(id) if err != nil { return err } userIdKey := fmt.Sprintf("%s%v", cacheUserIdPrefix, id) userUsernameKey := fmt.Sprintf("%s%v", cacheUserUsernamePrefix, data.Username) _, 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) }, userUsernameKey, userIdKey) return err } func (m *defaultUserModel) formatPrimary(primary interface{}) string { return fmt.Sprintf("%s%v", cacheUserIdPrefix, primary) } func (m *defaultUserModel) queryPrimary(conn sqlx.SqlConn, v, primary interface{}) error { query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", UserRows, m.table) return conn.QueryRow(v, query, primary) } func (m *defaultUserModel) SetCache(key string, v interface{}) error { return m.CachedConn.SetCache(key, v) } func (m *defaultUserModel) GetCache(key string, v interface{}) error { err := m.CachedConn.GetCache(key, v) if err == sql.ErrNoRows { err = ErrRdsNotFound } return err } func (m *defaultUserModel) SetWithExpire(key string, v interface{}, expire time.Duration) error { return m.CachedConn.SetWithExpire(key, v, expire) } func (m *defaultUserModel) CacheStorage() Cache { return m } //获取用户信息 func GetI2bilUserInfo(userId int64, engine *xorm.Engine) (*UserXorm, error) { user := new(UserXorm) _, err := engine.SQL("select * from i2bill_user where id = ?", userId).Get(user) if err != nil { return nil, err } return user, nil } func GetAcquirePerm(userId int64, rpcClient transformclient.Transform, engine *xorm.Engine, ctx context.Context) (*transform.GetErpRoleRes, error) { var res = new(transform.GetErpRoleRes) partUser, err := GetPartTimeXormByUserId(userId, engine) if err != nil { return nil, err } if partUser.Id != 0 && partUser.MkId != "" { res, err = GetErpUser("", partUser.MkId, rpcClient, ctx) if err != nil { return nil, err } } user, err := GetI2bilUserInfo(userId, engine) if err != nil { return nil, err } resMobile, err := GetErpUser(user.Mobile, "", rpcClient, ctx) if err != nil { return nil, err } if resMobile != nil && resMobile.UserId != "" { res = resMobile } return res, nil } type AcquirePermInfo struct { *transform.GetErpRoleRes Role int64 // 1 兼职,2mk } func GetAcquirePermInfo(userId int64, rpcClient transformclient.Transform, engine *xorm.Engine, ctx context.Context) (*AcquirePermInfo, error) { //mk user, err := GetI2bilUserInfo(userId, engine) if err != nil { return nil, err } erpInfo, err := GetErpUser(user.Mobile, "", rpcClient, ctx) if err != nil { return nil, err } if erpInfo != nil && erpInfo.UserId != "" { return &AcquirePermInfo{erpInfo, 2}, nil } //兼职 partUser, err := GetPartTimeXormByUserId(userId, engine) if err != nil { return nil, err } if partUser.Id != 0 && partUser.MkId != "" { erpInfo, err := GetErpUser("", partUser.MkId, rpcClient, ctx) if err != nil { return nil, err } if erpInfo != nil && erpInfo.UserId != "" { return &AcquirePermInfo{erpInfo, 1}, nil } } return nil, nil } func GetErpUser(mobile string, erpUserId string, rpcClient transformclient.Transform, ctx context.Context) (*transform.GetErpRoleRes, error) { in := new(transform.GetErpRoleReq) in.Mobile = mobile in.UserId = erpUserId erpRoles, err := rpcClient.GetErpRole(ctx, in) if err != nil { return nil, err } if erpRoles.UserId != "" { roles := strings.Split(erpRoles.Role, ",") for _, r := range roles { if r == "LAMK" || r == "LAMKM" || r == "student/readingStudent" { return erpRoles, nil } } } return nil, nil } //获取校区权限 func GetUserSchoolPerm(erpUserId string, rpcClient transformclient.Transform, engine *xorm.Engine, ctx context.Context) ([]*transform.OrganSchool, error) { in := erpUserId result, err := rpcClient.GetErpOrganSchPerByUserId(ctx, &transform.GetErpOrganSchPerByUserIdReq{UserId: in}) if err != nil { return nil, err } return result.School, nil }