当前位置: 首页 > news >正文

北京科技网站开发手机端页面模板

北京科技网站开发,手机端页面模板,企业建立网站步骤,石家庄做网站优化公司go-zero微服务入门教程 本教程主要模拟实现用户注册和用户信息查询两个接口。 准备工作 安装基础环境 安装etcd#xff0c; mysql#xff0c;redis#xff0c;建议采用docker安装。 MySQL安装好之后#xff0c;新建数据库dsms_admin#xff0c;并新建表sys_user#…go-zero微服务入门教程 本教程主要模拟实现用户注册和用户信息查询两个接口。 准备工作 安装基础环境 安装etcd mysqlredis建议采用docker安装。 MySQL安装好之后新建数据库dsms_admin并新建表sys_user建表语句见后文。 安装插件 这里采用GoLand开发工具请自行搜索安装插件Goctl。 创建工程 这里采用开发工具GoLandFile New Project 创建api目录、rpc目录、common目录。 编写API Gateway代码 编写api文件 在api目录下创建新目录doc/sys。 在api/doc/sys下创建user.api。 user.api文件内容如下 syntax v1info(title: 用户相关desc: 用户相关author: 宋发元 )type (UserInfoResp {Code int64 json:codeMessage string json:messageData UserInfoData json:data}UserInfoData {Avatar string json:avatarName string json:nameMenuTree []*ListMenuTree json:menuTreeMenuTreeVue []*ListMenuTreeVue json:menuTreeVueResetPwd bool json:resetPwd,defaultfalse}ListMenuTree {Id int64 json:idPath string json:pathName string json:nameParentId int64 json:parentIdIcon string json:icon}ListMenuTreeVue {Id int64 json:idParentId int64 json:parentIdTitle string json:titlePath string json:pathName string json:nameIcon string json:iconVueRedirent string json:vueRedirentVueComponent string json:vueComponentMeta MenuTreeMeta json:meta}MenuTreeMeta {Title string json:titleIcon string json:icon}AddUserReq {Name string json:nameNickName string json:nickNamePassword string json:password,optionalEmail string json:emailRoleId int64 json:roleIdStatus int64 json:status,default1}AddUserResp {Code int64 json:codeMessage string json:messageData ReceiptUserData json:data}ReceiptUserData {Id int64 json:id} )server (group : sys/userprefix : /sys/user )service admin-api{doc(summary : 用户管理-获取当前用户信息)handler UserInfoget /currentUser returns (UserInfoResp)doc(summary : 用户管理-新增用户)handler UserAddpost /add(AddUserReq)returns(AddUserResp) }用goctl生成API Gateway代码 生成的文件结构如下 api ├── admin.go //main入口定义 ├── doc │ └── sys │ └── user.api //api定义文件 ├── etc │ └── admin-api.yaml //配置文件 └── internal├── config│ └── config.go //定义配置├── handler│ ├── routes.go //定义路由处理│ └── sys│ └── user│ ├── useraddhandler.go //实现addhandler│ └── userinfohandler.go //实现infohandler├── logic│ └── sys│ └── user│ ├── useraddlogic.go //实现addlogic│ └── userinfologic.go //实现infologic├── svc│ └── servicecontext.go //定义ServiceContext└── types└── types.go //定义请求、返回结构体编写rpc服务 编写sys.proto文件 在rpc下创建新目录sys。 在rpc/sys目录下创建sys.proto文件。 sys.proto文件内容如下 syntax proto3;package sysclient;option go_package ./sysclient;message InfoReq{int64 UserId 1; } message InfoResp{string avatar 1;string name 2;repeated MenuListTree menuListTree 3;repeated string backgroundUrls4;bool resetPwd5; }message MenuListTree{int64 id1;string name2;string icon3;int64 parentId4;string path5;string vuePath6;string vueComponent7;string vueIcon8;string vueRedirect9;string backgroundUrl10; }message UserAddReq{string name1;string nickName2;string password3;string email4;int64 roleId5;int64 status6;string createBy7; }message UserAddResp{int64 id1; }service Sys{rpc UserInfo(InfoReq)returns(InfoResp);rpc UserAdd(UserAddReq)returns(UserAddResp); }用goctl生成rpc代码 生成的文件结构如下 sys ├── etc │ └── sys.yaml //yaml配置文件 ├── internal │ ├── config │ │ └── config.go //yaml配置文件对应的结构体定义 │ ├── logic //业务逻辑 │ │ ├── useraddlogic.go │ │ └── userinfologic.go │ ├── server //rpc server │ │ └── sysserver.go │ └── svc //资源依赖 │ └── servicecontext.go ├── sys //rpc client call entry │ └── sys.go ├── sys.go //main函数入口 ├── sys.proto //proto源文件 └── sysclient //pb.go├── sys.pb.go└── sys_grpc.pb.go修改API Gateway代码调用rpc服务 admin-api.yaml 修改配置文件admin-api.yaml增加如下内容这里的192.168.2.204为基础环境服务器IP。 Timeout: 60000Mysql:Datasource: root:123456tcp(192.168.2.204:3306)/dsms_admin?charsetutf8mb4parseTimetruelocAsia%2FShanghaiCacheRedis:- Host: 192.168.2.204:6379Pass: qkgxChxNkCwKType: nodeRedis:Address: 192.168.2.204:6379Pass: qkgxChxNkCwKSysRpc:Timeout: 30000Etcd:Hosts:- 192.168.2.204:2379Key: sysa.rpc通过etcd自动去发现可用的rpc服务。 config.go 修改api/internal/config/config.go如下增加rpc服务依赖。 SysRpc zrpc.RpcClientConfCacheRedis cache.ClusterConfRedis struct {Address stringPass string}Mysql struct {Datasource string}servicecontext.go 修改api/internal/svc/servicecontext.go如下 type ServiceContext struct {Config config.ConfigSys sys.SysRedis *redis.Redis }func NewServiceContext(c config.Config) *ServiceContext {newRedis : redis.New(c.Redis.Address, redisConfig(c))return ServiceContext{Config: c,Sys: sys.NewSys(zrpc.MustNewClient(c.SysRpc, zrpc.WithUnaryClientInterceptor(interceptor))),Redis: newRedis,} }func redisConfig(c config.Config) redis.Option {return func(r *redis.Redis) {r.Type redis.NodeTyper.Pass c.Redis.Pass} }func interceptor(ctx context.Context, method string, req any, reply any, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {md : metadata.New(map[string]string{x: xx})ctx metadata.NewOutgoingContext(ctx, md)// logx.Debug(调用rpc服务前)err : invoker(ctx, method, req, reply, cc)if err ! nil {return err}// logx.Debug(调用rpc服务后)return nil }通过ServiceContext在不同业务逻辑之间传递依赖。 useraddlogic.go 修改api/internal/logic/useraddlogic.go里的UserAdd方法如下 func (l *UserAddLogic) UserAdd(req *types.AddUserReq) (resp *types.AddUserResp, err error) {res, err : l.svcCtx.Sys.UserAdd(l.ctx, sysclient.UserAddReq{Name: req.Name,NickName: req.NickName,Password: req.Password,Email: req.Email,RoleId: req.RoleId,Status: req.Status,//CreateBy: l.ctx.Value(cache.JwtFieldUserName).(string),CreateBy: songfayuan,})if err ! nil {reqJson, _ : json.Marshal(req)logx.WithContext(l.ctx).Errorf(添加用户信息失败请求参数%s异常信息%s, reqJson, err.Error())return nil, rpcerror.New(err)}return types.AddUserResp{Code: 200,Message: 添加用户成功,Data: types.ReceiptUserData{Id: res.Id},}, nil }userinfologic.go 修改api/internal/logic/userinfologic.go里的UserInfo方法如下 func (l *UserInfoLogic) UserInfo() (*types.UserInfoResp, error) {//这里的key和生成jwt token时传入的key一致//userId, _ : l.ctx.Value(cache.JwtFieldUserId).(json.Number).Int64()var userId int64 1resp, err : l.svcCtx.Sys.UserInfo(l.ctx, sysclient.InfoReq{UserId: userId,})if err ! nil {logx.WithContext(l.ctx).Errorf(根据userId%s, 查询用户异常%s, strconv.FormatInt(userId, 10), err.Error())return nil, rpcerror.New(err)}var MenuTree []*types.ListMenuTree//组装ant ui中的菜单for _, item : range resp.MenuListTree {MenuTree append(MenuTree, types.ListMenuTree{Id: item.Id,Path: item.Path,Name: item.Name,ParentId: item.ParentId,Icon: item.Icon,})}if MenuTree nil {MenuTree make([]*types.ListMenuTree, 0)}//组装element ui中的菜单var MenuTreeVue []*types.ListMenuTreeVuefor _, item : range resp.MenuListTree {if len(strings.TrimSpace(item.VuePath)) ! 0 {MenuTreeVue append(MenuTreeVue, types.ListMenuTreeVue{Id: item.Id,ParentId: item.ParentId,Title: item.Name,Path: item.VuePath,Name: item.Name,Icon: item.VueIcon,VueRedirent: item.VueRedirect,VueComponent: item.VueComponent,Meta: types.MenuTreeMeta{Title: item.Name,Icon: item.VueIcon,},})}}if MenuTreeVue nil {MenuTreeVue make([]*types.ListMenuTreeVue, 0)}err l.svcCtx.Redis.Set(strconv.FormatInt(userId, 10), strings.Join(resp.BackgroundUrls, ,))if err ! nil {logx.Errorf(设置用户%s, 权限到Redis异常%v, resp.Name, err)}return types.UserInfoResp{Code: 200,Message: 成功,Data: types.UserInfoData{Avatar: resp.Avatar,Name: resp.Name,MenuTree: MenuTree,MenuTreeVue: MenuTreeVue,ResetPwd: resp.ResetPwd,},}, nil }定义数据库表结构并生成CRUD代码 在rpc目录下创建model/sysmodel目录在rpc目录下创建doc/sql/sys目录。 创建sys_user.sql 在rpc/doc/sql/sys目录下编写sql文件sys_user.sql如下 -- goctl model mysql ddl -src doc/sql/sys/sys_user.sql -dir ./model/sysmodel-- ---------------------------- -- Table structure for sys_user -- ---------------------------- DROP TABLE IF EXISTS sys_user; CREATE TABLE sys_user (id bigint(20) NOT NULL AUTO_INCREMENT COMMENT 编号,name varchar(128) NOT NULL DEFAULT COMMENT 账号,nick_name varchar(128) NOT NULL DEFAULT COMMENT 名称,avatar varchar(255) NOT NULL DEFAULT COMMENT 头像,password varchar(128) NOT NULL DEFAULT COMMENT 密码,salt varchar(40) NOT NULL DEFAULT COMMENT 加密盐,email varchar(128) NOT NULL DEFAULT COMMENT 邮箱,mobile varchar(32) NOT NULL DEFAULT COMMENT 手机号,status tinyint(4) NOT NULL DEFAULT 1 COMMENT 状态 -1禁用 1正常,create_by varchar(128) NOT NULL DEFAULT COMMENT 创建人,create_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间,update_by varchar(128) NOT NULL DEFAULT COMMENT 更新人,update_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间,del_flag tinyint(4) unsigned NOT NULL DEFAULT 0 COMMENT 是否删除 1已删除 0正常,PRIMARY KEY (id),KEY name (name) USING BTREE ) ENGINEInnoDB AUTO_INCREMENT1 DEFAULT CHARSETutf8mb4 COMMENT用户管理; -- ---------------------------- -- Records of sys_user -- ---------------------------- INSERT INTO sys_user VALUES (1, admin, admin, , $2a$10$hDlSis2/3IPGNYQhFlFfK.Wmi7iH9/jr6wcN.5c.rh7fc/uUnCo4S, , admindsms.com, 13612345678, 1, admin, 2018-08-14 11:11:11, , 2023-01-04 10:17:30, 0);生成CRUD代码 方法一 通过工具生成这种方式生成带缓存的代码。本文采用方法二生成 选择代码位置。 生成的代码。 方法二采纳 在rpc路径下执行如下命令生成不带缓存的代码。 goctl model mysql ddl -src doc/sql/sys/sys_user.sql -dir ./model/sysmodel完善CRUD代码 sysusermodel.go 在model/sysmodel/sysusermodel.go文件中添加常用crud的代码完整代码如下。 package sysmodelimport (contexterrorsgithub.com/zeromicro/go-zero/core/stores/sqlxtime ) import sq github.com/Masterminds/squirrelvar _ SysUserModel (*customSysUserModel)(nil)type (// SysUserModel is an interface to be customized, add more methods here,// and implement the added methods in customSysUserModel.SysUserModel interface {sysUserModelwithSession(session sqlx.Session) SysUserModelTrans(ctx context.Context, fn func(context context.Context, session sqlx.Session) error) errorUpdateBuilder() sq.UpdateBuilderUpdateByQuery(ctx context.Context, updateBuilder sq.UpdateBuilder) errorRowBuilder() sq.SelectBuilderFindOneByQuery(ctx context.Context, rowBuilder sq.SelectBuilder) (*SysUser, error)FindRowsByQuery(ctx context.Context, rowBuilder sq.SelectBuilder, orderBy string) ([]*SysUser, error)CountBuilder(field string) sq.SelectBuilderFindCount(ctx context.Context, countBuilder sq.SelectBuilder) (int64, error)FindAll(ctx context.Context, rowBuilder sq.SelectBuilder, orderBy string) ([]*SysUserList, error)TableName() string}customSysUserModel struct {*defaultSysUserModel}SysUserList struct {Id int64 db:id // 编号Name string db:name // 账号NickName string db:nick_name // 名称Avatar string db:avatar // 头像Password string db:password // 密码Salt string db:salt // 加密盐Email string db:email // 邮箱Mobile string db:mobile // 手机号Status int64 db:status // 状态 -1禁用 1正常CreateBy string db:create_by // 创建人CreateTime time.Time db:create_time // 创建时间UpdateBy string db:update_by // 更新人UpdateTime time.Time db:update_time // 更新时间DelFlag int64 db:del_flag // 是否删除 1已删除 0正常RoleId int64 db:role_idRoleName string db:role_name} )func (m *customSysUserModel) UpdateByQuery(ctx context.Context, updateBuilder sq.UpdateBuilder) error {query, values, err : updateBuilder.Where(del_flag ?, 0).ToSql()if err ! nil {return err}_, err m.conn.ExecCtx(ctx, query, values...)return err }func (m *customSysUserModel) UpdateBuilder() sq.UpdateBuilder {return sq.Update(m.table) }func (m *customSysUserModel) Trans(ctx context.Context, fn func(context context.Context, session sqlx.Session) error) error {return m.conn.TransactCtx(ctx, func(ctx context.Context, session sqlx.Session) error {return fn(ctx, session)}) }func (m *customSysUserModel) TableName() string {return m.table }func (m *customSysUserModel) FindAll(ctx context.Context, rowBuilder sq.SelectBuilder, orderBy string) ([]*SysUserList, error) {if orderBy {rowBuilder rowBuilder.OrderBy(id AEC)} else {rowBuilder rowBuilder.OrderBy(orderBy)}query, values, err : rowBuilder.Where(del_flag ?, 0).ToSql()if err ! nil {return nil, err}var resp []*SysUserListerr m.conn.QueryRowsCtx(ctx, resp, query, values...)switch err {case nil:return resp, nilcase sqlx.ErrNotFound:return nil, errors.New(查询记录为空)default:return nil, err} }func (m *customSysUserModel) FindCount(ctx context.Context, countBuilder sq.SelectBuilder) (int64, error) {query, values, err : countBuilder.Where(del_flag ?, 0).ToSql()if err ! nil {return 0, err}var resp int64err m.conn.QueryRowCtx(ctx, resp, query, values...)switch err {case nil:return resp, nildefault:return 0, err} }func (m *customSysUserModel) CountBuilder(field string) sq.SelectBuilder {return sq.Select(COUNT( field )).From(m.table) }func (m *customSysUserModel) FindRowsByQuery(ctx context.Context, rowBuilder sq.SelectBuilder, orderBy string) ([]*SysUser, error) {if orderBy {rowBuilder rowBuilder.OrderBy(id DESC)} else {rowBuilder rowBuilder.OrderBy(orderBy)}query, values, err : rowBuilder.Where(del_flag ?, 0).ToSql()if err ! nil {return nil, err}var resp []*SysUsererr m.conn.QueryRowCtx(ctx, resp, query, values...)switch err {case nil:return resp, nilcase sqlx.ErrNotFound:return nil, errors.New(查询记录为空)default:return nil, err} }func (m *customSysUserModel) FindOneByQuery(ctx context.Context, rowBuilder sq.SelectBuilder) (*SysUser, error) {query, values, err : rowBuilder.Where(del_flag ?, 0).Limit(1).ToSql()if err ! nil {return nil, err}var resp SysUsererr m.conn.QueryRowCtx(ctx, resp, query, values...)switch err {case nil:return resp, nildefault:return nil, err} }func (m *customSysUserModel) RowBuilder() sq.SelectBuilder {return sq.Select(sysUserRows).From(m.table) }// NewSysUserModel returns a model for the database table. func NewSysUserModel(conn sqlx.SqlConn) SysUserModel {return customSysUserModel{defaultSysUserModel: newSysUserModel(conn),} }func (m *customSysUserModel) withSession(session sqlx.Session) SysUserModel {return NewSysUserModel(sqlx.NewSqlConnFromSession(session)) }修改rpc代码调用crud代码 sys.yaml 修改rpc/sys/etc/sys.yaml如下内容 Name: sys.rpc ListenOn: 0.0.0.0:8080 Timeout: 10000 Etcd:Hosts:- 192.168.2.204:2379Key: sysa.rpcMysql:Datasource: root:123456tcp(192.168.2.204:3306)/dsms_admin?charsetutf8mb4parseTimetruelocAsia%2FShanghaiCacheRedis:- Host: 192.168.2.204:6379Pass: qkgxChxNkCwKType: nodeconfig.go 修改rpc/sys/internal/config/config.go如下 type Config struct {zrpc.RpcServerConfMysql struct {Datasource string}CacheRedis cache.ClusterConf }servicecontext.go 修改rpc/sys/internal/svc/servicecontext.go如下 type ServiceContext struct {Config config.ConfigCache cache.CacheRedis *redis.RedisUserModel sysmodel.SysUserModel }func NewServiceContext(c config.Config) *ServiceContext {sqlConn : sqlx.NewMysql(c.Mysql.Datasource)ca : cache.New(c.CacheRedis, syncx.NewSingleFlight(), cache.NewStat(dc), errors.New(data not find))rConn : redis.New(c.CacheRedis[0].Host, func(r *redis.Redis) {r.Type c.CacheRedis[0].Typer.Pass c.CacheRedis[0].Pass})return ServiceContext{Config: c,Cache: ca,Redis: rConn,UserModel: sysmodel.NewSysUserModel(sqlConn),} }useraddlogic.go 修改rpc/sys/internal/logic/useraddlogic.go如下 func (l *UserAddLogic) UserAdd(in *sysclient.UserAddReq) (*sysclient.UserAddResp, error) {if in.Name {return nil, errors.New(账号不能为空)}if in.NickName {return nil, errors.New(姓名不能为空)}if in.Email {return nil, errors.New(邮箱不能为空)}//校验账号是否已存在selectBuilder : l.svcCtx.UserModel.CountBuilder(id).Where(sq.Eq{name: in.Name})count, _ : l.svcCtx.UserModel.FindCount(l.ctx, selectBuilder)if count 0 {logx.WithContext(l.ctx).Errorf(账号已存在添加失败userName %s, in.Name)return nil, errors.New(账号已存在)}if in.Password {in.Password 123456}hashedPassword, err : utils.GenerateFromPassword(in.Password)if err ! nil {return nil, errors.New(密码加密出错)}//插入数据result, err : l.svcCtx.UserModel.Insert(l.ctx, sysmodel.SysUser{Name: in.Name,NickName: in.NickName,Avatar: ,Password: hashedPassword,Salt: ,Email: in.Email,Mobile: ,Status: 0,CreateBy: in.CreateBy,UpdateTime: time.Time{},DelFlag: 0,})if err ! nil {return nil, err}insertId, err : result.LastInsertId()if err ! nil {return nil, err}return sysclient.UserAddResp{Id: insertId}, nil }userinfologic.go 修改rpc/sys/internal/logic/userinfologic.go如下 func (l *UserInfoLogic) UserInfo(in *sysclient.InfoReq) (*sysclient.InfoResp, error) {rowBuilder : l.svcCtx.UserModel.RowBuilder().Where(sq.Eq{id: in.UserId})userInfo, err : l.svcCtx.UserModel.FindOneByQuery(l.ctx, rowBuilder)switch err {case nil:case sqlx.ErrNotFound:logx.WithContext(l.ctx).Infof(用户不存在userId:%s, in.UserId)return nil, fmt.Errorf(用户不存在userId:%s, strconv.FormatInt(in.UserId, 10))default:return nil, err}//var list []*sys.MenuListTree//var listUrls []stringreturn sysclient.InfoResp{Avatar: 11111,Name: userInfo.Name,MenuListTree: nil,BackgroundUrls: nil,ResetPwd: false,}, nil }common目录 common目录下为通用工具直接拷贝进去即可。 bcrypt.go common/utils/bcrypt.go package utilsimport (bytescrypto/md5crypto/randcrypto/rsacrypto/x509encoding/base64encoding/hexencoding/pemfmtloggithub.com/tjfoc/gmsm/sm2x509g github.com/tjfoc/gmsm/x509golang.org/x/crypto/bcrypt )func GenerateFromPassword(pwd string) (hashedPassword string, err error) {password : []byte(pwd)// Hashing the password with the default cost of 10hashedPasswordBytes, err : bcrypt.GenerateFromPassword(password, bcrypt.DefaultCost)hashedPassword string(hashedPasswordBytes)return }func CompareHashAndPassword(hashedPwd, plainPwd string) bool {byteHash : []byte(hashedPwd)err : bcrypt.CompareHashAndPassword(byteHash, []byte(plainPwd))if err ! nil {return false}return true }// EncryptSm2 加密 func EncryptSm2(privateKey, content string) string {// 从十六进制导入公私钥priv, err : x509g.ReadPrivateKeyFromHex(privateKey)if err ! nil {log.Fatal(err)}// 公钥加密部分msg : []byte(content)pub : priv.PublicKeycipherTxt, err : sm2.Encrypt(pub, msg, rand.Reader, sm2.C1C2C3) // sm2加密if err ! nil {log.Fatal(err)}// fmt.Printf(加密文字:%s\n加密结果:%x\n, msg, cipherTxt)encodeRes : fmt.Sprintf(%x, cipherTxt)return encodeRes }// DecryptSm2 解密 func DecryptSm2(privateKey, encryptData string) (string, error) {// 从十六进制导入公私钥priv, err : x509g.ReadPrivateKeyFromHex(privateKey)if err ! nil {return , err}// 私钥解密部分hexData, err : hex.DecodeString(encryptData)if err ! nil {return , err}plainTxt, err : sm2.Decrypt(priv, hexData, sm2.C1C2C3) // sm2解密if err ! nil {return , err}// fmt.Printf(解密后的明文%s\n私钥%s \n 匹配一致, plainTxt, x509.WritePrivateKeyToHex(priv))return string(plainTxt), nil }// EncryptAndDecrypt 加密/解密 func EncryptAndDecrypt(privateKey, content string) {// 从十六进制导入公私钥priv, err : x509g.ReadPrivateKeyFromHex(privateKey)if err ! nil {log.Fatal(err)}// 公钥加密部分msg : []byte(content)pub : priv.PublicKeycipherTxt, err : sm2.Encrypt(pub, msg, rand.Reader, sm2.C1C2C3) // sm2加密if err ! nil {log.Fatal(err)}fmt.Printf(加密文字:%s\n加密结果:%x\n, msg, cipherTxt)// 私钥解密部分plainTxt, err : sm2.Decrypt(priv, cipherTxt, sm2.C1C2C3) // sm2解密if err ! nil {log.Fatal(err)}if !bytes.Equal(msg, plainTxt) {log.Fatal(原文不匹配:, msg)}fmt.Printf(解密后的明文%s\n私钥%s \n 匹配一致, plainTxt, x509g.WritePrivateKeyToHex(priv)) }// EncryptRSA 加密 func EncryptRSA(content, publicKey string) (encryptStr string, err error) {// var publicKey -----BEGIN PUBLIC KEY-----// MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDaIWAL13RUbJN2hfmTSyOBotf// 71pq8jc2ploPBHtN3smTUkYPbX2MIbO9TrRj3u67s/kGQZrz6tyQ68oexpukPN4/// ypzp64UA5CQENSA41ZxTpYADbFQsiX9Spv6aDHhHzUlZtWRru9ptcFO3tDKq0ACT// OAR1ZEHFwQGhzwaAowIDAQAB// -----END PUBLIC KEY-----block, _ : pem.Decode([]byte(publicKey))if block nil {return , fmt.Errorf(failed to parse public key PEM)}publicKeyInterface, err : x509.ParsePKIXPublicKey(block.Bytes)if err ! nil {return , err}// 类型断言rsaPublicKey : publicKeyInterface.(*rsa.PublicKey)// 加密数据encryptedData, err : rsa.EncryptPKCS1v15(rand.Reader, rsaPublicKey, []byte(content))if err ! nil {return , fmt.Errorf(error encrypting data:%v, err)}return base64.StdEncoding.EncodeToString(encryptedData), err}// DecryptRSA 解密 func DecryptRSA(encryptStr, privateKey string) (content string, err error) {// var privateKey -----BEGIN PRIVATE KEY-----// MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANohYAvXdFT5sk3a// FZNLI4Gi1/vWmryNzamWg8Ee03eyZNSRg9tfYwhs71OtGPe7ruzQZBmvPq3JDr// yh7Gm6Q83j/KnOnrhQDkJAQ1IDjVnFOlgANsVCyJf1Km/poMeEfNSVm1ZGu72m1w// U7e0MqrQAJM4BHVkQcXBAaHPBoCjAgMBAAECgYA/aJJN/uyvQwKlBPALn4WDJ73e// PmrvScfpGAR39xqM8WVxcOoy0Y6FRX1wupHWefWIqQSQIH1wEoM5LGzX8yflSo// lG3E0mgJzrMAOTs5FVkdN4tV6rKYq/vA9R67AD0a9nq7yOFeTqjGzWj4l7Vptvu4// prK5GWVi0mpB2kKQJBAP0n1EMAHQSW38zOngfaqC6cvnjEbX4NnhSPRZVzlu3y// ZkitiA/Y96yCCybCWD0TkF43Z1p0wIGuXSJ1Igku6bcCQQDclMziUz1RnQDl7RIN// 449vbmG2mGLoXp5HTD9QP0NB46w64WwXIX7IZL2GubndTRFUFTTPLZZ80XbhFtp6// 19B1AkEAnIgjJGaOisbrjQz5BCw8r821rKDwfu/WninUwcteOLUYb7n1Fq92vZEP// aiDjRKizLL6fRnxIiCcTaXn52KnMUwJBAJaKOxYPRx8G7tD8rcCq2H5tLTFNWNv// B8iTAfbLZiR2tFlu9S0IIBW1ox9qa63b5gKjgmoOq9C9x8swpKUH2u0CQAKDHqwh// aH6lVtV8cw55Ob8Dsh3PgFUazuM1e5PjmZku3/2jeQQJrecu/S6LooPdeUfEtV// OB/5HvFhGpEu2/E// -----END PRIVATE KEY-----block, _ : pem.Decode([]byte(privateKey))if block nil {return , fmt.Errorf(failed to parse private key PEM)}privateKeyData, err : x509.ParsePKCS8PrivateKey(block.Bytes)if err ! nil {return , err}privateKeyInterface : privateKeyData.(*rsa.PrivateKey)// 解密数据byt, err : base64.StdEncoding.DecodeString(encryptStr)if err ! nil {return , fmt.Errorf(base64 DecodeString err:%v, err)}decryptedData, err : rsa.DecryptPKCS1v15(rand.Reader, privateKeyInterface, byt)if err ! nil {return , fmt.Errorf(error decrypting data:%v, err)}return string(decryptedData), nil}func Md5(s []byte) string {m : md5.New()m.Write(s)return hex.EncodeToString(m.Sum(nil)) }code.go common/errors/code.go package errorsconst BaseCode 50000const RpcCode 51000const MustUpdatePwdCode 50005const LoginExpired 50001base.go common/errors/base.go package errorstype CommonError interface {Error() stringErrorType() stringData() *CommonErrorResp }type CommonErrorResp struct {Code int json:codeMessage string json:messageType string json:error }errorx.go common/errors/errorx/errorx.go package errorximport go-zero-test/common/errorsvar _ errors.CommonError (*ErrorX)(nil)type ErrorX struct {Code int json:codeMessage string json:messageType string json:error }func (e *ErrorX) Error() string {return e.Message }func (e *ErrorX) ErrorType() string {return e.Type }func (e *ErrorX) Data() *errors.CommonErrorResp {return errors.CommonErrorResp{Code: e.Code,Message: e.Message,Type: e.Type,} }func New(s string) error {return ErrorX{Code: errors.BaseCode, Message: s, Type: base error} }func NewCodeErr(code int, s string) error {return ErrorX{Code: code, Message: s, Type: base error} }rpcerror.go common/errors/rpcerror/rpcerror.go package rpcerrorimport go-zero-test/common/errorsvar _ errors.CommonError (*RpcError)(nil)type RpcError struct {Code int json:codeMessage string json:messageType string json:error }func (e *RpcError) Error() string {return e.Message }func (e *RpcError) ErrorType() string {return e.Type }func (e *RpcError) Data() *errors.CommonErrorResp {return errors.CommonErrorResp{Code: e.Code,Message: e.Message,Type: e.Type,} }// New rpc返回错误 func New(e error) error {msg : e.Error()[len(rpc error: code Unknown desc ):]return RpcError{Code: errors.RpcCode, Message: msg, Type: rpc error} }// NewError 返回自定义错误rpc返回错误 func NewError(s string, err error) error {msgType : err.Error()[len(rpc error: code Unknown desc ):]return RpcError{Code: errors.RpcCode, Message: s, Type: msgType} }完整调用演示 最后在根目录go-zero-test执行下命令。 go mod tidy运行rpc服务 修改路径。 之后直接启动即可。 运行api 修改路径。 之后直接启动即可。 api调用 命令请求 curl -i localhost:8888/sys/user/currentUser返回结果 HTTP/1.1 200 OK Content-Type: application/json; charsetutf-8 Traceparent: 00-7cf8f53fe7009655963024f44767cd53-67d21fe606d82a15-00 Date: Thu, 22 Feb 2024 06:27:28 GMT Content-Length: 120{code:200,message:成功,data:{avatar:11111,name:admin,menuTree:[],menuTreeVue:[],resetPwd:false}}%或者postman调用也行。 后续研发 后续新增服务、新增接口流程同编写rpc服务模块。
http://www.pierceye.com/news/455877/

