From 2d7ea2e3025bc37a46d7a4e310e30a09c2347912 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Thu, 1 Jun 2023 18:34:41 +0800 Subject: [PATCH] fixc --- ddl/fs_user.sql | 34 ++++ go.mod | 5 +- go.sum | 2 + model/fsusermodel.go | 24 +++ model/fsusermodel_gen.go | 153 ++++++++++++++++++ .../internal/handler/getproductlisthandler.go | 10 +- product/internal/logic/getproductlistlogic.go | 12 +- product/internal/svc/servicecontext.go | 9 +- product/product.go | 1 - utils/auth/auth.go | 64 ++++++++ 10 files changed, 304 insertions(+), 10 deletions(-) create mode 100644 ddl/fs_user.sql create mode 100755 model/fsusermodel.go create mode 100755 model/fsusermodel_gen.go create mode 100644 utils/auth/auth.go diff --git a/ddl/fs_user.sql b/ddl/fs_user.sql new file mode 100644 index 00000000..8241087c --- /dev/null +++ b/ddl/fs_user.sql @@ -0,0 +1,34 @@ +-- fusentest.fs_user definition + +CREATE TABLE `fs_user` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `face_id` bigint(20) NOT NULL DEFAULT '0' COMMENT 'facebook的userid', + `sub` bigint(20) NOT NULL DEFAULT '0' COMMENT 'google的sub', + `first_name` varchar(64) DEFAULT NULL COMMENT 'FirstName', + `last_name` varchar(64) DEFAULT NULL COMMENT 'LastName', + `username` varchar(255) DEFAULT NULL COMMENT '用户名', + `company` varchar(64) DEFAULT NULL COMMENT '公司名称', + `mobile` varchar(16) DEFAULT NULL COMMENT '手机号码', + `auth_key` varchar(32) NOT NULL, + `password_hash` varchar(255) NOT NULL, + `verification_token` varchar(255) DEFAULT NULL, + `password_reset_token` varchar(255) DEFAULT NULL, + `email` varchar(255) NOT NULL COMMENT '邮箱', + `type` tinyint(1) NOT NULL COMMENT '1普通餐厅 2连锁餐厅', + `status` tinyint(3) unsigned DEFAULT '1' COMMENT '1正常 0不正常', + `is_del` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否删除 1删除', + `created_at` int(11) NOT NULL DEFAULT '0' COMMENT '添加时间', + `updated_at` int(11) NOT NULL DEFAULT '0' COMMENT '更新时间', + `is_order_status_email` tinyint(1) NOT NULL DEFAULT '0' COMMENT '订单状态改变时是否接收邮件', + `is_email_advertisement` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否接收邮件广告', + `is_order_status_phone` tinyint(1) NOT NULL DEFAULT '0' COMMENT '订单状态改变是是否接收电话', + `is_phone_advertisement` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否接收短信广告', + `is_open_render` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否打开个性化渲染(1:开启,0:关闭)', + `is_thousand_face` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否已经存在千人千面(1:存在,0:不存在)', + `is_low_rendering` tinyint(1) unsigned zerofill NOT NULL DEFAULT '0' COMMENT '是否开启低渲染模型渲染', + `is_remove_bg` tinyint(1) NOT NULL DEFAULT '1' COMMENT '用户上传logo是否去除背景', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE KEY `email` (`email`) USING BTREE, + UNIQUE KEY `username` (`username`) USING BTREE, + UNIQUE KEY `password_reset_token` (`password_reset_token`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=88 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='用户表'; \ No newline at end of file diff --git a/go.mod b/go.mod index 60d41c0f..002880ba 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,10 @@ module fusenapi go 1.20 -require github.com/zeromicro/go-zero v1.5.2 +require ( + github.com/golang-jwt/jwt v3.2.2+incompatible + github.com/zeromicro/go-zero v1.5.2 +) require ( github.com/beorn7/perks v1.0.1 // indirect diff --git a/go.sum b/go.sum index 1ba6a256..5bbedf7f 100644 --- a/go.sum +++ b/go.sum @@ -88,6 +88,8 @@ github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= +github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= diff --git a/model/fsusermodel.go b/model/fsusermodel.go new file mode 100755 index 00000000..39ec5d31 --- /dev/null +++ b/model/fsusermodel.go @@ -0,0 +1,24 @@ +package model + +import "github.com/zeromicro/go-zero/core/stores/sqlx" + +var _ FsUserModel = (*customFsUserModel)(nil) + +type ( + // FsUserModel is an interface to be customized, add more methods here, + // and implement the added methods in customFsUserModel. + FsUserModel interface { + fsUserModel + } + + customFsUserModel struct { + *defaultFsUserModel + } +) + +// NewFsUserModel returns a model for the database table. +func NewFsUserModel(conn sqlx.SqlConn) FsUserModel { + return &customFsUserModel{ + defaultFsUserModel: newFsUserModel(conn), + } +} diff --git a/model/fsusermodel_gen.go b/model/fsusermodel_gen.go new file mode 100755 index 00000000..f8c8f646 --- /dev/null +++ b/model/fsusermodel_gen.go @@ -0,0 +1,153 @@ +// Code generated by goctl. DO NOT EDIT. + +package model + +import ( + "context" + "database/sql" + "fmt" + "strings" + + "github.com/zeromicro/go-zero/core/stores/builder" + "github.com/zeromicro/go-zero/core/stores/sqlc" + "github.com/zeromicro/go-zero/core/stores/sqlx" + "github.com/zeromicro/go-zero/core/stringx" +) + +var ( + fsUserFieldNames = builder.RawFieldNames(&FsUser{}) + fsUserRows = strings.Join(fsUserFieldNames, ",") + fsUserRowsExpectAutoSet = strings.Join(stringx.Remove(fsUserFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",") + fsUserRowsWithPlaceHolder = strings.Join(stringx.Remove(fsUserFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?" +) + +type ( + fsUserModel interface { + Insert(ctx context.Context, data *FsUser) (sql.Result, error) + FindOne(ctx context.Context, id int64) (*FsUser, error) + FindOneByEmail(ctx context.Context, email string) (*FsUser, error) + FindOneByPasswordResetToken(ctx context.Context, passwordResetToken sql.NullString) (*FsUser, error) + FindOneByUsername(ctx context.Context, username sql.NullString) (*FsUser, error) + Update(ctx context.Context, data *FsUser) error + Delete(ctx context.Context, id int64) error + } + + defaultFsUserModel struct { + conn sqlx.SqlConn + table string + } + + FsUser struct { + Id int64 `db:"id"` // ID + FaceId int64 `db:"face_id"` // facebook的userid + Sub int64 `db:"sub"` // google的sub + FirstName sql.NullString `db:"first_name"` // FirstName + LastName sql.NullString `db:"last_name"` // LastName + Username sql.NullString `db:"username"` // 用户名 + Company sql.NullString `db:"company"` // 公司名称 + Mobile sql.NullString `db:"mobile"` // 手机号码 + AuthKey string `db:"auth_key"` + PasswordHash string `db:"password_hash"` + VerificationToken sql.NullString `db:"verification_token"` + PasswordResetToken sql.NullString `db:"password_reset_token"` + Email string `db:"email"` // 邮箱 + Type int64 `db:"type"` // 1普通餐厅 2连锁餐厅 + Status int64 `db:"status"` // 1正常 0不正常 + IsDel int64 `db:"is_del"` // 是否删除 1删除 + CreatedAt int64 `db:"created_at"` // 添加时间 + UpdatedAt int64 `db:"updated_at"` // 更新时间 + IsOrderStatusEmail int64 `db:"is_order_status_email"` // 订单状态改变时是否接收邮件 + IsEmailAdvertisement int64 `db:"is_email_advertisement"` // 是否接收邮件广告 + IsOrderStatusPhone int64 `db:"is_order_status_phone"` // 订单状态改变是是否接收电话 + IsPhoneAdvertisement int64 `db:"is_phone_advertisement"` // 是否接收短信广告 + IsOpenRender int64 `db:"is_open_render"` // 是否打开个性化渲染(1:开启,0:关闭) + IsThousandFace int64 `db:"is_thousand_face"` // 是否已经存在千人千面(1:存在,0:不存在) + IsLowRendering int64 `db:"is_low_rendering"` // 是否开启低渲染模型渲染 + IsRemoveBg int64 `db:"is_remove_bg"` // 用户上传logo是否去除背景 + } +) + +func newFsUserModel(conn sqlx.SqlConn) *defaultFsUserModel { + return &defaultFsUserModel{ + conn: conn, + table: "`fs_user`", + } +} + +func (m *defaultFsUserModel) Delete(ctx context.Context, id int64) error { + query := fmt.Sprintf("delete from %s where `id` = ?", m.table) + _, err := m.conn.ExecCtx(ctx, query, id) + return err +} + +func (m *defaultFsUserModel) FindOne(ctx context.Context, id int64) (*FsUser, error) { + query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", fsUserRows, m.table) + var resp FsUser + err := m.conn.QueryRowCtx(ctx, &resp, query, id) + switch err { + case nil: + return &resp, nil + case sqlc.ErrNotFound: + return nil, ErrNotFound + default: + return nil, err + } +} + +func (m *defaultFsUserModel) FindOneByEmail(ctx context.Context, email string) (*FsUser, error) { + var resp FsUser + query := fmt.Sprintf("select %s from %s where `email` = ? limit 1", fsUserRows, m.table) + err := m.conn.QueryRowCtx(ctx, &resp, query, email) + switch err { + case nil: + return &resp, nil + case sqlc.ErrNotFound: + return nil, ErrNotFound + default: + return nil, err + } +} + +func (m *defaultFsUserModel) FindOneByPasswordResetToken(ctx context.Context, passwordResetToken sql.NullString) (*FsUser, error) { + var resp FsUser + query := fmt.Sprintf("select %s from %s where `password_reset_token` = ? limit 1", fsUserRows, m.table) + err := m.conn.QueryRowCtx(ctx, &resp, query, passwordResetToken) + switch err { + case nil: + return &resp, nil + case sqlc.ErrNotFound: + return nil, ErrNotFound + default: + return nil, err + } +} + +func (m *defaultFsUserModel) FindOneByUsername(ctx context.Context, username sql.NullString) (*FsUser, error) { + var resp FsUser + query := fmt.Sprintf("select %s from %s where `username` = ? limit 1", fsUserRows, m.table) + err := m.conn.QueryRowCtx(ctx, &resp, query, username) + switch err { + case nil: + return &resp, nil + case sqlc.ErrNotFound: + return nil, ErrNotFound + default: + return nil, err + } +} + +func (m *defaultFsUserModel) Insert(ctx context.Context, data *FsUser) (sql.Result, error) { + query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, fsUserRowsExpectAutoSet) + ret, err := m.conn.ExecCtx(ctx, query, data.FaceId, data.Sub, data.FirstName, data.LastName, data.Username, data.Company, data.Mobile, data.AuthKey, data.PasswordHash, data.VerificationToken, data.PasswordResetToken, data.Email, data.Type, data.Status, data.IsDel, data.IsOrderStatusEmail, data.IsEmailAdvertisement, data.IsOrderStatusPhone, data.IsPhoneAdvertisement, data.IsOpenRender, data.IsThousandFace, data.IsLowRendering, data.IsRemoveBg) + return ret, err +} + +func (m *defaultFsUserModel) Update(ctx context.Context, newData *FsUser) error { + query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, fsUserRowsWithPlaceHolder) + _, err := m.conn.ExecCtx(ctx, query, newData.FaceId, newData.Sub, newData.FirstName, newData.LastName, newData.Username, newData.Company, newData.Mobile, newData.AuthKey, newData.PasswordHash, newData.VerificationToken, newData.PasswordResetToken, newData.Email, newData.Type, newData.Status, newData.IsDel, newData.IsOrderStatusEmail, newData.IsEmailAdvertisement, newData.IsOrderStatusPhone, newData.IsPhoneAdvertisement, newData.IsOpenRender, newData.IsThousandFace, newData.IsLowRendering, newData.IsRemoveBg, newData.Id) + return err +} + +func (m *defaultFsUserModel) tableName() string { + return m.table +} diff --git a/product/internal/handler/getproductlisthandler.go b/product/internal/handler/getproductlisthandler.go index efbe0594..22a3d962 100644 --- a/product/internal/handler/getproductlisthandler.go +++ b/product/internal/handler/getproductlisthandler.go @@ -1,6 +1,7 @@ package handler import ( + "fusenapi/utils/auth" "net/http" "fusenapi/product/internal/logic" @@ -11,14 +12,19 @@ import ( func GetProductListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { + //检测登录权限 + userInfo, err := auth.CheckAuth(r) + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + return + } var req types.GetProductListReq if err := httpx.Parse(r, &req); err != nil { httpx.ErrorCtx(r.Context(), w, err) return } - l := logic.NewGetProductListLogic(r.Context(), svcCtx) - resp, err := l.GetProductList(&req) + resp, err := l.GetProductList(&req, userInfo.UserId) if err != nil { httpx.ErrorCtx(r.Context(), w, err) } else { diff --git a/product/internal/logic/getproductlistlogic.go b/product/internal/logic/getproductlistlogic.go index b15c9e34..be15ff1c 100644 --- a/product/internal/logic/getproductlistlogic.go +++ b/product/internal/logic/getproductlistlogic.go @@ -2,6 +2,8 @@ package logic import ( "context" + "errors" + "fusenapi/model" "fusenapi/utils/image" "fusenapi/product/internal/svc" @@ -25,11 +27,19 @@ func NewGetProductListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Ge } // 获取产品列表 -func (l *GetProductListLogic) GetProductList(req *types.GetProductListReq) (resp *types.Response, err error) { +func (l *GetProductListLogic) GetProductList(req *types.GetProductListReq, uid int64) (resp *types.Response, err error) { //获取合适尺寸 if req.Size > 0 { req.Size = image.GetCurrentSize(req.Size) } //获取是否存在千人千面 + userModel := model.NewFsUserModel(l.svcCtx.MysqlConn) + userInfo, err := userModel.FindOne(l.ctx, uid) + if err != nil { + return nil, err + } + if userInfo.Id == 0 { + return nil, errors.New("user not exists") + } return } diff --git a/product/internal/svc/servicecontext.go b/product/internal/svc/servicecontext.go index d1c7fc03..0f1c06b7 100644 --- a/product/internal/svc/servicecontext.go +++ b/product/internal/svc/servicecontext.go @@ -1,19 +1,18 @@ package svc import ( - "fusenapi/model" "fusenapi/product/internal/config" "github.com/zeromicro/go-zero/core/stores/sqlx" ) type ServiceContext struct { - Config config.Config - FsProductModel model.FsProductModel + Config config.Config + MysqlConn sqlx.SqlConn } func NewServiceContext(c config.Config) *ServiceContext { return &ServiceContext{ - Config: c, - FsProductModel: model.NewFsProductModel(sqlx.NewMysql(c.DataSource)), + Config: c, + MysqlConn: sqlx.NewMysql(c.DataSource), } } diff --git a/product/product.go b/product/product.go index e5afc4c9..99047491 100644 --- a/product/product.go +++ b/product/product.go @@ -22,7 +22,6 @@ func main() { server := rest.MustNewServer(c.RestConf) defer server.Stop() - ctx := svc.NewServiceContext(c) handler.RegisterHandlers(server, ctx) diff --git a/utils/auth/auth.go b/utils/auth/auth.go new file mode 100644 index 00000000..df1e2487 --- /dev/null +++ b/utils/auth/auth.go @@ -0,0 +1,64 @@ +package auth + +import ( + "encoding/json" + "errors" + "github.com/golang-jwt/jwt" + "net/http" + "time" +) + +type UserInfo struct { + UserId int64 `json:"user_id"` +} + +// 签名key +var signKey = "FushenFGbhgfhgKgGH556HGlXrsfJKhhjYFGKLO==" +var expireTime = int64(3600) + +// 生成token +func GenJwtToken(userInfo UserInfo) (token string, err error) { + t := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ + "user_id": userInfo.UserId, + "exp": time.Now().Add(time.Second * time.Duration(expireTime)).Unix(), //过期时间 + "iss": "fusen", + }) + token, err = t.SignedString([]byte(signKey)) + if err != nil { + return "", err + } + return +} + +// 解释token +func ParseJwtToken(token string) (UserInfo, error) { + t, err := jwt.ParseWithClaims(token, jwt.MapClaims{}, func(token *jwt.Token) (interface{}, error) { + return []byte(signKey), nil + }) + if err != nil { + return UserInfo{}, err + } + d, err := json.Marshal(t.Claims) + if err != nil { + return UserInfo{}, err + } + var userInfo UserInfo + if err = json.Unmarshal(d, &userInfo); err != nil { + return UserInfo{}, err + } + return userInfo, nil +} + +// 检测授权 +func CheckAuth(r *http.Request) (UserInfo, error) { + token := r.Header.Get("Authorization") + if token == "" { + return UserInfo{}, errors.New("token is required") + } + //解析token + userInfo, err := ParseJwtToken(token) + if err != nil { + return UserInfo{}, err + } + return userInfo, nil +}