一:商城微服务简介
该商城主要包括的微服务有:购物车、首页、订单服务、支付服务、用户服务、商品服务,主要采用的是go-zero来实现
商城的思维导图如下
从以上思维导图可以看出,我们根据业务职能做如下微服务的划分:
商品服务(product) - 商品的添加、信息查询、库存管理等功能
购物车服务(cart) - 购物车的增删改查、收藏等功能
订单服务(order) - 生成订单,订单管理等功能
支付服务(pay) - 通过调用第三方支付实现支付等功能
账号服务(user) - 用户信息、实名认证、账号设置、地址管理等功能
首页服务(home) - 首页商品推荐、排行榜、限时开抢、banner等功能
每个服务都可以再分为 api 服务和 rpc 服务。
api 服务对外,可提供给 app 调用。
rpc 服务是对内的,可提供给内部 api 服务或者其他 rpc 服务调用。
整个项目的流程大致如下:
二:项目目录结构创建
二用户表设计及Model开发
CREATE TABLE `user` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户ID',
`userIdentity` varchar(255) DEFAULT '' COMMENT '用户唯一标识',
`userName` varchar(50) NOT NULL DEFAULT '' COMMENT '用户名',
`passWord` varchar(50) NOT NULL DEFAULT '' COMMENT '用户密码,MD5加密',
`userNick` varchar(100) DEFAULT '' COMMENT '用户昵称',
`userFace` varchar(255) DEFAULT '' COMMENT '用户头像地址',
`UserSex` tinyint(1) DEFAULT '0' COMMENT '用户性别:0男,1女,2保密',
`userEmail` varchar(255) DEFAULT '' COMMENT '用户邮箱',
`userPhone` varchar(20) NOT NULL DEFAULT '' COMMENT '手机号',
`loginAddress` varchar(255) DEFAULT '' COMMENT '用户登录IP地址',
`create_time` timestamp default CURRENT_TIMESTAMP not null comment '创建时间',
`update_time` timestamp default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `userName` (`userName`),
UNIQUE KEY `userPhone` (`userPhone`),
KEY `updateTime` (`updateTime`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
用户MODEL生成
把目录切换到user/model目录下,然后在终端运行如下命令
goctl model mysql ddl -src user.sql -d -dir .
运行完后在model目录会看到如下内容
三:用户RPC接口生成
1.编写proto文件
在rpc目录下建立account.proto文件
syntax = "proto3";
package account;
option go_package = "./account";
message RegisterReq{
string UserName = 1;
string PassWord = 2;
string UserNick = 3;
string UserFace = 4;
int64 UserSex = 5;
string UserEmail = 6;
}
message LoginReq{
string UserName = 1;
string PassWord = 2;
}
message CommonResply{
int64 Code = 1;
string Message = 2;
string Data = 3;
}
message UserInfoReq{
string UserIdentity = 1;
}
service user{
rpc Register(RegisterReq) returns(CommonResply);
rpc Login(LoginReq) returns(CommonResply);
rpc UserInfo(UserInfoReq) returns (CommonResply);
}
这时候在这个目录下运行这个命令
goctl rpc protoc account.proto --go_out=./types --go-grpc_out=./types --zrpc_out=. -style go-zero
就会生成相应的RPC 文件,生成后的目录如下
2.rpc配置
(1)修改rpc/etc下的account.yml增加相应的配置
(2)在internal目录下的config.go建立相应的配置
(3)在internal目录下的loginc目录编写相应接口的逻辑
登录接口的代码如下:
package logic标签:COMMENT,gozero,服务,string,DEFAULT,rpc,构建,user,商城 From: https://www.cnblogs.com/lisus2000/p/17688080.html
import (
"context"
"encoding/json"
"github.com/golang-jwt/jwt/v4"
"microshop/user/model"
"microshop/user/rpc/user"
"time"
"microshop/user/api/internal/svc"
"microshop/user/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type LoginLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LoginLogic {
return &LoginLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *LoginLogic) Login(req *types.LoginReq) (resp *types.CommonResply, err error) {
// todo: add your logic here and delete this line
cnt, cntErr := l.svcCtx.Rpc.Login(l.ctx, &user.LoginReq{
UserName: req.UserName,
PassWord: req.Password,
})
if cntErr != nil {
return nil, cntErr
}
var userData model.User
userErr := json.Unmarshal([]byte(cnt.Data), &userData)
if userErr != nil {
return nil, userErr
}
//jwt
payloads := make(map[string]any)
payloads["userIdentity"] = userData.UserIdentity
accessToken, tokenErr := l.GetToken(time.Now().Unix(), l.svcCtx.Config.Auth.AccessSecret, payloads, l.svcCtx.Config.Auth.AccessExpire)
if tokenErr != nil {
return nil, tokenErr
}
return &types.CommonResply{
Code: cnt.Code,
Message: cnt.Message,
Data: accessToken,
}, nil
}
func (l *LoginLogic) GetToken(iat int64, secretKey string, payloads map[string]any, seconds int64) (string, error) {
claims := make(jwt.MapClaims)
claims["expTime"] = iat + seconds
claims["iat"] = iat
for k, v := range payloads {
claims[k] = v
}
token := jwt.New(jwt.SigningMethodHS256)
token.Claims = claims
return token.SignedString([]byte(secretKey))
}