From e36d4a28808ac2c359f73480e6a604dc703fde8c Mon Sep 17 00:00:00 2001 From: han-joker Date: Thu, 1 Dec 2022 22:08:16 +0800 Subject: [PATCH] estimate price --- .gitignore | 3 +- .../customer/api/valuation/valuation.pb.go | 246 ++++++++++++++++++ .../customer/api/valuation/valuation.proto | 19 ++ .../api/valuation/valuation_grpc.pb.go | 105 ++++++++ backend/customer/internal/biz/customer.go | 52 ++++ backend/map/internal/biz/mapservice.go | 70 +++++ .../valuation/api/mapService/mapService.proto | 20 ++ backend/valuation/internal/biz/valuation.go | 113 ++++++++ docker-compose.yml | 14 +- volumes/mysql/init.sql | 2 + 10 files changed, 641 insertions(+), 3 deletions(-) create mode 100644 backend/customer/api/valuation/valuation.pb.go create mode 100644 backend/customer/api/valuation/valuation.proto create mode 100644 backend/customer/api/valuation/valuation_grpc.pb.go create mode 100644 backend/map/internal/biz/mapservice.go create mode 100644 backend/valuation/api/mapService/mapService.proto create mode 100644 backend/valuation/internal/biz/valuation.go create mode 100644 volumes/mysql/init.sql diff --git a/.gitignore b/.gitignore index a953efe..53513d0 100644 --- a/.gitignore +++ b/.gitignore @@ -39,4 +39,5 @@ bin/ *.swp # vols -data/ \ No newline at end of file +data/ +volumns/ \ No newline at end of file diff --git a/backend/customer/api/valuation/valuation.pb.go b/backend/customer/api/valuation/valuation.pb.go new file mode 100644 index 0000000..2e56dbc --- /dev/null +++ b/backend/customer/api/valuation/valuation.pb.go @@ -0,0 +1,246 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v3.21.6 +// source: api/valuation/valuation.proto + +package valuation + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +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 GetEstimatePriceReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Origin string `protobuf:"bytes,1,opt,name=origin,proto3" json:"origin,omitempty"` + Destination string `protobuf:"bytes,2,opt,name=destination,proto3" json:"destination,omitempty"` +} + +func (x *GetEstimatePriceReq) Reset() { + *x = GetEstimatePriceReq{} + if protoimpl.UnsafeEnabled { + mi := &file_api_valuation_valuation_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetEstimatePriceReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetEstimatePriceReq) ProtoMessage() {} + +func (x *GetEstimatePriceReq) ProtoReflect() protoreflect.Message { + mi := &file_api_valuation_valuation_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetEstimatePriceReq.ProtoReflect.Descriptor instead. +func (*GetEstimatePriceReq) Descriptor() ([]byte, []int) { + return file_api_valuation_valuation_proto_rawDescGZIP(), []int{0} +} + +func (x *GetEstimatePriceReq) GetOrigin() string { + if x != nil { + return x.Origin + } + return "" +} + +func (x *GetEstimatePriceReq) GetDestination() string { + if x != nil { + return x.Destination + } + return "" +} + +type GetEstimatePriceReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Origin string `protobuf:"bytes,1,opt,name=origin,proto3" json:"origin,omitempty"` + Destination string `protobuf:"bytes,2,opt,name=destination,proto3" json:"destination,omitempty"` + Price int64 `protobuf:"varint,3,opt,name=price,proto3" json:"price,omitempty"` +} + +func (x *GetEstimatePriceReply) Reset() { + *x = GetEstimatePriceReply{} + if protoimpl.UnsafeEnabled { + mi := &file_api_valuation_valuation_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetEstimatePriceReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetEstimatePriceReply) ProtoMessage() {} + +func (x *GetEstimatePriceReply) ProtoReflect() protoreflect.Message { + mi := &file_api_valuation_valuation_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetEstimatePriceReply.ProtoReflect.Descriptor instead. +func (*GetEstimatePriceReply) Descriptor() ([]byte, []int) { + return file_api_valuation_valuation_proto_rawDescGZIP(), []int{1} +} + +func (x *GetEstimatePriceReply) GetOrigin() string { + if x != nil { + return x.Origin + } + return "" +} + +func (x *GetEstimatePriceReply) GetDestination() string { + if x != nil { + return x.Destination + } + return "" +} + +func (x *GetEstimatePriceReply) GetPrice() int64 { + if x != nil { + return x.Price + } + return 0 +} + +var File_api_valuation_valuation_proto protoreflect.FileDescriptor + +var file_api_valuation_valuation_proto_rawDesc = []byte{ + 0x0a, 0x1d, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, + 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x0d, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x4f, + 0x0a, 0x13, 0x47, 0x65, 0x74, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x50, 0x72, 0x69, + 0x63, 0x65, 0x52, 0x65, 0x71, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x12, 0x20, 0x0a, + 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0x67, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x50, 0x72, + 0x69, 0x63, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, + 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, + 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x32, 0x69, 0x0a, 0x09, 0x56, 0x61, 0x6c, 0x75, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x5c, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x45, 0x73, 0x74, 0x69, + 0x6d, 0x61, 0x74, 0x65, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x22, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x73, 0x74, + 0x69, 0x6d, 0x61, 0x74, 0x65, 0x50, 0x72, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x24, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x47, 0x65, + 0x74, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x50, 0x72, 0x69, 0x63, 0x65, 0x52, 0x65, + 0x70, 0x6c, 0x79, 0x42, 0x22, 0x5a, 0x20, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x65, 0x72, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x76, 0x61, + 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_api_valuation_valuation_proto_rawDescOnce sync.Once + file_api_valuation_valuation_proto_rawDescData = file_api_valuation_valuation_proto_rawDesc +) + +func file_api_valuation_valuation_proto_rawDescGZIP() []byte { + file_api_valuation_valuation_proto_rawDescOnce.Do(func() { + file_api_valuation_valuation_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_valuation_valuation_proto_rawDescData) + }) + return file_api_valuation_valuation_proto_rawDescData +} + +var file_api_valuation_valuation_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_api_valuation_valuation_proto_goTypes = []interface{}{ + (*GetEstimatePriceReq)(nil), // 0: api.valuation.GetEstimatePriceReq + (*GetEstimatePriceReply)(nil), // 1: api.valuation.GetEstimatePriceReply +} +var file_api_valuation_valuation_proto_depIdxs = []int32{ + 0, // 0: api.valuation.Valuation.GetEstimatePrice:input_type -> api.valuation.GetEstimatePriceReq + 1, // 1: api.valuation.Valuation.GetEstimatePrice:output_type -> api.valuation.GetEstimatePriceReply + 1, // [1:2] is the sub-list for method output_type + 0, // [0:1] 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_api_valuation_valuation_proto_init() } +func file_api_valuation_valuation_proto_init() { + if File_api_valuation_valuation_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_api_valuation_valuation_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetEstimatePriceReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_valuation_valuation_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetEstimatePriceReply); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_api_valuation_valuation_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_api_valuation_valuation_proto_goTypes, + DependencyIndexes: file_api_valuation_valuation_proto_depIdxs, + MessageInfos: file_api_valuation_valuation_proto_msgTypes, + }.Build() + File_api_valuation_valuation_proto = out.File + file_api_valuation_valuation_proto_rawDesc = nil + file_api_valuation_valuation_proto_goTypes = nil + file_api_valuation_valuation_proto_depIdxs = nil +} diff --git a/backend/customer/api/valuation/valuation.proto b/backend/customer/api/valuation/valuation.proto new file mode 100644 index 0000000..4a61f8f --- /dev/null +++ b/backend/customer/api/valuation/valuation.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; + +package api.valuation; + +option go_package = "customer/api/valuation;valuation"; + +service Valuation { + rpc GetEstimatePrice (GetEstimatePriceReq) returns (GetEstimatePriceReply); +} + +message GetEstimatePriceReq { + string origin = 1; + string destination = 2; +} +message GetEstimatePriceReply { + string origin = 1; + string destination = 2; + int64 price = 3; +} \ No newline at end of file diff --git a/backend/customer/api/valuation/valuation_grpc.pb.go b/backend/customer/api/valuation/valuation_grpc.pb.go new file mode 100644 index 0000000..0d86f31 --- /dev/null +++ b/backend/customer/api/valuation/valuation_grpc.pb.go @@ -0,0 +1,105 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.6 +// source: api/valuation/valuation.proto + +package valuation + +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.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// ValuationClient is the client API for Valuation 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 ValuationClient interface { + GetEstimatePrice(ctx context.Context, in *GetEstimatePriceReq, opts ...grpc.CallOption) (*GetEstimatePriceReply, error) +} + +type valuationClient struct { + cc grpc.ClientConnInterface +} + +func NewValuationClient(cc grpc.ClientConnInterface) ValuationClient { + return &valuationClient{cc} +} + +func (c *valuationClient) GetEstimatePrice(ctx context.Context, in *GetEstimatePriceReq, opts ...grpc.CallOption) (*GetEstimatePriceReply, error) { + out := new(GetEstimatePriceReply) + err := c.cc.Invoke(ctx, "/api.valuation.Valuation/GetEstimatePrice", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ValuationServer is the server API for Valuation service. +// All implementations must embed UnimplementedValuationServer +// for forward compatibility +type ValuationServer interface { + GetEstimatePrice(context.Context, *GetEstimatePriceReq) (*GetEstimatePriceReply, error) + mustEmbedUnimplementedValuationServer() +} + +// UnimplementedValuationServer must be embedded to have forward compatible implementations. +type UnimplementedValuationServer struct { +} + +func (UnimplementedValuationServer) GetEstimatePrice(context.Context, *GetEstimatePriceReq) (*GetEstimatePriceReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetEstimatePrice not implemented") +} +func (UnimplementedValuationServer) mustEmbedUnimplementedValuationServer() {} + +// UnsafeValuationServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ValuationServer will +// result in compilation errors. +type UnsafeValuationServer interface { + mustEmbedUnimplementedValuationServer() +} + +func RegisterValuationServer(s grpc.ServiceRegistrar, srv ValuationServer) { + s.RegisterService(&Valuation_ServiceDesc, srv) +} + +func _Valuation_GetEstimatePrice_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetEstimatePriceReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ValuationServer).GetEstimatePrice(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/api.valuation.Valuation/GetEstimatePrice", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ValuationServer).GetEstimatePrice(ctx, req.(*GetEstimatePriceReq)) + } + return interceptor(ctx, in, info, handler) +} + +// Valuation_ServiceDesc is the grpc.ServiceDesc for Valuation service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Valuation_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "api.valuation.Valuation", + HandlerType: (*ValuationServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetEstimatePrice", + Handler: _Valuation_GetEstimatePrice_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "api/valuation/valuation.proto", +} diff --git a/backend/customer/internal/biz/customer.go b/backend/customer/internal/biz/customer.go index b0ea5a1..4a7d19b 100644 --- a/backend/customer/internal/biz/customer.go +++ b/backend/customer/internal/biz/customer.go @@ -1,7 +1,12 @@ package biz import ( + "context" + "customer/api/valuation" "database/sql" + "github.com/go-kratos/kratos/contrib/registry/consul/v2" + "github.com/go-kratos/kratos/v2/transport/grpc" + "github.com/hashicorp/consul/api" "gorm.io/gorm" ) @@ -32,3 +37,50 @@ type CustomerToken struct { Token string `gorm:"type:varchar(4095);" json:"token"` TokenCreatedAt sql.NullTime `gorm:"" json:"token_created_at"` } + +type CustomerBiz struct { +} + +func NewCustomerBiz() *CustomerBiz { + return &CustomerBiz{} +} + +func (cb *CustomerBiz) GetEstimatePrice(origin, destination string) (int64, error) { + // 一,grpc 获取 + // 1.获取consul客户端 + consulConfig := api.DefaultConfig() + consulConfig.Address = "localhost:8500" + consulClient, err := api.NewClient(consulConfig) + // 2.获取服务发现管理器 + dis := consul.New(consulClient) + if err != nil { + return 0, err + } + // 2.1,连接目标grpc服务器 + endpoint := "discovery:///Valuation" + conn, err := grpc.DialInsecure( + context.Background(), + grpc.WithEndpoint(endpoint), // 目标服务的名字 + // 使用服务发现 + grpc.WithDiscovery(dis), + ) + if err != nil { + return 0, nil + } + //关闭 + defer func() { + _ = conn.Close() + }() + + // 2.2,发送获取验证码请求 + client := valuation.NewValuationClient(conn) + reply, err := client.GetEstimatePrice(context.Background(), &valuation.GetEstimatePriceReq{ + Origin: origin, + Destination: destination, + }) + if err != nil { + return 0, err + } + + return reply.Price, nil +} diff --git a/backend/map/internal/biz/mapservice.go b/backend/map/internal/biz/mapservice.go new file mode 100644 index 0000000..cab34cf --- /dev/null +++ b/backend/map/internal/biz/mapservice.go @@ -0,0 +1,70 @@ +package biz + +import ( + "encoding/json" + "errors" + "fmt" + "github.com/go-kratos/kratos/v2/log" + "io" + "net/http" +) + +type MapServiceBiz struct { + log *log.Helper +} + +func NewMapServiceBiz(logger log.Logger) *MapServiceBiz { + return &MapServiceBiz{log: log.NewHelper(logger)} +} + +// 获取驾驶信息 +func (msbiz *MapServiceBiz) GetDriverInfo(origin, destination string) (string, string, error) { + // 一,请求获取 + key := "4b37316ad0582dc767eaefa58cfd3f34" + api := "https://restapi.amap.com/v3/direction/driving" + parameters := fmt.Sprintf("origin=%s&destination=%s&extensions=base&output=json&key=%s", origin, destination, key) + url := api + "?" + parameters + resp, err := http.Get(url) + if err != nil { + return "", "", err + } + defer func() { + _ = resp.Body.Close() + }() + body, err := io.ReadAll(resp.Body) // io.Reader + if err != nil { + return "", "", err + } + + // 二,解析出来,json + ddResp := DirectionDrivingResp{} + if err := json.Unmarshal(body, &ddResp); err != nil { + return "", "", err + } + + // 三,判定LSB请求结果 + if ddResp.Status == "0" { + return "", "", errors.New(ddResp.Info) + } + + // 四,正确返回,默认使用第一条路线 + path := ddResp.Route.Paths[0] + return path.Distance, path.Duration, nil +} + +type DirectionDrivingResp struct { + Status string `json:"status,omitempty"` + Info string `json:"info,omitempty"` + Infocode string `json:"infocode,omitempty"` + Count string `json:"count,omitempty"` + Route struct { + Origin string `json:"origin,omitempty"` + Destination string `json:"destination,omitempty"` + Paths []Path `json:"paths,omitempty"` + } `json:"route"` +} +type Path struct { + Distance string `json:"distance,omitempty"` + Duration string `json:"duration,omitempty"` + Strategy string `json:"strategy,omitempty"` +} diff --git a/backend/valuation/api/mapService/mapService.proto b/backend/valuation/api/mapService/mapService.proto new file mode 100644 index 0000000..6748068 --- /dev/null +++ b/backend/valuation/api/mapService/mapService.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; + +package api.mapService; + +option go_package = "valuation/api/mapService;mapService"; + +service MapService { + rpc GetDrivingInfo (GetDrivingInfoReq) returns (GetDrivingReply); +} + +message GetDrivingInfoReq { + string origin = 1; + string destination = 2; +} +message GetDrivingReply { + string origin = 1; + string destination = 2; + string distance = 3; + string duration = 4; +} \ No newline at end of file diff --git a/backend/valuation/internal/biz/valuation.go b/backend/valuation/internal/biz/valuation.go new file mode 100644 index 0000000..7d6cee4 --- /dev/null +++ b/backend/valuation/internal/biz/valuation.go @@ -0,0 +1,113 @@ +package biz + +import ( + "context" + "github.com/go-kratos/kratos/contrib/registry/consul/v2" + "github.com/go-kratos/kratos/v2/transport/grpc" + "github.com/hashicorp/consul/api" + "gorm.io/gorm" + "strconv" + "valuation/api/mapService" +) + +type PriceRule struct { + gorm.Model + PriceRuleWork +} + +type PriceRuleWork struct { + CityID uint `gorm:"" json:"city_id"` + StartFee int64 `gorm:"" json:"start_fee"` + DistanceFee int64 `gorm:"" json:"distance_fee"` + DurationFee int64 `gorm:"" json:"duration_fee"` + StartAt int `gorm:"type:int" json:"start_at"` // 0 [0 + EndAt int `gorm:"type:int" json:"end_at"` // 7 0) +} + +// 定义操作priceRule的接口 +type PriceRuleInterface interface { + // 获取规则 + GetRule(cityid uint, curr int) (*PriceRule, error) +} + +type ValuationBiz struct { + pri PriceRuleInterface +} + +func NewValuationBiz(pri PriceRuleInterface) *ValuationBiz { + return &ValuationBiz{ + pri: pri, + } +} + +// 获取价格 +func (vb *ValuationBiz) GetPrice(ctx context.Context, distance, duration string, cityId uint, curr int) (int64, error) { + // 一,获取规则 + rule, err := vb.pri.GetRule(cityId, curr) + if err != nil { + return 0, err + } + // 二,将距离和时长,转换为int64 + distancInt64, err := strconv.ParseInt(distance, 10, 64) + if err != nil { + return 0, err + } + durationInt64, err := strconv.ParseInt(duration, 10, 64) + if err != nil { + return 0, err + } + + // 三,基于rule计算 + distancInt64 /= 1000 + durationInt64 /= 60 + var startDistance int64 = 5 + total := rule.StartFee + + rule.DistanceFee*(distancInt64-startDistance) + + rule.DurationFee*durationInt64 + + return total, nil +} + +// 获取距离和时长 +func (*ValuationBiz) GetDrivingInfo(ctx context.Context, origin, destination string) (distance string, duration string, err error) { + // 一,发出GRPC请求 + // 使用服务发现 + // 1.获取consul客户端 + consulConfig := api.DefaultConfig() + consulConfig.Address = "localhost:8500" + consulClient, err := api.NewClient(consulConfig) + if err != nil { + return + } + // 2.获取服务发现管理器 + dis := consul.New(consulClient) + + // 2.1,连接目标grpc服务器 + endpoint := "discovery:///Map" + conn, err := grpc.DialInsecure( + context.Background(), + grpc.WithEndpoint(endpoint), // 目标服务的名字 + grpc.WithDiscovery(dis), // 使用服务发现 + ) + if err != nil { + return + } + //关闭 + defer func() { + _ = conn.Close() + }() + + // 2.2,发送获取驾驶距离和时长请求,RPC调用 + client := mapService.NewMapServiceClient(conn) + reply, err := client.GetDrivingInfo(context.Background(), &mapService.GetDrivingInfoReq{ + Origin: origin, + Destination: destination, + }) + if err != nil { + return + } + distance, duration = reply.Distance, reply.Duration + + // 返回正确信息 + return +} diff --git a/docker-compose.yml b/docker-compose.yml index ee06e5e..2a00354 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,6 +5,14 @@ services: ports: - "8500:8500" command: agent -dev -client=0.0.0.0 +# prometheus: +# image: prom/prometheus +# container_name: laomaDJConsulPrometheus +# ports: +# - "9090:9090" +# volumes: +# - ./data/prometheus/etc:/etc/prometheus +# - ./data/prometheus/data:/prometheus redis: container_name: laomaDJRedis image: redis @@ -19,7 +27,9 @@ services: - "3306:3306" environment: MYSQL_ROOT_PASSWORD: mashibing - MYSQL_DATABASE: laomadj_customer +# MYSQL_DATABASE: laomadj_customer + command: --init-file /docker-entrypoint-initdb.d/init.sql volumes: - - ./data/mysql:/var/lib/mysql + - ./volumes/mysql/data:/var/lib/mysql + - ./volumes/mysql/init.sql:/docker-entrypoint-initdb.d/init.sql # docker-compose up -d \ No newline at end of file diff --git a/volumes/mysql/init.sql b/volumes/mysql/init.sql new file mode 100644 index 0000000..f18987e --- /dev/null +++ b/volumes/mysql/init.sql @@ -0,0 +1,2 @@ +create database if not exists laomadj_customer; +create database if not exists laomadj_valuation;