diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 1bee3d6..9b4bda6 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -26,7 +26,7 @@ jobs: - name: Detect changes id: filter run: | - SERVICES="bff product admin user ad chore express sale wecom task equipment" + SERVICES="bff product admin user ad chore express sale wecom task equipment lonelog" pattern_for() { case "$1" in @@ -92,6 +92,7 @@ jobs: - wecom - task - equipment + - log env: BUILD_LIST: ${{ needs.changes.outputs.build_list }} NAME: lone/${{ matrix.name }} diff --git a/pkg/utils/status.go b/pkg/utils/status.go index 6c9bda8..15808fa 100644 --- a/pkg/utils/status.go +++ b/pkg/utils/status.go @@ -64,6 +64,7 @@ const ( StatusAdminWaitPass = 19 //等待审核 StatusAdminSecondRefuse = 16 //审核失败 StatusDel = 7 //删除 + StatusFail = 2 //失败 RpcTimeOut = 5000 //服务连接超时时间 毫秒 ) diff --git a/rpc/order/order.pb b/rpc/order/order.pb index 291afcd..79a9892 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 786dad3..bdf99d0 100644 --- a/rpc/order/order.proto +++ b/rpc/order/order.proto @@ -109,6 +109,16 @@ message AdminCreateOrderRequest { int32 type =4; } +message UpdateOrderDeliverStatusRequest { + string sign_time = 1; + int32 deliver_status = 2; + string id = 3; +} + +message UpdateOrderDeliverStatusResponse { + int32 num = 1; +} + service order { rpc Items(OrderItemsRequest) returns(Response){ option (google.api.http) = { @@ -212,4 +222,5 @@ service order { body: "*" }; }; + rpc UpdateOrderDeliverStatus(UpdateOrderDeliverStatusRequest) returns(UpdateOrderDeliverStatusResponse); } \ No newline at end of file diff --git a/rpc/order/pb/order.pb.go b/rpc/order/pb/order.pb.go index 7c10060..3f3447c 100644 --- a/rpc/order/pb/order.pb.go +++ b/rpc/order/pb/order.pb.go @@ -1038,6 +1038,110 @@ func (x *AdminCreateOrderRequest) GetType() int32 { return 0 } +type UpdateOrderDeliverStatusRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + SignTime string `protobuf:"bytes,1,opt,name=sign_time,json=signTime,proto3" json:"sign_time,omitempty"` + DeliverStatus int32 `protobuf:"varint,2,opt,name=deliver_status,json=deliverStatus,proto3" json:"deliver_status,omitempty"` + Id string `protobuf:"bytes,3,opt,name=id,proto3" json:"id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateOrderDeliverStatusRequest) Reset() { + *x = UpdateOrderDeliverStatusRequest{} + mi := &file_order_order_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateOrderDeliverStatusRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateOrderDeliverStatusRequest) ProtoMessage() {} + +func (x *UpdateOrderDeliverStatusRequest) ProtoReflect() protoreflect.Message { + mi := &file_order_order_proto_msgTypes[16] + 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 UpdateOrderDeliverStatusRequest.ProtoReflect.Descriptor instead. +func (*UpdateOrderDeliverStatusRequest) Descriptor() ([]byte, []int) { + return file_order_order_proto_rawDescGZIP(), []int{16} +} + +func (x *UpdateOrderDeliverStatusRequest) GetSignTime() string { + if x != nil { + return x.SignTime + } + return "" +} + +func (x *UpdateOrderDeliverStatusRequest) GetDeliverStatus() int32 { + if x != nil { + return x.DeliverStatus + } + return 0 +} + +func (x *UpdateOrderDeliverStatusRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +type UpdateOrderDeliverStatusResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Num int32 `protobuf:"varint,1,opt,name=num,proto3" json:"num,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateOrderDeliverStatusResponse) Reset() { + *x = UpdateOrderDeliverStatusResponse{} + mi := &file_order_order_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateOrderDeliverStatusResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateOrderDeliverStatusResponse) ProtoMessage() {} + +func (x *UpdateOrderDeliverStatusResponse) ProtoReflect() protoreflect.Message { + mi := &file_order_order_proto_msgTypes[17] + 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 UpdateOrderDeliverStatusResponse.ProtoReflect.Descriptor instead. +func (*UpdateOrderDeliverStatusResponse) Descriptor() ([]byte, []int) { + return file_order_order_proto_rawDescGZIP(), []int{17} +} + +func (x *UpdateOrderDeliverStatusResponse) GetNum() int32 { + if x != nil { + return x.Num + } + return 0 +} + var File_order_order_proto protoreflect.FileDescriptor const file_order_order_proto_rawDesc = "" + @@ -1119,7 +1223,13 @@ const file_order_order_proto_rawDesc = "" + "address_id\x18\x01 \x01(\x03R\taddressId\x12\x12\n" + "\x04note\x18\x02 \x01(\tR\x04note\x12\x12\n" + "\x04info\x18\x03 \x01(\tR\x04info\x12\x12\n" + - "\x04type\x18\x04 \x01(\x05R\x04type2\xf4\v\n" + + "\x04type\x18\x04 \x01(\x05R\x04type\"u\n" + + "\x1fUpdateOrderDeliverStatusRequest\x12\x1b\n" + + "\tsign_time\x18\x01 \x01(\tR\bsignTime\x12%\n" + + "\x0edeliver_status\x18\x02 \x01(\x05R\rdeliverStatus\x12\x0e\n" + + "\x02id\x18\x03 \x01(\tR\x02id\"4\n" + + " UpdateOrderDeliverStatusResponse\x12\x10\n" + + "\x03num\x18\x01 \x01(\x05R\x03num2\xe1\f\n" + "\x05order\x12T\n" + "\x05Items\x12\x18.order.OrderItemsRequest\x1a\x0f.order.Response\" \x82\xd3\xe4\x93\x02\x1a:\x01*\x12\x15/admin/v3/order/items\x12X\n" + "\tWebCreate\x12\x19.order.CreateOrderRequest\x1a\x0f.order.Response\"\x1f\x82\xd3\xe4\x93\x02\x19:\x01*\"\x14/api/v3/order/create\x12b\n" + @@ -1136,7 +1246,8 @@ const file_order_order_proto_rawDesc = "" + "\x0eAddressByStore\x12!.order.AddressByStoreItemsRequest\x1a\x0f.order.Response\"(\x82\xd3\xe4\x93\x02\":\x01*\x12\x1d/admin/v3/address/store/items\x12r\n" + "\x12OrderAuditingItems\x12 .order.OrderAuditingItemsRequest\x1a\x0f.order.Response\")\x82\xd3\xe4\x93\x02#:\x01*\x12\x1e/admin/v3/order/auditing/items\x12b\n" + "\rOrderAuditing\x12\x1b.order.OrderAuditingRequest\x1a\x0f.order.Response\"#\x82\xd3\xe4\x93\x02\x1d:\x01*\"\x18/admin/v3/order/auditing\x12a\n" + - "\vOrderCreate\x12\x1e.order.AdminCreateOrderRequest\x1a\x0f.order.Response\"!\x82\xd3\xe4\x93\x02\x1b:\x01*\"\x16/admin/v3/order/createB\x19Z\x17lone-services/rpc/orderb\x06proto3" + "\vOrderCreate\x12\x1e.order.AdminCreateOrderRequest\x1a\x0f.order.Response\"!\x82\xd3\xe4\x93\x02\x1b:\x01*\"\x16/admin/v3/order/create\x12k\n" + + "\x18UpdateOrderDeliverStatus\x12&.order.UpdateOrderDeliverStatusRequest\x1a'.order.UpdateOrderDeliverStatusResponseB\x19Z\x17lone-services/rpc/orderb\x06proto3" var ( file_order_order_proto_rawDescOnce sync.Once @@ -1150,24 +1261,26 @@ func file_order_order_proto_rawDescGZIP() []byte { return file_order_order_proto_rawDescData } -var file_order_order_proto_msgTypes = make([]protoimpl.MessageInfo, 16) +var file_order_order_proto_msgTypes = make([]protoimpl.MessageInfo, 18) var file_order_order_proto_goTypes = []any{ - (*OrderItemsRequest)(nil), // 0: order.OrderItemsRequest - (*Response)(nil), // 1: order.Response - (*CreateOrderRequest)(nil), // 2: order.CreateOrderRequest - (*CreateOrderOneRequest)(nil), // 3: order.CreateOrderOneRequest - (*EditAddressRequest)(nil), // 4: order.EditAddressRequest - (*EmptyRequest)(nil), // 5: order.EmptyRequest - (*EditCartRequest)(nil), // 6: order.EditCartRequest - (*CartRequest)(nil), // 7: order.CartRequest - (*IdRequest)(nil), // 8: order.IdRequest - (*IdAndTypeRequest)(nil), // 9: order.IdAndTypeRequest - (*TypeRequest)(nil), // 10: order.TypeRequest - (*AddressItemsRequest)(nil), // 11: order.AddressItemsRequest - (*AddressByStoreItemsRequest)(nil), // 12: order.AddressByStoreItemsRequest - (*OrderAuditingItemsRequest)(nil), // 13: order.OrderAuditingItemsRequest - (*OrderAuditingRequest)(nil), // 14: order.OrderAuditingRequest - (*AdminCreateOrderRequest)(nil), // 15: order.AdminCreateOrderRequest + (*OrderItemsRequest)(nil), // 0: order.OrderItemsRequest + (*Response)(nil), // 1: order.Response + (*CreateOrderRequest)(nil), // 2: order.CreateOrderRequest + (*CreateOrderOneRequest)(nil), // 3: order.CreateOrderOneRequest + (*EditAddressRequest)(nil), // 4: order.EditAddressRequest + (*EmptyRequest)(nil), // 5: order.EmptyRequest + (*EditCartRequest)(nil), // 6: order.EditCartRequest + (*CartRequest)(nil), // 7: order.CartRequest + (*IdRequest)(nil), // 8: order.IdRequest + (*IdAndTypeRequest)(nil), // 9: order.IdAndTypeRequest + (*TypeRequest)(nil), // 10: order.TypeRequest + (*AddressItemsRequest)(nil), // 11: order.AddressItemsRequest + (*AddressByStoreItemsRequest)(nil), // 12: order.AddressByStoreItemsRequest + (*OrderAuditingItemsRequest)(nil), // 13: order.OrderAuditingItemsRequest + (*OrderAuditingRequest)(nil), // 14: order.OrderAuditingRequest + (*AdminCreateOrderRequest)(nil), // 15: order.AdminCreateOrderRequest + (*UpdateOrderDeliverStatusRequest)(nil), // 16: order.UpdateOrderDeliverStatusRequest + (*UpdateOrderDeliverStatusResponse)(nil), // 17: order.UpdateOrderDeliverStatusResponse } var file_order_order_proto_depIdxs = []int32{ 0, // 0: order.order.Items:input_type -> order.OrderItemsRequest @@ -1186,24 +1299,26 @@ var file_order_order_proto_depIdxs = []int32{ 13, // 13: order.order.OrderAuditingItems:input_type -> order.OrderAuditingItemsRequest 14, // 14: order.order.OrderAuditing:input_type -> order.OrderAuditingRequest 15, // 15: order.order.OrderCreate:input_type -> order.AdminCreateOrderRequest - 1, // 16: order.order.Items:output_type -> order.Response - 1, // 17: order.order.WebCreate:output_type -> order.Response - 1, // 18: order.order.WebCreateOne:output_type -> order.Response - 1, // 19: order.order.WebAddressCreate:output_type -> order.Response - 1, // 20: order.order.WebAddressEdit:output_type -> order.Response - 1, // 21: order.order.WebAddressDel:output_type -> order.Response - 1, // 22: order.order.WebAddressDef:output_type -> order.Response - 1, // 23: order.order.WebAddressInfo:output_type -> order.Response - 1, // 24: order.order.WebAddressItems:output_type -> order.Response - 1, // 25: order.order.WebCart:output_type -> order.Response - 1, // 26: order.order.WebCartEdit:output_type -> order.Response - 1, // 27: order.order.AddressItem:output_type -> order.Response - 1, // 28: order.order.AddressByStore:output_type -> order.Response - 1, // 29: order.order.OrderAuditingItems:output_type -> order.Response - 1, // 30: order.order.OrderAuditing:output_type -> order.Response - 1, // 31: order.order.OrderCreate:output_type -> order.Response - 16, // [16:32] is the sub-list for method output_type - 0, // [0:16] is the sub-list for method input_type + 16, // 16: order.order.UpdateOrderDeliverStatus:input_type -> order.UpdateOrderDeliverStatusRequest + 1, // 17: order.order.Items:output_type -> order.Response + 1, // 18: order.order.WebCreate:output_type -> order.Response + 1, // 19: order.order.WebCreateOne:output_type -> order.Response + 1, // 20: order.order.WebAddressCreate:output_type -> order.Response + 1, // 21: order.order.WebAddressEdit:output_type -> order.Response + 1, // 22: order.order.WebAddressDel:output_type -> order.Response + 1, // 23: order.order.WebAddressDef:output_type -> order.Response + 1, // 24: order.order.WebAddressInfo:output_type -> order.Response + 1, // 25: order.order.WebAddressItems:output_type -> order.Response + 1, // 26: order.order.WebCart:output_type -> order.Response + 1, // 27: order.order.WebCartEdit:output_type -> order.Response + 1, // 28: order.order.AddressItem:output_type -> order.Response + 1, // 29: order.order.AddressByStore:output_type -> order.Response + 1, // 30: order.order.OrderAuditingItems:output_type -> order.Response + 1, // 31: order.order.OrderAuditing:output_type -> order.Response + 1, // 32: order.order.OrderCreate:output_type -> order.Response + 17, // 33: order.order.UpdateOrderDeliverStatus:output_type -> order.UpdateOrderDeliverStatusResponse + 17, // [17:34] is the sub-list for method output_type + 0, // [0:17] 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 @@ -1220,7 +1335,7 @@ func file_order_order_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_order_order_proto_rawDesc), len(file_order_order_proto_rawDesc)), NumEnums: 0, - NumMessages: 16, + NumMessages: 18, NumExtensions: 0, NumServices: 1, }, diff --git a/rpc/order/pb/order_grpc.pb.go b/rpc/order/pb/order_grpc.pb.go index cf3fd83..edd1347 100644 --- a/rpc/order/pb/order_grpc.pb.go +++ b/rpc/order/pb/order_grpc.pb.go @@ -19,22 +19,23 @@ import ( const _ = grpc.SupportPackageIsVersion9 const ( - Order_Items_FullMethodName = "/order.order/Items" - Order_WebCreate_FullMethodName = "/order.order/WebCreate" - Order_WebCreateOne_FullMethodName = "/order.order/WebCreateOne" - Order_WebAddressCreate_FullMethodName = "/order.order/WebAddressCreate" - Order_WebAddressEdit_FullMethodName = "/order.order/WebAddressEdit" - Order_WebAddressDel_FullMethodName = "/order.order/WebAddressDel" - Order_WebAddressDef_FullMethodName = "/order.order/WebAddressDef" - Order_WebAddressInfo_FullMethodName = "/order.order/WebAddressInfo" - Order_WebAddressItems_FullMethodName = "/order.order/WebAddressItems" - Order_WebCart_FullMethodName = "/order.order/WebCart" - Order_WebCartEdit_FullMethodName = "/order.order/WebCartEdit" - Order_AddressItem_FullMethodName = "/order.order/AddressItem" - Order_AddressByStore_FullMethodName = "/order.order/AddressByStore" - Order_OrderAuditingItems_FullMethodName = "/order.order/OrderAuditingItems" - Order_OrderAuditing_FullMethodName = "/order.order/OrderAuditing" - Order_OrderCreate_FullMethodName = "/order.order/OrderCreate" + Order_Items_FullMethodName = "/order.order/Items" + Order_WebCreate_FullMethodName = "/order.order/WebCreate" + Order_WebCreateOne_FullMethodName = "/order.order/WebCreateOne" + Order_WebAddressCreate_FullMethodName = "/order.order/WebAddressCreate" + Order_WebAddressEdit_FullMethodName = "/order.order/WebAddressEdit" + Order_WebAddressDel_FullMethodName = "/order.order/WebAddressDel" + Order_WebAddressDef_FullMethodName = "/order.order/WebAddressDef" + Order_WebAddressInfo_FullMethodName = "/order.order/WebAddressInfo" + Order_WebAddressItems_FullMethodName = "/order.order/WebAddressItems" + Order_WebCart_FullMethodName = "/order.order/WebCart" + Order_WebCartEdit_FullMethodName = "/order.order/WebCartEdit" + Order_AddressItem_FullMethodName = "/order.order/AddressItem" + Order_AddressByStore_FullMethodName = "/order.order/AddressByStore" + Order_OrderAuditingItems_FullMethodName = "/order.order/OrderAuditingItems" + Order_OrderAuditing_FullMethodName = "/order.order/OrderAuditing" + Order_OrderCreate_FullMethodName = "/order.order/OrderCreate" + Order_UpdateOrderDeliverStatus_FullMethodName = "/order.order/UpdateOrderDeliverStatus" ) // OrderClient is the client API for Order service. @@ -57,6 +58,7 @@ type OrderClient interface { OrderAuditingItems(ctx context.Context, in *OrderAuditingItemsRequest, opts ...grpc.CallOption) (*Response, error) OrderAuditing(ctx context.Context, in *OrderAuditingRequest, opts ...grpc.CallOption) (*Response, error) OrderCreate(ctx context.Context, in *AdminCreateOrderRequest, opts ...grpc.CallOption) (*Response, error) + UpdateOrderDeliverStatus(ctx context.Context, in *UpdateOrderDeliverStatusRequest, opts ...grpc.CallOption) (*UpdateOrderDeliverStatusResponse, error) } type orderClient struct { @@ -227,6 +229,16 @@ func (c *orderClient) OrderCreate(ctx context.Context, in *AdminCreateOrderReque return out, nil } +func (c *orderClient) UpdateOrderDeliverStatus(ctx context.Context, in *UpdateOrderDeliverStatusRequest, opts ...grpc.CallOption) (*UpdateOrderDeliverStatusResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(UpdateOrderDeliverStatusResponse) + err := c.cc.Invoke(ctx, Order_UpdateOrderDeliverStatus_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + // OrderServer is the server API for Order service. // All implementations must embed UnimplementedOrderServer // for forward compatibility. @@ -247,6 +259,7 @@ type OrderServer interface { OrderAuditingItems(context.Context, *OrderAuditingItemsRequest) (*Response, error) OrderAuditing(context.Context, *OrderAuditingRequest) (*Response, error) OrderCreate(context.Context, *AdminCreateOrderRequest) (*Response, error) + UpdateOrderDeliverStatus(context.Context, *UpdateOrderDeliverStatusRequest) (*UpdateOrderDeliverStatusResponse, error) mustEmbedUnimplementedOrderServer() } @@ -305,6 +318,9 @@ func (UnimplementedOrderServer) OrderAuditing(context.Context, *OrderAuditingReq func (UnimplementedOrderServer) OrderCreate(context.Context, *AdminCreateOrderRequest) (*Response, error) { return nil, status.Error(codes.Unimplemented, "method OrderCreate not implemented") } +func (UnimplementedOrderServer) UpdateOrderDeliverStatus(context.Context, *UpdateOrderDeliverStatusRequest) (*UpdateOrderDeliverStatusResponse, error) { + return nil, status.Error(codes.Unimplemented, "method UpdateOrderDeliverStatus not implemented") +} func (UnimplementedOrderServer) mustEmbedUnimplementedOrderServer() {} func (UnimplementedOrderServer) testEmbeddedByValue() {} @@ -614,6 +630,24 @@ func _Order_OrderCreate_Handler(srv interface{}, ctx context.Context, dec func(i return interceptor(ctx, in, info, handler) } +func _Order_UpdateOrderDeliverStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateOrderDeliverStatusRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(OrderServer).UpdateOrderDeliverStatus(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Order_UpdateOrderDeliverStatus_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(OrderServer).UpdateOrderDeliverStatus(ctx, req.(*UpdateOrderDeliverStatusRequest)) + } + return interceptor(ctx, in, info, handler) +} + // Order_ServiceDesc is the grpc.ServiceDesc for Order service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -685,6 +719,10 @@ var Order_ServiceDesc = grpc.ServiceDesc{ MethodName: "OrderCreate", Handler: _Order_OrderCreate_Handler, }, + { + MethodName: "UpdateOrderDeliverStatus", + Handler: _Order_UpdateOrderDeliverStatus_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "order/order.proto", diff --git a/services/express/internal/dao/deliveryOrder.go b/services/express/internal/dao/deliveryOrder.go index b22835d..e08ee6d 100644 --- a/services/express/internal/dao/deliveryOrder.go +++ b/services/express/internal/dao/deliveryOrder.go @@ -3,16 +3,26 @@ package dao import "lone-services/pkg/utils" const ( - DeliverTypeOrder = 1 //订单 - DeliverTypeSupply = 3 //补货 + DeliveryTypeOrder = 1 //订单 + DeliveryTypeSupply = 3 //补货 SendStatusOver = 1 //为已签收 SendStatusWait = 2 //为待发货 SendStatusIn = 3 //为发货中 SendStatusOk = 4 //为已发货 SendStatusCancel = 5 //已取消 + + DeliverySendTypeSf uint8 = 1 + DeliverySendTypeJd uint8 = 2 + DeliverySendTypeOther uint8 = 3 ) +var DeliverySendType = map[uint8]string{ + DeliverySendTypeSf: "SF", // 示例 + DeliverySendTypeJd: "JD", + DeliverySendTypeOther: "ZT", +} + type DeliveryOrderCreate struct { Id int64 `gorm:"column:id;type:int(11);primary_key;AUTO_INCREMENT;comment:ID" json:"id"` ObjId string `gorm:"column:obj_id;type:varchar(255);comment:对像id" json:"obj_id"` @@ -112,3 +122,11 @@ type DeliveryOrderPrintEdit struct { SendTime utils.CustomTime `gorm:"column:send_time;type:datetime;comment:发货时间" json:"send_time"` CreateTime utils.CustomTime `gorm:"column:create_time;type:datetime;default:CURRENT_TIMESTAMP;comment:添加时间" json:"create_time"` } + +type ProductPrint struct { + Id int `gorm:"column:id;type:int(11);primary_key;AUTO_INCREMENT;comment:ID" json:"id"` + Name string `gorm:"column:name;type:varchar(256);comment:产品名;NOT NULL" json:"name"` + Weight float32 `gorm:"column:weight;type:decimal(10,3);comment:重量" json:"weight"` + Cubage string `gorm:"column:cubage;type:varchar(255);comment:体积" json:"cubage"` + Waybill string `gorm:"column:waybill;type:varchar(255);comment:运货单图片" json:"waybill"` +} diff --git a/services/express/internal/dao/express.go b/services/express/internal/dao/express.go index e391fe0..a9df9c2 100644 --- a/services/express/internal/dao/express.go +++ b/services/express/internal/dao/express.go @@ -1,5 +1,10 @@ package dao +const ( + ExpressCompanySf = 1 //顺丰 + ExpressCompanyJd = 2 //京东 +) + type Express struct { Id int64 `json:"id" gorm:"id"` // ID Name string `json:"name" gorm:"name"` // 名称 diff --git a/services/express/internal/logic/expressDeliveringLogic.go b/services/express/internal/logic/expressDeliveringLogic.go index 32ae23b..83d0258 100644 --- a/services/express/internal/logic/expressDeliveringLogic.go +++ b/services/express/internal/logic/expressDeliveringLogic.go @@ -2,13 +2,27 @@ package logic import ( "context" + "errors" + "fmt" + "io" "lone-services/pkg/modelbase" "lone-services/pkg/utils" "lone-services/rpc/express/pb" + order "lone-services/rpc/order/pb" + product "lone-services/rpc/product/pb" "lone-services/services/express/internal/dao" "lone-services/services/express/internal/model" "lone-services/services/express/internal/svc" + "lone-services/services/express/internal/transit" + "lone-services/services/express/validator" + "math" + "math/rand" + "net/http" + "os" + "path/filepath" "strconv" + "strings" + "time" "github.com/zeromicro/go-zero/core/logx" ) @@ -30,6 +44,14 @@ func NewExpressDeliveringLogic(ctx context.Context, svcCtx *svc.ServiceContext) // ExpressDelivering 发货 func (l *ExpressDeliveringLogic) ExpressDelivering(in *express.DeliveringRequest) (*express.Response, error) { + var v validator.DeliveringValidator + 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) + } var itemsEdit []dao.DeliveryOrderPrintEdit w := modelbase.Params{ Eq: map[string]string{"id": strconv.FormatInt(in.Id, utils.NumberTen)}} @@ -49,371 +71,460 @@ func (l *ExpressDeliveringLogic) ExpressDelivering(in *express.DeliveringRequest return l.fail(utils.ErrorOrderOver) } - //if transitId < dao.NumberOne { - // transitId = utils.GetConfigInt("transit.send_id") - //} - //tw := models.Params{Eq: map[string]string{"id": strconv.Itoa(transitId)}} - //var transitInfo dao.TransitSend - //err = models.TransitModel{}.Init().GetOne(tw, &transitInfo) - //if err != nil { - // utils.Logger.Error("发货地址信息没有找到", transitId, err) - // return dao.DeliverGoodsPrint{}, utils.Define(utils.ErrorNotFund, "没有查询到发货信息") - //} - //if transitInfo.Id < dao.NumberOne { - // return dao.DeliverGoodsPrint{}, utils.Define(utils.ErrorNotFund, "没有查询到发货信息") - //} - // - //var items []dao.DeliverGoodsPrint - //items = append(items, dao.DeliverGoodsPrint{ - // DeliverGoodsPrintEdit: itemsEdit[dao.NumberZero], - //}) - //s.getOrderInfo(&items) - //info := itemsEdit[dao.NumberZero] - ////更新使用的快递类型 - //info.TransitType = transitInfo.TransitId - // - //info.OrderSn = s.getOrderSn(info.TransitType, u.Id) - //items[dao.NumberZero].OrderSn = info.OrderSn - //status := info.Status - //client, res, cErr := s.createTransit(items[dao.NumberZero], transitInfo) - //if cErr != nil { - // return dao.DeliverGoodsPrint{}, cErr - //} - //info.TransitInfo = res.PostInfo - //info.TransitContent = res.RequestInfo - //info.TransitSn = strings.Join(res.WaybillNo, utils.DecollatorComma) - // - //items[dao.NumberZero].AdminName = u.Name - //res2, gErr := s.getDown(client, res.WaybillNo, items[dao.NumberZero]) - //if gErr != nil { - // s.cancel(client, w, info, status) - // utils.Logger.Error(res2, gErr) - // return dao.DeliverGoodsPrint{}, utils.Define(utils.ErrorNotFund, "下载发货单出错") - //} - // - //info.Express = utils.StructToJson(res2.Files) - //info.PrintStatus = dao.StatusOk - //info.AdminId = u.Id - //info.AdminName = u.Name - //info.TransitId = transitId - //info.TransitName = transitInfo.Name - //info.Status = models.SendStatusOk - //info.SendTime = utils.Now() - // - //items[dao.NumberZero].PrintStatus = info.PrintStatus - //items[dao.NumberZero].AdminId = info.AdminId - //items[dao.NumberZero].AdminName = info.AdminName - //items[dao.NumberZero].TransitId = info.TransitId - //items[dao.NumberZero].TransitInfo = info.TransitInfo - //items[dao.NumberZero].TransitContent = info.TransitContent - //items[dao.NumberZero].TransitSn = info.TransitSn - //items[dao.NumberZero].TransitName = info.TransitName - //items[dao.NumberZero].Status = info.Status - //items[dao.NumberZero].Express = info.Express - // - //var history dao.DeliverGoodsHistoryCreate - //history.DeliverId = info.Id - //history.TransitName = models.DeliverSendType[info.TransitType] - //history.TransitInfo = info.TransitInfo - //history.TransitContent = info.TransitContent - //history.TransitType = info.TransitType - //history.OrderSn = info.OrderSn - // - //var exps []dao.DeliverGoodsExpCreate - //for i := 0; i < len(res.WaybillNo); i++ { - // exps = append(exps, dao.DeliverGoodsExpCreate{ - // DeliverGoodsId: info.Id, - // TransitType: info.TransitType, - // ExpSn: res.WaybillNo[i], - // OrderSn: info.OrderSn, - // }) - //} - // - //sErr := s.saveDelever(w, &info, &history, &exps) - //if sErr != nil { - // s.cancel(client, w, info, status) - // utils.Logger.Error(res2, sErr) - // return dao.DeliverGoodsPrint{}, sErr - //} - // - //return items[dao.NumberZero], nil + tw := modelbase.Params{Eq: map[string]string{"id": strconv.FormatInt(in.TransitId, utils.NumberTen)}} + var transitInfo dao.ExpressSend + err = model.ExpressModel{}.Init().GetOne(tw, &transitInfo) + if err != nil { + l.Logger.Error("发货地址信息没有找到", in.TransitId, err) + return l.out(utils.ErrorNotFund, "没有查询到发货信息") + } + if transitInfo.Id < utils.NumberOne { + return l.out(utils.ErrorNotFund, "没有查询到发货信息") + } - return &express.Response{}, nil + var items []dao.DeliveryOrderPrint + items = append(items, dao.DeliveryOrderPrint{ + DeliveryOrderPrintEdit: itemsEdit[utils.NumberZero], + }) + gStatus := l.getOrderInfo(&items) + if gStatus != utils.Ok { + return l.fail(gStatus) + } + info := itemsEdit[utils.NumberZero] + //更新使用的快递类型 + info.TransitType = transitInfo.TransitId + + info.OrderSn = l.getOrderSn(info.TransitType, int(adminInfo.ID)) + items[utils.NumberZero].OrderSn = info.OrderSn + status := info.Status + client, res, cErr := l.createTransit(items[utils.NumberZero], transitInfo) + if cErr != utils.Ok { + return l.fail(cErr) + } + info.TransitInfo = res.PostInfo + info.TransitContent = res.RequestInfo + info.TransitSn = strings.Join(res.WaybillNo, utils.DecollatorComma) + + items[utils.NumberZero].AdminName = adminInfo.Name + res2, gErr := l.getDown(client, res.WaybillNo, items[utils.NumberZero]) + if gErr != nil { + l.cancel(client, w, info, status) + l.Logger.Error(res2, gErr) + return l.fail(utils.SetError(utils.ErrorNotFund, "下载发货单出错")) + } + + info.Express = utils.StructToJson(res2.Files) + info.PrintStatus = utils.StatusOk + info.AdminId = int(adminInfo.ID) + info.AdminName = adminInfo.Name + info.TransitId = int(in.TransitId) + info.TransitName = transitInfo.Name + info.Status = dao.SendStatusOk + info.SendTime = utils.Now() + + items[utils.NumberZero].PrintStatus = info.PrintStatus + items[utils.NumberZero].AdminId = info.AdminId + items[utils.NumberZero].AdminName = info.AdminName + items[utils.NumberZero].TransitId = info.TransitId + items[utils.NumberZero].TransitInfo = info.TransitInfo + items[utils.NumberZero].TransitContent = info.TransitContent + items[utils.NumberZero].TransitSn = info.TransitSn + items[utils.NumberZero].TransitName = info.TransitName + items[utils.NumberZero].Status = info.Status + items[utils.NumberZero].Express = info.Express + + var history dao.DeliveryHistoryCreate + history.DeliverId = info.Id + history.TransitName = dao.DeliverySendType[info.TransitType] + history.TransitInfo = info.TransitInfo + history.TransitContent = info.TransitContent + history.TransitType = info.TransitType + history.OrderSn = info.OrderSn + + var exps []dao.DeliveryExpCreate + for i := 0; i < len(res.WaybillNo); i++ { + exps = append(exps, dao.DeliveryExpCreate{ + DeliveryOrderId: info.Id, + TransitType: info.TransitType, + ExpSn: res.WaybillNo[i], + OrderSn: info.OrderSn, + }) + } + + sErr := l.saveDelever(w, &info, &history, &exps) + if sErr != utils.Ok { + l.cancel(client, w, info, status) + l.Logger.Error(res2, sErr) + return l.fail(sErr) + } + + return l.ok(items[utils.NumberZero]) } -//func (l *ExpressDeliveringLogic) createTransit(info dao.DeliverGoodsPrint, transitInfo dao.TransitSend) (transit.Transit, transit.TransitResult, utils.Error) { -// var client transit.Transit -// switch transitInfo.TransitId { -// case models.TransitCompanySf: -// client = transit.NewSfClient(transitInfo) -// case models.TransitCompanyJd: -// client = transit.NewJdClient(transitInfo) -// default: -// return client, transit.TransitResult{}, utils.Define(utils.Fail, "不支持的快递公司") -// } -// res, err := client.Create(info) -// if err != nil || res.ErrorCode != dao.StatusOkString { -// utils.Logger.Error("create transit err", err, res) -// return client, res, utils.Define(utils.Fail, res.ApiErrorMsg) -// } -// -// return client, res, nil -//} -// -//func (l *ExpressDeliveringLogic) saveDelever(w models.Params, info *dao.DeliverGoodsPrintEdit, history *dao.DeliverGoodsHistoryCreate, exps *[]dao.DeliverGoodsExpCreate) utils.Error { -// model := models.DeliverGoodsModel{}.Init() -// model.Begin() -// edit, err := model.Edit(w, info) -// if err != nil || edit < utils.NumberOne { -// model.Rollback() -// utils.Logger.Error("save deliver goods err ", err) -// return utils.Define(utils.Fail, "生成快递单失败") -// } -// -// err = models.DeliverGoodsExpModel{}.Init().CreateMulti(exps) -// if err != nil { -// model.Rollback() -// utils.Logger.Error("save exp err ", err) -// return utils.Define(utils.Fail, "生成EXP失败") -// } -// -// err = models.DeliverGoodsHistoryModel{}.Init().Create(history) -// if err != nil { -// model.Rollback() -// utils.Logger.Error("save history err ", err) -// return utils.Define(utils.Fail, "生成订单历史失败") -// } -// -// if info.Type == models.DeliverTypeOrder { -// w = models.Params{Eq: map[string]string{"id": info.ObjId}} -// orderStatus := dao.OrderDeliverGoodsStatus{ -// DeliverStatus: info.Status, -// } -// _, err = models.OrderModel{}.Init().Edit(w, &orderStatus) -// if err != nil { -// model.Rollback() -// utils.Logger.Error("save update order err ", err) -// return utils.Define(utils.Fail, "更新订单状态失败") -// } -// } -// -// model.Commit() -// return nil -//} +func (l *ExpressDeliveringLogic) saveDelever(w modelbase.Params, info *dao.DeliveryOrderPrintEdit, history *dao.DeliveryHistoryCreate, exps *[]dao.DeliveryExpCreate) utils.Status { + modelObj := model.DeliveryOrderModel{}.Init() + modelObj.Begin() + edit, err := modelObj.Edit(w, info) + if err != nil || edit < utils.NumberOne { + modelObj.Rollback() + l.Logger.Error("save deliver goods err ", err) + return utils.SetError(utils.Fail, "生成快递单失败") + } -//func (l *ExpressDeliveringLogic) getOrderInfo(items *[]dao.DeliverGoodsPrint) { -// products := s.getProducts() -// for value, item := range *items { -// obj := &(*items)[value] -// mobile, aErr := utils.Crypto{}.AESDecryptECB(item.Mobile) -// if aErr == nil { -// obj.Mobile = mobile -// } -// obj.Url = utils.GetConfigString("transit.url") -// obj.Number, obj.Weight, obj.ProductItems = s.getProductInfo(item.ObjSn, item.ProductInfo, &products) -// } -//} + err = model.DeliveryOrderExpModel{}.Init().CreateMulti(exps) + if err != nil { + modelObj.Rollback() + l.Logger.Error("save exp err ", err) + return utils.SetError(utils.Fail, "生成EXP失败") + } -//func (l *ExpressDeliveringLogic) getOrderSn(orderType uint8, adminId int) string { -// first := models.DeliverSendType[orderType] -// -// sn := first + time.Now().Format("20060102150405") -// sn += fmt.Sprintf("%d%d", orderType, adminId) -// randomNum := rand.Intn(90000000) + 10000000 -// sn += fmt.Sprintf("%d", randomNum) -// -// return sn -//} -// -//func (l *ExpressDeliveringLogic) createTransit(info dao.DeliverGoodsPrint, transitInfo dao.TransitSend) (transit.Transit, transit.TransitResult, utils.Error) { -// var client transit.Transit -// switch transitInfo.TransitId { -// case models.TransitCompanySf: -// client = transit.NewSfClient(transitInfo) -// case models.TransitCompanyJd: -// client = transit.NewJdClient(transitInfo) -// default: -// return client, transit.TransitResult{}, utils.Define(utils.Fail, "不支持的快递公司") -// } -// res, err := client.Create(info) -// if err != nil || res.ErrorCode != dao.StatusOkString { -// utils.Logger.Error("create transit err", err, res) -// return client, res, utils.Define(utils.Fail, res.ApiErrorMsg) -// } -// -// return client, res, nil -//} + err = model.DeliveryHistoryModel{}.Init().Create(history) + if err != nil { + modelObj.Rollback() + l.Logger.Error("save history err ", err) + return utils.SetError(utils.Fail, "生成订单历史失败") + } -//func (s PrintService) getDown(client transit.Transit, orders []string, info dao.DeliverGoodsPrint) (transit.TransitResult, error) { -// ret, err := client.DownSheet(orders, info) -// if err != nil || len(ret.Files) < dao.NumberOne { -// utils.Logger.Error("get down err ", orders, err, ret) -// if len(ret.Files) < dao.NumberOne { -// err = errors.New("files is empty") -// } -// return ret, err -// } -// path := utils.GetConfigString("transit.path") + "/" -// var tmpFiles []transit.TransitFiles -// for i := 0; i < len(ret.Files); i++ { -// tName := ret.Files[i].WaybillNo + ".pdf" -// err := s.downloadSfPDF(ret.Files[i], path+tName) -// if err != nil { -// utils.Logger.Error("get down err ", orders, err, ret) -// return ret, err -// } -// -// tmpFiles = append(tmpFiles, transit.TransitFiles{ -// File: tName, -// WaybillNo: ret.Files[i].WaybillNo, -// }) -// } -// -// ret.Files = tmpFiles -// -// return ret, nil -//} -// -//func (s PrintService) downloadSfPDF(file transit.TransitFiles, path string) error { -// req, err := http.NewRequest("GET", file.Url, nil) -// if err != nil { -// return err -// } -// -// // 2. 必须加这个请求头(顺丰强制) -// req.Header.Add("X-Auth-token", file.Token) -// // 3. 发送请求 -// client := &http.Client{} -// resp, err := client.Do(req) -// if err != nil { -// return err -// } -// defer func(Body io.ReadCloser) { -// err := Body.Close() -// if err != nil { -// utils.Logger.Error(err) -// } -// }(resp.Body) -// // 4. 创建目录 -// if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil { -// return err -// } -// // 5. 创建文件并保存 -// outFile, err := os.Create(path) -// if err != nil { -// return err -// } -// defer func(outFile *os.File) { -// err = outFile.Close() -// if err != nil { -// utils.Logger.Error(err) -// } -// }(outFile) -// // 6. 拷贝数据 -// _, err = io.Copy(outFile, resp.Body) -// return err -//} -// -//func (s PrintService) cancel(client transit.Transit, w models.Params, info dao.DeliverGoodsPrintEdit, status uint8) { -// sn := info.OrderSn -// if info.TransitType == models.TransitCompanyJd { -// sn = info.TransitSn -// } -// -// ret, canErr := client.Cancel(sn) -// if canErr != nil || ret.ErrorCode != dao.StatusOkString { -// utils.Logger.Error("cancel order err ", sn, canErr, ret) -// return -// } -// var history dao.DeliverGoodsHistoryCreate -// history.DeliverId = info.Id -// history.TransitName = models.DeliverSendType[info.TransitType] -// history.TransitInfo = ret.PostInfo -// history.TransitContent = ret.RequestInfo -// history.TransitType = info.TransitType -// history.OrderSn = info.OrderSn -// -// info.OrderSn = dao.StringEmpty -// info.Status = status -// info.Express = dao.StringEmpty -// _, err := models.DeliverGoodsModel{}.Init().Edit(w, &info) -// models.DeliverGoodsHistoryModel{}.Init().Create(&history) -// ww := models.Params{Eq: map[string]string{"deliver_goods_id": strconv.Itoa(info.Id)}} -// editExp := dao.DeliverGoodsExpStatus{ -// Status: dao.StatusFail, -// } -// models.DeliverGoodsExpModel{}.Init().Edit(ww, &editExp) -// if err != nil { -// utils.Logger.Error("cancel up order err ", info.Id, err) -// } -// if info.Type == models.DeliverTypeOrder { -// w = models.Params{Eq: map[string]string{"id": info.ObjId}} -// up := dao.OrderDeliverGoodsStatus{ -// DeliverStatus: status, -// } -// _, err = models.OrderModel{}.Init().Edit(w, &up) -// if err != nil { -// utils.Logger.Error("cancel up order err ", info.ObjSn, err) -// } -// } -//} -// -//func (s PrintService) createTransit(info dao.DeliverGoodsPrint, transitInfo dao.TransitSend) (transit.Transit, transit.TransitResult, utils.Error) { -// var client transit.Transit -// switch transitInfo.TransitId { -// case models.TransitCompanySf: -// client = transit.NewSfClient(transitInfo) -// case models.TransitCompanyJd: -// client = transit.NewJdClient(transitInfo) -// default: -// return client, transit.TransitResult{}, utils.Define(utils.Fail, "不支持的快递公司") -// } -// res, err := client.Create(info) -// if err != nil || res.ErrorCode != dao.StatusOkString { -// utils.Logger.Error("create transit err", err, res) -// return client, res, utils.Define(utils.Fail, res.ApiErrorMsg) -// } -// -// return client, res, nil -//} -// -//func (s PrintService) saveDelever(w models.Params, info *dao.DeliverGoodsPrintEdit, history *dao.DeliverGoodsHistoryCreate, exps *[]dao.DeliverGoodsExpCreate) utils.Error { -// model := models.DeliverGoodsModel{}.Init() -// model.Begin() -// edit, err := model.Edit(w, info) -// if err != nil || edit < utils.NumberOne { -// model.Rollback() -// utils.Logger.Error("save deliver goods err ", err) -// return utils.Define(utils.Fail, "生成快递单失败") -// } -// -// err = models.DeliverGoodsExpModel{}.Init().CreateMulti(exps) -// if err != nil { -// model.Rollback() -// utils.Logger.Error("save exp err ", err) -// return utils.Define(utils.Fail, "生成EXP失败") -// } -// -// err = models.DeliverGoodsHistoryModel{}.Init().Create(history) -// if err != nil { -// model.Rollback() -// utils.Logger.Error("save history err ", err) -// return utils.Define(utils.Fail, "生成订单历史失败") -// } -// -// if info.Type == models.DeliverTypeOrder { -// w = models.Params{Eq: map[string]string{"id": info.ObjId}} -// orderStatus := dao.OrderDeliverGoodsStatus{ -// DeliverStatus: info.Status, -// } -// _, err = models.OrderModel{}.Init().Edit(w, &orderStatus) -// if err != nil { -// model.Rollback() -// utils.Logger.Error("save update order err ", err) -// return utils.Define(utils.Fail, "更新订单状态失败") -// } -// } -// -// model.Commit() -// return nil -//} + if info.Type == dao.DeliveryTypeOrder { + uSt := l.updateOrderDeliverStatus(info.ObjId, int32(info.Status)) + if uSt != utils.Ok { + modelObj.Rollback() + l.Logger.Error("cancel update order status err ", info.ObjId, info.Status) + return utils.SetError(utils.Fail, "更新订单状态失败") + } + } + + modelObj.Commit() + return utils.Ok +} + +func (l *ExpressDeliveringLogic) getOrderInfo(items *[]dao.DeliveryOrderPrint) utils.Status { + for value, item := range *items { + obj := &(*items)[value] + mobile, aErr := utils.Crypto{}.AESDecryptECB(item.Mobile) + if aErr == nil { + obj.Mobile = mobile + } + obj.Url = utils.GetConfigString("transit.url") + products, status := l.getProducts(item.ProductInfo) + if status != utils.Ok { + return status + } + obj.Number, obj.Weight, obj.ProductItems = l.getProductInfo(item.ObjSn, item.ProductInfo, &products) + } + return utils.Ok +} +func (l *ExpressDeliveringLogic) createTransit(info dao.DeliveryOrderPrint, transitInfo dao.ExpressSend) (transit.Transit, transit.TransitResult, utils.Status) { + var client transit.Transit + switch transitInfo.TransitId { + case dao.ExpressCompanySf: + client = transit.NewSfClient(transitInfo) + case dao.ExpressCompanyJd: + client = transit.NewJdClient(transitInfo) + default: + return client, transit.TransitResult{}, utils.SetError(utils.Fail, "不支持的快递公司") + } + res, err := client.Create(info) + if err != nil || res.ErrorCode != utils.StringStatusOk { + l.Logger.Error("create transit err", err, res) + return client, res, utils.SetError(utils.Fail, res.ApiErrorMsg) + } + + return client, res, utils.Ok +} + +func (l *ExpressDeliveringLogic) getDown(client transit.Transit, orders []string, info dao.DeliveryOrderPrint) (transit.TransitResult, error) { + ret, err := client.DownSheet(orders, info) + if err != nil || len(ret.Files) < utils.NumberOne { + l.Logger.Error("get down err ", orders, err, ret) + if len(ret.Files) < utils.NumberOne { + err = errors.New("files is empty") + } + return ret, err + } + path := utils.GetConfigString("transit.path") + "/" + var tmpFiles []transit.TransitFiles + for i := 0; i < len(ret.Files); i++ { + tName := ret.Files[i].WaybillNo + ".pdf" + err := l.downloadSfPDF(ret.Files[i], path+tName) + if err != nil { + l.Logger.Error("get down err ", orders, err, ret) + return ret, err + } + + tmpFiles = append(tmpFiles, transit.TransitFiles{ + File: tName, + WaybillNo: ret.Files[i].WaybillNo, + }) + } + + ret.Files = tmpFiles + + return ret, nil +} + +func (l *ExpressDeliveringLogic) downloadSfPDF(file transit.TransitFiles, path string) error { + req, err := http.NewRequest("GET", file.Url, nil) + if err != nil { + return err + } + + // 2. 必须加这个请求头(顺丰强制) + req.Header.Add("X-Auth-token", file.Token) + // 3. 发送请求 + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + return err + } + defer func(Body io.ReadCloser) { + err := Body.Close() + if err != nil { + l.Logger.Error(err) + } + }(resp.Body) + // 4. 创建目录 + if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil { + return err + } + // 5. 创建文件并保存 + outFile, err := os.Create(path) + if err != nil { + return err + } + defer func(outFile *os.File) { + err = outFile.Close() + if err != nil { + l.Logger.Error(err) + } + }(outFile) + // 6. 拷贝数据 + _, err = io.Copy(outFile, resp.Body) + return err +} + +func (l *ExpressDeliveringLogic) cancel(client transit.Transit, w modelbase.Params, info dao.DeliveryOrderPrintEdit, status uint8) { + sn := info.OrderSn + if info.TransitType == dao.ExpressCompanyJd { + sn = info.TransitSn + } + + ret, canErr := client.Cancel(sn) + if canErr != nil || ret.ErrorCode != utils.StringStatusOk { + l.Logger.Error("cancel order err ", sn, canErr, ret) + return + } + var history dao.DeliveryHistoryCreate + history.DeliverId = info.Id + history.TransitName = dao.DeliverySendType[info.TransitType] + history.TransitInfo = ret.PostInfo + history.TransitContent = ret.RequestInfo + history.TransitType = info.TransitType + history.OrderSn = info.OrderSn + + info.OrderSn = utils.StringEmpty + info.Status = status + info.Express = utils.StringEmpty + mobdelObj := model.DeliveryOrderModel{}.Init() + mobdelObj.Begin() + _, err := mobdelObj.Edit(w, &info) + err = model.DeliveryHistoryModel{}.Init().Create(&history) + if err != nil { + mobdelObj.Rollback() + l.Logger.Error("cancel up order err ", info.Id, err) + return + } + + ww := modelbase.Params{Eq: map[string]string{"deliver_goods_id": strconv.Itoa(info.Id)}} + editExp := dao.DeliveryExpStatus{ + Status: utils.StatusFail, + } + _, err = model.DeliveryOrderExpModel{}.Init().Edit(ww, &editExp) + if err != nil { + mobdelObj.Rollback() + l.Logger.Error("cancel up order err ", info.Id, err) + return + } + if info.Type == dao.DeliveryTypeOrder { + uSt := l.updateOrderDeliverStatus(info.ObjId, int32(status)) + if uSt != utils.Ok { + mobdelObj.Rollback() + l.Logger.Error("cancel update order status err ", info.ObjId, status) + return + } + } + mobdelObj.Commit() +} + +func (l *ExpressDeliveringLogic) updateOrderDeliverStatus(id string, status int32) utils.Status { + cli, err := svc.GetRpcClient(l.svcCtx.OrderSvcName) + if err != nil { + logx.Errorf("get order err: %v", err) + return utils.ErrorInternalServer + } + + client := order.NewOrderClient(cli.Conn()) + _, err = client.UpdateOrderDeliverStatus(l.ctx, &order.UpdateOrderDeliverStatusRequest{Id: id, DeliverStatus: status}) + if err != nil { + logx.Errorf("get order err: %v", err) + return utils.ErrorInternalServer + } + + return utils.Ok +} + +func (l *ExpressDeliveringLogic) getProducts(info string) (map[int]dao.ProductPrint, utils.Status) { + var productInfo []express.DeliverOrderProductInfo + ok := utils.JsonStringToStruct(info, &productInfo) + if !ok { + return nil, utils.ErrorJsonDataError + } + var ids []int64 + for _, item := range productInfo { + ids = append(ids, item.ProductId) + } + + cli, err := svc.GetRpcClient(l.svcCtx.ProductSvcName) + if err != nil { + l.Logger.Error(err) + return nil, utils.ErrorInternalServer + } + + productClient := product.NewProductClient(cli.Conn()) + productItems, err := productClient.ItemsByIds(l.ctx, &product.ItemsByIdsReq{Ids: ids}) + if err != nil { + logx.Errorf("get products err: %v", err) + return nil, utils.SetError(utils.Fail, "获取产品信息错误") + } + + products := make(map[int]dao.ProductPrint) + for _, item := range productItems.Items { + products[int(item.Id)] = dao.ProductPrint{ + Id: int(item.Id), + Name: item.Name, + Weight: float32(item.Weight), + Cubage: item.Cubage, + Waybill: item.Waybill, + } + } + + return products, utils.Ok +} + +func (l *ExpressDeliveringLogic) getProductInfo(orderSn string, info string, product *map[int]dao.ProductPrint) (int, float32, []dao.DeliveryOrderProduct) { + var items []dao.DeliveryOrderProduct + totalNum := 0 + totalWeight := float32(0) + + if len(info) == utils.NumberZero { + return totalNum, totalWeight, items + } + + var productInfo []express.DeliverOrderProductInfo + ok := utils.JsonStringToStruct(info, &productInfo) + if !ok { + return totalNum, totalWeight, items + } + + for _, item := range productInfo { + + tmp := l.orderInfo(orderSn, item, product) + items = append(items, tmp) + + // 统计总数、总重量 + totalNum += tmp.ProductNumber + totalWeight += tmp.ProductWeight + } + + return totalNum, totalWeight, items +} + +// 体积 +func (l *ExpressDeliveringLogic) getBox(tmp *dao.DeliveryOrderProduct, product *map[int]dao.ProductPrint) { + if product == nil { + return + } + + p, exists := (*product)[tmp.ProductId] + if !exists { + return + } + + tmp.ProductWeight = l.toFixed3(p.Weight * float32(tmp.ProductNumber)) + + cubage := strings.Split(p.Cubage, "*") + tmp.ProductLength = l.getBoxInfo(cubage, 0) + tmp.ProductWidth = l.getBoxInfo(cubage, 1) + tmp.ProductHeight = l.getBoxInfo(cubage, 2) + + // 计算体积 + tmp.ProductCubage = l.toFixed3(tmp.ProductLength * tmp.ProductWidth * tmp.ProductHeight) +} + +// 构建单个商品对象 +func (l *ExpressDeliveringLogic) orderInfo(orderSn string, item express.DeliverOrderProductInfo, product *map[int]dao.ProductPrint) dao.DeliveryOrderProduct { + tmp := dao.DeliveryOrderProduct{OrderSn: orderSn} + + l.getProduct(item, &tmp) + l.getBox(&tmp, product) + + return tmp +} +func (l *ExpressDeliveringLogic) getProduct(itemMap express.DeliverOrderProductInfo, tmp *dao.DeliveryOrderProduct) { + tmp.ProductId = int(itemMap.ProductId) + tmp.ProductName = itemMap.ProductName + tmp.ProductNumber = int(itemMap.Number) + tmp.Price = float32(utils.RoundFloat(itemMap.Price)) +} + +// 长度高 +func (l *ExpressDeliveringLogic) getBoxInfo(cubage []string, index int) float32 { + if index >= len(cubage) { + return utils.NumberZero + } + + val, err := strconv.ParseFloat(strings.TrimSpace(cubage[index]), 64) + if err != nil { + return utils.NumberZero + } + + return l.toFixed3(float32(val)) +} + +// 保留3位小数 +func (l *ExpressDeliveringLogic) toFixed3(f float32) float32 { + return float32(math.Round(float64(f)*1000) / 1000) +} + +func (l *ExpressDeliveringLogic) getOrderSn(orderType uint8, adminId int) string { + first := dao.DeliverySendType[orderType] + + sn := first + time.Now().Format("20060102150405") + sn += fmt.Sprintf("%d%d", orderType, adminId) + randomNum := rand.Intn(90000000) + 10000000 + sn += fmt.Sprintf("%d", randomNum) + + return sn +} + +func (l *ExpressDeliveringLogic) getTransitInfo(transitInfo dao.ExpressSend) (transit.Transit, utils.Status) { + var client transit.Transit + switch transitInfo.TransitId { + case dao.ExpressCompanySf: + client = transit.NewSfClient(transitInfo) + case dao.ExpressCompanyJd: + client = transit.NewJdClient(transitInfo) + default: + return client, utils.SetError(utils.ErrorNotFund, "没有找到快递公司") + } + + return client, utils.Ok +} + +func (l *ExpressDeliveringLogic) getSfMap(items []dao.ExpressQueryItems) map[string]bool { + ret := make(map[string]bool) + for _, item := range items { + ret[item.LastMd5] = true + } + return ret +} diff --git a/services/express/internal/logic/infoLogic.go b/services/express/internal/logic/infoLogic.go index 0f0be6a..a606cec 100644 --- a/services/express/internal/logic/infoLogic.go +++ b/services/express/internal/logic/infoLogic.go @@ -34,7 +34,10 @@ func (l *InfoLogic) Info(in *express.IdRequest) (*express.Response, error) { 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) + } var info dao.ExpressInfo modelObj := model.ExpressModel{}.Init() w := modelbase.Params{Eq: map[string]string{"id": strconv.Itoa(int(in.Id))}} diff --git a/services/express/internal/model/deliveryOrderExp.go b/services/express/internal/model/deliveryOrderExp.go new file mode 100644 index 0000000..ba0ec01 --- /dev/null +++ b/services/express/internal/model/deliveryOrderExp.go @@ -0,0 +1,29 @@ +package model + +import ( + "lone-services/pkg/modelbase" + "lone-services/services/express/internal/dao" +) + +type DeliveryOrderExpModel struct { + modelbase.Base +} + +func (m DeliveryOrderExpModel) TableName() string { + return modelbase.Prefix() + "delivery_order_exp" +} + +func (m DeliveryOrderExpModel) Init() DeliveryOrderExpModel { + m.Table = m.TableName() + return m +} + +func (m DeliveryOrderExpModel) Create(data *dao.DeliveryExpCreate) error { + return m.Base.Create(data) +} + +// CreateMulti 添加数据 +func (m DeliveryOrderExpModel) CreateMulti(data *[]dao.DeliveryExpCreate) error { + o := m.Session() + return o.Create(data).Error +} diff --git a/services/express/internal/svc/servicecontext.go b/services/express/internal/svc/servicecontext.go index be0d50e..aebe381 100644 --- a/services/express/internal/svc/servicecontext.go +++ b/services/express/internal/svc/servicecontext.go @@ -1,23 +1,98 @@ package svc import ( + "fmt" + "lone-services/pkg/discovery" "lone-services/pkg/utils" "lone-services/services/express/internal/config" + "net" + "strconv" + "sync" + "time" + "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 + Config config.Config + DB *gorm.DB + Prefix string + ProductSvcName string //服务名 + OrderSvcName string } func NewServiceContext(c config.Config, db *gorm.DB) *ServiceContext { - + productSvc := utils.GetConfigString("services.product") + orderSvc := utils.GetConfigString("services.order") + if productSvc == utils.StringEmpty { + logx.Error("config services.product empty") + } + if orderSvc == utils.StringEmpty { + logx.Error("config services.order empty") + } return &ServiceContext{ - Config: c, - DB: db, - Prefix: utils.GetConfigString("mysql.prefix"), + Config: c, + DB: db, + Prefix: utils.GetConfigString("mysql.prefix"), + ProductSvcName: productSvc, + OrderSvcName: orderSvc, } } diff --git a/services/express/validator/delivery.go b/services/express/validator/delivery.go index 0338c27..b0ba622 100644 --- a/services/express/validator/delivery.go +++ b/services/express/validator/delivery.go @@ -4,13 +4,14 @@ import "lone-services/pkg/validate" type DeliveringValidator struct { Id int64 `form:"id" json:"id" validate:"required"` - TransitId int64 `form:"transit_id" json:"transit_id"` + TransitId int64 `form:"transit_id" json:"transit_id" validate:"required"` } // GetMessage 提示消息 func (p DeliveringValidator) GetMessage() validate.ValidatorMessages { return validate.ValidatorMessages{ - validate.FieldId: validate.FieldIdValue, + validate.FieldId: validate.FieldIdValue, + "TransitId.required": "请输入快递ID", } } diff --git a/services/order/internal/dao/order.go b/services/order/internal/dao/order.go index 26b70a9..1039c1a 100644 --- a/services/order/internal/dao/order.go +++ b/services/order/internal/dao/order.go @@ -32,7 +32,7 @@ const ( SendStatusOk = 4 //为已发货 SendStatusCancel = 5 //已取消 - OrderVerifyStatusOK = 1 + OrderVerifyStatusOK = 1 OrderVerifyStatusFail = 2 OrderVerifyStatusWait = 3 ) diff --git a/services/order/internal/logic/orderCreateLogic.go b/services/order/internal/logic/orderCreateLogic.go index e758472..d001ab8 100644 --- a/services/order/internal/logic/orderCreateLogic.go +++ b/services/order/internal/logic/orderCreateLogic.go @@ -135,6 +135,7 @@ func (l *OrderCreateLogic) OrderCreate(in *order.AdminCreateOrderRequest) (*orde cli, err := svc.GetRpcClient(l.svcCtx.ProductSvcName) if err != nil { mobileObj.Rollback() + l.Logger.Error(err) return l.fail(utils.Fail) } diff --git a/services/order/internal/logic/updateOrderDeliverStatusLogic.go b/services/order/internal/logic/updateOrderDeliverStatusLogic.go new file mode 100644 index 0000000..000f96c --- /dev/null +++ b/services/order/internal/logic/updateOrderDeliverStatusLogic.go @@ -0,0 +1,57 @@ +package logic + +import ( + "context" + "lone-services/pkg/modelbase" + "lone-services/pkg/utils" + "lone-services/services/order/internal/dao" + "lone-services/services/order/internal/model" + "lone-services/services/order/validator" + + "lone-services/rpc/order/pb" + "lone-services/services/order/internal/svc" + + "github.com/zeromicro/go-zero/core/logx" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +type UpdateOrderDeliverStatusLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger + BaseLogic +} + +func NewUpdateOrderDeliverStatusLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateOrderDeliverStatusLogic { + return &UpdateOrderDeliverStatusLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *UpdateOrderDeliverStatusLogic) UpdateOrderDeliverStatus(in *order.UpdateOrderDeliverStatusRequest) (*order.UpdateOrderDeliverStatusResponse, error) { + var v validator.AdminOrderAuditingValidator + if fail := l.checkParams(in, &v); fail != nil { + return nil, status.Error(codes.InvalidArgument, fail.Msg) + } + + data := dao.OrderDeliverGoodsStatus{ + DeliverStatus: uint8(in.DeliverStatus), + } + + if in.SignTime != utils.StringEmpty { + sTime, err := utils.ParseCustomTime(in.SignTime) + if err != nil { + sTime = utils.Now() + } + data.SignTime = sTime + } + w := modelbase.Params{Eq: map[string]string{"id": in.Id}} + row, err := model.OrderModel{}.Init().Edit(w, &data) + if err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + return &order.UpdateOrderDeliverStatusResponse{Num: int32(row)}, nil +} diff --git a/services/order/internal/server/orderServer.go b/services/order/internal/server/orderServer.go index ec8d70a..4008d5c 100644 --- a/services/order/internal/server/orderServer.go +++ b/services/order/internal/server/orderServer.go @@ -102,3 +102,8 @@ func (s *OrderServer) OrderCreate(ctx context.Context, in *order.AdminCreateOrde l := logic.NewOrderCreateLogic(ctx, s.svcCtx) return l.OrderCreate(in) } + +func (s *OrderServer) UpdateOrderDeliverStatus(ctx context.Context, in *order.UpdateOrderDeliverStatusRequest) (*order.UpdateOrderDeliverStatusResponse, error) { + l := logic.NewUpdateOrderDeliverStatusLogic(ctx, s.svcCtx) + return l.UpdateOrderDeliverStatus(in) +} diff --git a/services/order/orderClient/order.go b/services/order/orderClient/order.go index 9f049a9..f0e9e8e 100644 --- a/services/order/orderClient/order.go +++ b/services/order/orderClient/order.go @@ -14,22 +14,24 @@ import ( ) type ( - AddressByStoreItemsRequest = order.AddressByStoreItemsRequest - AddressItemsRequest = order.AddressItemsRequest - AdminCreateOrderRequest = order.AdminCreateOrderRequest - CartRequest = order.CartRequest - CreateOrderOneRequest = order.CreateOrderOneRequest - CreateOrderRequest = order.CreateOrderRequest - EditAddressRequest = order.EditAddressRequest - EditCartRequest = order.EditCartRequest - EmptyRequest = order.EmptyRequest - IdAndTypeRequest = order.IdAndTypeRequest - IdRequest = order.IdRequest - OrderAuditingItemsRequest = order.OrderAuditingItemsRequest - OrderAuditingRequest = order.OrderAuditingRequest - OrderItemsRequest = order.OrderItemsRequest - Response = order.Response - TypeRequest = order.TypeRequest + AddressByStoreItemsRequest = order.AddressByStoreItemsRequest + AddressItemsRequest = order.AddressItemsRequest + AdminCreateOrderRequest = order.AdminCreateOrderRequest + CartRequest = order.CartRequest + CreateOrderOneRequest = order.CreateOrderOneRequest + CreateOrderRequest = order.CreateOrderRequest + EditAddressRequest = order.EditAddressRequest + EditCartRequest = order.EditCartRequest + EmptyRequest = order.EmptyRequest + IdAndTypeRequest = order.IdAndTypeRequest + IdRequest = order.IdRequest + OrderAuditingItemsRequest = order.OrderAuditingItemsRequest + OrderAuditingRequest = order.OrderAuditingRequest + OrderItemsRequest = order.OrderItemsRequest + Response = order.Response + TypeRequest = order.TypeRequest + UpdateOrderDeliverStatusRequest = order.UpdateOrderDeliverStatusRequest + UpdateOrderDeliverStatusResponse = order.UpdateOrderDeliverStatusResponse Order interface { Items(ctx context.Context, in *OrderItemsRequest, opts ...grpc.CallOption) (*Response, error) @@ -48,6 +50,7 @@ type ( OrderAuditingItems(ctx context.Context, in *OrderAuditingItemsRequest, opts ...grpc.CallOption) (*Response, error) OrderAuditing(ctx context.Context, in *OrderAuditingRequest, opts ...grpc.CallOption) (*Response, error) OrderCreate(ctx context.Context, in *AdminCreateOrderRequest, opts ...grpc.CallOption) (*Response, error) + UpdateOrderDeliverStatus(ctx context.Context, in *UpdateOrderDeliverStatusRequest, opts ...grpc.CallOption) (*UpdateOrderDeliverStatusResponse, error) } defaultOrder struct { @@ -140,3 +143,8 @@ func (m *defaultOrder) OrderCreate(ctx context.Context, in *AdminCreateOrderRequ client := order.NewOrderClient(m.cli.Conn()) return client.OrderCreate(ctx, in, opts...) } + +func (m *defaultOrder) UpdateOrderDeliverStatus(ctx context.Context, in *UpdateOrderDeliverStatusRequest, opts ...grpc.CallOption) (*UpdateOrderDeliverStatusResponse, error) { + client := order.NewOrderClient(m.cli.Conn()) + return client.UpdateOrderDeliverStatus(ctx, in, opts...) +} diff --git a/services/order/validator/order.go b/services/order/validator/order.go index 5e3023e..8e094d2 100644 --- a/services/order/validator/order.go +++ b/services/order/validator/order.go @@ -94,3 +94,16 @@ type OrderItemsValidator struct { func (p OrderItemsValidator) GetMessage() validate.ValidatorMessages { return validate.ValidatorMessages{} } + +type UpdateOrderDeliverStatusValidator struct { + Id string `validate:"required"` + DeliverStatus int32 `validate:"required"` + SignTime string +} + +func (p UpdateOrderDeliverStatusValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + validate.FieldId: validate.FieldIdValue, + "DeliverStatus.required": "发货状态不能为空", + } +} diff --git a/services/sale/run.toml b/services/sale/run.toml index 6f83ec6..26ee240 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:10300" + listenOn = "0.0.0.0:10700" mode = "dev" [log] path = "logs" @@ -53,7 +53,5 @@ [encrypt] data_key = "u2t9T3luZtoRfhBstkFN6TiIMW38BA8a" - [services] - chore = "chore-service" - user = "user-service" \ No newline at end of file + chore = "chore-service" \ No newline at end of file diff --git a/services/task/.gitignore b/services/task/.gitignore index 6d3dca9..b2927df 100644 --- a/services/task/.gitignore +++ b/services/task/.gitignore @@ -1,2 +1,3 @@ run.toml -etc/task.yaml \ No newline at end of file +etc/task.yaml +tmp \ No newline at end of file diff --git a/services/task/run.toml b/services/task/run.toml index caa1552..772c1fb 100644 --- a/services/task/run.toml +++ b/services/task/run.toml @@ -1,7 +1,7 @@ [base] port = 8060 name = "task-service" - listenOn = "0.0.0.0:10101" + listenOn = "0.0.0.0:10900" mode = "dev" [log] path = "logs"