From 53d203ee14bbc2274d97e4db1589bbd8aa50fe2f Mon Sep 17 00:00:00 2001 From: zzw <1464003642@qq.com> Date: Fri, 28 Aug 2026 15:35:33 +0800 Subject: [PATCH] fix: sale create fields --- rpc/chore/chore.pb | Bin 14336 -> 14549 bytes rpc/chore/chore.proto | 16 ++ rpc/chore/pb/chore.pb.go | 189 ++++++++++++++++-- rpc/chore/pb/chore_grpc.pb.go | 40 ++++ rpc/product/product.proto | 18 +- rpc/sale/pb/sale.pb.go | 104 ++-------- rpc/sale/pb/sale_grpc.pb.go | 80 ++++---- rpc/sale/sale.pb | Bin 17526 -> 17218 bytes rpc/sale/sale.proto | 13 +- services/chore/choreclient/chore.go | 11 + .../chore/internal/logic/regionsByIdsLogic.go | 71 +++++++ services/chore/internal/server/choreServer.go | 6 + services/sale/internal/logic/createLogic.go | 26 ++- services/sale/internal/logic/editLogic.go | 25 ++- services/sale/internal/logic/helper.go | 35 ++++ services/sale/internal/server/saleServer.go | 12 +- services/sale/internal/svc/serviceContext.go | 20 +- services/sale/run.toml | 7 +- services/sale/saleClient/sale.go | 16 +- services/sale/validator/validator.go | 104 ++++------ 20 files changed, 542 insertions(+), 251 deletions(-) create mode 100644 services/chore/internal/logic/regionsByIdsLogic.go diff --git a/rpc/chore/chore.pb b/rpc/chore/chore.pb index cd54c0ab0ca9a4bac1e89956cc655c4ca3dd538f..8d31a51f6e8f92fb1ba85314099a0ff23284f1f6 100644 GIT binary patch delta 243 zcmZoDxLUZu$&_g#`(_tYH^zD;WiI}p)bz~!yke(H&y?bz)IuQvF6PXXVhKhCW)0>b z5L3y3iwmO2vm`ZFh>wdYGX*Hk2$Tl0goLt+{IH%4Zo3rw38%>x)GZ?aGZ0GT@pmjD0& diff --git a/rpc/chore/chore.proto b/rpc/chore/chore.proto index c4b3e41..e26ac36 100644 --- a/rpc/chore/chore.proto +++ b/rpc/chore/chore.proto @@ -27,6 +27,9 @@ service Chore { get: "/api/v3/chore/regions" }; } + + // 按 id 批量查地区名称 + rpc RegionsByIds(RegionsByIdsReq) returns (RegionsByIdsData); } message Response { @@ -51,4 +54,17 @@ message DecryptMobileReq { message RegionsReq { int32 parent_id = 1; +} + +message RegionsByIdsReq { + repeated int64 ids = 1; +} + +message RegionItem { + int64 id = 1; + string name = 2; +} + +message RegionsByIdsData { + repeated RegionItem items = 1; } \ No newline at end of file diff --git a/rpc/chore/pb/chore.pb.go b/rpc/chore/pb/chore.pb.go index 2b17b87..cf4f372 100644 --- a/rpc/chore/pb/chore.pb.go +++ b/rpc/chore/pb/chore.pb.go @@ -274,6 +274,146 @@ func (x *RegionsReq) GetParentId() int32 { return 0 } +type RegionsByIdsReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + Ids []int64 `protobuf:"varint,1,rep,packed,name=ids,proto3" json:"ids,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RegionsByIdsReq) Reset() { + *x = RegionsByIdsReq{} + mi := &file_chore_chore_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RegionsByIdsReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegionsByIdsReq) ProtoMessage() {} + +func (x *RegionsByIdsReq) ProtoReflect() protoreflect.Message { + mi := &file_chore_chore_proto_msgTypes[5] + 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 RegionsByIdsReq.ProtoReflect.Descriptor instead. +func (*RegionsByIdsReq) Descriptor() ([]byte, []int) { + return file_chore_chore_proto_rawDescGZIP(), []int{5} +} + +func (x *RegionsByIdsReq) GetIds() []int64 { + if x != nil { + return x.Ids + } + return nil +} + +type RegionItem struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RegionItem) Reset() { + *x = RegionItem{} + mi := &file_chore_chore_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RegionItem) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegionItem) ProtoMessage() {} + +func (x *RegionItem) ProtoReflect() protoreflect.Message { + mi := &file_chore_chore_proto_msgTypes[6] + 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 RegionItem.ProtoReflect.Descriptor instead. +func (*RegionItem) Descriptor() ([]byte, []int) { + return file_chore_chore_proto_rawDescGZIP(), []int{6} +} + +func (x *RegionItem) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *RegionItem) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type RegionsByIdsData struct { + state protoimpl.MessageState `protogen:"open.v1"` + Items []*RegionItem `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RegionsByIdsData) Reset() { + *x = RegionsByIdsData{} + mi := &file_chore_chore_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RegionsByIdsData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegionsByIdsData) ProtoMessage() {} + +func (x *RegionsByIdsData) ProtoReflect() protoreflect.Message { + mi := &file_chore_chore_proto_msgTypes[7] + 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 RegionsByIdsData.ProtoReflect.Descriptor instead. +func (*RegionsByIdsData) Descriptor() ([]byte, []int) { + return file_chore_chore_proto_rawDescGZIP(), []int{7} +} + +func (x *RegionsByIdsData) GetItems() []*RegionItem { + if x != nil { + return x.Items + } + return nil +} + var File_chore_chore_proto protoreflect.FileDescriptor const file_chore_chore_proto_rawDesc = "" + @@ -293,12 +433,21 @@ const file_chore_chore_proto_rawDesc = "" + "\rorigin_mobile\x18\x01 \x01(\tR\foriginMobile\")\n" + "\n" + "RegionsReq\x12\x1b\n" + - "\tparent_id\x18\x01 \x01(\x05R\bparentId2\xd0\x02\n" + + "\tparent_id\x18\x01 \x01(\x05R\bparentId\"#\n" + + "\x0fRegionsByIdsReq\x12\x10\n" + + "\x03ids\x18\x01 \x03(\x03R\x03ids\"0\n" + + "\n" + + "RegionItem\x12\x0e\n" + + "\x02id\x18\x01 \x01(\x03R\x02id\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\";\n" + + "\x10RegionsByIdsData\x12'\n" + + "\x05items\x18\x01 \x03(\v2\x11.chore.RegionItemR\x05items2\x91\x03\n" + "\x05Chore\x12P\n" + "\x06Policy\x12\x10.chore.PolicyReq\x1a\x0f.chore.Response\"#\x82\xd3\xe4\x93\x02\x1d:\x01*\x12\x18/api/v3/chore/oss/policy\x12F\n" + "\x04Test\x12\x0e.chore.TestReq\x1a\x0f.chore.Response\"\x1d\x82\xd3\xe4\x93\x02\x17:\x01*\"\x12/api/v3/chore/test\x12_\n" + "\rDecryptMobile\x12\x17.chore.DecryptMobileReq\x1a\x0f.chore.Response\"$\x82\xd3\xe4\x93\x02\x1e\x12\x1c/api/v3/chore/decrypt/mobile\x12L\n" + - "\aRegions\x12\x11.chore.RegionsReq\x1a\x0f.chore.Response\"\x1d\x82\xd3\xe4\x93\x02\x17\x12\x15/api/v3/chore/regionsB\x19Z\x17lone-services/rpc/choreb\x06proto3" + "\aRegions\x12\x11.chore.RegionsReq\x1a\x0f.chore.Response\"\x1d\x82\xd3\xe4\x93\x02\x17\x12\x15/api/v3/chore/regions\x12?\n" + + "\fRegionsByIds\x12\x16.chore.RegionsByIdsReq\x1a\x17.chore.RegionsByIdsDataB\x19Z\x17lone-services/rpc/choreb\x06proto3" var ( file_chore_chore_proto_rawDescOnce sync.Once @@ -312,28 +461,34 @@ func file_chore_chore_proto_rawDescGZIP() []byte { return file_chore_chore_proto_rawDescData } -var file_chore_chore_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_chore_chore_proto_msgTypes = make([]protoimpl.MessageInfo, 8) var file_chore_chore_proto_goTypes = []any{ (*Response)(nil), // 0: chore.Response (*PolicyReq)(nil), // 1: chore.PolicyReq (*TestReq)(nil), // 2: chore.TestReq (*DecryptMobileReq)(nil), // 3: chore.DecryptMobileReq (*RegionsReq)(nil), // 4: chore.RegionsReq + (*RegionsByIdsReq)(nil), // 5: chore.RegionsByIdsReq + (*RegionItem)(nil), // 6: chore.RegionItem + (*RegionsByIdsData)(nil), // 7: chore.RegionsByIdsData } var file_chore_chore_proto_depIdxs = []int32{ - 1, // 0: chore.Chore.Policy:input_type -> chore.PolicyReq - 2, // 1: chore.Chore.Test:input_type -> chore.TestReq - 3, // 2: chore.Chore.DecryptMobile:input_type -> chore.DecryptMobileReq - 4, // 3: chore.Chore.Regions:input_type -> chore.RegionsReq - 0, // 4: chore.Chore.Policy:output_type -> chore.Response - 0, // 5: chore.Chore.Test:output_type -> chore.Response - 0, // 6: chore.Chore.DecryptMobile:output_type -> chore.Response - 0, // 7: chore.Chore.Regions:output_type -> chore.Response - 4, // [4:8] is the sub-list for method output_type - 0, // [0:4] 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 + 6, // 0: chore.RegionsByIdsData.items:type_name -> chore.RegionItem + 1, // 1: chore.Chore.Policy:input_type -> chore.PolicyReq + 2, // 2: chore.Chore.Test:input_type -> chore.TestReq + 3, // 3: chore.Chore.DecryptMobile:input_type -> chore.DecryptMobileReq + 4, // 4: chore.Chore.Regions:input_type -> chore.RegionsReq + 5, // 5: chore.Chore.RegionsByIds:input_type -> chore.RegionsByIdsReq + 0, // 6: chore.Chore.Policy:output_type -> chore.Response + 0, // 7: chore.Chore.Test:output_type -> chore.Response + 0, // 8: chore.Chore.DecryptMobile:output_type -> chore.Response + 0, // 9: chore.Chore.Regions:output_type -> chore.Response + 7, // 10: chore.Chore.RegionsByIds:output_type -> chore.RegionsByIdsData + 6, // [6:11] is the sub-list for method output_type + 1, // [1:6] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name } func init() { file_chore_chore_proto_init() } @@ -347,7 +502,7 @@ func file_chore_chore_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_chore_chore_proto_rawDesc), len(file_chore_chore_proto_rawDesc)), NumEnums: 0, - NumMessages: 5, + NumMessages: 8, NumExtensions: 0, NumServices: 1, }, diff --git a/rpc/chore/pb/chore_grpc.pb.go b/rpc/chore/pb/chore_grpc.pb.go index 0cae512..daa276a 100644 --- a/rpc/chore/pb/chore_grpc.pb.go +++ b/rpc/chore/pb/chore_grpc.pb.go @@ -23,6 +23,7 @@ const ( Chore_Test_FullMethodName = "/chore.Chore/Test" Chore_DecryptMobile_FullMethodName = "/chore.Chore/DecryptMobile" Chore_Regions_FullMethodName = "/chore.Chore/Regions" + Chore_RegionsByIds_FullMethodName = "/chore.Chore/RegionsByIds" ) // ChoreClient is the client API for Chore service. @@ -33,6 +34,8 @@ type ChoreClient interface { Test(ctx context.Context, in *TestReq, opts ...grpc.CallOption) (*Response, error) DecryptMobile(ctx context.Context, in *DecryptMobileReq, opts ...grpc.CallOption) (*Response, error) Regions(ctx context.Context, in *RegionsReq, opts ...grpc.CallOption) (*Response, error) + // 服务间调用:按 id 批量查地区名称 + RegionsByIds(ctx context.Context, in *RegionsByIdsReq, opts ...grpc.CallOption) (*RegionsByIdsData, error) } type choreClient struct { @@ -83,6 +86,16 @@ func (c *choreClient) Regions(ctx context.Context, in *RegionsReq, opts ...grpc. return out, nil } +func (c *choreClient) RegionsByIds(ctx context.Context, in *RegionsByIdsReq, opts ...grpc.CallOption) (*RegionsByIdsData, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(RegionsByIdsData) + err := c.cc.Invoke(ctx, Chore_RegionsByIds_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + // ChoreServer is the server API for Chore service. // All implementations must embed UnimplementedChoreServer // for forward compatibility. @@ -91,6 +104,8 @@ type ChoreServer interface { Test(context.Context, *TestReq) (*Response, error) DecryptMobile(context.Context, *DecryptMobileReq) (*Response, error) Regions(context.Context, *RegionsReq) (*Response, error) + // 服务间调用:按 id 批量查地区名称 + RegionsByIds(context.Context, *RegionsByIdsReq) (*RegionsByIdsData, error) mustEmbedUnimplementedChoreServer() } @@ -113,6 +128,9 @@ func (UnimplementedChoreServer) DecryptMobile(context.Context, *DecryptMobileReq func (UnimplementedChoreServer) Regions(context.Context, *RegionsReq) (*Response, error) { return nil, status.Error(codes.Unimplemented, "method Regions not implemented") } +func (UnimplementedChoreServer) RegionsByIds(context.Context, *RegionsByIdsReq) (*RegionsByIdsData, error) { + return nil, status.Error(codes.Unimplemented, "method RegionsByIds not implemented") +} func (UnimplementedChoreServer) mustEmbedUnimplementedChoreServer() {} func (UnimplementedChoreServer) testEmbeddedByValue() {} @@ -206,6 +224,24 @@ func _Chore_Regions_Handler(srv interface{}, ctx context.Context, dec func(inter return interceptor(ctx, in, info, handler) } +func _Chore_RegionsByIds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RegionsByIdsReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ChoreServer).RegionsByIds(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Chore_RegionsByIds_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ChoreServer).RegionsByIds(ctx, req.(*RegionsByIdsReq)) + } + return interceptor(ctx, in, info, handler) +} + // Chore_ServiceDesc is the grpc.ServiceDesc for Chore service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -229,6 +265,10 @@ var Chore_ServiceDesc = grpc.ServiceDesc{ MethodName: "Regions", Handler: _Chore_Regions_Handler, }, + { + MethodName: "RegionsByIds", + Handler: _Chore_RegionsByIds_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "chore/chore.proto", diff --git a/rpc/product/product.proto b/rpc/product/product.proto index 0bc766f..fa7ec18 100644 --- a/rpc/product/product.proto +++ b/rpc/product/product.proto @@ -94,15 +94,6 @@ service Product { }; } - // 增减库存 - // type: 1 增加, 2 减少 - rpc Number(NumberReq) returns (google.protobuf.Empty); - // 批量增减库存(服务内按 id 排序后在同一事务中执行,防死锁) - rpc NumberItems(NumberItemsReq) returns (google.protobuf.Empty); - rpc InfoById(InfoByIdReq) returns (Item); - rpc ItemsByIds(ItemsByIdsReq) returns (ItemsByIdsData); - - // 增加库存 rpc NumberAdd(NumberAddReq) returns (Response) { option (google.api.http) = { @@ -110,6 +101,15 @@ service Product { body: "*" }; } + + // 增减库存 + rpc Number(NumberReq) returns (google.protobuf.Empty); + // 批量增减库存 + rpc NumberItems(NumberItemsReq) returns (google.protobuf.Empty); + // 获取单个产品详情 + rpc InfoById(InfoByIdReq) returns (Item); + // 获取多个产品详情 + rpc ItemsByIds(ItemsByIdsReq) returns (ItemsByIdsData); } message Response { diff --git a/rpc/sale/pb/sale.pb.go b/rpc/sale/pb/sale.pb.go index 09fbd81..85d99e6 100644 --- a/rpc/sale/pb/sale.pb.go +++ b/rpc/sale/pb/sale.pb.go @@ -399,13 +399,9 @@ type CreateReq struct { SaleId int64 `protobuf:"varint,9,opt,name=sale_id,json=saleId,proto3" json:"sale_id,omitempty"` Type uint32 `protobuf:"varint,10,opt,name=type,proto3" json:"type,omitempty"` TerritoryId int64 `protobuf:"varint,11,opt,name=territory_id,json=territoryId,proto3" json:"territory_id,omitempty"` - TerritoryName string `protobuf:"bytes,12,opt,name=territory_name,json=territoryName,proto3" json:"territory_name,omitempty"` ProvinceId int64 `protobuf:"varint,13,opt,name=province_id,json=provinceId,proto3" json:"province_id,omitempty"` CityId int64 `protobuf:"varint,14,opt,name=city_id,json=cityId,proto3" json:"city_id,omitempty"` DistrictId int64 `protobuf:"varint,15,opt,name=district_id,json=districtId,proto3" json:"district_id,omitempty"` - RegionProvince string `protobuf:"bytes,16,opt,name=region_province,json=regionProvince,proto3" json:"region_province,omitempty"` - RegionCity string `protobuf:"bytes,17,opt,name=region_city,json=regionCity,proto3" json:"region_city,omitempty"` - RegionDistrict string `protobuf:"bytes,18,opt,name=region_district,json=regionDistrict,proto3" json:"region_district,omitempty"` Address string `protobuf:"bytes,19,opt,name=address,proto3" json:"address,omitempty"` IdCardBack string `protobuf:"bytes,20,opt,name=id_card_back,json=idCardBack,proto3" json:"id_card_back,omitempty"` BusinessLicense string `protobuf:"bytes,21,opt,name=business_license,json=businessLicense,proto3" json:"business_license,omitempty"` @@ -520,13 +516,6 @@ func (x *CreateReq) GetTerritoryId() int64 { return 0 } -func (x *CreateReq) GetTerritoryName() string { - if x != nil { - return x.TerritoryName - } - return "" -} - func (x *CreateReq) GetProvinceId() int64 { if x != nil { return x.ProvinceId @@ -548,27 +537,6 @@ func (x *CreateReq) GetDistrictId() int64 { return 0 } -func (x *CreateReq) GetRegionProvince() string { - if x != nil { - return x.RegionProvince - } - return "" -} - -func (x *CreateReq) GetRegionCity() string { - if x != nil { - return x.RegionCity - } - return "" -} - -func (x *CreateReq) GetRegionDistrict() string { - if x != nil { - return x.RegionDistrict - } - return "" -} - func (x *CreateReq) GetAddress() string { if x != nil { return x.Address @@ -603,13 +571,9 @@ type EditReq struct { SaleId int64 `protobuf:"varint,9,opt,name=sale_id,json=saleId,proto3" json:"sale_id,omitempty"` Type uint32 `protobuf:"varint,10,opt,name=type,proto3" json:"type,omitempty"` TerritoryId int64 `protobuf:"varint,11,opt,name=territory_id,json=territoryId,proto3" json:"territory_id,omitempty"` - TerritoryName string `protobuf:"bytes,12,opt,name=territory_name,json=territoryName,proto3" json:"territory_name,omitempty"` ProvinceId int64 `protobuf:"varint,13,opt,name=province_id,json=provinceId,proto3" json:"province_id,omitempty"` CityId int64 `protobuf:"varint,14,opt,name=city_id,json=cityId,proto3" json:"city_id,omitempty"` DistrictId int64 `protobuf:"varint,15,opt,name=district_id,json=districtId,proto3" json:"district_id,omitempty"` - RegionProvince string `protobuf:"bytes,16,opt,name=region_province,json=regionProvince,proto3" json:"region_province,omitempty"` - RegionCity string `protobuf:"bytes,17,opt,name=region_city,json=regionCity,proto3" json:"region_city,omitempty"` - RegionDistrict string `protobuf:"bytes,18,opt,name=region_district,json=regionDistrict,proto3" json:"region_district,omitempty"` Address string `protobuf:"bytes,19,opt,name=address,proto3" json:"address,omitempty"` IdCardBack string `protobuf:"bytes,20,opt,name=id_card_back,json=idCardBack,proto3" json:"id_card_back,omitempty"` BusinessLicense string `protobuf:"bytes,21,opt,name=business_license,json=businessLicense,proto3" json:"business_license,omitempty"` @@ -724,13 +688,6 @@ func (x *EditReq) GetTerritoryId() int64 { return 0 } -func (x *EditReq) GetTerritoryName() string { - if x != nil { - return x.TerritoryName - } - return "" -} - func (x *EditReq) GetProvinceId() int64 { if x != nil { return x.ProvinceId @@ -752,27 +709,6 @@ func (x *EditReq) GetDistrictId() int64 { return 0 } -func (x *EditReq) GetRegionProvince() string { - if x != nil { - return x.RegionProvince - } - return "" -} - -func (x *EditReq) GetRegionCity() string { - if x != nil { - return x.RegionCity - } - return "" -} - -func (x *EditReq) GetRegionDistrict() string { - if x != nil { - return x.RegionDistrict - } - return "" -} - func (x *EditReq) GetAddress() string { if x != nil { return x.Address @@ -1379,7 +1315,7 @@ const file_sale_sale_proto_rawDesc = "" + "\x06mobile\x18\x02 \x01(\tR\x06mobile\x12\x12\n" + "\x04name\x18\x03 \x01(\tR\x04name\"1\n" + "\tNamesData\x12$\n" + - "\x05items\x18\x01 \x03(\v2\x0e.sale.NameItemR\x05items\"\x89\x05\n" + + "\x05items\x18\x01 \x03(\v2\x0e.sale.NameItemR\x05items\"\xef\x03\n" + "\tCreateReq\x12\x16\n" + "\x06mobile\x18\x01 \x01(\tR\x06mobile\x12\x12\n" + "\x04name\x18\x02 \x01(\tR\x04name\x12\"\n" + @@ -1393,21 +1329,16 @@ const file_sale_sale_proto_rawDesc = "" + "\asale_id\x18\t \x01(\x03R\x06saleId\x12\x12\n" + "\x04type\x18\n" + " \x01(\rR\x04type\x12!\n" + - "\fterritory_id\x18\v \x01(\x03R\vterritoryId\x12%\n" + - "\x0eterritory_name\x18\f \x01(\tR\rterritoryName\x12\x1f\n" + + "\fterritory_id\x18\v \x01(\x03R\vterritoryId\x12\x1f\n" + "\vprovince_id\x18\r \x01(\x03R\n" + "provinceId\x12\x17\n" + "\acity_id\x18\x0e \x01(\x03R\x06cityId\x12\x1f\n" + "\vdistrict_id\x18\x0f \x01(\x03R\n" + - "districtId\x12'\n" + - "\x0fregion_province\x18\x10 \x01(\tR\x0eregionProvince\x12\x1f\n" + - "\vregion_city\x18\x11 \x01(\tR\n" + - "regionCity\x12'\n" + - "\x0fregion_district\x18\x12 \x01(\tR\x0eregionDistrict\x12\x18\n" + + "districtId\x12\x18\n" + "\aaddress\x18\x13 \x01(\tR\aaddress\x12 \n" + "\fid_card_back\x18\x14 \x01(\tR\n" + "idCardBack\x12)\n" + - "\x10business_license\x18\x15 \x01(\tR\x0fbusinessLicense\"\xfb\x04\n" + + "\x10business_license\x18\x15 \x01(\tR\x0fbusinessLicense\"\xe1\x03\n" + "\aEditReq\x12\x0e\n" + "\x02id\x18\x01 \x01(\x03R\x02id\x12\x16\n" + "\x06mobile\x18\x02 \x01(\tR\x06mobile\x12\x12\n" + @@ -1421,17 +1352,12 @@ const file_sale_sale_proto_rawDesc = "" + "\asale_id\x18\t \x01(\x03R\x06saleId\x12\x12\n" + "\x04type\x18\n" + " \x01(\rR\x04type\x12!\n" + - "\fterritory_id\x18\v \x01(\x03R\vterritoryId\x12%\n" + - "\x0eterritory_name\x18\f \x01(\tR\rterritoryName\x12\x1f\n" + + "\fterritory_id\x18\v \x01(\x03R\vterritoryId\x12\x1f\n" + "\vprovince_id\x18\r \x01(\x03R\n" + "provinceId\x12\x17\n" + "\acity_id\x18\x0e \x01(\x03R\x06cityId\x12\x1f\n" + "\vdistrict_id\x18\x0f \x01(\x03R\n" + - "districtId\x12'\n" + - "\x0fregion_province\x18\x10 \x01(\tR\x0eregionProvince\x12\x1f\n" + - "\vregion_city\x18\x11 \x01(\tR\n" + - "regionCity\x12'\n" + - "\x0fregion_district\x18\x12 \x01(\tR\x0eregionDistrict\x12\x18\n" + + "districtId\x12\x18\n" + "\aaddress\x18\x13 \x01(\tR\aaddress\x12 \n" + "\fid_card_back\x18\x14 \x01(\tR\n" + "idCardBack\x12)\n" + @@ -1504,10 +1430,10 @@ const file_sale_sale_proto_rawDesc = "" + "\rNamesInternal\x12\x0e.sale.NamesReq\x1a\x0f.sale.NamesData\x12E\n" + "\x06Create\x12\x0f.sale.CreateReq\x1a\x0e.sale.Response\"\x1a\x82\xd3\xe4\x93\x02\x14:\x01*\"\x0f/admin/v3/sales\x12A\n" + "\x04Edit\x12\r.sale.EditReq\x1a\x0e.sale.Response\"\x1a\x82\xd3\xe4\x93\x02\x14:\x01*\x1a\x0f/admin/v3/sales\x12F\n" + - "\x04Info\x12\r.sale.InfoReq\x1a\x0e.sale.Response\"\x1f\x82\xd3\xe4\x93\x02\x19:\x01*\x12\x14/admin/v3/sales/info\x12-\n" + - "\fInfoInternal\x12\r.sale.InfoReq\x1a\x0e.sale.InfoData\x12C\n" + + "\x04Info\x12\r.sale.InfoReq\x1a\x0e.sale.Response\"\x1f\x82\xd3\xe4\x93\x02\x19:\x01*\x12\x14/admin/v3/sales/info\x12C\n" + "\x05Items\x12\x0e.sale.ItemsReq\x1a\x0e.sale.Response\"\x1a\x82\xd3\xe4\x93\x02\x14:\x01*\x12\x0f/admin/v3/sales\x12L\n" + - "\x06Status\x12\x0f.sale.StatusReq\x1a\x0e.sale.Response\"!\x82\xd3\xe4\x93\x02\x1b:\x01*\x1a\x16/admin/v3/sales/statusB\x18Z\x16lone-services/rpc/saleb\x06proto3" + "\x06Status\x12\x0f.sale.StatusReq\x1a\x0e.sale.Response\"!\x82\xd3\xe4\x93\x02\x1b:\x01*\x1a\x16/admin/v3/sales/status\x12-\n" + + "\fInfoInternal\x12\r.sale.InfoReq\x1a\x0e.sale.InfoDataB\x18Z\x16lone-services/rpc/saleb\x06proto3" var ( file_sale_sale_proto_rawDescOnce sync.Once @@ -1552,9 +1478,9 @@ var file_sale_sale_proto_depIdxs = []int32{ 7, // 9: sale.Sale.Create:input_type -> sale.CreateReq 8, // 10: sale.Sale.Edit:input_type -> sale.EditReq 9, // 11: sale.Sale.Info:input_type -> sale.InfoReq - 9, // 12: sale.Sale.InfoInternal:input_type -> sale.InfoReq - 13, // 13: sale.Sale.Items:input_type -> sale.ItemsReq - 14, // 14: sale.Sale.Status:input_type -> sale.StatusReq + 13, // 12: sale.Sale.Items:input_type -> sale.ItemsReq + 14, // 13: sale.Sale.Status:input_type -> sale.StatusReq + 9, // 14: sale.Sale.InfoInternal:input_type -> sale.InfoReq 0, // 15: sale.Sale.GroupItems:output_type -> sale.Response 0, // 16: sale.Sale.GroupCreate:output_type -> sale.Response 0, // 17: sale.Sale.GroupNames:output_type -> sale.Response @@ -1564,9 +1490,9 @@ var file_sale_sale_proto_depIdxs = []int32{ 0, // 21: sale.Sale.Create:output_type -> sale.Response 0, // 22: sale.Sale.Edit:output_type -> sale.Response 0, // 23: sale.Sale.Info:output_type -> sale.Response - 12, // 24: sale.Sale.InfoInternal:output_type -> sale.InfoData - 0, // 25: sale.Sale.Items:output_type -> sale.Response - 0, // 26: sale.Sale.Status:output_type -> sale.Response + 0, // 24: sale.Sale.Items:output_type -> sale.Response + 0, // 25: sale.Sale.Status:output_type -> sale.Response + 12, // 26: sale.Sale.InfoInternal:output_type -> sale.InfoData 15, // [15:27] is the sub-list for method output_type 3, // [3:15] is the sub-list for method input_type 3, // [3:3] is the sub-list for extension type_name diff --git a/rpc/sale/pb/sale_grpc.pb.go b/rpc/sale/pb/sale_grpc.pb.go index 9ca8042..e49e419 100644 --- a/rpc/sale/pb/sale_grpc.pb.go +++ b/rpc/sale/pb/sale_grpc.pb.go @@ -28,9 +28,9 @@ const ( Sale_Create_FullMethodName = "/sale.Sale/Create" Sale_Edit_FullMethodName = "/sale.Sale/Edit" Sale_Info_FullMethodName = "/sale.Sale/Info" - Sale_InfoInternal_FullMethodName = "/sale.Sale/InfoInternal" Sale_Items_FullMethodName = "/sale.Sale/Items" Sale_Status_FullMethodName = "/sale.Sale/Status" + Sale_InfoInternal_FullMethodName = "/sale.Sale/InfoInternal" ) // SaleClient is the client API for Sale service. @@ -48,10 +48,10 @@ type SaleClient interface { Create(ctx context.Context, in *CreateReq, opts ...grpc.CallOption) (*Response, error) Edit(ctx context.Context, in *EditReq, opts ...grpc.CallOption) (*Response, error) Info(ctx context.Context, in *InfoReq, opts ...grpc.CallOption) (*Response, error) - // 服务间调用:销售详情(含分组;mobile 脱敏,origin_mobile 为加密串) - InfoInternal(ctx context.Context, in *InfoReq, opts ...grpc.CallOption) (*InfoData, error) Items(ctx context.Context, in *ItemsReq, opts ...grpc.CallOption) (*Response, error) Status(ctx context.Context, in *StatusReq, opts ...grpc.CallOption) (*Response, error) + // 销售详情 + InfoInternal(ctx context.Context, in *InfoReq, opts ...grpc.CallOption) (*InfoData, error) } type saleClient struct { @@ -152,16 +152,6 @@ func (c *saleClient) Info(ctx context.Context, in *InfoReq, opts ...grpc.CallOpt return out, nil } -func (c *saleClient) InfoInternal(ctx context.Context, in *InfoReq, opts ...grpc.CallOption) (*InfoData, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(InfoData) - err := c.cc.Invoke(ctx, Sale_InfoInternal_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - func (c *saleClient) Items(ctx context.Context, in *ItemsReq, opts ...grpc.CallOption) (*Response, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(Response) @@ -182,6 +172,16 @@ func (c *saleClient) Status(ctx context.Context, in *StatusReq, opts ...grpc.Cal return out, nil } +func (c *saleClient) InfoInternal(ctx context.Context, in *InfoReq, opts ...grpc.CallOption) (*InfoData, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(InfoData) + err := c.cc.Invoke(ctx, Sale_InfoInternal_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + // SaleServer is the server API for Sale service. // All implementations must embed UnimplementedSaleServer // for forward compatibility. @@ -197,10 +197,10 @@ type SaleServer interface { Create(context.Context, *CreateReq) (*Response, error) Edit(context.Context, *EditReq) (*Response, error) Info(context.Context, *InfoReq) (*Response, error) - // 服务间调用:销售详情(含分组;mobile 脱敏,origin_mobile 为加密串) - InfoInternal(context.Context, *InfoReq) (*InfoData, error) Items(context.Context, *ItemsReq) (*Response, error) Status(context.Context, *StatusReq) (*Response, error) + // 销售详情 + InfoInternal(context.Context, *InfoReq) (*InfoData, error) mustEmbedUnimplementedSaleServer() } @@ -238,15 +238,15 @@ func (UnimplementedSaleServer) Edit(context.Context, *EditReq) (*Response, error func (UnimplementedSaleServer) Info(context.Context, *InfoReq) (*Response, error) { return nil, status.Error(codes.Unimplemented, "method Info not implemented") } -func (UnimplementedSaleServer) InfoInternal(context.Context, *InfoReq) (*InfoData, error) { - return nil, status.Error(codes.Unimplemented, "method InfoInternal not implemented") -} func (UnimplementedSaleServer) Items(context.Context, *ItemsReq) (*Response, error) { return nil, status.Error(codes.Unimplemented, "method Items not implemented") } func (UnimplementedSaleServer) Status(context.Context, *StatusReq) (*Response, error) { return nil, status.Error(codes.Unimplemented, "method Status not implemented") } +func (UnimplementedSaleServer) InfoInternal(context.Context, *InfoReq) (*InfoData, error) { + return nil, status.Error(codes.Unimplemented, "method InfoInternal not implemented") +} func (UnimplementedSaleServer) mustEmbedUnimplementedSaleServer() {} func (UnimplementedSaleServer) testEmbeddedByValue() {} @@ -430,24 +430,6 @@ func _Sale_Info_Handler(srv interface{}, ctx context.Context, dec func(interface return interceptor(ctx, in, info, handler) } -func _Sale_InfoInternal_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(InfoReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(SaleServer).InfoInternal(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Sale_InfoInternal_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(SaleServer).InfoInternal(ctx, req.(*InfoReq)) - } - return interceptor(ctx, in, info, handler) -} - func _Sale_Items_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ItemsReq) if err := dec(in); err != nil { @@ -484,6 +466,24 @@ func _Sale_Status_Handler(srv interface{}, ctx context.Context, dec func(interfa return interceptor(ctx, in, info, handler) } +func _Sale_InfoInternal_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(InfoReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SaleServer).InfoInternal(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Sale_InfoInternal_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SaleServer).InfoInternal(ctx, req.(*InfoReq)) + } + return interceptor(ctx, in, info, handler) +} + // Sale_ServiceDesc is the grpc.ServiceDesc for Sale service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -527,10 +527,6 @@ var Sale_ServiceDesc = grpc.ServiceDesc{ MethodName: "Info", Handler: _Sale_Info_Handler, }, - { - MethodName: "InfoInternal", - Handler: _Sale_InfoInternal_Handler, - }, { MethodName: "Items", Handler: _Sale_Items_Handler, @@ -539,6 +535,10 @@ var Sale_ServiceDesc = grpc.ServiceDesc{ MethodName: "Status", Handler: _Sale_Status_Handler, }, + { + MethodName: "InfoInternal", + Handler: _Sale_InfoInternal_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "sale/sale.proto", diff --git a/rpc/sale/sale.pb b/rpc/sale/sale.pb index 776acd0a6ed6d2281e2b956c4b117f8613478a67..500cdddbcb33ee0e7da5096552396ec230b79aeb 100644 GIT binary patch delta 66 zcmey?!FZ^Raf6d7(?99WE~e)gncg#R7BSajoSbP9J=xqco#`R-<^`4taQ}^mYJ8FDj@(?%Lfq-fQkyqb8$lzCTEsZN(h1#aY2Nf zfg(Z(lTtE^ONug+OC*GlO>%*X3Q2IWC#Iwnr4|=U2v6>{ie~!FvYE|NVQ@QibFbAU S_Q{`|^d`qSO`fdatONjX!F2Ng diff --git a/rpc/sale/sale.proto b/rpc/sale/sale.proto index 2a864b4..068e04a 100644 --- a/rpc/sale/sale.proto +++ b/rpc/sale/sale.proto @@ -57,8 +57,6 @@ service Sale { body: "*" }; } - // 服务间调用:销售详情(含分组;mobile 脱敏,origin_mobile 为加密串) - rpc InfoInternal(InfoReq) returns (InfoData); rpc Items(ItemsReq) returns (Response) { option (google.api.http) = { get: "/admin/v3/sales" @@ -71,6 +69,9 @@ service Sale { body: "*" }; } + + // 销售详情 + rpc InfoInternal(InfoReq) returns (InfoData); } message Response { @@ -119,13 +120,9 @@ message CreateReq { int64 sale_id = 9; uint32 type = 10; int64 territory_id = 11; - string territory_name = 12; int64 province_id = 13; int64 city_id = 14; int64 district_id = 15; - string region_province = 16; - string region_city = 17; - string region_district = 18; string address = 19; string id_card_back = 20; string business_license = 21; @@ -143,13 +140,9 @@ message EditReq { int64 sale_id = 9; uint32 type = 10; int64 territory_id = 11; - string territory_name = 12; int64 province_id = 13; int64 city_id = 14; int64 district_id = 15; - string region_province = 16; - string region_city = 17; - string region_district = 18; string address = 19; string id_card_back = 20; string business_license = 21; diff --git a/services/chore/choreclient/chore.go b/services/chore/choreclient/chore.go index f8f96a7..b58fca8 100644 --- a/services/chore/choreclient/chore.go +++ b/services/chore/choreclient/chore.go @@ -16,6 +16,9 @@ import ( type ( DecryptMobileReq = chore.DecryptMobileReq PolicyReq = chore.PolicyReq + RegionItem = chore.RegionItem + RegionsByIdsData = chore.RegionsByIdsData + RegionsByIdsReq = chore.RegionsByIdsReq RegionsReq = chore.RegionsReq Response = chore.Response TestReq = chore.TestReq @@ -25,6 +28,8 @@ type ( Test(ctx context.Context, in *TestReq, opts ...grpc.CallOption) (*Response, error) DecryptMobile(ctx context.Context, in *DecryptMobileReq, opts ...grpc.CallOption) (*Response, error) Regions(ctx context.Context, in *RegionsReq, opts ...grpc.CallOption) (*Response, error) + // 服务间调用:按 id 批量查地区名称 + RegionsByIds(ctx context.Context, in *RegionsByIdsReq, opts ...grpc.CallOption) (*RegionsByIdsData, error) } defaultChore struct { @@ -57,3 +62,9 @@ func (m *defaultChore) Regions(ctx context.Context, in *RegionsReq, opts ...grpc client := chore.NewChoreClient(m.cli.Conn()) return client.Regions(ctx, in, opts...) } + +// 服务间调用:按 id 批量查地区名称 +func (m *defaultChore) RegionsByIds(ctx context.Context, in *RegionsByIdsReq, opts ...grpc.CallOption) (*RegionsByIdsData, error) { + client := chore.NewChoreClient(m.cli.Conn()) + return client.RegionsByIds(ctx, in, opts...) +} diff --git a/services/chore/internal/logic/regionsByIdsLogic.go b/services/chore/internal/logic/regionsByIdsLogic.go new file mode 100644 index 0000000..de66fc2 --- /dev/null +++ b/services/chore/internal/logic/regionsByIdsLogic.go @@ -0,0 +1,71 @@ +package logic + +import ( + "context" + "strconv" + + "lone-services/pkg/modelbase" + "lone-services/pkg/utils" + chore "lone-services/rpc/chore/pb" + "lone-services/services/chore/internal/dao" + "lone-services/services/chore/internal/model" + "lone-services/services/chore/internal/svc" + + "github.com/zeromicro/go-zero/core/logx" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +type RegionsByIdsLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewRegionsByIdsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RegionsByIdsLogic { + return &RegionsByIdsLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +// 服务间调用:按 id 批量查地区名称 +func (l *RegionsByIdsLogic) RegionsByIds(in *chore.RegionsByIdsReq) (*chore.RegionsByIdsData, error) { + if len(in.GetIds()) < utils.NumberOne { + return nil, status.Error(codes.InvalidArgument, utils.ErrorParams.Msg) + } + + seen := make(map[int64]struct{}, len(in.GetIds())) + ids := make([]string, 0, len(in.GetIds())) + for _, id := range in.GetIds() { + if id < utils.NumberOne { + continue + } + if _, ok := seen[id]; ok { + continue + } + seen[id] = struct{}{} + ids = append(ids, strconv.FormatInt(id, 10)) + } + if len(ids) < utils.NumberOne { + return nil, status.Error(codes.InvalidArgument, utils.ErrorParams.Msg) + } + + var list []dao.Region + if err := (model.RegionModel{}.Init().Items(modelbase.Params{ + In: map[string][]string{"id in ?": ids}, + }, &list)); err != nil { + l.Errorf("regions by ids: %v", err) + return nil, status.Error(codes.Internal, utils.Fail.Msg) + } + + items := make([]*chore.RegionItem, 0, len(list)) + for _, row := range list { + items = append(items, &chore.RegionItem{ + Id: int64(row.Id), + Name: row.Name, + }) + } + return &chore.RegionsByIdsData{Items: items}, nil +} diff --git a/services/chore/internal/server/choreServer.go b/services/chore/internal/server/choreServer.go index 68390ab..866f5aa 100644 --- a/services/chore/internal/server/choreServer.go +++ b/services/chore/internal/server/choreServer.go @@ -42,3 +42,9 @@ func (s *ChoreServer) Regions(ctx context.Context, in *chore.RegionsReq) (*chore l := logic.NewRegionsLogic(ctx, s.svcCtx) return l.Regions(in) } + +// 服务间调用:按 id 批量查地区名称 +func (s *ChoreServer) RegionsByIds(ctx context.Context, in *chore.RegionsByIdsReq) (*chore.RegionsByIdsData, error) { + l := logic.NewRegionsByIdsLogic(ctx, s.svcCtx) + return l.RegionsByIds(in) +} diff --git a/services/sale/internal/logic/createLogic.go b/services/sale/internal/logic/createLogic.go index 394a772..85c5990 100644 --- a/services/sale/internal/logic/createLogic.go +++ b/services/sale/internal/logic/createLogic.go @@ -59,6 +59,28 @@ func (l *CreateLogic) Create(in *sale.CreateReq) (*sale.Response, error) { return failResponse(utils.ErrorDataIsExist), nil } + names, nErr := fetchRegionNames(l.ctx, l.svcCtx.ChoreSvcName, req.TerritoryId, req.ProvinceId, req.CityId, req.DistrictId) + if nErr != nil { + l.Errorf("sale regions: %v", nErr) + return failResponse(utils.Fail), nil + } + territoryName := names[req.TerritoryId] + if territoryName == utils.StringEmpty { + return outResponse(utils.ErrorParams, "请选择地域"), nil + } + province := names[req.ProvinceId] + if province == utils.StringEmpty { + return outResponse(utils.ErrorParams, "请选择省份"), nil + } + city := names[req.CityId] + if city == utils.StringEmpty { + return outResponse(utils.ErrorParams, "请选择城市"), nil + } + district := names[req.DistrictId] + if district == utils.StringEmpty { + return outResponse(utils.ErrorParams, "请选择区县"), nil + } + data := dao.SaleCreate{ SaleId: req.SaleId, Mobile: encryptMobile, @@ -66,12 +88,12 @@ func (l *CreateLogic) Create(in *sale.CreateReq) (*sale.Response, error) { IdCardFront: req.IdCardFront, IdCardBack: req.IdCardBack, BusinessLicense: req.BusinessLicense, - Region: buildRegion(req.RegionProvince, req.RegionCity, req.RegionDistrict), + Region: buildRegion(province, city, district), ProvinceId: req.ProvinceId, CityId: req.CityId, DistrictId: req.DistrictId, TerritoryId: req.TerritoryId, - TerritoryName: req.TerritoryName, + TerritoryName: territoryName, GroupId: req.GroupId, Address: req.Address, Status: dao.SaleStatusApproved, diff --git a/services/sale/internal/logic/editLogic.go b/services/sale/internal/logic/editLogic.go index de63da2..0074003 100644 --- a/services/sale/internal/logic/editLogic.go +++ b/services/sale/internal/logic/editLogic.go @@ -73,12 +73,33 @@ func (l *EditLogic) Edit(in *sale.EditReq) (*sale.Response, error) { info.IdCardFront = req.IdCardFront info.IdCardBack = req.IdCardBack info.BusinessLicense = req.BusinessLicense - info.Region = buildRegion(req.RegionProvince, req.RegionCity, req.RegionDistrict) + names, nErr := fetchRegionNames(l.ctx, l.svcCtx.ChoreSvcName, req.TerritoryId, req.ProvinceId, req.CityId, req.DistrictId) + if nErr != nil { + l.Errorf("sale regions: %v", nErr) + return failResponse(utils.Fail), nil + } + territoryName := names[req.TerritoryId] + if territoryName == utils.StringEmpty { + return outResponse(utils.ErrorParams, "请选择地域"), nil + } + province := names[req.ProvinceId] + if province == utils.StringEmpty { + return outResponse(utils.ErrorParams, "请选择省份"), nil + } + city := names[req.CityId] + if city == utils.StringEmpty { + return outResponse(utils.ErrorParams, "请选择城市"), nil + } + district := names[req.DistrictId] + if district == utils.StringEmpty { + return outResponse(utils.ErrorParams, "请选择区县"), nil + } + info.Region = buildRegion(province, city, district) info.ProvinceId = req.ProvinceId info.CityId = req.CityId info.DistrictId = req.DistrictId info.TerritoryId = req.TerritoryId - info.TerritoryName = req.TerritoryName + info.TerritoryName = territoryName info.GroupId = req.GroupId info.Address = req.Address info.Type = uint8(req.Type) diff --git a/services/sale/internal/logic/helper.go b/services/sale/internal/logic/helper.go index 4301e8d..c998717 100644 --- a/services/sale/internal/logic/helper.go +++ b/services/sale/internal/logic/helper.go @@ -1,10 +1,13 @@ package logic import ( + "context" "strconv" "lone-services/pkg/modelbase" + "lone-services/pkg/rpcclient" "lone-services/pkg/utils" + chore "lone-services/rpc/chore/pb" "lone-services/services/sale/internal/dao" "lone-services/services/sale/internal/model" "lone-services/services/sale/validator" @@ -26,6 +29,38 @@ func buildRegion(province, city, district string) dao.RegionNames { } } +func fetchRegionNames(ctx context.Context, choreSvcName string, ids ...int64) (map[int64]string, error) { + seen := make(map[int64]struct{}, len(ids)) + reqIds := make([]int64, 0, len(ids)) + for _, id := range ids { + if id < utils.NumberOne { + continue + } + if _, ok := seen[id]; ok { + continue + } + seen[id] = struct{}{} + reqIds = append(reqIds, id) + } + result := make(map[int64]string, len(reqIds)) + if len(reqIds) < utils.NumberOne { + return result, nil + } + + cli, err := rpcclient.Get(choreSvcName) + if err != nil { + return nil, err + } + res, err := chore.NewChoreClient(cli.Conn()).RegionsByIds(ctx, &chore.RegionsByIdsReq{Ids: reqIds}) + if err != nil { + return nil, err + } + for _, item := range res.GetItems() { + result[item.GetId()] = item.GetName() + } + return result, nil +} + func querySaleNames(req validator.NamesValidator) ([]dao.SaleNameItem, error) { w := modelbase.Params{ Eq: map[string]string{"status": strconv.Itoa(int(dao.SaleStatusApproved))}, diff --git a/services/sale/internal/server/saleServer.go b/services/sale/internal/server/saleServer.go index 572683a..c43d735 100644 --- a/services/sale/internal/server/saleServer.go +++ b/services/sale/internal/server/saleServer.go @@ -70,12 +70,6 @@ func (s *SaleServer) Info(ctx context.Context, in *sale.InfoReq) (*sale.Response return l.Info(in) } -// 服务间调用:销售详情(含分组;mobile 脱敏,origin_mobile 为加密串) -func (s *SaleServer) InfoInternal(ctx context.Context, in *sale.InfoReq) (*sale.InfoData, error) { - l := logic.NewInfoInternalLogic(ctx, s.svcCtx) - return l.InfoInternal(in) -} - func (s *SaleServer) Items(ctx context.Context, in *sale.ItemsReq) (*sale.Response, error) { l := logic.NewItemsLogic(ctx, s.svcCtx) return l.Items(in) @@ -85,3 +79,9 @@ func (s *SaleServer) Status(ctx context.Context, in *sale.StatusReq) (*sale.Resp l := logic.NewStatusLogic(ctx, s.svcCtx) return l.Status(in) } + +// 销售详情 +func (s *SaleServer) InfoInternal(ctx context.Context, in *sale.InfoReq) (*sale.InfoData, error) { + l := logic.NewInfoInternalLogic(ctx, s.svcCtx) + return l.InfoInternal(in) +} diff --git a/services/sale/internal/svc/serviceContext.go b/services/sale/internal/svc/serviceContext.go index 5985725..e5ebfba 100644 --- a/services/sale/internal/svc/serviceContext.go +++ b/services/sale/internal/svc/serviceContext.go @@ -4,19 +4,27 @@ import ( "lone-services/pkg/utils" "lone-services/services/sale/internal/config" + "github.com/zeromicro/go-zero/core/logx" "gorm.io/gorm" ) type ServiceContext struct { - Config config.Config - DB *gorm.DB - Prefix string + Config config.Config + DB *gorm.DB + Prefix string + ChoreSvcName string } func NewServiceContext(c config.Config, db *gorm.DB) *ServiceContext { + choreSvc := utils.GetConfigString("services.chore") + if choreSvc == utils.StringEmpty { + logx.Error("config services.chore empty") + } + return &ServiceContext{ - Config: c, - DB: db, - Prefix: utils.GetConfigString("mysql.prefix"), + Config: c, + DB: db, + Prefix: utils.GetConfigString("mysql.prefix"), + ChoreSvcName: choreSvc, } } diff --git a/services/sale/run.toml b/services/sale/run.toml index 05a692a..94aee8e 100644 --- a/services/sale/run.toml +++ b/services/sale/run.toml @@ -2,7 +2,7 @@ login_out_time=43200 #api接口超时时间分 login_refresh_out_time=83200 name = "sale-service" - listenOn = "0.0.0.0:10900" + listenOn = "0.0.0.0:10300" mode = "dev" [log] path = "logs" @@ -52,4 +52,7 @@ db = 0 [encrypt] - data_key = "u2t9T3luZtoRfhBstkFN6TiIMW38BA8a" \ No newline at end of file + data_key = "u2t9T3luZtoRfhBstkFN6TiIMW38BA8a" + +[services] + chore = "chore-service" \ No newline at end of file diff --git a/services/sale/saleClient/sale.go b/services/sale/saleClient/sale.go index 2700ee3..4d7ff6c 100644 --- a/services/sale/saleClient/sale.go +++ b/services/sale/saleClient/sale.go @@ -42,10 +42,10 @@ type ( Create(ctx context.Context, in *CreateReq, opts ...grpc.CallOption) (*Response, error) Edit(ctx context.Context, in *EditReq, opts ...grpc.CallOption) (*Response, error) Info(ctx context.Context, in *InfoReq, opts ...grpc.CallOption) (*Response, error) - // 服务间调用:销售详情(含分组;mobile 脱敏,origin_mobile 为加密串) - InfoInternal(ctx context.Context, in *InfoReq, opts ...grpc.CallOption) (*InfoData, error) Items(ctx context.Context, in *ItemsReq, opts ...grpc.CallOption) (*Response, error) Status(ctx context.Context, in *StatusReq, opts ...grpc.CallOption) (*Response, error) + // 销售详情 + InfoInternal(ctx context.Context, in *InfoReq, opts ...grpc.CallOption) (*InfoData, error) } defaultSale struct { @@ -106,12 +106,6 @@ func (m *defaultSale) Info(ctx context.Context, in *InfoReq, opts ...grpc.CallOp return client.Info(ctx, in, opts...) } -// 服务间调用:销售详情(含分组;mobile 脱敏,origin_mobile 为加密串) -func (m *defaultSale) InfoInternal(ctx context.Context, in *InfoReq, opts ...grpc.CallOption) (*InfoData, error) { - client := sale.NewSaleClient(m.cli.Conn()) - return client.InfoInternal(ctx, in, opts...) -} - func (m *defaultSale) Items(ctx context.Context, in *ItemsReq, opts ...grpc.CallOption) (*Response, error) { client := sale.NewSaleClient(m.cli.Conn()) return client.Items(ctx, in, opts...) @@ -121,3 +115,9 @@ func (m *defaultSale) Status(ctx context.Context, in *StatusReq, opts ...grpc.Ca client := sale.NewSaleClient(m.cli.Conn()) return client.Status(ctx, in, opts...) } + +// 销售详情 +func (m *defaultSale) InfoInternal(ctx context.Context, in *InfoReq, opts ...grpc.CallOption) (*InfoData, error) { + client := sale.NewSaleClient(m.cli.Conn()) + return client.InfoInternal(ctx, in, opts...) +} diff --git a/services/sale/validator/validator.go b/services/sale/validator/validator.go index 436185c..73716ce 100644 --- a/services/sale/validator/validator.go +++ b/services/sale/validator/validator.go @@ -56,44 +56,36 @@ type CreateValidator struct { SaleId int64 `validate:"omitempty,gte=0"` Type uint32 `validate:"required,oneof=1 2 3"` TerritoryId int64 `validate:"required,gt=0"` - TerritoryName string `validate:"required,max=255"` ProvinceId int64 `validate:"required,gt=0"` CityId int64 `validate:"required,gt=0"` DistrictId int64 `validate:"required,gt=0"` - RegionProvince string `validate:"required,max=64"` - RegionCity string `validate:"required,max=64"` - RegionDistrict string `validate:"required,max=64"` Address string `validate:"required,max=255"` } func (p CreateValidator) GetMessage() validate.ValidatorMessages { return validate.ValidatorMessages{ - "Mobile.required": "手机号不能为空", - "Name.required": "姓名不能为空", - "IdCardFront.required": "身份证正面不能为空", - "IdCardFront.max": "身份证正面地址过长", - "IdCardBack.required": "身份证反面不能为空", - "IdCardBack.max": "身份证反面地址过长", - "BusinessLicense.max": "营业执照地址过长", - "Password.required": "密码不能为空", - "Password.min": "密码长度不能小于6位", - "GroupId.required": "请选择销售分组", - "GroupId.gt": "请选择销售分组", - "Type.required": "请选择类型", - "Type.oneof": "类型不对", - "TerritoryId.required": "请选择地域", - "TerritoryId.gt": "请选择地域", - "TerritoryName.required": "地域名称不能为空", - "ProvinceId.required": "请选择省份", - "ProvinceId.gt": "请选择省份", - "CityId.required": "请选择城市", - "CityId.gt": "请选择城市", - "DistrictId.required": "请选择区县", - "DistrictId.gt": "请选择区县", - "RegionProvince.required": "地区省份不能为空", - "RegionCity.required": "地区城市不能为空", - "RegionDistrict.required": "地区区县不能为空", - "Address.required": "详细地址不能为空", + "Mobile.required": "手机号不能为空", + "Name.required": "姓名不能为空", + "IdCardFront.required": "身份证正面不能为空", + "IdCardFront.max": "身份证正面地址过长", + "IdCardBack.required": "身份证反面不能为空", + "IdCardBack.max": "身份证反面地址过长", + "BusinessLicense.max": "营业执照地址过长", + "Password.required": "密码不能为空", + "Password.min": "密码长度不能小于6位", + "GroupId.required": "请选择销售分组", + "GroupId.gt": "请选择销售分组", + "Type.required": "请选择类型", + "Type.oneof": "类型不对", + "TerritoryId.required": "请选择地域", + "TerritoryId.gt": "请选择地域", + "ProvinceId.required": "请选择省份", + "ProvinceId.gt": "请选择省份", + "CityId.required": "请选择城市", + "CityId.gt": "请选择城市", + "DistrictId.required": "请选择区县", + "DistrictId.gt": "请选择区县", + "Address.required": "详细地址不能为空", } } @@ -111,44 +103,36 @@ type EditValidator struct { SaleId int64 `validate:"omitempty,gte=0"` Type uint32 `validate:"required,oneof=1 2 3"` TerritoryId int64 `validate:"required,gt=0"` - TerritoryName string `validate:"required,max=255"` ProvinceId int64 `validate:"required,gt=0"` CityId int64 `validate:"required,gt=0"` DistrictId int64 `validate:"required,gt=0"` - RegionProvince string `validate:"required,max=64"` - RegionCity string `validate:"required,max=64"` - RegionDistrict string `validate:"required,max=64"` Address string `validate:"required,max=255"` } func (p EditValidator) GetMessage() validate.ValidatorMessages { return validate.ValidatorMessages{ - "Id.required": "ID不能为空", - "Id.gt": "ID必须大于0", - "Mobile.required": "手机号不能为空", - "Name.required": "姓名不能为空", - "IdCardFront.required": "身份证正面不能为空", - "IdCardFront.max": "身份证正面地址过长", - "IdCardBack.required": "身份证反面不能为空", - "IdCardBack.max": "身份证反面地址过长", - "BusinessLicense.max": "营业执照地址过长", - "GroupId.required": "请选择销售分组", - "GroupId.gt": "请选择销售分组", - "Type.required": "请选择类型", - "Type.oneof": "类型不对", - "TerritoryId.required": "请选择地域", - "TerritoryId.gt": "请选择地域", - "TerritoryName.required": "地域名称不能为空", - "ProvinceId.required": "请选择省份", - "ProvinceId.gt": "请选择省份", - "CityId.required": "请选择城市", - "CityId.gt": "请选择城市", - "DistrictId.required": "请选择区县", - "DistrictId.gt": "请选择区县", - "RegionProvince.required": "地区省份不能为空", - "RegionCity.required": "地区城市不能为空", - "RegionDistrict.required": "地区区县不能为空", - "Address.required": "详细地址不能为空", + "Id.required": "ID不能为空", + "Id.gt": "ID必须大于0", + "Mobile.required": "手机号不能为空", + "Name.required": "姓名不能为空", + "IdCardFront.required": "身份证正面不能为空", + "IdCardFront.max": "身份证正面地址过长", + "IdCardBack.required": "身份证反面不能为空", + "IdCardBack.max": "身份证反面地址过长", + "BusinessLicense.max": "营业执照地址过长", + "GroupId.required": "请选择销售分组", + "GroupId.gt": "请选择销售分组", + "Type.required": "请选择类型", + "Type.oneof": "类型不对", + "TerritoryId.required": "请选择地域", + "TerritoryId.gt": "请选择地域", + "ProvinceId.required": "请选择省份", + "ProvinceId.gt": "请选择省份", + "CityId.required": "请选择城市", + "CityId.gt": "请选择城市", + "DistrictId.required": "请选择区县", + "DistrictId.gt": "请选择区县", + "Address.required": "详细地址不能为空", } }