相关文章:

  • 浙江联科网站建设选择宁波seo优化公司
  • 上海建站网络科技app营销策略有哪些
  • 怎么检查网站有没有被挂马知乎做笔记的网站
  • 温岭网站制作爱网站查询
  • 徐州学习网站建设影视公司组织架构
  • 怎么看别人的网站有没有做301蓝色扁平化企业网站
  • 郑州建站模板网络程序员
  • 健身顾问在哪些网站做推广北京网络推广外包公司排行
  • 天津网站开发工资水平建设网站如何写文案
  • 做a漫画在线观看网站注册个免费网站
  • 杭州网站设计网页长安东莞网站推广
  • 福州网站建设软件怎样上传自己的网站
  • wordpress手机站如何做wordpress 查询文章
  • 企业专业网站设计公wordpress打开慢
  • 网站制作方案怎么做青岛住房和城乡建设部网站
  • 织梦系统做的网站忘记登录密码百家 主题 wordpress
  • 营销推广软文婚纱摄影网站seo方案
  • 上海网站制作网站建设汶川县建设局网站
  • 东莞seo网站推广怎么做能够让网站流量大
  • 郑州网站建设做推广吗灰色关键词排名方法
  • 在线推广企业网站的方法有哪些网站推广到海外怎么做
  • 怎么用视频做网站首页php网站开发职位
  • 网站平台怎么做typecho跟wordpress
  • 网站建设找什么公司微网站建设流程
  • 如何制作数据库网站哔哩哔哩推广平台
  • 免费建立手机网站网站建设下载模板之后怎么修改
  • wordpress 网站暂停做社区生意的网站
  • 渭南做网站的公司商业网站后缀名
  • 凡科建站电话邙山网站建设
  • 哪些网站可以做ppi小程序源码什么意思