diff --git a/README.md b/README.md index 37dd270..b672f59 100644 --- a/README.md +++ b/README.md @@ -237,6 +237,123 @@ func NewServiceContext(c config.Config, db *gorm.DB) *ServiceContext { ``` +编辑2调用其它服务 `internal/svc/servicecontext.go`: + +```go +import ( +"fmt" +"net" +"strconv" +"sync" +"time" + +"lone-services/pkg/discovery" +"lone-services/pkg/utils" +"lone-services/services/order/internal/config" + +"github.com/zeromicro/go-zero/core/logx" +"github.com/zeromicro/go-zero/zrpc" +"gorm.io/gorm" +) + +// 缓存条目 +type rpcClientCacheEntry struct { +cli zrpc.Client +target string +expireAt time.Time +} + +const rpcClientCacheTTL = 30 * time.Second //缓存过期时间 + +var ( +rpcCacheLock sync.Mutex +rpcCache = make(map[string]*rpcClientCacheEntry) +) + +func GetRpcClient(serviceName string) (zrpc.Client, error) { +if serviceName == utils.StringEmpty { +err := fmt.Errorf("rpc serviceName is empty") +logx.Error(err) +return nil, err +} + +cacheKey := serviceName + +rpcCacheLock.Lock() +entry, ok := rpcCache[cacheKey] +if ok && time.Now().Before(entry.expireAt) { +rpcCacheLock.Unlock() +return entry.cli, nil +} +delete(rpcCache, cacheKey) +rpcCacheLock.Unlock() + +inst, err := discovery.Pick(serviceName) +if err != nil { +err = fmt.Errorf("discovery pick %s failed: %w", serviceName, err) +logx.Error(err) +return nil, err +} + +target := net.JoinHostPort(inst.IP, strconv.FormatUint(inst.Port, utils.NumberTen)) + +cli := zrpc.MustNewClient(zrpc.RpcClientConf{ +Target: target, +Timeout: utils.RpcTimeOut, //rpc调用超时5s +}) + +rpcCacheLock.Lock() +rpcCache[cacheKey] = &rpcClientCacheEntry{ +cli: cli, +target: target, +expireAt: time.Now().Add(rpcClientCacheTTL), +} +rpcCacheLock.Unlock() + +return cli, nil +} + +type ServiceContext struct { +Config config.Config +DB *gorm.DB +Prefix string + +ExpressSvcName string //服务名 +} + +func NewServiceContext(c config.Config, db *gorm.DB) *ServiceContext { +//启动仅读取配置,不建立rpc连接 多个服务就多个 +expressSvc := utils.GetConfigString("services.express") + +if expressSvc == utils.StringEmpty { +logx.Error("config services.express empty") +} + +svcCtx := &ServiceContext{ +Config: c, +DB: db, +Prefix: utils.GetConfigString("mysql.prefix"), +ExpressSvcName: expressSvc, +} + +return svcCtx +} + + +调用方法logic中 +//调用其它服务实例 +//cli, err := svc.GetRpcClient(l.svcCtx.ExpressSvcName) +//if err != nil { +// l.Logger.Errorf("get express rpc err: %v", err) +// //降级逻辑 +// return l.out(utils.ErrorInternalServer, "express"+utils.ErrorInternalServer.Msg) +//} +//expClient := express.NewExpressClient(cli.Conn()) +//res, _ := expClient.Ping(context.Background(), &express.Request{}) +//l.Logger.Error("res: %v", res) + +``` + ### 7. 接入 Docker Compose 在 `deploy/docker-compose.override.yml` 增加服务: diff --git a/deploy/apisix/lua/auth.lua b/deploy/apisix/lua/auth.lua index bea8aa3..9039569 100644 --- a/deploy/apisix/lua/auth.lua +++ b/deploy/apisix/lua/auth.lua @@ -102,8 +102,20 @@ function _M.access(conf, ctx) if json.name then ngx.req.set_header("X-User-Name", json.name) end - if json.username then - ngx.req.set_header("X-Username", json.username) + if json.store_name then + ngx.req.set_header("X-Store-Name", json.store_name) + end + if json.store_id then + ngx.req.set_header("X-Store-Id", tostring(json.store_id)) + end + if json.sale_name then + ngx.req.set_header("X-Sale-Name", json.sale_name) + end + if json.sale_id then + ngx.req.set_header("X-Sale-Id", tostring(json.sale_id)) + end + if json.group_id then + ngx.req.set_header("X-Group-Id", tostring(json.group_id)) end end diff --git a/pkg/utils/loginInfo.go b/pkg/utils/loginInfo.go index 38f4bb3..3594ec9 100644 --- a/pkg/utils/loginInfo.go +++ b/pkg/utils/loginInfo.go @@ -18,6 +18,11 @@ type UserInfo struct { UserAgent string // 完整原始ua BrowserName string // 浏览器名称 BrowserVer string // 浏览器版本 + StoreName string // 店铺名称 + StoreId int64 // 店铺id + SaleName string // 销售名称 + SaleId int64 // 销售id + GroupId int64 // 分组ID Valid bool } @@ -32,25 +37,45 @@ func GetUserFromCtx(ctx context.Context) UserInfo { ipList := md.Get("x-client-ip") userAgentList := md.Get("x-user-agent") + storeName := md.Get("x-store-name") + storeId := md.Get("x-store-id") + saleName := md.Get("x-sale-name") + saleId := md.Get("x-sale-id") + groupId := md.Get("x-group-id") + if len(refreshList) == NumberZero { refreshList = md.Get("X-Refresh") } var userInfo UserInfo - if len(uidList) > 0 { - userInfo.RawUID = uidList[0] + if len(uidList) > NumberZero { + userInfo.RawUID = uidList[NumberZero] } - if len(nameList) > 0 { - userInfo.Name = nameList[0] + if len(nameList) > NumberZero { + userInfo.Name = nameList[NumberZero] } - if len(refreshList) > 0 { - userInfo.Refresh = refreshList[0] + if len(storeName) > NumberZero { + userInfo.StoreName = storeName[NumberZero] } - - if len(ipList) > 0 { - userInfo.ClientIP = ipList[0] + if len(storeId) > NumberZero { + userInfo.StoreId, _ = strconv.ParseInt(storeId[NumberZero], NumberTen, NumberSixtyFourth) } - if len(userAgentList) > 0 { - userInfo.UserAgent = userAgentList[0] + if len(saleName) > NumberZero { + userInfo.SaleName = saleName[NumberZero] + } + if len(saleId) > NumberZero { + userInfo.SaleId, _ = strconv.ParseInt(saleId[NumberZero], NumberTen, NumberSixtyFourth) + } + if len(groupId) > NumberZero { + userInfo.GroupId, _ = strconv.ParseInt(groupId[NumberZero], NumberTen, NumberSixtyFourth) + } + if len(refreshList) > NumberZero { + userInfo.Refresh = refreshList[NumberZero] + } + if len(ipList) > NumberZero { + userInfo.ClientIP = ipList[NumberZero] + } + if len(userAgentList) > NumberZero { + userInfo.UserAgent = userAgentList[NumberZero] userInfo.UserAgent, _ = url.QueryUnescape(userInfo.UserAgent) ua := user_agent.New(userInfo.UserAgent) userInfo.BrowserName, userInfo.BrowserVer = ua.Browser() diff --git a/pkg/utils/status.go b/pkg/utils/status.go index d6b467c..46ee40f 100644 --- a/pkg/utils/status.go +++ b/pkg/utils/status.go @@ -48,10 +48,25 @@ const ( StringZero = "0" StringStatusOk = "1" StringStatusNo = "2" + + StoreAuthBind = 1 // 绑定 + StoreAuthUnBind = 2 // 解绑 + + StatusApply = 2 //申请 + StatusFirstVerify = 3 //一审 + StatusSecondVerify = 4 //二审 + StatusApplyRefuse = 5 //申请拒绝 + StatusVerifyRefuse = 6 //一审拒绝 + StatusAdminFirstVerify = 13 //一审 + StatusAdminSecondVerify = 14 //二审 + StatusAdminWaitPass = 19 //等待审核 + StatusAdminSecondRefuse = 16 //审核失败 + + RpcTimeOut = 5000 //服务连接超时时间 毫秒 ) const ( - // LoginUser 所有的登录 加上服务名:id + // Login LoginUser 所有的登录 加上服务名:id // %s 为,admin,user ,... Login = "login:service:%s:token:" LoginKey = "login:service:%s:info:" @@ -63,10 +78,11 @@ const ( ) var ( - //新使用方法 - Ok = Status{Code: 10000, Msg: "OK"} - Fail = Status{Code: 999, Msg: "fail"} - ErrorExist = Status{Code: 998, Msg: "已存在"} + // Ok 新使用方法 + Ok = Status{Code: 10000, Msg: "OK"} + Fail = Status{Code: 999, Msg: "fail"} + ErrorExist = Status{Code: 998, Msg: "已存在"} + ErrorInternalServer = Status{Code: 997, Msg: "服务错误"} ErrorParams = Status{Code: 10001, Msg: "缺少参数或传值不对"} ErrorMissingParams = Status{Code: 10001, Msg: "缺少参数"} diff --git a/rpc/express/express.pb b/rpc/express/express.pb new file mode 100644 index 0000000..e06ab43 Binary files /dev/null and b/rpc/express/express.pb differ diff --git a/rpc/express/express.proto b/rpc/express/express.proto new file mode 100644 index 0000000..a04b156 --- /dev/null +++ b/rpc/express/express.proto @@ -0,0 +1,34 @@ +syntax = "proto3"; + +package express; +option go_package="./express"; +import "google/api/annotations.proto"; + + +message Request { + string ping = 1; +} + +message Response { + int32 code = 1; + string msg = 2; + string data = 3; +} + +message EmtpyRequest { +} + +service Express { + rpc Ping(Request) returns(Response){ + option (google.api.http) = { + post: "/admin/v3/express/ping" + body: "*" + }; + }; + rpc Items(EmtpyRequest) returns(Response){ + option (google.api.http) = { + post: "/admin/v3/express/items" + body: "*" + }; + }; +} diff --git a/rpc/express/pb/express.pb.go b/rpc/express/pb/express.pb.go new file mode 100644 index 0000000..131ff5b --- /dev/null +++ b/rpc/express/pb/express.pb.go @@ -0,0 +1,233 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc v4.25.8 +// source: express/express.proto + +package express + +import ( + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Request struct { + state protoimpl.MessageState `protogen:"open.v1"` + Ping string `protobuf:"bytes,1,opt,name=ping,proto3" json:"ping,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Request) Reset() { + *x = Request{} + mi := &file_express_express_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Request) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Request) ProtoMessage() {} + +func (x *Request) ProtoReflect() protoreflect.Message { + mi := &file_express_express_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Request.ProtoReflect.Descriptor instead. +func (*Request) Descriptor() ([]byte, []int) { + return file_express_express_proto_rawDescGZIP(), []int{0} +} + +func (x *Request) GetPing() string { + if x != nil { + return x.Ping + } + return "" +} + +type Response struct { + state protoimpl.MessageState `protogen:"open.v1"` + Code int32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` + Msg string `protobuf:"bytes,2,opt,name=msg,proto3" json:"msg,omitempty"` + Data string `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Response) Reset() { + *x = Response{} + mi := &file_express_express_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Response) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Response) ProtoMessage() {} + +func (x *Response) ProtoReflect() protoreflect.Message { + mi := &file_express_express_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Response.ProtoReflect.Descriptor instead. +func (*Response) Descriptor() ([]byte, []int) { + return file_express_express_proto_rawDescGZIP(), []int{1} +} + +func (x *Response) GetCode() int32 { + if x != nil { + return x.Code + } + return 0 +} + +func (x *Response) GetMsg() string { + if x != nil { + return x.Msg + } + return "" +} + +func (x *Response) GetData() string { + if x != nil { + return x.Data + } + return "" +} + +type EmtpyRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *EmtpyRequest) Reset() { + *x = EmtpyRequest{} + mi := &file_express_express_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *EmtpyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EmtpyRequest) ProtoMessage() {} + +func (x *EmtpyRequest) ProtoReflect() protoreflect.Message { + mi := &file_express_express_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EmtpyRequest.ProtoReflect.Descriptor instead. +func (*EmtpyRequest) Descriptor() ([]byte, []int) { + return file_express_express_proto_rawDescGZIP(), []int{2} +} + +var File_express_express_proto protoreflect.FileDescriptor + +const file_express_express_proto_rawDesc = "" + + "\n" + + "\x15express/express.proto\x12\aexpress\x1a\x1cgoogle/api/annotations.proto\"\x1d\n" + + "\aRequest\x12\x12\n" + + "\x04ping\x18\x01 \x01(\tR\x04ping\"D\n" + + "\bResponse\x12\x12\n" + + "\x04code\x18\x01 \x01(\x05R\x04code\x12\x10\n" + + "\x03msg\x18\x02 \x01(\tR\x03msg\x12\x12\n" + + "\x04data\x18\x03 \x01(\tR\x04data\"\x0e\n" + + "\fEmtpyRequest2\xb0\x01\n" + + "\aExpress\x12N\n" + + "\x04Ping\x12\x10.express.Request\x1a\x11.express.Response\"!\x82\xd3\xe4\x93\x02\x1b:\x01*\"\x16/admin/v3/express/ping\x12U\n" + + "\x05Items\x12\x15.express.EmtpyRequest\x1a\x11.express.Response\"\"\x82\xd3\xe4\x93\x02\x1c:\x01*\"\x17/admin/v3/express/itemsB\vZ\t./expressb\x06proto3" + +var ( + file_express_express_proto_rawDescOnce sync.Once + file_express_express_proto_rawDescData []byte +) + +func file_express_express_proto_rawDescGZIP() []byte { + file_express_express_proto_rawDescOnce.Do(func() { + file_express_express_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_express_express_proto_rawDesc), len(file_express_express_proto_rawDesc))) + }) + return file_express_express_proto_rawDescData +} + +var file_express_express_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_express_express_proto_goTypes = []any{ + (*Request)(nil), // 0: express.Request + (*Response)(nil), // 1: express.Response + (*EmtpyRequest)(nil), // 2: express.EmtpyRequest +} +var file_express_express_proto_depIdxs = []int32{ + 0, // 0: express.Express.Ping:input_type -> express.Request + 2, // 1: express.Express.Items:input_type -> express.EmtpyRequest + 1, // 2: express.Express.Ping:output_type -> express.Response + 1, // 3: express.Express.Items:output_type -> express.Response + 2, // [2:4] is the sub-list for method output_type + 0, // [0:2] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_express_express_proto_init() } +func file_express_express_proto_init() { + if File_express_express_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_express_express_proto_rawDesc), len(file_express_express_proto_rawDesc)), + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_express_express_proto_goTypes, + DependencyIndexes: file_express_express_proto_depIdxs, + MessageInfos: file_express_express_proto_msgTypes, + }.Build() + File_express_express_proto = out.File + file_express_express_proto_goTypes = nil + file_express_express_proto_depIdxs = nil +} diff --git a/rpc/express/pb/express_grpc.pb.go b/rpc/express/pb/express_grpc.pb.go new file mode 100644 index 0000000..fd1c711 --- /dev/null +++ b/rpc/express/pb/express_grpc.pb.go @@ -0,0 +1,159 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.6.2 +// - protoc v4.25.8 +// source: express/express.proto + +package express + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + Express_Ping_FullMethodName = "/express.Express/Ping" + Express_Items_FullMethodName = "/express.Express/Items" +) + +// ExpressClient is the client API for Express service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type ExpressClient interface { + Ping(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) + Items(ctx context.Context, in *EmtpyRequest, opts ...grpc.CallOption) (*Response, error) +} + +type expressClient struct { + cc grpc.ClientConnInterface +} + +func NewExpressClient(cc grpc.ClientConnInterface) ExpressClient { + return &expressClient{cc} +} + +func (c *expressClient) Ping(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(Response) + err := c.cc.Invoke(ctx, Express_Ping_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *expressClient) Items(ctx context.Context, in *EmtpyRequest, opts ...grpc.CallOption) (*Response, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(Response) + err := c.cc.Invoke(ctx, Express_Items_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ExpressServer is the server API for Express service. +// All implementations must embed UnimplementedExpressServer +// for forward compatibility. +type ExpressServer interface { + Ping(context.Context, *Request) (*Response, error) + Items(context.Context, *EmtpyRequest) (*Response, error) + mustEmbedUnimplementedExpressServer() +} + +// UnimplementedExpressServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedExpressServer struct{} + +func (UnimplementedExpressServer) Ping(context.Context, *Request) (*Response, error) { + return nil, status.Error(codes.Unimplemented, "method Ping not implemented") +} +func (UnimplementedExpressServer) Items(context.Context, *EmtpyRequest) (*Response, error) { + return nil, status.Error(codes.Unimplemented, "method Items not implemented") +} +func (UnimplementedExpressServer) mustEmbedUnimplementedExpressServer() {} +func (UnimplementedExpressServer) testEmbeddedByValue() {} + +// UnsafeExpressServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ExpressServer will +// result in compilation errors. +type UnsafeExpressServer interface { + mustEmbedUnimplementedExpressServer() +} + +func RegisterExpressServer(s grpc.ServiceRegistrar, srv ExpressServer) { + // If the following call panics, it indicates UnimplementedExpressServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&Express_ServiceDesc, srv) +} + +func _Express_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Request) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ExpressServer).Ping(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Express_Ping_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ExpressServer).Ping(ctx, req.(*Request)) + } + return interceptor(ctx, in, info, handler) +} + +func _Express_Items_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(EmtpyRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ExpressServer).Items(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Express_Items_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ExpressServer).Items(ctx, req.(*EmtpyRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// Express_ServiceDesc is the grpc.ServiceDesc for Express service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Express_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "express.Express", + HandlerType: (*ExpressServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Ping", + Handler: _Express_Ping_Handler, + }, + { + MethodName: "Items", + Handler: _Express_Items_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "express/express.proto", +} diff --git a/rpc/order/order.pb b/rpc/order/order.pb index 2beb57e..0b586a2 100644 Binary files a/rpc/order/order.pb and b/rpc/order/order.pb differ diff --git a/rpc/order/order.proto b/rpc/order/order.proto index 8ef430f..99d98f6 100644 --- a/rpc/order/order.proto +++ b/rpc/order/order.proto @@ -37,6 +37,7 @@ message EditAddressRequest { string district_ids = 5; bool default = 6; int64 id = 7; + int32 type = 8; } message StatusAddressRequest { diff --git a/rpc/order/pb/order.pb.go b/rpc/order/pb/order.pb.go index abc4474..2907376 100644 --- a/rpc/order/pb/order.pb.go +++ b/rpc/order/pb/order.pb.go @@ -251,6 +251,7 @@ type EditAddressRequest struct { DistrictIds string `protobuf:"bytes,5,opt,name=district_ids,json=districtIds,proto3" json:"district_ids,omitempty"` Default bool `protobuf:"varint,6,opt,name=default,proto3" json:"default,omitempty"` Id int64 `protobuf:"varint,7,opt,name=id,proto3" json:"id,omitempty"` + Type int32 `protobuf:"varint,8,opt,name=type,proto3" json:"type,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -334,6 +335,13 @@ func (x *EditAddressRequest) GetId() int64 { return 0 } +func (x *EditAddressRequest) GetType() int32 { + if x != nil { + return x.Type + } + return 0 +} + type StatusAddressRequest struct { state protoimpl.MessageState `protogen:"open.v1"` Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` @@ -805,7 +813,7 @@ const file_order_order_proto_rawDesc = "" + "\x12CreateOrderRequest\x12\x1d\n" + "\n" + "address_id\x18\x01 \x01(\x03R\taddressId\x12\x12\n" + - "\x04note\x18\x02 \x01(\tR\x04note\"\xc3\x01\n" + + "\x04note\x18\x02 \x01(\tR\x04note\"\xd7\x01\n" + "\x12EditAddressRequest\x12\x1a\n" + "\bdistrict\x18\x01 \x01(\tR\bdistrict\x12\x18\n" + "\aaddress\x18\x02 \x01(\tR\aaddress\x12\x12\n" + @@ -813,7 +821,8 @@ const file_order_order_proto_rawDesc = "" + "\x06mobile\x18\x04 \x01(\tR\x06mobile\x12!\n" + "\fdistrict_ids\x18\x05 \x01(\tR\vdistrictIds\x12\x18\n" + "\adefault\x18\x06 \x01(\bR\adefault\x12\x0e\n" + - "\x02id\x18\a \x01(\x03R\x02id\">\n" + + "\x02id\x18\a \x01(\x03R\x02id\x12\x12\n" + + "\x04type\x18\b \x01(\x05R\x04type\">\n" + "\x14StatusAddressRequest\x12\x0e\n" + "\x02id\x18\x01 \x01(\x03R\x02id\x12\x16\n" + "\x06status\x18\x02 \x01(\x05R\x06status\"\x0e\n" + diff --git a/services/admin/internal/config/config.go b/services/admin/internal/config/config.go index 724c850..a1979dd 100644 --- a/services/admin/internal/config/config.go +++ b/services/admin/internal/config/config.go @@ -1,10 +1,7 @@ package config -import "github.com/zeromicro/go-zero/zrpc" - type Config struct { - Nacos NacosConf - LonelogRpc zrpc.RpcClientConf + Nacos NacosConf } type NacosConf struct { diff --git a/services/express/.gitignore b/services/express/.gitignore new file mode 100644 index 0000000..b16af82 --- /dev/null +++ b/services/express/.gitignore @@ -0,0 +1,3 @@ +run.toml +tmp +etc/express.yaml \ No newline at end of file diff --git a/services/express/express.go b/services/express/express.go new file mode 100644 index 0000000..1a5dd28 --- /dev/null +++ b/services/express/express.go @@ -0,0 +1,158 @@ +package main + +import ( + "flag" + "lone-services/pkg/discovery" + "lone-services/pkg/modelbase" + "lone-services/pkg/mysql" + "lone-services/pkg/redis" + "lone-services/pkg/utils" + "lone-services/pkg/validate" + express "lone-services/rpc/express/pb" + "lone-services/services/express/internal/config" + "lone-services/services/express/internal/server" + "lone-services/services/express/internal/svc" + "net" + "os" + "strconv" + + "github.com/zeromicro/go-zero/core/conf" + "github.com/zeromicro/go-zero/core/logx" + "github.com/zeromicro/go-zero/core/service" + "github.com/zeromicro/go-zero/zrpc" + "google.golang.org/grpc" + "google.golang.org/grpc/reflection" +) + +var configFile = flag.String("f", "etc/express.yaml", "the config file") + +func main() { + flag.Parse() + var c config.Config + conf.MustLoad(*configFile, &c) + + // Nacos配置拉取初始化 + nacosParam := utils.NacosConfig{ + Hosts: c.Nacos.Hosts, + NamespaceId: c.Nacos.NamespaceId, + Group: c.Nacos.Group, + ConfigID: c.Nacos.ConfigID, + } + utils.InitConfig(nacosParam) + + // 日志配置 + logConf := logx.LogConf{ + ServiceName: utils.GetConfigString("log.serviceName"), + Mode: utils.GetConfigString("log.mode"), + Encoding: utils.GetConfigString("log.encoding"), + Level: utils.GetConfigString("log.level"), + Path: utils.GetConfigString("log.path"), + KeepDays: utils.GetConfigInt("log.keepDays"), + MaxSize: utils.GetConfigInt("log.maxSize"), + MaxBackups: utils.GetConfigInt("log.maxBackups"), + Compress: utils.GetConfigBool("log.compress"), + } + logx.SetUp(logConf) + logx.AddWriter(logx.NewWriter(os.Stdout)) + + listenOn := utils.GetConfigString("base.listenOn") + mode := utils.GetConfigString("base.mode") + serviceName := utils.GetConfigString("base.name") + + // 初始化服务发现 + if err := discovery.Init(discovery.Config{ + Hosts: c.Nacos.Hosts, + NamespaceId: c.Nacos.NamespaceId, + Group: c.Nacos.Group, + }); err != nil { + logx.Errorf("nacos init: %v", err) + os.Exit(1) + } + + port, err := listenPort(listenOn) + if err != nil { + logx.Errorf("parse ListenOn: %v", err) + os.Exit(1) + } + + // 注册服务 + if err := discovery.Register(discovery.Instance{ + ServiceName: serviceName, + IP: c.Nacos.RegisterIP, + Port: port, + Group: c.Nacos.Group, + }); err != nil { + logx.Errorf("nacos register: %v", err) + os.Exit(1) + } + logx.Infof("服务注册成功: %s:%d", c.Nacos.RegisterIP, port) + + defer func() { + if err := discovery.Deregister(); err != nil { + logx.Errorf("nacos deregister: %v", err) + } + }() + + // 初始化MySQL + db, err := mysql.New(mysql.Config{ + Host: utils.GetConfigString("mysql.host"), + Port: utils.GetConfigInt("mysql.port"), + User: utils.GetConfigString("mysql.user"), + Password: utils.GetConfigString("mysql.password"), + Database: utils.GetConfigString("mysql.database"), + Charset: utils.GetConfigString("mysql.charset"), + Prefix: utils.GetConfigString("mysql.prefix"), + ReadHost: utils.GetConfigString("mysql_read.host"), + ReadPort: utils.GetConfigInt("mysql_read.port"), + ReadUser: utils.GetConfigString("mysql_read.user"), + ReadPassword: utils.GetConfigString("mysql_read.password"), + ReadDatabase: utils.GetConfigString("mysql_read.database"), + }) + if err != nil { + logx.Errorf("mysql init: %v", err) + os.Exit(1) + } + + // 初始化Redis + if err := redis.Init(redis.Config{ + Host: utils.GetConfigString("redis.host"), + Port: utils.GetConfigInt("redis.port"), + Password: utils.GetConfigString("redis.password"), + DB: utils.GetConfigInt("redis.db"), + }); err != nil { + logx.Errorf("redis init: %v", err) + os.Exit(1) + } + + debug := utils.GetConfigBool("mysql.debug") + modelbase.Init(db, modelbase.Config{Prefix: utils.GetConfigString("mysql.prefix"), Debug: debug}) + + // 初始化服务信息 + rpcConf := zrpc.RpcServerConf{ + ListenOn: listenOn, + } + rpcConf.Mode = mode + ctx := svc.NewServiceContext(c, db) + + s := zrpc.MustNewServer(rpcConf, func(grpcServer *grpc.Server) { + express.RegisterExpressServer(grpcServer, server.NewExpressServer(ctx)) + if mode == service.DevMode || mode == service.TestMode { + reflection.Register(grpcServer) + } + }) + defer s.Stop() + + s.AddUnaryInterceptors(validate.UnaryServerInterceptor(validate.MustNew())) + + logx.Infof("Starting rpc server at %s...", listenOn) + s.Start() +} + +// listenPort 拆分端口 +func listenPort(listenOn string) (uint64, error) { + _, portStr, err := net.SplitHostPort(listenOn) + if err != nil { + return utils.NumberZero, err + } + return strconv.ParseUint(portStr, utils.NumberTen, utils.NumberSixtyFourth) +} diff --git a/services/express/expressclient/express.go b/services/express/expressclient/express.go new file mode 100644 index 0000000..263ce84 --- /dev/null +++ b/services/express/expressclient/express.go @@ -0,0 +1,45 @@ +// Code generated by goctl. DO NOT EDIT. +// goctl 1.10.2 +// Source: express.proto + +package expressClient + +import ( + "context" + + "lone-services/rpc/express/pb" + + "github.com/zeromicro/go-zero/zrpc" + "google.golang.org/grpc" +) + +type ( + EmtpyRequest = express.EmtpyRequest + Request = express.Request + Response = express.Response + + Express interface { + Ping(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) + Items(ctx context.Context, in *EmtpyRequest, opts ...grpc.CallOption) (*Response, error) + } + + defaultExpress struct { + cli zrpc.Client + } +) + +func NewExpress(cli zrpc.Client) Express { + return &defaultExpress{ + cli: cli, + } +} + +func (m *defaultExpress) Ping(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) { + client := express.NewExpressClient(m.cli.Conn()) + return client.Ping(ctx, in, opts...) +} + +func (m *defaultExpress) Items(ctx context.Context, in *EmtpyRequest, opts ...grpc.CallOption) (*Response, error) { + client := express.NewExpressClient(m.cli.Conn()) + return client.Items(ctx, in, opts...) +} diff --git a/services/express/internal/config/config.go b/services/express/internal/config/config.go new file mode 100644 index 0000000..a1979dd --- /dev/null +++ b/services/express/internal/config/config.go @@ -0,0 +1,13 @@ +package config + +type Config struct { + Nacos NacosConf +} + +type NacosConf struct { + Hosts []string + NamespaceId string `json:",optional"` + Group string `json:",optional"` + RegisterIP string `json:",optional"` + ConfigID string `json:",optional"` +} diff --git a/services/express/internal/logic/base.go b/services/express/internal/logic/base.go new file mode 100644 index 0000000..cbd496c --- /dev/null +++ b/services/express/internal/logic/base.go @@ -0,0 +1,44 @@ +package logic + +import ( + "lone-services/pkg/utils" + "lone-services/pkg/validate" + express "lone-services/rpc/express/pb" + "reflect" + + jsoniter "github.com/json-iterator/go" +) + +type BaseLogic struct { +} + +func (l *BaseLogic) checkParams(in interface{}, v validate.IValidator) *express.Response { + rv := reflect.ValueOf(in) + if rv.Kind() != reflect.Ptr || rv.IsNil() { + return &express.Response{ + Code: utils.ErrorParams.Code, + Msg: "request must be non‑nil proto pointer", + } + } + + resp := validate.ValidateFromProto(in, v) + if resp != utils.StringEmpty { + return &express.Response{ + Code: utils.ErrorParams.Code, + Msg: resp, + } + } + return nil +} + +func (l *BaseLogic) fail(status utils.Status) (*express.Response, error) { + return l.out(status, status.Msg) +} +func (l *BaseLogic) out(status utils.Status, msg string) (*express.Response, error) { + return &express.Response{Code: status.Code, Msg: msg}, nil +} + +func (l *BaseLogic) ok(data any) (*express.Response, error) { + buf, _ := jsoniter.Marshal(data) + return &express.Response{Code: utils.Ok.Code, Msg: utils.Ok.Msg, Data: string(buf)}, nil +} diff --git a/services/express/internal/logic/itemsLogic.go b/services/express/internal/logic/itemsLogic.go new file mode 100644 index 0000000..01d7980 --- /dev/null +++ b/services/express/internal/logic/itemsLogic.go @@ -0,0 +1,30 @@ +package logic + +import ( + "context" + + "lone-services/rpc/express/pb" + "lone-services/services/express/internal/svc" + + "github.com/zeromicro/go-zero/core/logx" +) + +type ItemsLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewItemsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ItemsLogic { + return &ItemsLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *ItemsLogic) Items(in *express.EmtpyRequest) (*express.Response, error) { + // todo: add your logic here and delete this line + + return &express.Response{}, nil +} diff --git a/services/express/internal/logic/pinglogic.go b/services/express/internal/logic/pinglogic.go new file mode 100644 index 0000000..ef3efb3 --- /dev/null +++ b/services/express/internal/logic/pinglogic.go @@ -0,0 +1,31 @@ +package logic + +import ( + "context" + express "lone-services/rpc/express/pb" + + "lone-services/services/express/internal/svc" + + "github.com/zeromicro/go-zero/core/logx" +) + +type PingLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger + BaseLogic +} + +func NewPingLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PingLogic { + return &PingLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *PingLogic) Ping(in *express.Request) (*express.Response, error) { + // todo: add your logic here and delete this line + + return l.ok("this is a test") +} diff --git a/services/express/internal/server/expressServer.go b/services/express/internal/server/expressServer.go new file mode 100644 index 0000000..1f51ebe --- /dev/null +++ b/services/express/internal/server/expressServer.go @@ -0,0 +1,34 @@ +// Code generated by goctl. DO NOT EDIT. +// goctl 1.10.2 +// Source: express.proto + +package server + +import ( + "context" + + "lone-services/rpc/express/pb" + "lone-services/services/express/internal/logic" + "lone-services/services/express/internal/svc" +) + +type ExpressServer struct { + svcCtx *svc.ServiceContext + express.UnimplementedExpressServer +} + +func NewExpressServer(svcCtx *svc.ServiceContext) *ExpressServer { + return &ExpressServer{ + svcCtx: svcCtx, + } +} + +func (s *ExpressServer) Ping(ctx context.Context, in *express.Request) (*express.Response, error) { + l := logic.NewPingLogic(ctx, s.svcCtx) + return l.Ping(in) +} + +func (s *ExpressServer) Items(ctx context.Context, in *express.EmtpyRequest) (*express.Response, error) { + l := logic.NewItemsLogic(ctx, s.svcCtx) + return l.Items(in) +} diff --git a/services/express/internal/svc/servicecontext.go b/services/express/internal/svc/servicecontext.go new file mode 100644 index 0000000..be0d50e --- /dev/null +++ b/services/express/internal/svc/servicecontext.go @@ -0,0 +1,23 @@ +package svc + +import ( + "lone-services/pkg/utils" + "lone-services/services/express/internal/config" + + "gorm.io/gorm" +) + +type ServiceContext struct { + Config config.Config + DB *gorm.DB + Prefix string +} + +func NewServiceContext(c config.Config, db *gorm.DB) *ServiceContext { + + return &ServiceContext{ + Config: c, + DB: db, + Prefix: utils.GetConfigString("mysql.prefix"), + } +} diff --git a/services/order/internal/dao/address.go b/services/order/internal/dao/address.go new file mode 100644 index 0000000..4c40b7b --- /dev/null +++ b/services/order/internal/dao/address.go @@ -0,0 +1,25 @@ +package dao + +const DeliveryAddressDefaultYes = 1 //默认 +const DeliveryAddressDefaultNo = 2 //不默认 +const DeliveryAddressTypeStore = 1 + +type Address struct { + Id int64 `json:"id" gorm:"id"` + TargetId int64 `json:"target_id" gorm:"target_id"` // 对象ID + District string `json:"district" gorm:"district"` // 地区 + DistrictIds string `json:"district_ids" gorm:"district_ids"` // 地区IDS + Default int32 `json:"default" gorm:"default"` // 默认:1为默认,2为不默认 + Address string `json:"address" gorm:"address"` // 地址 + SaleId int64 `json:"sale_id" gorm:"sale_id"` // 销售ID + GroupId int64 `json:"group_id" gorm:"group_id"` // 分组ID + Name string `json:"name" gorm:"name"` // 收货人姓名 + Mobile string `json:"mobile" gorm:"mobile"` // 收货人手机 + Type int32 `json:"type" gorm:"type"` // 类型 1门店 , 2销售,3为用户 + Status int32 `json:"status" gorm:"status"` // 状态,1是正常,2为申请,3为一审核,4为二审核中,5为拒绝申请,6为审核失败,7为删除 + Reason string `json:"reason" gorm:"reason"` + NewContent string `json:"new_content" gorm:"new_content"` // 编辑后的内容 + TypeName string `json:"type_name" gorm:"type_name"` // 类型名 + AdminId int64 `json:"admin_id" gorm:"admin_id"` + AdminName string `json:"admin_name" gorm:"admin_name"` +} diff --git a/services/order/internal/dao/cart.go b/services/order/internal/dao/cart.go new file mode 100644 index 0000000..c18931a --- /dev/null +++ b/services/order/internal/dao/cart.go @@ -0,0 +1,10 @@ +package dao + +type Cart struct { + Id int64 `json:"id" gorm:"id"` + Content string `json:"content" gorm:"content"` // 内容 + StoreId int64 `json:"store_id" gorm:"store_id"` // 门店ID + SaleId int64 `json:"sale_id" gorm:"sale_id"` // 销售ID + Type bool `json:"type" gorm:"type"` // 类型,1为门店添加,2为销售添加 + UserId int64 `json:"user_id" gorm:"user_id"` // 用户ID +} diff --git a/services/order/internal/dao/order.go b/services/order/internal/dao/order.go new file mode 100644 index 0000000..aab1a6f --- /dev/null +++ b/services/order/internal/dao/order.go @@ -0,0 +1,223 @@ +package dao + +import ( + "lone-services/pkg/utils" +) + +const ( + OrderPayTypeWechat = 1 //微信 + OrderPayTypeAlipay = 2 //支付宝 + OrderPayTypeRemaining = 3 //余额 + + OrderPayStatusOk = 1 //为已支付 + OrderPayStatusWait = 2 //为未支付 + OrderPayStatusIn = 3 //为支付中 + OrderPayStatusFail = 4 //支付失败 + OrderPayStatusLose = 5 //已失效 + + OrderTypeSale = 1 //销售 + OrderTypeStore = 2 //为门店 + OrderTypePersonal = 3 //为个人 + OrderTypeHome = 4 //为个人家庭试用 +) + +type OrderCreate struct { + Id int64 `gorm:"column:id;type:bigint(20);primary_key;AUTO_INCREMENT" json:"id"` + OrderSn string `gorm:"column:ordersn;type:varchar(100);comment:订单号;NOT NULL" json:"ordersn"` + StoreId int `gorm:"column:store_id;type:int(11);comment:美容院关联ID号" json:"store_id"` + StoreName string `gorm:"column:store_name;type:varchar(50);comment:门店名" json:"store_name"` + SaleName string `gorm:"column:sale_name;type:varchar(50);comment:销售姓名" json:"sale_name"` + SaleMobile string `gorm:"column:sale_mobile;type:char(60);comment:销售电话" json:"sale_mobile"` + SaleProvince int `gorm:"column:sale_province;type:int(11);default:0;comment:销售到的地域" json:"sale_province"` + UserId int `gorm:"column:user_id;type:int(11);comment:用户ID" json:"user_id"` + UserName string `gorm:"column:user_name;type:varchar(255);comment:用户名" json:"user_name"` + SaleId int `gorm:"column:sale_id;type:int(11);comment:销售员ID号" json:"sale_id"` + Mobile string `gorm:"column:mobile;type:char(60);comment:收货人手机号;NOT NULL" json:"mobile"` + Address string `gorm:"column:address;type:varchar(255);comment:收货人地址;NOT NULL" json:"address"` + Addressee string `gorm:"column:addressee;type:varchar(50);comment:收货人姓名;NOT NULL" json:"addressee"` + DistrictIds string `gorm:"column:district_ids;type:varchar(255);comment:地区IDS;NOT NULL" json:"district_ids"` + TotalPrice float64 `gorm:"column:total_price;type:decimal(10,2);comment:总价;NOT NULL" json:"total_price"` + GroupId int `gorm:"column:group_id;type:int(11);default:0" json:"group_id"` + PayPrice float64 `gorm:"column:pay_price;type:decimal(10,2);comment:实际支付金额" json:"pay_price"` + PayType uint8 `gorm:"column:pay_type;type:tinyint(1);default:1;comment:支付类型,1为微信,2为支付宝,3为余额支付" json:"pay_type"` + Status uint8 `gorm:"column:status;type:tinyint(1);default:2;comment:支付状态,1为已支付,2为未支付,3为支付中,4支付失败,5已失效;NOT NULL" json:"status"` + IsSupply uint8 `gorm:"column:is_supply;type:tinyint(1);default:1;comment:是否补过货,1为没有,2为补过" json:"is_supply"` + Note string `gorm:"column:note;type:varchar(255);comment:备注" json:"note"` + VerifyStatus uint8 `gorm:"column:verify_status;type:tinyint(1);default:0;comment:审核状态,1为通过,2为失败,3为待审核,0为正常订单不需要审核" json:"verify_status"` + ProductIds string `gorm:"column:product_ids;type:varchar(150);comment:产品IDs" json:"product_ids"` + Type uint8 `gorm:"column:type;type:tinyint(1);default:0;comment:类型 1 销售,2为门店,3为个人,4为个人家庭试用,5为个人门店试用" json:"type"` +} + +type OrderInfo struct { + Id int64 `gorm:"column:id;type:bigint(20);primary_key;AUTO_INCREMENT" json:"id"` + OrderSn string `gorm:"column:ordersn;type:varchar(100);comment:订单号;NOT NULL" json:"ordersn"` + StoreId int `gorm:"column:store_id;type:int(11);comment:美容院关联ID号" json:"store_id"` + StoreName string `gorm:"column:store_name;type:varchar(50);comment:门店名" json:"store_name"` + SaleName string `gorm:"column:sale_name;type:varchar(50);comment:销售姓名" json:"sale_name"` + SaleMobile string `gorm:"column:sale_mobile;type:char(60);comment:销售电话" json:"sale_mobile"` + UserId int `gorm:"column:user_id;type:int(11);comment:用户ID" json:"user_id"` + UserName string `gorm:"column:user_name;type:varchar(255);comment:用户名" json:"user_name"` + SaleId int `gorm:"column:sale_id;type:int(11);comment:销售员ID号" json:"sale_id"` + Mobile string `gorm:"column:mobile;type:char(60);comment:收货人手机号;NOT NULL" json:"mobile"` + Address string `gorm:"column:address;type:varchar(255);comment:收货人地址;NOT NULL" json:"address"` + Addressee string `gorm:"column:addressee;type:varchar(50);comment:收货人姓名;NOT NULL" json:"addressee"` + DistrictIds string `gorm:"column:district_ids;type:varchar(255);comment:地区IDS;NOT NULL" json:"district_ids"` + TotalPrice float64 `gorm:"column:total_price;type:decimal(10,2);comment:总价;NOT NULL" json:"total_price"` + PayPrice float64 `gorm:"column:pay_price;type:decimal(10,2);comment:实际支付金额" json:"pay_price"` + PayType uint8 `gorm:"column:pay_type;type:tinyint(1);default:1;comment:支付类型,1为微信,2为支付宝,3为余额支付" json:"pay_type"` + DeliverStatus uint8 `gorm:"column:deliver_status;type:tinyint(1);default:2;comment:发货状态,1为已签收,2为待发货,3为发货中,4为已发货" json:"deliver_status"` + Status uint8 `gorm:"column:status;type:tinyint(1);default:2;comment:支付状态,1为已支付,2为未支付,3为支付中,4支付失败,5已失效;NOT NULL" json:"status"` + IsSupply uint8 `gorm:"column:is_supply;type:tinyint(1);default:1;comment:是否补过货,1为没有,2为补过" json:"is_supply"` + Note string `gorm:"column:note;type:varchar(255);comment:备注" json:"note"` + ProductIds string `gorm:"column:product_ids;type:varchar(150);comment:产品IDs" json:"product_ids"` + OutTradeNo string `gorm:"column:out_trade_no;type:varchar(50);comment:支付订单号" json:"out_trade_no"` + OldAddress string `gorm:"column:old_address;type:varchar(255);comment:老的收发货信息,如果有这个就表明是修改过收货地址" json:"old_address"` + Type uint8 `gorm:"column:type;type:tinyint(1);default:0;comment:类型 1 销售,2为门店,3为个人,4为个人家庭试用,5为个人门店试用" json:"type"` + SignTime utils.CustomTime `gorm:"column:sign_time;type:datetime;comment:签收时间" json:"sign_time"` + CreateType uint8 `gorm:"column:create_type;type:tinyint(1);default:1;comment:下单人类型,1为销售,2为门店,3为个人;NOT NULL" json:"create_type"` + CreateTime utils.CustomTime `gorm:"column:create_time;type:datetime;default:CURRENT_TIMESTAMP;comment:订单创建时间" json:"create_time"` + ProductItems []OrderProducts `gorm:"-" json:"product_items"` + RefundStatus uint8 `gorm:"column:refund_status" json:"refund_status"` + AesMobile string `gorm:"-" json:"aes_mobile"` + OriginalMobile string `gorm:"-" json:"original_mobile,omitempty"` +} + +type OrderPay struct { + Id int64 `gorm:"column:id;type:bigint(20);primary_key;AUTO_INCREMENT" json:"id"` + TotalPrice float64 `gorm:"column:total_price;type:decimal(10,2);comment:总价;NOT NULL" json:"total_price"` + OrderSn string `gorm:"column:ordersn;type:varchar(100);comment:订单号;NOT NULL" json:"ordersn"` + PayPrice float64 `gorm:"column:pay_price;type:decimal(10,2);comment:实际支付金额" json:"pay_price"` + PayType uint8 `gorm:"column:pay_type;type:tinyint(1);default:1;comment:支付类型,1为微信,2为支付宝,3为余额支付" json:"pay_type"` + DistrictIds string `gorm:"column:district_ids;type:varchar(255);comment:地区IDS;NOT NULL" json:"district_ids"` + GroupId int `gorm:"column:group_id;type:int(11);default:0;comment:分组ID" json:"group_id"` + Status uint8 `gorm:"column:status;type:tinyint(1);default:2;comment:支付状态,1为已支付,2为未支付,3为支付中,4支付失败,5已失效;NOT NULL" json:"status"` + Mobile string `gorm:"column:mobile;type:char(60);comment:收货人手机号;NOT NULL" json:"mobile"` + Address string `gorm:"column:address;type:varchar(255);comment:收货人地址;NOT NULL" json:"address"` + Addressee string `gorm:"column:addressee;type:varchar(50);comment:收货人姓名;NOT NULL" json:"addressee"` + OutTradeNo string `gorm:"column:out_trade_no;type:varchar(50);comment:支付订单号;NOT NULL" json:"out_trade_no"` +} + +type OrderDown struct { + Id int64 `gorm:"column:id;type:bigint(20);primary_key;AUTO_INCREMENT" json:"id"` + OrderSn string `gorm:"column:ordersn;type:varchar(100);comment:订单号;NOT NULL" json:"ordersn"` + StoreId int `gorm:"column:store_id;type:int(11);comment:美容院关联ID号" json:"store_id"` + StoreName string `gorm:"column:store_name;type:varchar(50);comment:门店名" json:"store_name"` + SaleName string `gorm:"column:sale_name;type:varchar(50);comment:销售姓名" json:"sale_name"` + SaleMobile string `gorm:"column:sale_mobile;type:char(60);comment:销售电话" json:"sale_mobile"` + SaleId int `gorm:"column:sale_id;type:int(11);comment:销售员ID号" json:"sale_id"` + Mobile string `gorm:"column:mobile;type:char(60);comment:收货人手机号;NOT NULL" json:"mobile"` + Address string `gorm:"column:address;type:varchar(255);comment:收货人地址;NOT NULL" json:"address"` + Addressee string `gorm:"column:addressee;type:varchar(50);comment:收货人姓名;NOT NULL" json:"addressee"` + DistrictIds string `gorm:"column:district_ids;type:varchar(255);comment:地区IDS;NOT NULL" json:"district_ids"` + TotalPrice float64 `gorm:"column:total_price;type:decimal(10,2);comment:总价;NOT NULL" json:"total_price"` + PayPrice float64 `gorm:"column:pay_price;type:decimal(10,2);comment:实际支付金额" json:"pay_price"` + PayType uint8 `gorm:"column:pay_type;type:tinyint(1);default:1;comment:支付类型,1为微信,2为支付宝,3为余额支付" json:"pay_type"` + Status uint8 `gorm:"column:status;type:tinyint(1);default:2;comment:支付状态,1为已支付,2为未支付,3为支付中,4支付失败,5已失效;NOT NULL" json:"status"` + ProductIds string `gorm:"column:product_ids;type:varchar(150);comment:产品IDs" json:"product_ids"` + SignTime utils.CustomTime `gorm:"column:sign_time;type:datetime;comment:签收时间" json:"sign_time"` + CreateType uint8 `gorm:"column:create_type;type:tinyint(1);default:1;comment:下单人类型,1为销售,2为门店,3为个人;NOT NULL" json:"create_type"` + CreateTime utils.CustomTime `gorm:"column:create_time;type:datetime;default:CURRENT_TIMESTAMP;comment:订单创建时间" json:"create_time"` + ProductName string `gorm:"-" json:"product_name"` + TypeName string `gorm:"-" json:"type_name"` + BankInfo string `gorm:"-" json:"bank_info"` + OriginalMobile string `gorm:"-" json:"original_mobile"` + OriginalSaleMobile string `gorm:"-" json:"original_sale_mobile"` +} + +type OrderSaleItems struct { + Id int64 `gorm:"column:id;type:bigint(20);primary_key;AUTO_INCREMENT" json:"id"` + OrderSn string `gorm:"column:ordersn;type:varchar(100);comment:订单号;NOT NULL" json:"ordersn"` + StoreName string `gorm:"column:store_name;type:varchar(50);comment:门店名" json:"store_name"` + TotalPrice float64 `gorm:"column:total_price;type:decimal(10,2);comment:总价;NOT NULL" json:"total_price"` + PayPrice float64 `gorm:"column:pay_price;type:decimal(10,2);comment:实际支付金额" json:"pay_price"` + ProductIds string `gorm:"column:product_ids;type:varchar(150);comment:产品IDs" json:"product_ids"` + SignTime utils.CustomTime `gorm:"column:sign_time;type:datetime;comment:签收时间" json:"sign_time"` + CreateTime utils.CustomTime `gorm:"column:create_time;type:datetime;default:CURRENT_TIMESTAMP;comment:订单创建时间" json:"create_time"` + ProductItems []OrderProducts `gorm:"-" json:"product_items"` +} + +type OrderAccount struct { + Id int `gorm:"column:id;type:bigint(20);primary_key;AUTO_INCREMENT" json:"id"` + OrderSn string `gorm:"column:ordersn;type:varchar(100);comment:订单号;NOT NULL" json:"ordersn"` + StoreId int `gorm:"column:store_id;type:int(11);comment:美容院关联ID号" json:"store_id"` + UserId int `gorm:"column:user_id;type:int(11);comment:用户ID" json:"user_id"` + SaleId int `gorm:"column:sale_id;type:int(11);comment:销售员ID号" json:"sale_id"` + TotalPrice float64 `gorm:"column:total_price;type:decimal(10,2);comment:总价;NOT NULL" json:"total_price"` + PayPrice float64 `gorm:"column:pay_price;type:decimal(10,2);comment:实际支付金额" json:"pay_price"` + PayType uint8 `gorm:"column:pay_type;type:tinyint(1);default:1;comment:支付类型,1为微信,2为支付宝,3为余额支付" json:"pay_type"` + ProductIds string `gorm:"column:product_ids;type:varchar(150);comment:产品IDs" json:"product_ids"` + Type uint8 `gorm:"column:type;type:tinyint(1);default:0;comment:类型 1 销售,2为门店,3为个人,4为个人家庭试用,5为个人门店试用" json:"type"` + Products []OrderProducts `gorm:"-" json:"products"` + TaskAwardMonthStatus uint8 `gorm:"column:task_awark_month_status;type:tinyint(1);default:2;comment:结算任务与奖励月,1 为已结算,2为未结算" json:"task_awark_month_status"` + TaskAwardQuarterStatus uint8 `gorm:"column:task_awark_quarter_status;type:tinyint(1);default:2;comment:结算任务与奖励季度,1 为已结算,2为未结算" json:"task_awark_quarter_status"` + TaskAwardHalfYearStatus uint8 `gorm:"column:task_awark_half_year_status;type:tinyint(1);default:2;comment:结算任务与奖励半年,1 为已结算,2为未结算" json:"task_awark_half_year_status"` + TaskAwardYearStatus uint8 `gorm:"column:task_awark_year_status;type:tinyint(1);default:2;comment:结算任务与奖励年,1 为已结算,2为未结算" json:"task_awark_year_status"` + CreateTime utils.CustomTime `gorm:"column:create_time;type:datetime;default:CURRENT_TIMESTAMP;comment:订单创建时间" json:"create_time"` +} + +type OrderAccountStatus struct { + AccountStatus uint8 `gorm:"column:account_status;type:tinyint(1);default:2;comment:结算订单状态,1为已结算,2为未结算,3为结算中" json:"account_status"` +} + +type OrderShareStatus struct { + ShareStatus uint8 `gorm:"column:share_status;type:tinyint(1);default:2;comment:结算抽成状态,1为已结算,2为未结算,3为结算中" json:"share_status"` +} + +type OrderDeliverGoodsStatus struct { + SignTime utils.CustomTime `gorm:"column:sign_time;type:datetime;comment:签收时间" json:"sign_time"` + DeliverStatus uint8 `gorm:"column:deliver_status;type:tinyint(1);default:2;comment:发货状态,1为已签收,2为待发货,3为发货中,4为已发货" json:"deliver_status"` +} + +type OrderImitateInfo struct { + Id int64 `gorm:"column:id;type:bigint(20);primary_key;AUTO_INCREMENT" json:"id"` + OrderSn string `gorm:"column:ordersn;type:varchar(100);comment:订单号;NOT NULL" json:"ordersn"` + Mobile string `gorm:"column:mobile;type:char(60);comment:收货人手机号;NOT NULL" json:"mobile"` + Address string `gorm:"column:address;type:varchar(255);comment:收货人地址;NOT NULL" json:"address"` + Addressee string `gorm:"column:addressee;type:varchar(50);comment:收货人姓名;NOT NULL" json:"addressee"` + DistrictIds string `gorm:"column:district_ids;type:varchar(255);comment:地区IDS;NOT NULL" json:"district_ids"` + PayType uint8 `gorm:"column:pay_type;type:tinyint(1);default:1;comment:支付类型,1为微信,2为支付宝,3为余额支付" json:"pay_type"` + DeliverStatus uint8 `gorm:"column:deliver_status;type:tinyint(1);default:2;comment:发货状态,1为已签收,2为待发货,3为发货中,4为已发货" json:"deliver_status"` + Status uint8 `gorm:"column:status;type:tinyint(1);default:2;comment:支付状态,1为已支付,2为未支付,3为支付中,4支付失败,5已失效;NOT NULL" json:"status"` + VerifyStatus uint8 `gorm:"column:verify_status;type:tinyint(1);default:0;comment:审核状态,1为通过,2为失败,3为待审核,0为正常订单不需要审核" json:"verify_status"` + ProductIds string `gorm:"column:product_ids;type:varchar(150);comment:产品IDs" json:"product_ids"` +} + +type OrderImitateItems struct { + OrderImitateInfo + ProductItems []OrderProducts `gorm:"-" json:"product_items"` +} + +type OrderDownInfo struct { + Id int64 `gorm:"column:id;type:bigint(20);primary_key;AUTO_INCREMENT" json:"id"` + OrderSn string `gorm:"column:ordersn;type:varchar(100);comment:订单号;NOT NULL" json:"ordersn"` + StoreId int `gorm:"column:store_id;type:int(11);comment:美容院关联ID号" json:"store_id"` + StoreName string `gorm:"column:store_name;type:varchar(50);comment:门店名" json:"store_name"` + SaleName string `gorm:"column:sale_name;type:varchar(50);comment:销售姓名" json:"sale_name"` + UserId int `gorm:"column:user_id;type:int(11);comment:用户ID" json:"user_id"` + UserName string `gorm:"column:user_name;type:varchar(255);comment:用户名" json:"user_name"` + SaleId int `gorm:"column:sale_id;type:int(11);comment:销售员ID号" json:"sale_id"` + Mobile string `gorm:"column:mobile;type:char(60);comment:收货人手机号;NOT NULL" json:"mobile"` + Address string `gorm:"column:address;type:varchar(255);comment:收货人地址;NOT NULL" json:"address"` + Addressee string `gorm:"column:addressee;type:varchar(50);comment:收货人姓名;NOT NULL" json:"addressee"` + DistrictIds string `gorm:"column:district_ids;type:varchar(255);comment:地区IDS;NOT NULL" json:"district_ids"` + Status uint8 `gorm:"column:status;type:tinyint(1);default:2;comment:支付状态,1为已支付,2为未支付,3为支付中,4支付失败,5已失效;NOT NULL" json:"status"` + ProductIds string `gorm:"column:product_ids;type:varchar(150);comment:产品IDs" json:"product_ids"` + CreateTime utils.CustomTime `gorm:"column:create_time;type:datetime;default:CURRENT_TIMESTAMP;comment:订单创建时间" json:"create_time"` + CreateDate string `gorm:"-" json:"create_date"` + ProductName string `gorm:"-" json:"product_name"` + ProductNumber int `gorm:"-" json:"product_number"` + StoreBusinessLicense string `gorm:"-" json:"store_business_license"` +} + +type OrderTaskAndAwardMonth struct { + TaskAwardMonthStatus uint8 `gorm:"column:task_award_month_status;type:tinyint(1);default:2;comment:结算任务与奖励月,1 为已结算,2为未结算" json:"task_awark_month_status"` +} +type OrderTaskAndAwardQuarter struct { + TaskAwardQuarterStatus uint8 `gorm:"column:task_award_quarter_status;type:tinyint(1);default:2;comment:结算任务与奖励季度,1 为已结算,2为未结算" json:"task_awark_quarter_status"` +} +type OrderTaskAndAwardHalfYear struct { + TaskAwardHalfYearStatus uint8 `gorm:"column:task_award_half_year_status;type:tinyint(1);default:2;comment:结算任务与奖励半年,1 为已结算,2为未结算" json:"task_awark_half_year_status"` +} +type OrderTaskAndAwardYear struct { + TaskAwardYearStatus uint8 `gorm:"column:task_award_year_status;type:tinyint(1);default:2;comment:结算任务与奖励年,1 为已结算,2为未结算" json:"task_awark_year_status"` +} diff --git a/services/order/internal/dao/orderProduct.go b/services/order/internal/dao/orderProduct.go new file mode 100644 index 0000000..b29399c --- /dev/null +++ b/services/order/internal/dao/orderProduct.go @@ -0,0 +1,44 @@ +package dao + +import "lone-services/pkg/utils" + +type OrderProductCreate struct { + Id int64 `gorm:"column:id;type:bigint(20);primary_key;AUTO_INCREMENT" json:"id"` + Ordersn string `gorm:"column:ordersn;type:varchar(100);comment:订单号;NOT NULL" json:"ordersn"` + ProductId int `gorm:"column:product_id;type:int(11);comment:产品ID;NOT NULL" json:"product_id"` + ProductName string `gorm:"column:product_name;type:varchar(255);comment:产品名;NOT NULL" json:"product_name"` + Price float64 `gorm:"column:price;type:decimal(10,2);comment:产品单价格;NOT NULL" json:"price"` + Number int `gorm:"column:number;type:int(11);default:0;comment:购买的数量;NOT NULL" json:"number"` + Status uint8 `gorm:"column:status;type:tinyint(1);default:1;comment:状态:1为正常,2为已推货" json:"status"` + ReturnNumber int `gorm:"column:return_number;type:int(11);default:0;comment:退货数量" json:"return_number"` +} + +type OrderProductInfo struct { + Id int64 `gorm:"column:id;type:bigint(20);primary_key;AUTO_INCREMENT" json:"id"` + Ordersn string `gorm:"column:ordersn;type:varchar(100);comment:订单号;NOT NULL" json:"ordersn"` + ProductId int `gorm:"column:product_id;type:int(11);comment:产品ID;NOT NULL" json:"product_id"` + ProductName string `gorm:"column:product_name;type:varchar(255);comment:产品名;NOT NULL" json:"product_name"` + Price float64 `gorm:"column:price;type:decimal(10,2);comment:产品单价格;NOT NULL" json:"price"` + Number int `gorm:"column:number;type:int(11);default:0;comment:购买的数量;NOT NULL" json:"number"` + Status uint8 `gorm:"column:status;type:tinyint(1);default:1;comment:状态:1为正常,2为已推货" json:"status"` + ReturnNumber int `gorm:"column:return_number;type:int(11);default:0;comment:退货数量" json:"return_number"` + CreateType uint8 `gorm:"column:create_type;type:tinyint(1);default:1;comment:下单人类型,1为销售,2为门店,3为个人;NOT NULL" json:"create_type"` + CreateTime utils.CustomTime `gorm:"column:create_time;type:datetime;default:CURRENT_TIMESTAMP;comment:订单创建时间" json:"create_time"` +} + +type OrderProductPay struct { + ProductId int `gorm:"column:product_id;type:int(11);comment:产品ID;NOT NULL" json:"product_id"` + Number int `gorm:"column:number;type:int(11);default:0;comment:购买的数量;NOT NULL" json:"number"` + ProductName string `gorm:"column:product_name;type:varchar(255);comment:产品名;NOT NULL" json:"product_name"` + Type uint8 `gorm:"-" json:"type"` + Price float64 `gorm:"column:price;type:decimal(10,2);comment:产品单价格;NOT NULL" json:"price"` +} + +type OrderProducts struct { + Id int `gorm:"column:id;type:bigint(20);primary_key;AUTO_INCREMENT" json:"id"` + OrderSn string `gorm:"column:ordersn;type:varchar(100);comment:订单号;NOT NULL" json:"ordersn"` + ProductId int `gorm:"column:product_id;type:int(11);comment:产品ID;NOT NULL" json:"product_id"` + ProductName string `gorm:"column:product_name;type:varchar(255);comment:产品名;NOT NULL" json:"product_name"` + Price float32 `gorm:"column:price;type:decimal(10,2);comment:产品单价格;NOT NULL" json:"price"` + Number int `gorm:"column:number;type:int(11);default:0;comment:购买的数量;NOT NULL" json:"number"` +} diff --git a/services/order/internal/logic/addressItemLogic.go b/services/order/internal/logic/addressItemLogic.go index e40cd67..ab4730a 100644 --- a/services/order/internal/logic/addressItemLogic.go +++ b/services/order/internal/logic/addressItemLogic.go @@ -13,6 +13,7 @@ type AddressItemLogic struct { ctx context.Context svcCtx *svc.ServiceContext logx.Logger + BaseLogic } func NewAddressItemLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AddressItemLogic { diff --git a/services/order/internal/logic/base.go b/services/order/internal/logic/base.go new file mode 100644 index 0000000..16ca9b6 --- /dev/null +++ b/services/order/internal/logic/base.go @@ -0,0 +1,44 @@ +package logic + +import ( + "lone-services/pkg/utils" + "lone-services/pkg/validate" + order "lone-services/rpc/order/pb" + "reflect" + + jsoniter "github.com/json-iterator/go" +) + +type BaseLogic struct { +} + +func (l *BaseLogic) checkParams(in interface{}, v validate.IValidator) *order.Response { + rv := reflect.ValueOf(in) + if rv.Kind() != reflect.Ptr || rv.IsNil() { + return &order.Response{ + Code: utils.ErrorParams.Code, + Msg: "request must be non‑nil proto pointer", + } + } + + resp := validate.ValidateFromProto(in, v) + if resp != utils.StringEmpty { + return &order.Response{ + Code: utils.ErrorParams.Code, + Msg: resp, + } + } + return nil +} + +func (l *BaseLogic) fail(status utils.Status) (*order.Response, error) { + return l.out(status, status.Msg) +} +func (l *BaseLogic) out(status utils.Status, msg string) (*order.Response, error) { + return &order.Response{Code: status.Code, Msg: msg}, nil +} + +func (l *BaseLogic) ok(data any) (*order.Response, error) { + buf, _ := jsoniter.Marshal(data) + return &order.Response{Code: utils.Ok.Code, Msg: utils.Ok.Msg, Data: string(buf)}, nil +} diff --git a/services/order/internal/logic/itemsLogic.go b/services/order/internal/logic/itemsLogic.go index f4d3c6a..411b9cc 100644 --- a/services/order/internal/logic/itemsLogic.go +++ b/services/order/internal/logic/itemsLogic.go @@ -2,7 +2,6 @@ package logic import ( "context" - "lone-services/rpc/order/pb" "lone-services/services/order/internal/svc" @@ -13,6 +12,7 @@ type ItemsLogic struct { ctx context.Context svcCtx *svc.ServiceContext logx.Logger + BaseLogic } func NewItemsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ItemsLogic { @@ -23,9 +23,17 @@ func NewItemsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ItemsLogic } } -func (l *ItemsLogic) Items(in *order.ItemsRequest) (*order.Response, error) { - // todo: add your logic here and delete this line +func (l *ItemsLogic) Items(in *order.OrderItemsRequest) (*order.Response, error) { + //调用其它服务实例 + //cli, err := svc.GetRpcClient(l.svcCtx.ExpressSvcName) + //if err != nil { + // l.Logger.Errorf("get express rpc err: %v", err) + // //降级逻辑 + // return l.out(utils.ErrorInternalServer, "express"+utils.ErrorInternalServer.Msg) + //} + //expClient := express.NewExpressClient(cli.Conn()) + //res, _ := expClient.Ping(context.Background(), &express.Request{}) + //l.Logger.Error("res: %v", res) - //TODO new id now return &order.Response{}, nil } diff --git a/services/order/internal/logic/orderAuditingItemsLogic.go b/services/order/internal/logic/orderAuditingItemsLogic.go index 1f011a8..1997b29 100644 --- a/services/order/internal/logic/orderAuditingItemsLogic.go +++ b/services/order/internal/logic/orderAuditingItemsLogic.go @@ -13,6 +13,7 @@ type OrderAuditingItemsLogic struct { ctx context.Context svcCtx *svc.ServiceContext logx.Logger + BaseLogic } func NewOrderAuditingItemsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *OrderAuditingItemsLogic { diff --git a/services/order/internal/logic/orderAuditingLogic.go b/services/order/internal/logic/orderAuditingLogic.go index 10d6591..fe226e9 100644 --- a/services/order/internal/logic/orderAuditingLogic.go +++ b/services/order/internal/logic/orderAuditingLogic.go @@ -13,6 +13,7 @@ type OrderAuditingLogic struct { ctx context.Context svcCtx *svc.ServiceContext logx.Logger + BaseLogic } func NewOrderAuditingLogic(ctx context.Context, svcCtx *svc.ServiceContext) *OrderAuditingLogic { diff --git a/services/order/internal/logic/orderCreateLogic.go b/services/order/internal/logic/orderCreateLogic.go index 2854e46..af59d22 100644 --- a/services/order/internal/logic/orderCreateLogic.go +++ b/services/order/internal/logic/orderCreateLogic.go @@ -13,6 +13,7 @@ type OrderCreateLogic struct { ctx context.Context svcCtx *svc.ServiceContext logx.Logger + BaseLogic } func NewOrderCreateLogic(ctx context.Context, svcCtx *svc.ServiceContext) *OrderCreateLogic { diff --git a/services/order/internal/logic/webAddressCreateLogic.go b/services/order/internal/logic/webAddressCreateLogic.go index ca6435a..0f4a2d1 100644 --- a/services/order/internal/logic/webAddressCreateLogic.go +++ b/services/order/internal/logic/webAddressCreateLogic.go @@ -2,10 +2,14 @@ package logic import ( "context" - + "lone-services/pkg/utils" "lone-services/rpc/order/pb" + "lone-services/services/order/internal/dao" + "lone-services/services/order/internal/model" "lone-services/services/order/internal/svc" + "lone-services/services/order/validator" + jsoniter "github.com/json-iterator/go" "github.com/zeromicro/go-zero/core/logx" ) @@ -13,6 +17,7 @@ type WebAddressCreateLogic struct { ctx context.Context svcCtx *svc.ServiceContext logx.Logger + BaseLogic } func NewWebAddressCreateLogic(ctx context.Context, svcCtx *svc.ServiceContext) *WebAddressCreateLogic { @@ -24,7 +29,50 @@ func NewWebAddressCreateLogic(ctx context.Context, svcCtx *svc.ServiceContext) * } func (l *WebAddressCreateLogic) WebAddressCreate(in *order.EditAddressRequest) (*order.Response, error) { - // todo: add your logic here and delete this line + var v validator.AddressEditValidator + if fail := l.checkParams(in, &v); fail != nil { + return fail, nil + } + adminInfo := utils.GetUserFromCtx(l.ctx) + if adminInfo.ID < utils.NumberOne { + return l.fail(utils.ErrorNoLoginInfo) + } + encryPhone, cErr := utils.EncryptPhone(in.Mobile) + if cErr != nil { + l.Logger.Error(cErr) + return l.fail(utils.ErrorEncryptAesError) + } + + data := dao.Address{ + TargetId: adminInfo.ID, + TypeName: adminInfo.Name, + District: in.District, + DistrictIds: in.DistrictIds, + Address: in.Address, + Name: in.Name, + Mobile: encryPhone, + Type: in.Type, + Status: utils.StatusApply, + } + + jsonStr, err := jsoniter.MarshalToString(data) + if err != nil { + l.Logger.Error("转换失败:", err) + return l.fail(utils.ErrorJsonDataError) + } + + data.NewContent = jsonStr + data.SaleId = adminInfo.SaleId + data.GroupId = adminInfo.GroupId + + modelObj := model.AddressModel{}.Init() + + err = modelObj.Create(&data) + if err != nil { + l.Logger.Error(err) + return l.fail(utils.Fail) + } + + return l.ok(data.Id) - return &order.Response{}, nil } diff --git a/services/order/internal/logic/webAddressDefLogic.go b/services/order/internal/logic/webAddressDefLogic.go index cddd4d4..2891828 100644 --- a/services/order/internal/logic/webAddressDefLogic.go +++ b/services/order/internal/logic/webAddressDefLogic.go @@ -13,6 +13,7 @@ type WebAddressDefLogic struct { ctx context.Context svcCtx *svc.ServiceContext logx.Logger + BaseLogic } func NewWebAddressDefLogic(ctx context.Context, svcCtx *svc.ServiceContext) *WebAddressDefLogic { diff --git a/services/order/internal/logic/webAddressEditLogic.go b/services/order/internal/logic/webAddressEditLogic.go index c614eeb..3a7f38f 100644 --- a/services/order/internal/logic/webAddressEditLogic.go +++ b/services/order/internal/logic/webAddressEditLogic.go @@ -13,6 +13,7 @@ type WebAddressEditLogic struct { ctx context.Context svcCtx *svc.ServiceContext logx.Logger + BaseLogic } func NewWebAddressEditLogic(ctx context.Context, svcCtx *svc.ServiceContext) *WebAddressEditLogic { diff --git a/services/order/internal/logic/webAddressItemsLogic.go b/services/order/internal/logic/webAddressItemsLogic.go index 27b713a..d26e863 100644 --- a/services/order/internal/logic/webAddressItemsLogic.go +++ b/services/order/internal/logic/webAddressItemsLogic.go @@ -13,6 +13,7 @@ type WebAddressItemsLogic struct { ctx context.Context svcCtx *svc.ServiceContext logx.Logger + BaseLogic } func NewWebAddressItemsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *WebAddressItemsLogic { diff --git a/services/order/internal/logic/webAddressStatusLogic.go b/services/order/internal/logic/webAddressStatusLogic.go index 3ceb077..563903f 100644 --- a/services/order/internal/logic/webAddressStatusLogic.go +++ b/services/order/internal/logic/webAddressStatusLogic.go @@ -13,6 +13,7 @@ type WebAddressStatusLogic struct { ctx context.Context svcCtx *svc.ServiceContext logx.Logger + BaseLogic } func NewWebAddressStatusLogic(ctx context.Context, svcCtx *svc.ServiceContext) *WebAddressStatusLogic { diff --git a/services/order/internal/logic/webCartEditLogic.go b/services/order/internal/logic/webCartEditLogic.go index 333dcaa..0d46507 100644 --- a/services/order/internal/logic/webCartEditLogic.go +++ b/services/order/internal/logic/webCartEditLogic.go @@ -13,6 +13,7 @@ type WebCartEditLogic struct { ctx context.Context svcCtx *svc.ServiceContext logx.Logger + BaseLogic } func NewWebCartEditLogic(ctx context.Context, svcCtx *svc.ServiceContext) *WebCartEditLogic { diff --git a/services/order/internal/logic/webCartLogic.go b/services/order/internal/logic/webCartLogic.go index 30c9a90..2cf3e03 100644 --- a/services/order/internal/logic/webCartLogic.go +++ b/services/order/internal/logic/webCartLogic.go @@ -13,6 +13,7 @@ type WebCartLogic struct { ctx context.Context svcCtx *svc.ServiceContext logx.Logger + BaseLogic } func NewWebCartLogic(ctx context.Context, svcCtx *svc.ServiceContext) *WebCartLogic { diff --git a/services/order/internal/logic/webCreateLogic.go b/services/order/internal/logic/webCreateLogic.go index f205b94..ed4445e 100644 --- a/services/order/internal/logic/webCreateLogic.go +++ b/services/order/internal/logic/webCreateLogic.go @@ -13,6 +13,7 @@ type WebCreateLogic struct { ctx context.Context svcCtx *svc.ServiceContext logx.Logger + BaseLogic } func NewWebCreateLogic(ctx context.Context, svcCtx *svc.ServiceContext) *WebCreateLogic { diff --git a/services/order/internal/model/address.go b/services/order/internal/model/address.go new file mode 100644 index 0000000..11f0cdb --- /dev/null +++ b/services/order/internal/model/address.go @@ -0,0 +1,23 @@ +package model + +import ( + "lone-services/pkg/modelbase" + "lone-services/services/order/internal/dao" +) + +type AddressModel struct { + modelbase.Base +} + +func (m AddressModel) TableName() string { + return modelbase.Prefix() + "address" +} + +func (m AddressModel) Init() AddressModel { + m.Table = m.TableName() + return m +} + +func (m AddressModel) Create(data *dao.Address) error { + return m.Base.Create(data) +} diff --git a/services/order/internal/model/cart.go b/services/order/internal/model/cart.go new file mode 100644 index 0000000..92924af --- /dev/null +++ b/services/order/internal/model/cart.go @@ -0,0 +1,23 @@ +package model + +import ( + "lone-services/pkg/modelbase" + "lone-services/services/order/internal/dao" +) + +type CartModel struct { + modelbase.Base +} + +func (m CartModel) TableName() string { + return modelbase.Prefix() + "cart" +} + +func (m CartModel) Init() CartModel { + m.Table = m.TableName() + return m +} + +func (m CartModel) Create(data *dao.Cart) error { + return m.Base.Create(data) +} diff --git a/services/order/internal/model/order.go b/services/order/internal/model/order.go new file mode 100644 index 0000000..5c91cc1 --- /dev/null +++ b/services/order/internal/model/order.go @@ -0,0 +1,23 @@ +package model + +import ( + "lone-services/pkg/modelbase" + "lone-services/services/order/internal/dao" +) + +type OrderModel struct { + modelbase.Base +} + +func (m OrderModel) TableName() string { + return modelbase.Prefix() + "order" +} + +func (m OrderModel) Init() OrderModel { + m.Table = m.TableName() + return m +} + +func (m OrderModel) Create(data *dao.OrderCreate) error { + return m.Base.Create(data) +} diff --git a/services/order/internal/model/orderProduct.go b/services/order/internal/model/orderProduct.go new file mode 100644 index 0000000..be38ec3 --- /dev/null +++ b/services/order/internal/model/orderProduct.go @@ -0,0 +1,23 @@ +package model + +import ( + "lone-services/pkg/modelbase" + "lone-services/services/order/internal/dao" +) + +type OrderProductModel struct { + modelbase.Base +} + +func (m OrderProductModel) TableName() string { + return modelbase.Prefix() + "order_product" +} + +func (m OrderProductModel) Init() OrderProductModel { + m.Table = m.TableName() + return m +} + +func (m OrderProductModel) Create(data *dao.OrderProductCreate) error { + return m.Base.Create(data) +} diff --git a/services/order/internal/svc/servicecontext.go b/services/order/internal/svc/servicecontext.go index 243f6e9..f85286e 100644 --- a/services/order/internal/svc/servicecontext.go +++ b/services/order/internal/svc/servicecontext.go @@ -1,22 +1,100 @@ package svc import ( + "fmt" + "net" + "strconv" + "sync" + "time" + + "lone-services/pkg/discovery" "lone-services/pkg/utils" "lone-services/services/order/internal/config" + "github.com/zeromicro/go-zero/core/logx" + "github.com/zeromicro/go-zero/zrpc" "gorm.io/gorm" ) +// 缓存条目 +type rpcClientCacheEntry struct { + cli zrpc.Client + target string + expireAt time.Time +} + +const rpcClientCacheTTL = 30 * time.Second //缓存过期时间 + +var ( + rpcCacheLock sync.Mutex + rpcCache = make(map[string]*rpcClientCacheEntry) +) + +func GetRpcClient(serviceName string) (zrpc.Client, error) { + if serviceName == utils.StringEmpty { + err := fmt.Errorf("rpc serviceName is empty") + logx.Error(err) + return nil, err + } + + cacheKey := serviceName + + rpcCacheLock.Lock() + entry, ok := rpcCache[cacheKey] + if ok && time.Now().Before(entry.expireAt) { + rpcCacheLock.Unlock() + return entry.cli, nil + } + delete(rpcCache, cacheKey) + rpcCacheLock.Unlock() + + inst, err := discovery.Pick(serviceName) + if err != nil { + err = fmt.Errorf("discovery pick %s failed: %w", serviceName, err) + logx.Error(err) + return nil, err + } + + target := net.JoinHostPort(inst.IP, strconv.FormatUint(inst.Port, utils.NumberTen)) + + cli := zrpc.MustNewClient(zrpc.RpcClientConf{ + Target: target, + Timeout: utils.RpcTimeOut, //rpc调用超时5s + }) + + rpcCacheLock.Lock() + rpcCache[cacheKey] = &rpcClientCacheEntry{ + cli: cli, + target: target, + expireAt: time.Now().Add(rpcClientCacheTTL), + } + rpcCacheLock.Unlock() + + return cli, nil +} + type ServiceContext struct { Config config.Config DB *gorm.DB Prefix string + + ExpressSvcName string //服务名 } func NewServiceContext(c config.Config, db *gorm.DB) *ServiceContext { - return &ServiceContext{ - Config: c, - DB: db, - Prefix: utils.GetConfigString("mysql.prefix"), + //启动仅读取配置,不建立rpc连接 多个服务就多个 + expressSvc := utils.GetConfigString("services.express") + + if expressSvc == utils.StringEmpty { + logx.Error("config services.express empty") } + + svcCtx := &ServiceContext{ + Config: c, + DB: db, + Prefix: utils.GetConfigString("mysql.prefix"), + ExpressSvcName: expressSvc, + } + + return svcCtx } diff --git a/services/order/order.go b/services/order/order.go index 0e5cbf7..07b09b8 100644 --- a/services/order/order.go +++ b/services/order/order.go @@ -2,6 +2,7 @@ package main import ( "flag" + "fmt" "lone-services/pkg/discovery" "lone-services/pkg/modelbase" "lone-services/pkg/mysql" @@ -38,6 +39,7 @@ func main() { Group: c.Nacos.Group, ConfigID: c.Nacos.ConfigID, } + fmt.Println("Nacos Config:", nacosParam) utils.InitConfig(nacosParam) // 日志配置 diff --git a/services/order/tmp/runner-build b/services/order/tmp/runner-build new file mode 100644 index 0000000..060b470 Binary files /dev/null and b/services/order/tmp/runner-build differ diff --git a/services/order/validator/address.go b/services/order/validator/address.go new file mode 100644 index 0000000..ae36a94 --- /dev/null +++ b/services/order/validator/address.go @@ -0,0 +1,69 @@ +package validator + +import "lone-services/pkg/validate" + +// AddressDefValidator 查看列表 +type AddressDefValidator struct { + Id int64 `validate:"required"` +} + +// GetMessage 查看列表 - 提示消息 +func (p AddressDefValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + "Id.required": "Id不能为空", + } +} + +// AddressStatusValidator 查看列表 +type AddressStatusValidator struct { + Id int64 `validate:"required"` + Status int32 `validate:"required,oneof=1 2"` +} + +// GetMessage 查看列表 - 提示消息 +func (p AddressStatusValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + "Id.required": "Id不能为空", + "Status.required": "状态不能为空", + "Status.oneof": "状态不对", + } +} + +type AddressEditValidator struct { + Id int64 + District string `validate:"required"` + Address string `validate:"required"` + Name string `validate:"required"` + Mobile string `validate:"required"` + DistrictIds string `validate:"required"` + Type int32 `validate:"required,oneof=1 2 3"` //类型 1门店 , 2销售,3为用户 + Default bool +} + +// GetMessage 查看列表 - 提示消息 +func (p AddressEditValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + "District.required": "区域不能为空", + "Address.required": "地址不能为空", + "Name.required": "姓名不能为空", + "Mobile.required": "手机不能为空", + "DistrictIds.required": "区域ID不能为空", + "Type.required": "类型不能为空", + "Type.oneof": "类型不对", + } +} + +type AdminAddressItemsValidator struct { + Page int32 + Size int32 + DistrictId int64 + Mobile string + StoreId int64 + SaleId int64 + Time []string +} + +// GetMessage 查看列表 - 提示消息 +func (p AdminAddressItemsValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{} +} diff --git a/services/order/validator/cart.go b/services/order/validator/cart.go new file mode 100644 index 0000000..2bac657 --- /dev/null +++ b/services/order/validator/cart.go @@ -0,0 +1,13 @@ +package validator + +import "lone-services/pkg/validate" + +// CartEditValidator 查看列表 +type CartEditValidator struct { + Info string +} + +// GetMessage 查看列表 - 提示消息 +func (p CartEditValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{} +} diff --git a/services/order/validator/order.go b/services/order/validator/order.go new file mode 100644 index 0000000..1ddb16e --- /dev/null +++ b/services/order/validator/order.go @@ -0,0 +1,70 @@ +package validator + +import "lone-services/pkg/validate" + +type AdminOrderAuditingItemsValidator struct { + Page int32 + Size int32 +} + +// GetMessage 查看列表 - 提示消息 +func (p AdminOrderAuditingItemsValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{} +} + +type AdminOrderAuditingValidator struct { + Id int64 `validate:"required"` + Status int32 `validate:"required,oneof=1 2"` + Reason string `validate:"required_if=Status 2"` +} + +// GetMessage 修改状态 - 提示消息 +func (p AdminOrderAuditingValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + "Id.required": "ID不能为空", + "Status.required": "状态不能为空", + "Status.oneof": "状态传值不对", + "Reason.required_if": "理由不能为空", + } +} + +type AdminOrderCreateValidator struct { + AddressId int64 `validate:"required"` + Info string `validate:"required"` + Note string +} + +// GetMessage 修改状态 - 提示消息 +func (p AdminOrderCreateValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + "AddressId.required": "地址ID不能为空", + "Info.required": "内容不能为空", + } +} + +type OrderCreateValidator struct { + AddressId int64 `validate:"required"` + Note string +} + +func (p OrderCreateValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + "AddressId.required": "地址ID不能为空", + } +} + +type OrderItemsValidator struct { + Page int32 + Size int32 + ProductId int64 + OrderSn string + Mobile string + StoreId int64 + SaleId int64 + Time []string + Status int32 +} + +func (p OrderItemsValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{} +}