diff --git a/pkg/wecomrpc/client.go b/pkg/wecomrpc/client.go new file mode 100644 index 0000000..f52e6dc --- /dev/null +++ b/pkg/wecomrpc/client.go @@ -0,0 +1,28 @@ +package wecomrpc + +import ( + "context" + "fmt" + + "lone-services/pkg/rpcclient" + "lone-services/pkg/utils" + wecompb "lone-services/rpc/wecom/pb" +) + +func getClient(wecomSvcName string) (wecompb.WecomClient, error) { + if wecomSvcName == utils.StringEmpty { + return nil, fmt.Errorf("services.wecom empty") + } + cli, err := rpcclient.Get(wecomSvcName) + if err != nil { + return nil, err + } + return wecompb.NewWecomClient(cli.Conn()), nil +} + +func ensureCtx(ctx context.Context) context.Context { + if ctx == nil { + return context.Background() + } + return ctx +} diff --git a/pkg/wecomrpc/const.go b/pkg/wecomrpc/const.go new file mode 100644 index 0000000..043a548 --- /dev/null +++ b/pkg/wecomrpc/const.go @@ -0,0 +1,42 @@ +package wecomrpc + +const ( + BizTypeProduct uint8 = 1 // 产品 + BizTypeStore uint8 = 2 // 门店 + BizTypeAddress uint8 = 3 // 地址 + BizTypeSales uint8 = 4 // 销售 +) + +const ( + ActionNone uint8 = 0 + ActionPass uint8 = 1 + ActionReject uint8 = 2 +) + +const ( + ProductApplyReview uint8 = 1 // 提交审核(按钮消息) + ProductNeedReview uint8 = 2 // 通知申请人 + ProductSubmitReview uint8 = 3 // 通知一审人员 + ProductFirstReview uint8 = 4 // 一审审核结果 + ProductSecondReview uint8 = 5 // 二审审核结果 + ProductOrdinaryReview uint8 = 6 // 修改普通信息 +) + +const ( + StoreApplyReview uint8 = 1 // 提交审核(按钮消息) + StoreNeedReview uint8 = 2 // 通知申请人 + StoreSubmitReview uint8 = 3 // 通知一审人员 + StoreFirstReview uint8 = 4 // 一审审核结果 + StoreSecondReview uint8 = 5 // 二审审核结果 +) + +const ( + AddressApplyReview uint8 = 1 // 提交审核(按钮消息) + AddressSubmitReview uint8 = 2 // 通知一审人员 + AddressFirstReview uint8 = 3 // 一审审核结果 + AddressSecondReview uint8 = 4 // 二审审核结果 +) + +const ( + SalesApplyReview uint8 = 2 // 通知审核人员 +) diff --git a/pkg/wecomrpc/review_change.go b/pkg/wecomrpc/review_change.go new file mode 100644 index 0000000..de98a1c --- /dev/null +++ b/pkg/wecomrpc/review_change.go @@ -0,0 +1,51 @@ +package wecomrpc + +import ( + "context" + + "lone-services/pkg/utils" + wecompb "lone-services/rpc/wecom/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type ReviewChange struct { + Type uint8 // 业务类型:1产品 2门店 3地址 + BizId int64 + TaskId string + BeforeData string // JSON,空则写 null + AfterData string // JSON,空则写 null + AdminId int64 + AdminName string +} + +func CreateReviewChange(ctx context.Context, wecomSvcName string, change ReviewChange) { + ctx = ensureCtx(ctx) + client, err := getClient(wecomSvcName) + if err != nil { + logx.Errorf("wecomrpc CreateReviewChange get client: %v", err) + return + } + + before := change.BeforeData + after := change.AfterData + if before == utils.StringEmpty { + before = "null" + } + if after == utils.StringEmpty { + after = "null" + } + + _, err = client.CreateReviewChange(ctx, &wecompb.CreateReviewChangeReq{ + Type: uint32(change.Type), + BizId: change.BizId, + TaskId: change.TaskId, + BeforeData: before, + AfterData: after, + AdminId: change.AdminId, + AdminName: change.AdminName, + }) + if err != nil { + logx.Errorf("wecomrpc CreateReviewChange: %v", err) + } +} diff --git a/pkg/wecomrpc/send_message.go b/pkg/wecomrpc/send_message.go new file mode 100644 index 0000000..e527705 --- /dev/null +++ b/pkg/wecomrpc/send_message.go @@ -0,0 +1,38 @@ +package wecomrpc + +import ( + "context" + + wecompb "lone-services/rpc/wecom/pb" + + "github.com/zeromicro/go-zero/core/logx" +) + +type SendMessageJob struct { + BizId int + BizType uint8 + Type uint8 + Action uint8 // 0未用 1通过 2拒绝 + Reason string + Key string +} + +func SendMessage(ctx context.Context, wecomSvcName string, job SendMessageJob) { + ctx = ensureCtx(ctx) + client, err := getClient(wecomSvcName) + if err != nil { + logx.Errorf("wecomrpc SendMessage get client: %v", err) + return + } + _, err = client.SendMessage(ctx, &wecompb.SendMessageReq{ + BizId: int64(job.BizId), + BizType: uint32(job.BizType), + Type: uint32(job.Type), + Action: uint32(job.Action), + Reason: job.Reason, + Key: job.Key, + }) + if err != nil { + logx.Errorf("wecomrpc SendMessage: %v", err) + } +} diff --git a/rpc/chore/chore.proto b/rpc/chore/chore.proto index 8a01557..505af53 100644 --- a/rpc/chore/chore.proto +++ b/rpc/chore/chore.proto @@ -79,10 +79,7 @@ service Chore { get: "/admin/v3/chore/system/items" }; } - // 按 id 批量查地区名称 rpc RegionsByIds(RegionsByIdsReq) returns (RegionsByIdsData); - - // 服务间:写入编辑申请日志 rpc InternalActionApplyLogCreate(InternalActionApplyLogCreateReq) returns (InternalActionApplyLogCreateData); } diff --git a/rpc/wecom/pb/wecom.pb.go b/rpc/wecom/pb/wecom.pb.go index 6198c2f..117bb46 100644 --- a/rpc/wecom/pb/wecom.pb.go +++ b/rpc/wecom/pb/wecom.pb.go @@ -7,12 +7,13 @@ package wecom import ( - _ "google.golang.org/genproto/googleapis/api/annotations" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" unsafe "unsafe" + + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" ) const ( @@ -534,6 +535,183 @@ func (x *DeleteUserReq) GetId() int64 { return 0 } +// type: 1产品 2门店 3地址;before_data/after_data 为 JSON 字符串 +type CreateReviewChangeReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + Type uint32 `protobuf:"varint,1,opt,name=type,proto3" json:"type,omitempty"` + BizId int64 `protobuf:"varint,2,opt,name=biz_id,json=bizId,proto3" json:"biz_id,omitempty"` + TaskId string `protobuf:"bytes,3,opt,name=task_id,json=taskId,proto3" json:"task_id,omitempty"` + BeforeData string `protobuf:"bytes,4,opt,name=before_data,json=beforeData,proto3" json:"before_data,omitempty"` + AfterData string `protobuf:"bytes,5,opt,name=after_data,json=afterData,proto3" json:"after_data,omitempty"` + AdminId int64 `protobuf:"varint,6,opt,name=admin_id,json=adminId,proto3" json:"admin_id,omitempty"` + AdminName string `protobuf:"bytes,7,opt,name=admin_name,json=adminName,proto3" json:"admin_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreateReviewChangeReq) Reset() { + *x = CreateReviewChangeReq{} + mi := &file_wecom_wecom_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateReviewChangeReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateReviewChangeReq) ProtoMessage() {} + +func (x *CreateReviewChangeReq) ProtoReflect() protoreflect.Message { + mi := &file_wecom_wecom_proto_msgTypes[8] + 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 CreateReviewChangeReq.ProtoReflect.Descriptor instead. +func (*CreateReviewChangeReq) Descriptor() ([]byte, []int) { + return file_wecom_wecom_proto_rawDescGZIP(), []int{8} +} + +func (x *CreateReviewChangeReq) GetType() uint32 { + if x != nil { + return x.Type + } + return 0 +} + +func (x *CreateReviewChangeReq) GetBizId() int64 { + if x != nil { + return x.BizId + } + return 0 +} + +func (x *CreateReviewChangeReq) GetTaskId() string { + if x != nil { + return x.TaskId + } + return "" +} + +func (x *CreateReviewChangeReq) GetBeforeData() string { + if x != nil { + return x.BeforeData + } + return "" +} + +func (x *CreateReviewChangeReq) GetAfterData() string { + if x != nil { + return x.AfterData + } + return "" +} + +func (x *CreateReviewChangeReq) GetAdminId() int64 { + if x != nil { + return x.AdminId + } + return 0 +} + +func (x *CreateReviewChangeReq) GetAdminName() string { + if x != nil { + return x.AdminName + } + return "" +} + +type SendMessageReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + BizId int64 `protobuf:"varint,1,opt,name=biz_id,json=bizId,proto3" json:"biz_id,omitempty"` + BizType uint32 `protobuf:"varint,2,opt,name=biz_type,json=bizType,proto3" json:"biz_type,omitempty"` + Type uint32 `protobuf:"varint,3,opt,name=type,proto3" json:"type,omitempty"` + Action uint32 `protobuf:"varint,4,opt,name=action,proto3" json:"action,omitempty"` + Reason string `protobuf:"bytes,5,opt,name=reason,proto3" json:"reason,omitempty"` + Key string `protobuf:"bytes,6,opt,name=key,proto3" json:"key,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SendMessageReq) Reset() { + *x = SendMessageReq{} + mi := &file_wecom_wecom_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SendMessageReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SendMessageReq) ProtoMessage() {} + +func (x *SendMessageReq) ProtoReflect() protoreflect.Message { + mi := &file_wecom_wecom_proto_msgTypes[9] + 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 SendMessageReq.ProtoReflect.Descriptor instead. +func (*SendMessageReq) Descriptor() ([]byte, []int) { + return file_wecom_wecom_proto_rawDescGZIP(), []int{9} +} + +func (x *SendMessageReq) GetBizId() int64 { + if x != nil { + return x.BizId + } + return 0 +} + +func (x *SendMessageReq) GetBizType() uint32 { + if x != nil { + return x.BizType + } + return 0 +} + +func (x *SendMessageReq) GetType() uint32 { + if x != nil { + return x.Type + } + return 0 +} + +func (x *SendMessageReq) GetAction() uint32 { + if x != nil { + return x.Action + } + return 0 +} + +func (x *SendMessageReq) GetReason() string { + if x != nil { + return x.Reason + } + return "" +} + +func (x *SendMessageReq) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + type Response struct { state protoimpl.MessageState `protogen:"open.v1"` Code int32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` @@ -545,7 +723,7 @@ type Response struct { func (x *Response) Reset() { *x = Response{} - mi := &file_wecom_wecom_proto_msgTypes[8] + mi := &file_wecom_wecom_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -557,7 +735,7 @@ func (x *Response) String() string { func (*Response) ProtoMessage() {} func (x *Response) ProtoReflect() protoreflect.Message { - mi := &file_wecom_wecom_proto_msgTypes[8] + mi := &file_wecom_wecom_proto_msgTypes[10] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -570,7 +748,7 @@ func (x *Response) ProtoReflect() protoreflect.Message { // Deprecated: Use Response.ProtoReflect.Descriptor instead. func (*Response) Descriptor() ([]byte, []int) { - return file_wecom_wecom_proto_rawDescGZIP(), []int{8} + return file_wecom_wecom_proto_rawDescGZIP(), []int{10} } func (x *Response) GetCode() int32 { @@ -635,11 +813,29 @@ const file_wecom_wecom_proto_rawDesc = "" + "\x02id\x18\x01 \x01(\x03R\x02id\x12\x16\n" + "\x06status\x18\x02 \x01(\rR\x06status\"\x1f\n" + "\rDeleteUserReq\x12\x0e\n" + - "\x02id\x18\x01 \x01(\x03R\x02id\"D\n" + + "\x02id\x18\x01 \x01(\x03R\x02id\"\xd5\x01\n" + + "\x15CreateReviewChangeReq\x12\x12\n" + + "\x04type\x18\x01 \x01(\rR\x04type\x12\x15\n" + + "\x06biz_id\x18\x02 \x01(\x03R\x05bizId\x12\x17\n" + + "\atask_id\x18\x03 \x01(\tR\x06taskId\x12\x1f\n" + + "\vbefore_data\x18\x04 \x01(\tR\n" + + "beforeData\x12\x1d\n" + + "\n" + + "after_data\x18\x05 \x01(\tR\tafterData\x12\x19\n" + + "\badmin_id\x18\x06 \x01(\x03R\aadminId\x12\x1d\n" + + "\n" + + "admin_name\x18\a \x01(\tR\tadminName\"\x98\x01\n" + + "\x0eSendMessageReq\x12\x15\n" + + "\x06biz_id\x18\x01 \x01(\x03R\x05bizId\x12\x19\n" + + "\bbiz_type\x18\x02 \x01(\rR\abizType\x12\x12\n" + + "\x04type\x18\x03 \x01(\rR\x04type\x12\x16\n" + + "\x06action\x18\x04 \x01(\rR\x06action\x12\x16\n" + + "\x06reason\x18\x05 \x01(\tR\x06reason\x12\x10\n" + + "\x03key\x18\x06 \x01(\tR\x03key\"D\n" + "\bResponse\x12\x12\n" + "\x04code\x18\x01 \x01(\x05R\x04code\x12\x10\n" + "\x03msg\x18\x02 \x01(\tR\x03msg\x12\x12\n" + - "\x04data\x18\x03 \x01(\tR\x04data2\x8c\x06\n" + + "\x04data\x18\x03 \x01(\tR\x04data2\x88\a\n" + "\x05Wecom\x12S\n" + "\n" + "ItemsUsers\x12\x13.wecom.ItemsUserReq\x1a\x0f.wecom.Response\"\x1f\x82\xd3\xe4\x93\x02\x19:\x01*\x12\x14/admin/v3/wecom/user\x12T\n" + @@ -655,7 +851,9 @@ const file_wecom_wecom_proto_rawDesc = "" + "\x05Types\x12\x0f.wecom.EmptyReq\x1a\x0f.wecom.Response\" \x82\xd3\xe4\x93\x02\x1a:\x01*\x12\x15/admin/v3/wecom/types\x12T\n" + "\n" + "CreateTags\x12\x14.wecom.CreateTagsReq\x1a\x0f.wecom.Response\"\x1f\x82\xd3\xe4\x93\x02\x19:\x01*\"\x14/admin/v3/wecom/tags\x12R\n" + - "\tItemsTags\x12\x13.wecom.ItemsTagsReq\x1a\x0f.wecom.Response\"\x1f\x82\xd3\xe4\x93\x02\x19:\x01*\x12\x14/admin/v3/wecom/tagsB\x19Z\x17lone-services/rpc/wecomb\x06proto3" + "\tItemsTags\x12\x13.wecom.ItemsTagsReq\x1a\x0f.wecom.Response\"\x1f\x82\xd3\xe4\x93\x02\x19:\x01*\x12\x14/admin/v3/wecom/tags\x12C\n" + + "\x12CreateReviewChange\x12\x1c.wecom.CreateReviewChangeReq\x1a\x0f.wecom.Response\x125\n" + + "\vSendMessage\x12\x15.wecom.SendMessageReq\x1a\x0f.wecom.ResponseB\x19Z\x17lone-services/rpc/wecomb\x06proto3" var ( file_wecom_wecom_proto_rawDescOnce sync.Once @@ -669,42 +867,48 @@ func file_wecom_wecom_proto_rawDescGZIP() []byte { return file_wecom_wecom_proto_rawDescData } -var file_wecom_wecom_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_wecom_wecom_proto_msgTypes = make([]protoimpl.MessageInfo, 11) var file_wecom_wecom_proto_goTypes = []any{ - (*EmptyReq)(nil), // 0: wecom.EmptyReq - (*CreateTagsReq)(nil), // 1: wecom.CreateTagsReq - (*ItemsTagsReq)(nil), // 2: wecom.ItemsTagsReq - (*ItemsUserReq)(nil), // 3: wecom.ItemsUserReq - (*CreateUserReq)(nil), // 4: wecom.CreateUserReq - (*UpdateUserReq)(nil), // 5: wecom.UpdateUserReq - (*StatusUserReq)(nil), // 6: wecom.StatusUserReq - (*DeleteUserReq)(nil), // 7: wecom.DeleteUserReq - (*Response)(nil), // 8: wecom.Response + (*EmptyReq)(nil), // 0: wecom.EmptyReq + (*CreateTagsReq)(nil), // 1: wecom.CreateTagsReq + (*ItemsTagsReq)(nil), // 2: wecom.ItemsTagsReq + (*ItemsUserReq)(nil), // 3: wecom.ItemsUserReq + (*CreateUserReq)(nil), // 4: wecom.CreateUserReq + (*UpdateUserReq)(nil), // 5: wecom.UpdateUserReq + (*StatusUserReq)(nil), // 6: wecom.StatusUserReq + (*DeleteUserReq)(nil), // 7: wecom.DeleteUserReq + (*CreateReviewChangeReq)(nil), // 8: wecom.CreateReviewChangeReq + (*SendMessageReq)(nil), // 9: wecom.SendMessageReq + (*Response)(nil), // 10: wecom.Response } var file_wecom_wecom_proto_depIdxs = []int32{ - 3, // 0: wecom.Wecom.ItemsUsers:input_type -> wecom.ItemsUserReq - 4, // 1: wecom.Wecom.CreateUser:input_type -> wecom.CreateUserReq - 5, // 2: wecom.Wecom.UpdateUser:input_type -> wecom.UpdateUserReq - 6, // 3: wecom.Wecom.StatusUser:input_type -> wecom.StatusUserReq - 7, // 4: wecom.Wecom.DeleteUser:input_type -> wecom.DeleteUserReq - 0, // 5: wecom.Wecom.ItemsAgents:input_type -> wecom.EmptyReq - 0, // 6: wecom.Wecom.Types:input_type -> wecom.EmptyReq - 1, // 7: wecom.Wecom.CreateTags:input_type -> wecom.CreateTagsReq - 2, // 8: wecom.Wecom.ItemsTags:input_type -> wecom.ItemsTagsReq - 8, // 9: wecom.Wecom.ItemsUsers:output_type -> wecom.Response - 8, // 10: wecom.Wecom.CreateUser:output_type -> wecom.Response - 8, // 11: wecom.Wecom.UpdateUser:output_type -> wecom.Response - 8, // 12: wecom.Wecom.StatusUser:output_type -> wecom.Response - 8, // 13: wecom.Wecom.DeleteUser:output_type -> wecom.Response - 8, // 14: wecom.Wecom.ItemsAgents:output_type -> wecom.Response - 8, // 15: wecom.Wecom.Types:output_type -> wecom.Response - 8, // 16: wecom.Wecom.CreateTags:output_type -> wecom.Response - 8, // 17: wecom.Wecom.ItemsTags:output_type -> wecom.Response - 9, // [9:18] is the sub-list for method output_type - 0, // [0:9] 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 + 3, // 0: wecom.Wecom.ItemsUsers:input_type -> wecom.ItemsUserReq + 4, // 1: wecom.Wecom.CreateUser:input_type -> wecom.CreateUserReq + 5, // 2: wecom.Wecom.UpdateUser:input_type -> wecom.UpdateUserReq + 6, // 3: wecom.Wecom.StatusUser:input_type -> wecom.StatusUserReq + 7, // 4: wecom.Wecom.DeleteUser:input_type -> wecom.DeleteUserReq + 0, // 5: wecom.Wecom.ItemsAgents:input_type -> wecom.EmptyReq + 0, // 6: wecom.Wecom.Types:input_type -> wecom.EmptyReq + 1, // 7: wecom.Wecom.CreateTags:input_type -> wecom.CreateTagsReq + 2, // 8: wecom.Wecom.ItemsTags:input_type -> wecom.ItemsTagsReq + 8, // 9: wecom.Wecom.CreateReviewChange:input_type -> wecom.CreateReviewChangeReq + 9, // 10: wecom.Wecom.SendMessage:input_type -> wecom.SendMessageReq + 10, // 11: wecom.Wecom.ItemsUsers:output_type -> wecom.Response + 10, // 12: wecom.Wecom.CreateUser:output_type -> wecom.Response + 10, // 13: wecom.Wecom.UpdateUser:output_type -> wecom.Response + 10, // 14: wecom.Wecom.StatusUser:output_type -> wecom.Response + 10, // 15: wecom.Wecom.DeleteUser:output_type -> wecom.Response + 10, // 16: wecom.Wecom.ItemsAgents:output_type -> wecom.Response + 10, // 17: wecom.Wecom.Types:output_type -> wecom.Response + 10, // 18: wecom.Wecom.CreateTags:output_type -> wecom.Response + 10, // 19: wecom.Wecom.ItemsTags:output_type -> wecom.Response + 10, // 20: wecom.Wecom.CreateReviewChange:output_type -> wecom.Response + 10, // 21: wecom.Wecom.SendMessage:output_type -> wecom.Response + 11, // [11:22] is the sub-list for method output_type + 0, // [0:11] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name } func init() { file_wecom_wecom_proto_init() } @@ -718,7 +922,7 @@ func file_wecom_wecom_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_wecom_wecom_proto_rawDesc), len(file_wecom_wecom_proto_rawDesc)), NumEnums: 0, - NumMessages: 9, + NumMessages: 11, NumExtensions: 0, NumServices: 1, }, diff --git a/rpc/wecom/pb/wecom_grpc.pb.go b/rpc/wecom/pb/wecom_grpc.pb.go index 156d45c..6a7749f 100644 --- a/rpc/wecom/pb/wecom_grpc.pb.go +++ b/rpc/wecom/pb/wecom_grpc.pb.go @@ -19,15 +19,17 @@ import ( const _ = grpc.SupportPackageIsVersion9 const ( - Wecom_ItemsUsers_FullMethodName = "/wecom.Wecom/ItemsUsers" - Wecom_CreateUser_FullMethodName = "/wecom.Wecom/CreateUser" - Wecom_UpdateUser_FullMethodName = "/wecom.Wecom/UpdateUser" - Wecom_StatusUser_FullMethodName = "/wecom.Wecom/StatusUser" - Wecom_DeleteUser_FullMethodName = "/wecom.Wecom/DeleteUser" - Wecom_ItemsAgents_FullMethodName = "/wecom.Wecom/ItemsAgents" - Wecom_Types_FullMethodName = "/wecom.Wecom/Types" - Wecom_CreateTags_FullMethodName = "/wecom.Wecom/CreateTags" - Wecom_ItemsTags_FullMethodName = "/wecom.Wecom/ItemsTags" + Wecom_ItemsUsers_FullMethodName = "/wecom.Wecom/ItemsUsers" + Wecom_CreateUser_FullMethodName = "/wecom.Wecom/CreateUser" + Wecom_UpdateUser_FullMethodName = "/wecom.Wecom/UpdateUser" + Wecom_StatusUser_FullMethodName = "/wecom.Wecom/StatusUser" + Wecom_DeleteUser_FullMethodName = "/wecom.Wecom/DeleteUser" + Wecom_ItemsAgents_FullMethodName = "/wecom.Wecom/ItemsAgents" + Wecom_Types_FullMethodName = "/wecom.Wecom/Types" + Wecom_CreateTags_FullMethodName = "/wecom.Wecom/CreateTags" + Wecom_ItemsTags_FullMethodName = "/wecom.Wecom/ItemsTags" + Wecom_CreateReviewChange_FullMethodName = "/wecom.Wecom/CreateReviewChange" + Wecom_SendMessage_FullMethodName = "/wecom.Wecom/SendMessage" ) // WecomClient is the client API for Wecom service. @@ -43,6 +45,10 @@ type WecomClient interface { Types(ctx context.Context, in *EmptyReq, opts ...grpc.CallOption) (*Response, error) CreateTags(ctx context.Context, in *CreateTagsReq, opts ...grpc.CallOption) (*Response, error) ItemsTags(ctx context.Context, in *ItemsTagsReq, opts ...grpc.CallOption) (*Response, error) + // 内部接口:产品/门店/地址新增或修改时写入审核变更快照 + CreateReviewChange(ctx context.Context, in *CreateReviewChangeReq, opts ...grpc.CallOption) (*Response, error) + // 内部接口:发送企微审核/通知消息 + SendMessage(ctx context.Context, in *SendMessageReq, opts ...grpc.CallOption) (*Response, error) } type wecomClient struct { @@ -143,6 +149,26 @@ func (c *wecomClient) ItemsTags(ctx context.Context, in *ItemsTagsReq, opts ...g return out, nil } +func (c *wecomClient) CreateReviewChange(ctx context.Context, in *CreateReviewChangeReq, opts ...grpc.CallOption) (*Response, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(Response) + err := c.cc.Invoke(ctx, Wecom_CreateReviewChange_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *wecomClient) SendMessage(ctx context.Context, in *SendMessageReq, opts ...grpc.CallOption) (*Response, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(Response) + err := c.cc.Invoke(ctx, Wecom_SendMessage_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + // WecomServer is the server API for Wecom service. // All implementations must embed UnimplementedWecomServer // for forward compatibility. @@ -156,6 +182,10 @@ type WecomServer interface { Types(context.Context, *EmptyReq) (*Response, error) CreateTags(context.Context, *CreateTagsReq) (*Response, error) ItemsTags(context.Context, *ItemsTagsReq) (*Response, error) + // 内部接口:产品/门店/地址新增或修改时写入审核变更快照 + CreateReviewChange(context.Context, *CreateReviewChangeReq) (*Response, error) + // 内部接口:发送企微审核/通知消息 + SendMessage(context.Context, *SendMessageReq) (*Response, error) mustEmbedUnimplementedWecomServer() } @@ -193,6 +223,12 @@ func (UnimplementedWecomServer) CreateTags(context.Context, *CreateTagsReq) (*Re func (UnimplementedWecomServer) ItemsTags(context.Context, *ItemsTagsReq) (*Response, error) { return nil, status.Error(codes.Unimplemented, "method ItemsTags not implemented") } +func (UnimplementedWecomServer) CreateReviewChange(context.Context, *CreateReviewChangeReq) (*Response, error) { + return nil, status.Error(codes.Unimplemented, "method CreateReviewChange not implemented") +} +func (UnimplementedWecomServer) SendMessage(context.Context, *SendMessageReq) (*Response, error) { + return nil, status.Error(codes.Unimplemented, "method SendMessage not implemented") +} func (UnimplementedWecomServer) mustEmbedUnimplementedWecomServer() {} func (UnimplementedWecomServer) testEmbeddedByValue() {} @@ -376,6 +412,42 @@ func _Wecom_ItemsTags_Handler(srv interface{}, ctx context.Context, dec func(int return interceptor(ctx, in, info, handler) } +func _Wecom_CreateReviewChange_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateReviewChangeReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WecomServer).CreateReviewChange(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Wecom_CreateReviewChange_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WecomServer).CreateReviewChange(ctx, req.(*CreateReviewChangeReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Wecom_SendMessage_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SendMessageReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WecomServer).SendMessage(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Wecom_SendMessage_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WecomServer).SendMessage(ctx, req.(*SendMessageReq)) + } + return interceptor(ctx, in, info, handler) +} + // Wecom_ServiceDesc is the grpc.ServiceDesc for Wecom service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -419,6 +491,14 @@ var Wecom_ServiceDesc = grpc.ServiceDesc{ MethodName: "ItemsTags", Handler: _Wecom_ItemsTags_Handler, }, + { + MethodName: "CreateReviewChange", + Handler: _Wecom_CreateReviewChange_Handler, + }, + { + MethodName: "SendMessage", + Handler: _Wecom_SendMessage_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "wecom/wecom.proto", diff --git a/rpc/wecom/wecom.pb b/rpc/wecom/wecom.pb index 61aa1b6..465394b 100644 Binary files a/rpc/wecom/wecom.pb and b/rpc/wecom/wecom.pb differ diff --git a/rpc/wecom/wecom.proto b/rpc/wecom/wecom.proto index ead2574..866f26f 100644 --- a/rpc/wecom/wecom.proto +++ b/rpc/wecom/wecom.proto @@ -63,6 +63,9 @@ service Wecom { body: "*" }; } + + rpc CreateReviewChange(CreateReviewChangeReq) returns (Response); + rpc SendMessage(SendMessageReq) returns (Response); } message EmptyReq {} @@ -116,6 +119,27 @@ message DeleteUserReq { int64 id = 1; } +// type: 1产品 2门店 3地址;before_data/after_data 为 JSON 字符串 +message CreateReviewChangeReq { + uint32 type = 1; + int64 biz_id = 2; + string task_id = 3; + string before_data = 4; + string after_data = 5; + int64 admin_id = 6; + string admin_name = 7; +} + +// biz_type: 1产品 2门店 3地址 4销售;type: 消息场景;action: 0未用 1通过 2拒绝 +message SendMessageReq { + int64 biz_id = 1; + uint32 biz_type = 2; + uint32 type = 3; + uint32 action = 4; + string reason = 5; + string key = 6; +} + message Response { int32 code = 1; string msg = 2; diff --git a/services/product/internal/apply/apply.go b/services/product/internal/apply/apply.go index 7af92e9..d79d0ab 100644 --- a/services/product/internal/apply/apply.go +++ b/services/product/internal/apply/apply.go @@ -5,9 +5,9 @@ import ( "lone-services/pkg/redis" "lone-services/pkg/rpcclient" "lone-services/pkg/utils" + "lone-services/pkg/wecomrpc" chorepb "lone-services/rpc/chore/pb" "lone-services/services/product/internal/dao" - "lone-services/services/product/internal/wecom" "strconv" "time" @@ -67,7 +67,7 @@ func Del(ctx context.Context, uId, objId int) error { return redis.Client.Del(ctx, redisKey(uId, objId)).Err() } -func Set(ctx context.Context, choreSvcName string, uId, objId int, reason string) error { +func Set(ctx context.Context, choreSvcName, wecomSvcName string, uId, objId int, reason string) error { data := Data{ Uid: uId, Id: objId, @@ -88,10 +88,10 @@ func Set(ctx context.Context, choreSvcName string, uId, objId int, reason string return err } - wecom.NotifyProduct(wecom.NotifyJob{ - ObjId: objId, - ObjType: dao.EditLogTypeProduct, - Type: wecom.ProductApplyReview, + wecomrpc.SendMessage(ctx, wecomSvcName, wecomrpc.SendMessageJob{ + BizId: objId, + BizType: wecomrpc.BizTypeProduct, + Type: wecomrpc.ProductApplyReview, Reason: reason, Key: md5, }) @@ -129,7 +129,7 @@ func CanEdit(ctx context.Context, uId, objId int) bool { return data.Status == dao.ApplyStatusDone } -func Pass(ctx context.Context, choreSvcName string, uId, objId int) error { +func Pass(ctx context.Context, choreSvcName, wecomSvcName string, uId, objId int) error { data, err := Get(ctx, uId, objId) if err != nil { return err @@ -166,10 +166,10 @@ func Pass(ctx context.Context, choreSvcName string, uId, objId int) error { return err } - wecom.NotifyProduct(wecom.NotifyJob{ - ObjId: objId, - ObjType: dao.EditLogTypeProduct, - Type: wecom.ProductNeedReview, + wecomrpc.SendMessage(ctx, wecomSvcName, wecomrpc.SendMessageJob{ + BizId: objId, + BizType: wecomrpc.BizTypeProduct, + Type: wecomrpc.ProductNeedReview, Action: dao.ApplyStatusDone, Reason: reason, }) diff --git a/services/product/internal/dao/edit.go b/services/product/internal/dao/edit.go index 320f6db..b2c3f06 100644 --- a/services/product/internal/dao/edit.go +++ b/services/product/internal/dao/edit.go @@ -1,11 +1,13 @@ package dao -// 编辑日志对象类型 +import "lone-services/pkg/wecomrpc" + +// 编辑对象类型(与 wecomrpc.BizType* 一致,供申请日志等非企微场景复用) const ( - EditLogTypeProduct uint8 = 1 // 产品 - EditLogTypeStore uint8 = 2 // 门店 - EditLogTypeAddress uint8 = 3 // 地址 - EditLogTypeSales uint8 = 4 // 销售 + EditLogTypeProduct = wecomrpc.BizTypeProduct + EditLogTypeStore = wecomrpc.BizTypeStore + EditLogTypeAddress = wecomrpc.BizTypeAddress + EditLogTypeSales = wecomrpc.BizTypeSales ) // 编辑申请状态(Redis / action_apply_log) diff --git a/services/product/internal/logic/editapplylogic.go b/services/product/internal/logic/editapplylogic.go index 9494cfc..330b115 100644 --- a/services/product/internal/logic/editapplylogic.go +++ b/services/product/internal/logic/editapplylogic.go @@ -63,7 +63,7 @@ func (l *EditApplyLogic) EditApply(in *product.EditApplyReq) (*product.Response, return outResponse(utils.Fail, "已经申请过"), nil } - if err = apply.Set(l.ctx, l.svcCtx.ChoreSvcName, adminId, int(req.Id), req.Reason); err != nil { + if err = apply.Set(l.ctx, l.svcCtx.ChoreSvcName, l.svcCtx.WecomSvcName, adminId, int(req.Id), req.Reason); err != nil { l.Errorf("edit apply set: %v", err) return failResponse(utils.Fail), nil } @@ -96,7 +96,7 @@ func (l *EditApplyLogic) EditApplyPass(in *product.EditApplyPassReq) (*product.R } adminId := int(adminInfo.ID) - if err = apply.Pass(l.ctx, l.svcCtx.ChoreSvcName, adminId, int(req.Id)); err != nil { + if err = apply.Pass(l.ctx, l.svcCtx.ChoreSvcName, l.svcCtx.WecomSvcName, adminId, int(req.Id)); err != nil { if apply.IsAlreadyHandled(err) { return outResponse(utils.Fail, err.Error()), nil } diff --git a/services/product/internal/logic/editbaselogic.go b/services/product/internal/logic/editbaselogic.go index 29563e7..43e00d1 100644 --- a/services/product/internal/logic/editbaselogic.go +++ b/services/product/internal/logic/editbaselogic.go @@ -5,12 +5,12 @@ import ( "lone-services/pkg/modelbase" "lone-services/pkg/utils" "lone-services/pkg/validate" + "lone-services/pkg/wecomrpc" product "lone-services/rpc/product/pb" "lone-services/services/product/internal/apply" "lone-services/services/product/internal/dao" "lone-services/services/product/internal/model" "lone-services/services/product/internal/svc" - "lone-services/services/product/internal/wecom" "lone-services/services/product/validator" "strconv" "time" @@ -115,11 +115,18 @@ func (l *EditBaseLogic) EditBase(in *product.EditBaseReq) (*product.Response, er return failResponse(utils.Fail), nil } - addEditLog(int(req.Id), dao.EditLogTypeProduct, adminId, adminName, data, old) - wecom.NotifyProduct(wecom.NotifyJob{ - ObjId: int(req.Id), - ObjType: dao.EditLogTypeProduct, - Type: wecom.ProductOrdinaryReview, + wecomrpc.CreateReviewChange(l.ctx, l.svcCtx.WecomSvcName, wecomrpc.ReviewChange{ + Type: wecomrpc.BizTypeProduct, + BizId: req.Id, + BeforeData: utils.StructToJson(old), + AfterData: utils.StructToJson(data), + AdminId: int64(adminId), + AdminName: adminName, + }) + wecomrpc.SendMessage(l.ctx, l.svcCtx.WecomSvcName, wecomrpc.SendMessageJob{ + BizId: int(req.Id), + BizType: wecomrpc.BizTypeProduct, + Type: wecomrpc.ProductOrdinaryReview, }) _ = apply.Del(l.ctx, adminId, int(req.Id)) diff --git a/services/product/internal/logic/editlog_helper.go b/services/product/internal/logic/editlog_helper.go deleted file mode 100644 index 54a091c..0000000 --- a/services/product/internal/logic/editlog_helper.go +++ /dev/null @@ -1,27 +0,0 @@ -package logic - -import ( - "lone-services/pkg/utils" - "lone-services/services/product/internal/dao" - "lone-services/services/product/internal/model" - - "github.com/zeromicro/go-zero/core/logx" -) - -func addEditLog(objId int, objType uint8, adminId int, adminName string, data, oldData interface{}) { - content := map[string]interface{}{ - "new": data, - "old": oldData, - } - add := dao.EditLogCreate{ - ObjId: objId, - ObjType: objType, - Content: utils.StructToJson(content), - AdminId: adminId, - AdminName: adminName, - } - err := model.EditLogModel{}.Init().Create(&add) - if err != nil { - logx.Errorf("edit log create: %v", err) - } -} diff --git a/services/product/internal/logic/editsusceptiblelogic.go b/services/product/internal/logic/editsusceptiblelogic.go index c5b346c..35de665 100644 --- a/services/product/internal/logic/editsusceptiblelogic.go +++ b/services/product/internal/logic/editsusceptiblelogic.go @@ -5,12 +5,12 @@ import ( "lone-services/pkg/modelbase" "lone-services/pkg/utils" "lone-services/pkg/validate" + "lone-services/pkg/wecomrpc" product "lone-services/rpc/product/pb" "lone-services/services/product/internal/apply" "lone-services/services/product/internal/dao" "lone-services/services/product/internal/model" "lone-services/services/product/internal/svc" - "lone-services/services/product/internal/wecom" "lone-services/services/product/validator" "strconv" @@ -119,11 +119,18 @@ func (l *EditSusceptibleLogic) EditSusceptible(in *product.EditSusceptibleReq) ( return failResponse(utils.Fail), nil } - addEditLog(int(req.Id), dao.EditLogTypeProduct, adminId, adminName, data, old) - wecom.NotifyProduct(wecom.NotifyJob{ - ObjId: int(req.Id), - ObjType: dao.EditLogTypeProduct, - Type: wecom.ProductSubmitReview, + wecomrpc.CreateReviewChange(l.ctx, l.svcCtx.WecomSvcName, wecomrpc.ReviewChange{ + Type: wecomrpc.BizTypeProduct, + BizId: req.Id, + BeforeData: utils.StructToJson(old), + AfterData: utils.StructToJson(data), + AdminId: int64(adminId), + AdminName: adminName, + }) + wecomrpc.SendMessage(l.ctx, l.svcCtx.WecomSvcName, wecomrpc.SendMessageJob{ + BizId: int(req.Id), + BizType: wecomrpc.BizTypeProduct, + Type: wecomrpc.ProductSubmitReview, }) _ = apply.Del(l.ctx, adminId, int(req.Id)) diff --git a/services/product/internal/logic/verifystatuslogic.go b/services/product/internal/logic/verifystatuslogic.go index b26e77b..e1d6c9c 100644 --- a/services/product/internal/logic/verifystatuslogic.go +++ b/services/product/internal/logic/verifystatuslogic.go @@ -6,11 +6,11 @@ import ( "lone-services/pkg/modelbase" "lone-services/pkg/utils" "lone-services/pkg/validate" + "lone-services/pkg/wecomrpc" product "lone-services/rpc/product/pb" "lone-services/services/product/internal/dao" "lone-services/services/product/internal/model" "lone-services/services/product/internal/svc" - "lone-services/services/product/internal/wecom" "lone-services/services/product/validator" "strconv" "time" @@ -170,14 +170,14 @@ func (l *VerifyStatusLogic) verifyStatus(expectStatus uint8, in *product.VerifyS return failResponse(utils.Fail), nil } - notifyType := wecom.ProductFirstReview + notifyType := wecomrpc.ProductFirstReview if expectStatus == dao.VerifyStatusSecond { - notifyType = wecom.ProductSecondReview + notifyType = wecomrpc.ProductSecondReview } objID, _ := strconv.Atoi(info.VerifyId) - wecom.NotifyProduct(wecom.NotifyJob{ - ObjId: objID, - ObjType: dao.VerifyTypeProduct, + wecomrpc.SendMessage(l.ctx, l.svcCtx.WecomSvcName, wecomrpc.SendMessageJob{ + BizId: objID, + BizType: wecomrpc.BizTypeProduct, Type: notifyType, Action: uint8(req.Status), Reason: reason, diff --git a/services/product/internal/model/edit_log_model.go b/services/product/internal/model/edit_log_model.go deleted file mode 100644 index 2a4692a..0000000 --- a/services/product/internal/model/edit_log_model.go +++ /dev/null @@ -1,23 +0,0 @@ -package model - -import ( - "lone-services/pkg/modelbase" - "lone-services/services/product/internal/dao" -) - -type EditLogModel struct { - modelbase.Base -} - -func (m EditLogModel) TableName() string { - return modelbase.Prefix() + "edit_log" -} - -func (m EditLogModel) Init() EditLogModel { - m.Table = m.TableName() - return m -} - -func (m EditLogModel) Create(data *dao.EditLogCreate) error { - return m.Base.Create(data) -} diff --git a/services/product/internal/svc/servicecontext.go b/services/product/internal/svc/servicecontext.go index 91020b8..deb7430 100644 --- a/services/product/internal/svc/servicecontext.go +++ b/services/product/internal/svc/servicecontext.go @@ -13,6 +13,7 @@ type ServiceContext struct { DB *gorm.DB Prefix string ChoreSvcName string + WecomSvcName string } func NewServiceContext(c config.Config, db *gorm.DB) *ServiceContext { @@ -20,10 +21,15 @@ func NewServiceContext(c config.Config, db *gorm.DB) *ServiceContext { if choreSvc == utils.StringEmpty { logx.Error("config services.chore empty") } + wecomSvc := utils.GetConfigString("services.wecom") + if wecomSvc == utils.StringEmpty { + logx.Error("config services.wecom empty") + } return &ServiceContext{ Config: c, DB: db, Prefix: utils.GetConfigString("mysql.prefix"), ChoreSvcName: choreSvc, + WecomSvcName: wecomSvc, } } diff --git a/services/product/internal/wecom/notify.go b/services/product/internal/wecom/notify.go deleted file mode 100644 index d052ce5..0000000 --- a/services/product/internal/wecom/notify.go +++ /dev/null @@ -1,26 +0,0 @@ -package wecom - -import "github.com/zeromicro/go-zero/core/logx" - -const ( - ProductApplyReview uint8 = 1 // 编辑申请按钮卡片 - ProductNeedReview uint8 = 2 // 编辑申请结果通知申请人 - ProductSubmitReview uint8 = 3 // 提交敏感字段变更 → 通知一审 - ProductFirstReview uint8 = 4 // 一审结果通知 - ProductSecondReview uint8 = 5 // 二审结果通知 - ProductOrdinaryReview uint8 = 6 // 基础信息变更 diff 通知 -) - -type NotifyJob struct { - ObjId int - ObjType uint8 - Type uint8 - Action uint8 // 1: 通过, 2: 驳回 - Reason string - Key string // 编辑申请 Redis MD5 key,企微回调用 -} - -func NotifyProduct(job NotifyJob) { - logx.Infof("wecom stub skip: type=%d objId=%d action=%d reason=%s key=%s", - job.Type, job.ObjId, job.Action, job.Reason, job.Key) -} diff --git a/services/wecom/internal/client/message.go b/services/wecom/internal/client/message.go new file mode 100644 index 0000000..ecf40d6 --- /dev/null +++ b/services/wecom/internal/client/message.go @@ -0,0 +1,19 @@ +package client + +import ( + "lone-services/pkg/utils" + "lone-services/pkg/wecom/auth" + "lone-services/pkg/wecom/message" + "lone-services/services/wecom/internal/dao" +) + +func NewMessageClient(msgType uint8) *message.Client { + secret := utils.GetConfigString("wecom.notify_secret") + if msgType == dao.WecomTypeReview { + secret = utils.GetConfigString("wecom.review_secret") + } + return message.NewClient(auth.NewClient( + utils.GetConfigString("wecom.corp_id"), + secret, + )) +} diff --git a/services/wecom/internal/dao/message.go b/services/wecom/internal/dao/message.go new file mode 100644 index 0000000..5f634c6 --- /dev/null +++ b/services/wecom/internal/dao/message.go @@ -0,0 +1,84 @@ +package dao + +import ( + "lone-services/pkg/wecom/message" + "lone-services/pkg/wecomrpc" +) + +const ( + WecomTypeReview = 1 // 审核应用 + WecomTypeNotify = 2 // 通知应用 +) + +const ( + EditLogTypeProduct = wecomrpc.BizTypeProduct + EditLogTypeStore = wecomrpc.BizTypeStore + EditLogTypeAddress = wecomrpc.BizTypeAddress + EditLogTypeSales = wecomrpc.BizTypeSales + + ProductApplyReview = wecomrpc.ProductApplyReview + ProductNeedReview = wecomrpc.ProductNeedReview + ProductSubmitReview = wecomrpc.ProductSubmitReview + ProductFirstReview = wecomrpc.ProductFirstReview + ProductSecondReview = wecomrpc.ProductSecondReview + ProductOrdinaryReview = wecomrpc.ProductOrdinaryReview + + StoreApplyReview = wecomrpc.StoreApplyReview + StoreNeedReview = wecomrpc.StoreNeedReview + StoreSubmitReview = wecomrpc.StoreSubmitReview + StoreFirstReview = wecomrpc.StoreFirstReview + StoreSecondReview = wecomrpc.StoreSecondReview + + AddressApplyReview = wecomrpc.AddressApplyReview + AddressSubmitReview = wecomrpc.AddressSubmitReview + AddressFirstReview = wecomrpc.AddressFirstReview + AddressSecondReview = wecomrpc.AddressSecondReview + + SalesApplyReview = wecomrpc.SalesApplyReview + + ActionNone = wecomrpc.ActionNone + ActionPass = wecomrpc.ActionPass + ActionReject = wecomrpc.ActionReject +) + +type MessageConfig struct { + Title string + Desc string + SourceDesc string +} + +type FieldConfig struct { + Field string + Label string +} + +type WeComJob struct { + BizId int `json:"biz_id"` + BizType uint8 `json:"biz_type"` // 1:产品,2:门店,3:地址 + Type uint8 `json:"type"` + Action uint8 `json:"action"` + Ext map[string]any `json:"ext"` // 备注,理由,时间等字段 + // reason 理由 + // key 按钮需要的key +} + +type ReviewActionRequest struct { + AgentId int64 `json:"agentid"` + ResponseCode string `json:"response_code"` + Action string `json:"action"` + TaskId string `json:"task_id"` +} + +type Horizontal struct { + Content []message.HorizontalContent `json:"content"` + TaskId string `json:"task_id"` + DetailUrl string `json:"detail_url"` + Key string `json:"key"` +} + +type DiffItem struct { + Field string + Label string + Old string + New string +} diff --git a/services/wecom/internal/dao/review.go b/services/wecom/internal/dao/review.go new file mode 100644 index 0000000..dba1794 --- /dev/null +++ b/services/wecom/internal/dao/review.go @@ -0,0 +1,33 @@ +package dao + +import "lone-services/pkg/utils" + +const ( + WecomReviewActionAgree = "agree" + WecomReviewActionReject = "reject" + WecomReviewActionExpired = "expired" + WecomReviewAgree = 1 + WecomReviewReject = 2 + WecomReviewPending = 3 + WecomReviewExpired = 4 + + WecomReviewAgreeFormat = "已通过" + WecomReviewRejectFormat = "已拒绝" + + WecomReviewExpiredFormat = "已过期" +) + +type WecomReviewTask struct { + Id int `gorm:"column:id;primaryKey;autoIncrement;comment:主键ID" json:"id"` + AgentId int `gorm:"column:agent_id;type:int(11);not null;default:0;comment:agentId" json:"agent_id"` + ResponseCode string `gorm:"column:response_code;type:varchar(255);not null;default:'';comment:response_code" json:"response_code"` + TaskId string `gorm:"column:task_id;type:varchar(64);not null;default:0;comment:企业微信任务ID" json:"task_id"` + ObjId int `gorm:"column:obj_id;type:int(11);not null;default:0;comment:业务对象ID" json:"obj_id"` + ObjType uint8 `gorm:"column:obj_type;type:tinyint(1);not null;default:0;comment:业务对象类型,1:产品,2:门店,3:地址" json:"obj_type"` + Type uint8 `gorm:"column:type;type:tinyint(1);not null;default:0;comment:消息类型,1:审核,2:通知" json:"type"` + Payload string `gorm:"column:payload;type:text;not null;comment:原始内容" json:"payload"` + DetailUrl string `gorm:"column:detail_url;type:varchar(255);not null;default:'';comment:详情跳转链接" json:"detail_url"` + ReviewStatus uint8 `gorm:"column:review_status;type:tinyint(1);not null;default:3;comment:审核状态,3:待审核,1:通过,2:拒绝" json:"review_status"` + CreatedAt utils.CustomTime `gorm:"column:created_at;type:datetime;default:NULL;comment:创建时间" json:"created_at"` + UpdatedAt utils.CustomTime `gorm:"column:updated_at;type:datetime;default:NULL;comment:更新时间" json:"updated_at"` +} diff --git a/services/wecom/internal/dao/review_change.go b/services/wecom/internal/dao/review_change.go new file mode 100644 index 0000000..2fa6287 --- /dev/null +++ b/services/wecom/internal/dao/review_change.go @@ -0,0 +1,16 @@ +package dao + +import "lone-services/pkg/utils" + +// ReviewChange 审核变更快照(产品/门店/地址) +type ReviewChange struct { + Id int64 `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + Type uint8 `gorm:"column:type;type:tinyint unsigned;not null;default:0;comment:业务类型:1产品 2门店 3地址" json:"type"` + BizId int64 `gorm:"column:biz_id;type:int;not null;default:0;comment:业务ID" json:"biz_id"` + TaskId string `gorm:"column:task_id;type:varchar(64);not null;default:'';comment:企微审核任务ID" json:"task_id"` + BeforeData string `gorm:"column:before_data;type:json;comment:修改前数据JSON" json:"before_data"` + AfterData string `gorm:"column:after_data;type:json;comment:修改后数据JSON" json:"after_data"` + AdminId int64 `gorm:"column:admin_id;type:int;not null;default:0;comment:操作人ID" json:"admin_id"` + AdminName string `gorm:"column:admin_name;type:varchar(64);not null;default:'';comment:操作人姓名" json:"admin_name"` + CreatedAt utils.CustomTime `gorm:"column:created_at;type:datetime;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"` +} diff --git a/services/wecom/internal/logic/createReviewChangeLogic.go b/services/wecom/internal/logic/createReviewChangeLogic.go new file mode 100644 index 0000000..f022135 --- /dev/null +++ b/services/wecom/internal/logic/createReviewChangeLogic.go @@ -0,0 +1,61 @@ +package logic + +import ( + "context" + + "lone-services/pkg/utils" + "lone-services/pkg/validate" + wecom "lone-services/rpc/wecom/pb" + "lone-services/services/wecom/internal/dao" + "lone-services/services/wecom/internal/model" + "lone-services/services/wecom/internal/svc" + "lone-services/services/wecom/validator" + + "github.com/zeromicro/go-zero/core/logx" +) + +type CreateReviewChangeLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewCreateReviewChangeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateReviewChangeLogic { + return &CreateReviewChangeLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *CreateReviewChangeLogic) CreateReviewChange(in *wecom.CreateReviewChangeReq) (*wecom.Response, error) { + var req validator.CreateReviewChangeValidator + if msg := validate.ValidateFromProto(in, &req); msg != utils.StringEmpty { + return outResponse(utils.ErrorParams, msg), nil + } + + before := req.BeforeData + after := req.AfterData + if before == utils.StringEmpty { + before = "null" + } + if after == utils.StringEmpty { + after = "null" + } + + row := &dao.ReviewChange{ + Type: uint8(req.Type), + BizId: req.BizId, + TaskId: req.TaskId, + BeforeData: before, + AfterData: after, + AdminId: req.AdminId, + AdminName: req.AdminName, + CreatedAt: utils.Now(), + } + if err := (model.ReviewChangeModel{}).Init().Create(row); err != nil { + l.Errorf("create review change: %v", err) + return failResponse(utils.Fail), nil + } + return okResponse(map[string]any{"id": row.Id}), nil +} diff --git a/services/wecom/internal/logic/message/action/review_action.go b/services/wecom/internal/logic/message/action/review_action.go index cd34649..647dbab 100644 --- a/services/wecom/internal/logic/message/action/review_action.go +++ b/services/wecom/internal/logic/message/action/review_action.go @@ -1,115 +1,70 @@ package action import ( - "base-service/app/dao" - "base-service/app/models" - "base-service/app/services/wecom/client" - "base-service/pkg/wecom/message" - "base-service/utils" "context" "errors" - "fmt" "strconv" - "time" + + "lone-services/pkg/modelbase" + "lone-services/pkg/utils" + "lone-services/pkg/wecom/message" + "lone-services/services/wecom/internal/client" + "lone-services/services/wecom/internal/dao" + "lone-services/services/wecom/internal/model" + + "github.com/zeromicro/go-zero/core/logx" ) -type ReviewActionService struct { -} +type ReviewActionService struct{} -func (s ReviewActionService) UpdateCard(reqData *dao.ReviewActionRequest) error { - lockKey := fmt.Sprintf( - "wecom:review:lock:%s", - reqData.TaskId, - ) - - ok, err := utils.Redis.SetNX(lockKey, 1, 5*time.Second).Result() - - if err != nil { - utils.Logger.Error("redis read filed") - return err +func (s ReviewActionService) UpdateCard(ctx context.Context, reqData *dao.ReviewActionRequest) error { + if ctx == nil { + ctx = context.Background() } - if !ok { - utils.Logger.Info("You clicked too fast") - return errors.New("You clicked too fast") - } - w := models.Params{ + w := modelbase.Params{ Eq: map[string]string{ - "task_id": reqData.TaskId, + "task_id": reqData.TaskId, + "review_status": strconv.Itoa(dao.WecomReviewPending), }, } - task := dao.WecomReviewTask{} - err = models.WecomReviewTask{}.Init().GetOne( - w, - &task, - ) - if task.ReviewStatus != dao.WecomReviewPending { - utils.Logger.Info("task already reviewed") - return errors.New("task already reviewed") - } - if err != nil { - return err - } + replaceName := dao.WecomReviewExpiredFormat reviewStatus := dao.WecomReviewExpired - switch reqData.Action { - case dao.WecomReviewActionAgree: - replaceName = dao.WecomReviewAgreeFormat reviewStatus = dao.WecomReviewAgree - case dao.WecomReviewActionReject: - replaceName = dao.WecomReviewRejectFormat reviewStatus = dao.WecomReviewReject case dao.WecomReviewActionExpired: - replaceName = dao.WecomReviewExpiredFormat reviewStatus = dao.WecomReviewExpired - default: + } - replaceName = dao.WecomReviewExpiredFormat - reviewStatus = dao.WecomReviewExpired + rows, err := model.ReviewTaskModel{}.Init().Edit(w, map[string]string{ + "review_status": strconv.Itoa(reviewStatus), + "response_code": reqData.ResponseCode, + }) + if err != nil { + return err + } + if rows == 0 { + return errors.New("task already reviewed") } updateReq := &message.UpdateCardRequest{ AgentId: reqData.AgentId, - Atall: dao.NumberOne, + Atall: utils.NumberOne, ResponseCode: reqData.ResponseCode, - Button: &message.UpdateButton{ ReplaceName: replaceName, }, } - - messageClient := client.NewMessageClient(dao.WecomTypeReview) - - err = messageClient.Update(context.Background(), updateReq) - - if err != nil { - utils.Logger.Info("messageclient update filed", err) + if err = client.NewMessageClient(dao.WecomTypeReview).Update(ctx, updateReq); err != nil { + logx.Errorf("message client update failed: %v", err) return err } - - _, err = models.WecomReviewTask{}.Init().Edit( - w, - map[string]string{ - "review_status": strconv.Itoa(reviewStatus), - "response_code": reqData.ResponseCode, - }, - ) - return err - - // 只做更新卡片,去掉发送通知 - // notifyJob := dao.WeComJob{ - // ObjId: task.ObjId, - // ObjType: task.ObjType, - // Type: dao.WecomTypeNotify, - // NotifyObjId: task.NotifyObjId, - // Message: task.Message, - // } - - // return sender.WecomSenderService{}.Send(notifyJob) + return nil } diff --git a/services/wecom/internal/logic/message/builder/button_card.go b/services/wecom/internal/logic/message/builder/button_card.go index 876b9f0..24aa59f 100644 --- a/services/wecom/internal/logic/message/builder/button_card.go +++ b/services/wecom/internal/logic/message/builder/button_card.go @@ -1,8 +1,8 @@ package builder import ( - "base-service/pkg/wecom/message" - "base-service/utils" + "lone-services/pkg/utils" + "lone-services/pkg/wecom/message" ) type ButtonCardParams struct { diff --git a/services/wecom/internal/logic/message/builder/text_card.go b/services/wecom/internal/logic/message/builder/text_card.go index 7855caa..4847184 100644 --- a/services/wecom/internal/logic/message/builder/text_card.go +++ b/services/wecom/internal/logic/message/builder/text_card.go @@ -1,8 +1,8 @@ package builder import ( - "base-service/pkg/wecom/message" - "base-service/utils" + "lone-services/pkg/utils" + "lone-services/pkg/wecom/message" ) type TextCardParams struct { diff --git a/services/wecom/internal/logic/message/handlers/base.go b/services/wecom/internal/logic/message/handlers/base.go index 1c96530..204eb23 100644 --- a/services/wecom/internal/logic/message/handlers/base.go +++ b/services/wecom/internal/logic/message/handlers/base.go @@ -1,10 +1,12 @@ package handlers import ( - "base-service/app/dao" - "base-service/pkg/wecom/message" + "context" + + "lone-services/pkg/wecom/message" + "lone-services/services/wecom/internal/dao" ) type Handler interface { - Build(job dao.WeComJob) ([]*message.SendRequest, error) + Build(ctx context.Context, job dao.WeComJob) ([]*message.SendRequest, error) } diff --git a/services/wecom/internal/logic/message/handlers/factory.go b/services/wecom/internal/logic/message/handlers/factory.go index 4707a51..cfb1165 100644 --- a/services/wecom/internal/logic/message/handlers/factory.go +++ b/services/wecom/internal/logic/message/handlers/factory.go @@ -1,13 +1,13 @@ -package handlers +package handlers import ( - "base-service/app/dao" "errors" + "lone-services/services/wecom/internal/dao" ) func GetHandler(job dao.WeComJob) (Handler, error) { - switch job.ObjType { + switch job.BizType { // 产品 case dao.EditLogTypeProduct: diff --git a/services/wecom/internal/logic/message/handlers/notify_address_first.go b/services/wecom/internal/logic/message/handlers/notify_address_first.go index e497c64..c317996 100644 --- a/services/wecom/internal/logic/message/handlers/notify_address_first.go +++ b/services/wecom/internal/logic/message/handlers/notify_address_first.go @@ -1,49 +1,61 @@ -package handlers +package handlers import ( - "base-service/app/dao" - "base-service/app/models" - "base-service/app/services/wecom/message/builder" - util "base-service/app/services/wecom/message/utils" - "base-service/pkg/wecom/message" - "base-service/utils" - "strconv" + "context" + + "lone-services/pkg/utils" + "lone-services/pkg/wecom/message" + "lone-services/services/wecom/internal/dao" + "lone-services/services/wecom/internal/logic/message/builder" + msgutil "lone-services/services/wecom/internal/logic/message/utils" + + jsoniter "github.com/json-iterator/go" ) -type AddressNotifyFirstHandler struct { -} +type AddressNotifyFirstHandler struct{} -func (h AddressNotifyFirstHandler) Build(job dao.WeComJob) ([]*message.SendRequest, error) { +func (h AddressNotifyFirstHandler) Build(ctx context.Context, job dao.WeComJob) ([]*message.SendRequest, error) { + change, err := msgutil.GetLatestReviewChange(job.BizType, int64(job.BizId)) + if err != nil { + return nil, err + } - logInfo := dao.EditLogInfo{} - - models.EditLogModel{}.Init().GetOne(models.Params{ - Eq: map[string]string{ - "obj_id": strconv.Itoa(job.ObjId), - "obj_type": strconv.Itoa(int(job.ObjType)), - }, - Order: "id desc", - }, &logInfo) - - content := util.BuildContent( - struct{ Key, Value string }{"门店名称", getTypeNameFromContent(logInfo.Content)}, + content := msgutil.BuildContent( + struct{ Key, Value string }{"门店名称", getTypeNameFromContent(msgutil.DiffContent(change))}, struct{ Key, Value string }{"提醒消息", "您有一个地址需要审核"}, ) - crad := builder.TextCardParams{ + card := builder.TextCardParams{ ToUser: utils.GetConfigString("wecom.address_notify_second_ids"), Desc: "地址通知", Title: "地址审核通知", Content: content, } - req, err := builder.TextCard(crad) - + req, err := builder.TextCard(card) if err != nil { return nil, err } - - return []*message.SendRequest{ - req, - }, nil + return []*message.SendRequest{req}, nil +} + +func getTypeNameFromContent(content string) string { + if content == utils.StringEmpty { + return utils.StringEmpty + } + + var data struct { + Old map[string]any `json:"old"` + New map[string]any `json:"new"` + } + if err := jsoniter.Unmarshal([]byte(content), &data); err != nil { + return utils.StringEmpty + } + if v, ok := data.New["type_name"].(string); ok && v != utils.StringEmpty { + return v + } + if v, ok := data.Old["type_name"].(string); ok && v != utils.StringEmpty { + return v + } + return utils.StringEmpty } diff --git a/services/wecom/internal/logic/message/handlers/notify_address_second.go b/services/wecom/internal/logic/message/handlers/notify_address_second.go index e29dd19..0fd931e 100644 --- a/services/wecom/internal/logic/message/handlers/notify_address_second.go +++ b/services/wecom/internal/logic/message/handlers/notify_address_second.go @@ -1,77 +1,103 @@ -package handlers +package handlers import ( - "base-service/app/dao" - "base-service/app/models" - "base-service/app/services/wecom/message/builder" - "base-service/pkg/wecom/message" - "base-service/utils" + "context" + "encoding/json" "fmt" - "strconv" + + "lone-services/pkg/utils" + "lone-services/pkg/wecom/message" + "lone-services/services/wecom/internal/dao" + "lone-services/services/wecom/internal/logic/message/builder" + msgutil "lone-services/services/wecom/internal/logic/message/utils" ) -type AddressNotifySecondHandler struct { -} +type AddressNotifySecondHandler struct{} -func (h AddressNotifySecondHandler) Build(job dao.WeComJob) ([]*message.SendRequest, error) { - - logInfo := dao.EditLogInfo{} - - models.EditLogModel{}.Init().GetOne(models.Params{ - Eq: map[string]string{ - "obj_id": strconv.Itoa(job.ObjId), - "obj_type": strconv.Itoa(int(job.ObjType)), - }, - Order: "id desc", - }, &logInfo) - - if logInfo.Id == dao.NumberZero { - return nil, fmt.Errorf("edit log not found") - } - - // 需要返回的字段 - fields := []dao.FieldConfig{ - { - Field: "type_name", - Label: "门店名称", - }, - { - Field: "name", - Label: "收货人", - }, - { - Field: "address", - Label: "地址", - }, - { - Field: "district", - Label: "地区", - }, - { - Field: "mobile", - Label: "收货人电话", - }, - } - - content, err := BuildAddressDiff(logInfo.Content, fields) +func (h AddressNotifySecondHandler) Build(ctx context.Context, job dao.WeComJob) ([]*message.SendRequest, error) { + change, err := msgutil.GetLatestReviewChange(job.BizType, int64(job.BizId)) if err != nil { return nil, err } - crad := builder.TextCardParams{ + fields := []dao.FieldConfig{ + {Field: "type_name", Label: "门店名称"}, + {Field: "name", Label: "收货人"}, + {Field: "address", Label: "地址"}, + {Field: "district", Label: "地区"}, + {Field: "mobile", Label: "收货人电话"}, + } + + content, err := BuildAddressDiff(msgutil.DiffContent(change), fields) + if err != nil { + return nil, err + } + + card := builder.TextCardParams{ ToUser: utils.GetConfigString("wecom.address_reviewer_ids"), Desc: "地址通知", Title: "地址审核通知", Content: content, } - req, err := builder.TextCard(crad) - + req, err := builder.TextCard(card) if err != nil { return nil, err } - - return []*message.SendRequest{ - req, - }, nil + return []*message.SendRequest{req}, nil +} + +func BuildAddressDiff(content string, fields []dao.FieldConfig) ([]message.HorizontalContent, error) { + var data struct { + Old map[string]interface{} `json:"old"` + New map[string]interface{} `json:"new"` + } + if err := json.Unmarshal([]byte(content), &data); err != nil { + return nil, err + } + + result := make([]message.HorizontalContent, 0) + districtOld := msgutil.GetMapString(data.Old, "district") + districtNew := msgutil.GetMapString(data.New, "district") + + for _, field := range fields { + if field.Field == "district" { + continue + } + + oldValue := msgutil.GetMapString(data.Old, field.Field) + newValue := msgutil.GetMapString(data.New, field.Field) + + if field.Field == "type_name" && newValue == utils.StringEmpty { + newValue = oldValue + } + + if field.Field == "address" { + if districtOld != utils.StringEmpty { + oldValue = districtOld + oldValue + } + if districtNew != utils.StringEmpty { + newValue = districtNew + newValue + } + } + + if field.Field == "mobile" && oldValue != utils.StringEmpty { + if decryptOld, err := utils.Decrypt(oldValue); err == nil { + oldValue = decryptOld + } + } + + value := newValue + if oldValue != utils.StringEmpty && + oldValue != utils.StringZero && + oldValue != newValue { + value = fmt.Sprintf("%s → %s", oldValue, newValue) + } + + result = append(result, message.HorizontalContent{ + KeyName: field.Label, + Value: value, + }) + } + return result, nil } diff --git a/services/wecom/internal/logic/message/handlers/notify_address_submit.go b/services/wecom/internal/logic/message/handlers/notify_address_submit.go index c0b62d9..47d2c80 100644 --- a/services/wecom/internal/logic/message/handlers/notify_address_submit.go +++ b/services/wecom/internal/logic/message/handlers/notify_address_submit.go @@ -1,76 +1,38 @@ -package handlers +package handlers import ( - "base-service/app/dao" - "base-service/app/models" - "base-service/app/services/wecom/message/builder" - util "base-service/app/services/wecom/message/utils" - "base-service/pkg/wecom/message" - "base-service/utils" - "strconv" + "context" - jsoniter "github.com/json-iterator/go" + "lone-services/pkg/utils" + "lone-services/pkg/wecom/message" + "lone-services/services/wecom/internal/dao" + "lone-services/services/wecom/internal/logic/message/builder" + msgutil "lone-services/services/wecom/internal/logic/message/utils" ) -type AddressNotifySubmitHandler struct { -} +type AddressNotifySubmitHandler struct{} -func (h AddressNotifySubmitHandler) Build(job dao.WeComJob) ([]*message.SendRequest, error) { +func (h AddressNotifySubmitHandler) Build(ctx context.Context, job dao.WeComJob) ([]*message.SendRequest, error) { + change, err := msgutil.GetLatestReviewChange(job.BizType, int64(job.BizId)) + if err != nil { + return nil, err + } - logInfo := dao.EditLogInfo{} - - models.EditLogModel{}.Init().GetOne(models.Params{ - Eq: map[string]string{ - "obj_id": strconv.Itoa(job.ObjId), - "obj_type": strconv.Itoa(int(job.ObjType)), - }, - Order: "id desc", - }, &logInfo) - - content := util.BuildContent( - struct{ Key, Value string }{"门店名称", getTypeNameFromContent(logInfo.Content)}, + content := msgutil.BuildContent( + struct{ Key, Value string }{"门店名称", getTypeNameFromContent(msgutil.DiffContent(change))}, struct{ Key, Value string }{"提醒消息", "您有一个地址需要审核"}, ) - crad := builder.TextCardParams{ + card := builder.TextCardParams{ ToUser: utils.GetConfigString("wecom.address_notify_first_ids"), Desc: "地址通知", Title: "地址审核通知", Content: content, } - req, err := builder.TextCard(crad) - + req, err := builder.TextCard(card) if err != nil { return nil, err } - - return []*message.SendRequest{ - req, - }, nil -} - -func getTypeNameFromContent(content string) string { - if content == "" { - return "" - } - - var data struct { - Old map[string]any `json:"old"` - New map[string]any `json:"new"` - } - - if err := jsoniter.Unmarshal([]byte(content), &data); err != nil { - return "" - } - - if v, ok := data.New["type_name"].(string); ok && v != "" { - return v - } - - if v, ok := data.Old["type_name"].(string); ok && v != "" { - return v - } - - return "" + return []*message.SendRequest{req}, nil } diff --git a/services/wecom/internal/logic/message/handlers/notify_product_apply.go b/services/wecom/internal/logic/message/handlers/notify_product_apply.go index d3d6c3c..dac4baf 100644 --- a/services/wecom/internal/logic/message/handlers/notify_product_apply.go +++ b/services/wecom/internal/logic/message/handlers/notify_product_apply.go @@ -1,64 +1,50 @@ -package handlers +package handlers import ( - "base-service/app/dao" - "base-service/app/models" - "base-service/app/services/wecom/message/builder" - util "base-service/app/services/wecom/message/utils" - "base-service/pkg/wecom/message" - "strconv" + "context" + + "lone-services/pkg/wecom/message" + "lone-services/services/wecom/internal/dao" + "lone-services/services/wecom/internal/logic/message/builder" + msgutil "lone-services/services/wecom/internal/logic/message/utils" ) -type ProductNotifyApplyHandler struct { -} +type ProductNotifyApplyHandler struct{} -func (h ProductNotifyApplyHandler) Build(job dao.WeComJob) ([]*message.SendRequest, error) { - - product := dao.ProductInfo{} - models.ProductModel{}.Init().GetOne(models.Params{ - Eq: map[string]string{ - "id": strconv.Itoa(job.ObjId), - }, - }, &product) - - var ( - toUser string - content []message.HorizontalContent - ) - - user, err := util.GetActionWecomUser(job.ObjId, job.ObjType) - toUser = user.WecomUserId +func (h ProductNotifyApplyHandler) Build(ctx context.Context, job dao.WeComJob) ([]*message.SendRequest, error) { + product, err := msgutil.GetProductById(ctx, job.BizId) if err != nil { return nil, err } + user, err := msgutil.GetActionWecomUser(job.BizId, job.BizType) + if err != nil { + return nil, err + } + + var content []message.HorizontalContent switch job.Action { case dao.ActionPass: - - content = util.BuildContent( - struct{ Key, Value string }{"产品名称", product.Name}, + content = msgutil.BuildContent( + struct{ Key, Value string }{"产品名称", product.GetName()}, struct{ Key, Value string }{"审核状态", "已通过"}, ) - case dao.ActionReject: - content = util.BuildContent( - struct{ Key, Value string }{"产品名称", product.Name}, + content = msgutil.BuildContent( + struct{ Key, Value string }{"产品名称", product.GetName()}, struct{ Key, Value string }{"审核状态", "未通过"}, - struct{ Key, Value string }{"拒绝原因", util.GetExtString(job.Ext, "reason")}, + struct{ Key, Value string }{"拒绝原因", msgutil.GetExtString(job.Ext, "reason")}, ) } - card := builder.TextCardParams{ - ToUser: toUser, + + req, err := builder.TextCard(builder.TextCardParams{ + ToUser: user.WecomUserId, Desc: "产品通知", Title: "产品审核通知", Content: content, - } - - req, err := builder.TextCard(card) - + }) if err != nil { return nil, err } - return []*message.SendRequest{req}, nil } diff --git a/services/wecom/internal/logic/message/handlers/notify_product_first.go b/services/wecom/internal/logic/message/handlers/notify_product_first.go index b547cb3..df31931 100644 --- a/services/wecom/internal/logic/message/handlers/notify_product_first.go +++ b/services/wecom/internal/logic/message/handlers/notify_product_first.go @@ -1,26 +1,22 @@ -package handlers +package handlers import ( - "base-service/app/dao" - "base-service/app/models" - "base-service/app/services/wecom/message/builder" - util "base-service/app/services/wecom/message/utils" - "base-service/pkg/wecom/message" - "base-service/utils" - "strconv" + "context" + + "lone-services/pkg/utils" + "lone-services/pkg/wecom/message" + "lone-services/services/wecom/internal/dao" + "lone-services/services/wecom/internal/logic/message/builder" + msgutil "lone-services/services/wecom/internal/logic/message/utils" ) -type ProductNotifyFirstHandler struct { -} +type ProductNotifyFirstHandler struct{} -func (h ProductNotifyFirstHandler) Build(job dao.WeComJob) ([]*message.SendRequest, error) { - - product := dao.ProductInfo{} - models.ProductModel{}.Init().GetOne(models.Params{ - Eq: map[string]string{ - "id": strconv.Itoa(job.ObjId), - }, - }, &product) +func (h ProductNotifyFirstHandler) Build(ctx context.Context, job dao.WeComJob) ([]*message.SendRequest, error) { + product, err := msgutil.GetProductById(ctx, job.BizId) + if err != nil { + return nil, err + } var ( toUser string @@ -30,37 +26,31 @@ func (h ProductNotifyFirstHandler) Build(job dao.WeComJob) ([]*message.SendReque switch job.Action { case dao.ActionPass: toUser = utils.GetConfigString("wecom.product_notify_second_ids") - content = util.BuildContent( - struct{ Key, Value string }{"产品名称", product.Name}, + content = msgutil.BuildContent( + struct{ Key, Value string }{"产品名称", product.GetName()}, struct{ Key, Value string }{"提醒消息", "您有一个产品需要审核"}, ) - case dao.ActionReject: - user, err := util.GetActionWecomUser(job.ObjId, job.ObjType) - + user, err := msgutil.GetActionWecomUser(job.BizId, job.BizType) if err != nil { return nil, err } - toUser = user.WecomUserId - content = util.BuildContent( - struct{ Key, Value string }{"产品名称", product.Name}, + content = msgutil.BuildContent( + struct{ Key, Value string }{"产品名称", product.GetName()}, struct{ Key, Value string }{"审核状态", "未通过"}, - struct{ Key, Value string }{"拒绝原因", util.GetExtString(job.Ext, "reason")}, + struct{ Key, Value string }{"拒绝原因", msgutil.GetExtString(job.Ext, "reason")}, ) } - card := builder.TextCardParams{ + + req, err := builder.TextCard(builder.TextCardParams{ ToUser: toUser, Desc: "产品通知", Title: "产品审核通知", Content: content, - } - - req, err := builder.TextCard(card) - + }) if err != nil { return nil, err } - return []*message.SendRequest{req}, nil } diff --git a/services/wecom/internal/logic/message/handlers/notify_product_ordinary.go b/services/wecom/internal/logic/message/handlers/notify_product_ordinary.go index e67c14c..8483377 100644 --- a/services/wecom/internal/logic/message/handlers/notify_product_ordinary.go +++ b/services/wecom/internal/logic/message/handlers/notify_product_ordinary.go @@ -1,29 +1,18 @@ -package handlers +package handlers import ( - "base-service/app/dao" - "base-service/app/models" - util "base-service/app/services/wecom/message/utils" - "base-service/pkg/wecom/message" - "base-service/utils" - "strconv" + "context" + + "lone-services/pkg/utils" + "lone-services/pkg/wecom/message" + "lone-services/services/wecom/internal/dao" + msgutil "lone-services/services/wecom/internal/logic/message/utils" ) -type ProductNotifyOrdinaryHandler struct { -} - -func (h ProductNotifyOrdinaryHandler) Build(job dao.WeComJob) ([]*message.SendRequest, error) { - - product := dao.ProductInfo{} - - models.ProductModel{}.Init().GetOne(models.Params{ - Eq: map[string]string{ - "id": strconv.Itoa(job.ObjId), - }, - }, &product) - - user, err := util.GetApplicantUser(job.ObjId, job.ObjType, dao.NumberTwo) +type ProductNotifyOrdinaryHandler struct{} +func (h ProductNotifyOrdinaryHandler) Build(ctx context.Context, job dao.WeComJob) ([]*message.SendRequest, error) { + user, err := msgutil.GetApplicantUser(job.BizId, job.BizType, dao.UserTypeSale) if err != nil { return nil, err } @@ -32,18 +21,14 @@ func (h ProductNotifyOrdinaryHandler) Build(job dao.WeComJob) ([]*message.SendRe if err != nil { return nil, err } - reqs := []*message.SendRequest{ - req1, - } + reqs := []*message.SendRequest{req1} - if user.Id > dao.NumberZero { + if user.Id > utils.NumberZero { req2, err := toProductReviewer(user.WecomUserId, job) if err != nil { return nil, err } - reqs = append(reqs, req2) } - return reqs, nil } diff --git a/services/wecom/internal/logic/message/handlers/notify_product_second.go b/services/wecom/internal/logic/message/handlers/notify_product_second.go index 20fb7c0..9fea3ce 100644 --- a/services/wecom/internal/logic/message/handlers/notify_product_second.go +++ b/services/wecom/internal/logic/message/handlers/notify_product_second.go @@ -1,261 +1,164 @@ -package handlers +package handlers import ( - "base-service/app/dao" - "base-service/app/models" - "base-service/app/services/wecom/message/builder" - util "base-service/app/services/wecom/message/utils" - "base-service/pkg/wecom/message" - "base-service/utils" + "context" "encoding/json" "fmt" - "strconv" + + "lone-services/pkg/utils" + "lone-services/pkg/wecom/message" + productpb "lone-services/rpc/product/pb" + "lone-services/services/wecom/internal/dao" + "lone-services/services/wecom/internal/logic/message/builder" + msgutil "lone-services/services/wecom/internal/logic/message/utils" ) -type ProductNotifySecondHandler struct { -} +type ProductNotifySecondHandler struct{} -func (h ProductNotifySecondHandler) Build(job dao.WeComJob) ([]*message.SendRequest, error) { - - product := dao.ProductInfo{} - - models.ProductModel{}.Init().GetOne(models.Params{ - Eq: map[string]string{ - "id": strconv.Itoa(job.ObjId), - }, - }, &product) - - user, err := util.GetApplicantUser(job.ObjId, job.ObjType, dao.NumberTwo) +func (h ProductNotifySecondHandler) Build(ctx context.Context, job dao.WeComJob) ([]*message.SendRequest, error) { + product, err := msgutil.GetProductById(ctx, job.BizId) + if err != nil { + return nil, err + } + user, err := msgutil.GetApplicantUser(job.BizId, job.BizType, dao.UserTypeSale) if err != nil { return nil, err } switch job.Action { - case dao.ActionPass: - req1, err := toProductReviewer(utils.GetConfigString("wecom.product_reviewer_ids"), job) if err != nil { return nil, err } - reqs := []*message.SendRequest{ - req1, - } - - if user.Id > dao.NumberZero { + reqs := []*message.SendRequest{req1} + if user.Id > utils.NumberZero { req2, err := toProductApply(user.WecomUserId, product) if err != nil { return nil, err } - reqs = append(reqs, req2) } - return reqs, nil case dao.ActionReject: - - content := util.BuildContent( - struct{ Key, Value string }{"产品名称", product.Name}, + content := msgutil.BuildContent( + struct{ Key, Value string }{"产品名称", product.GetName()}, struct{ Key, Value string }{"审核状态", "未通过"}, - struct{ Key, Value string }{"拒绝原因", util.GetExtString(job.Ext, "reason")}, + struct{ Key, Value string }{"拒绝原因", msgutil.GetExtString(job.Ext, "reason")}, ) - - if user.Id > dao.NumberZero { - card := builder.TextCardParams{ + if user.Id > utils.NumberZero { + req, err := builder.TextCard(builder.TextCardParams{ ToUser: user.WecomUserId, Desc: "产品通知", Title: "产品审核通知", Content: content, - } - req, err := builder.TextCard(card) - + }) if err != nil { return nil, err } - - return []*message.SendRequest{ - req, - }, nil + return []*message.SendRequest{req}, nil } } return nil, nil } -func toProductApply(toUser string, product dao.ProductInfo) (*message.SendRequest, error) { - - content := util.BuildContent( - struct{ Key, Value string }{"产品名称", product.Name}, +func toProductApply(toUser string, product *productpb.Item) (*message.SendRequest, error) { + content := msgutil.BuildContent( + struct{ Key, Value string }{"产品名称", product.GetName()}, struct{ Key, Value string }{"审核状态", "已通过"}, ) - card := builder.TextCardParams{ + return builder.TextCard(builder.TextCardParams{ ToUser: toUser, Desc: "产品通知", Title: "产品审核通知", Content: content, - } - req, err := builder.TextCard(card) - - if err != nil { - return nil, err - } - return req, nil + }) } func toProductReviewer(toUser string, job dao.WeComJob) (*message.SendRequest, error) { - - logInfo := dao.EditLogInfo{} - - models.EditLogModel{}.Init().GetOne(models.Params{ - Eq: map[string]string{ - "obj_id": strconv.Itoa(job.ObjId), - "obj_type": strconv.Itoa(dao.EditLogTypeProduct), - }, - Order: "id desc", - }, &logInfo) - - if logInfo.Id == dao.NumberZero { - return nil, fmt.Errorf("edit log not found") - } - - title := "产品消息通知" - - diffList, err := buildProductDiff(logInfo.Content) + change, err := msgutil.GetLatestReviewChange(dao.EditLogTypeProduct, int64(job.BizId)) if err != nil { return nil, err } + title := "产品消息通知" + diffList, err := buildProductDiff(msgutil.DiffContent(change)) + if err != nil { + return nil, err + } if len(diffList) > 5 { diffList = diffList[:5] title += "(修改内容过多已自动截取)" } - diffList = append(diffList, message.HorizontalContent{ KeyName: "审核时间", Value: utils.Now().Format(), }) - card := builder.TextCardParams{ + return builder.TextCard(builder.TextCardParams{ ToUser: toUser, Desc: "产品通知", Title: title, Content: diffList, - } - req, err := builder.TextCard(card) - - if err != nil { - return nil, err - } - return req, nil + }) } func buildProductDiff(content string) ([]message.HorizontalContent, error) { - fields1 := []dao.FieldConfig{ - { - Field: "agent_price", - Label: "代理提成", - }, - { - Field: "price", - Label: "产品价格", - }, - { - Field: "store_price", - Label: "门店价格", - }, - { - Field: "sale_price", - Label: "销售底价", - }, - { - Field: "share_price", - Label: "抽成金额", - }, + {Field: "agent_price", Label: "代理提成"}, + {Field: "price", Label: "产品价格"}, + {Field: "store_price", Label: "门店价格"}, + {Field: "sale_price", Label: "销售底价"}, + {Field: "share_price", Label: "抽成金额"}, } - fields2 := []dao.FieldConfig{ - { - Field: "name", - Label: "产品名称", - }, - { - Field: "period_validity", - Label: "有效期", - }, - { - Field: "subhead", - Label: "副标题", - }, - { - Field: "weight", - Label: "重量", - }, - { - Field: "cubage", - Label: "体积", - }, - { - Field: "content", - Label: "产品描述", - }, + {Field: "name", Label: "产品名称"}, + {Field: "period_validity", Label: "有效期"}, + {Field: "subhead", Label: "副标题"}, + {Field: "weight", Label: "重量"}, + {Field: "cubage", Label: "体积"}, + {Field: "content", Label: "产品描述"}, } var data struct { Old map[string]interface{} `json:"old"` New map[string]interface{} `json:"new"` } - if err := json.Unmarshal([]byte(content), &data); err != nil { return nil, err } fields := fields2 - if _, ok := data.New["model_code"]; ok { fields = fields1 } result := make([]message.HorizontalContent, 0) - for _, field := range fields { - if len(result) >= 6 { break } - - oldValue := util.GetMapString(data.Old, field.Field) - newValue := util.GetMapString(data.New, field.Field) - + oldValue := msgutil.GetMapString(data.Old, field.Field) + newValue := msgutil.GetMapString(data.New, field.Field) if oldValue == newValue { continue } if field.Field == "content" { - result = append(result, message.HorizontalContent{ KeyName: "产品描述", Value: "产品描述进行了修改", }) - continue } value := newValue - - if oldValue != dao.StringEmpty && - oldValue != dao.StringZero { - - value = fmt.Sprintf( - "%s → %s", - oldValue, - newValue, - ) + if oldValue != utils.StringEmpty && oldValue != utils.StringZero { + value = fmt.Sprintf("%s → %s", oldValue, newValue) } - result = append(result, message.HorizontalContent{ KeyName: field.Label, Value: value, }) } - return result, nil } diff --git a/services/wecom/internal/logic/message/handlers/notify_product_submit.go b/services/wecom/internal/logic/message/handlers/notify_product_submit.go index f325e87..b7dcdd9 100644 --- a/services/wecom/internal/logic/message/handlers/notify_product_submit.go +++ b/services/wecom/internal/logic/message/handlers/notify_product_submit.go @@ -1,50 +1,34 @@ -package handlers +package handlers import ( - "base-service/app/dao" - "base-service/app/models" - "base-service/app/services/wecom/message/builder" - util "base-service/app/services/wecom/message/utils" - "base-service/pkg/wecom/message" - "base-service/utils" - "strconv" + "context" + + "lone-services/pkg/utils" + "lone-services/pkg/wecom/message" + "lone-services/services/wecom/internal/dao" + "lone-services/services/wecom/internal/logic/message/builder" + msgutil "lone-services/services/wecom/internal/logic/message/utils" ) -type ProductNotifySubmitHandler struct { -} - -func (h ProductNotifySubmitHandler) Build(job dao.WeComJob) ([]*message.SendRequest, error) { - - product := dao.ProductInfo{} - models.ProductModel{}.Init().GetOne(models.Params{ - Eq: map[string]string{ - "id": strconv.Itoa(job.ObjId), - }, - }, &product) - - var ( - toUser string - content []message.HorizontalContent - ) - - toUser = utils.GetConfigString("wecom.product_notify_first_ids") - content = util.BuildContent( - struct{ Key, Value string }{"产品名称", product.Name}, - struct{ Key, Value string }{"提醒消息", "您有一个产品需要审核"}, - ) - - card := builder.TextCardParams{ - ToUser: toUser, - Desc: "产品通知", - Title: "产品审核通知", - Content: content, - } - - req, err := builder.TextCard(card) +type ProductNotifySubmitHandler struct{} +func (h ProductNotifySubmitHandler) Build(ctx context.Context, job dao.WeComJob) ([]*message.SendRequest, error) { + product, err := msgutil.GetProductById(ctx, job.BizId) if err != nil { return nil, err } + req, err := builder.TextCard(builder.TextCardParams{ + ToUser: utils.GetConfigString("wecom.product_notify_first_ids"), + Desc: "产品通知", + Title: "产品审核通知", + Content: msgutil.BuildContent( + struct{ Key, Value string }{"产品名称", product.GetName()}, + struct{ Key, Value string }{"提醒消息", "您有一个产品需要审核"}, + ), + }) + if err != nil { + return nil, err + } return []*message.SendRequest{req}, nil } diff --git a/services/wecom/internal/logic/message/handlers/notify_sales_apply.go b/services/wecom/internal/logic/message/handlers/notify_sales_apply.go index eb9b220..fe92710 100644 --- a/services/wecom/internal/logic/message/handlers/notify_sales_apply.go +++ b/services/wecom/internal/logic/message/handlers/notify_sales_apply.go @@ -1,44 +1,34 @@ -package handlers +package handlers import ( - "base-service/app/dao" - "base-service/app/models" - "base-service/app/services/wecom/message/builder" - util "base-service/app/services/wecom/message/utils" - "base-service/pkg/wecom/message" - "base-service/utils" - "strconv" + "context" + + "lone-services/pkg/utils" + "lone-services/pkg/wecom/message" + "lone-services/services/wecom/internal/dao" + "lone-services/services/wecom/internal/logic/message/builder" + msgutil "lone-services/services/wecom/internal/logic/message/utils" ) -type SalesNotifyApplyHandler struct { -} - -func (h SalesNotifyApplyHandler) Build(job dao.WeComJob) ([]*message.SendRequest, error) { - - sales := dao.SaleInfo{} - models.SalesModel{}.Init().GetOne(models.Params{ - Eq: map[string]string{ - "id": strconv.Itoa(job.ObjId), - }, - }, &sales) - - content := util.BuildContent( - struct{ Key, Value string }{"销售名称", sales.Name}, - struct{ Key, Value string }{"提醒消息", "您有一个销售需要审核"}, - ) - - card := builder.TextCardParams{ - ToUser: utils.GetConfigString("wecom.sales_notify_apply_ids"), - Desc: "销售通知", - Title: "销售审核通知", - Content: content, - } - - req, err := builder.TextCard(card) +type SalesNotifyApplyHandler struct{} +func (h SalesNotifyApplyHandler) Build(ctx context.Context, job dao.WeComJob) ([]*message.SendRequest, error) { + change, err := msgutil.GetLatestReviewChange(job.BizType, int64(job.BizId)) if err != nil { return nil, err } + req, err := builder.TextCard(builder.TextCardParams{ + ToUser: utils.GetConfigString("wecom.sales_notify_apply_ids"), + Desc: "销售通知", + Title: "销售审核通知", + Content: msgutil.BuildContent( + struct{ Key, Value string }{"销售名称", msgutil.BizFieldFromChange(change, "name")}, + struct{ Key, Value string }{"提醒消息", "您有一个销售需要审核"}, + ), + }) + if err != nil { + return nil, err + } return []*message.SendRequest{req}, nil } diff --git a/services/wecom/internal/logic/message/handlers/notify_store_apply.go b/services/wecom/internal/logic/message/handlers/notify_store_apply.go index 5faeeb6..a3e35b8 100644 --- a/services/wecom/internal/logic/message/handlers/notify_store_apply.go +++ b/services/wecom/internal/logic/message/handlers/notify_store_apply.go @@ -1,64 +1,51 @@ -package handlers +package handlers import ( - "base-service/app/dao" - "base-service/app/models" - "base-service/app/services/wecom/message/builder" - util "base-service/app/services/wecom/message/utils" - "base-service/pkg/wecom/message" - "strconv" + "context" + + "lone-services/pkg/wecom/message" + "lone-services/services/wecom/internal/dao" + "lone-services/services/wecom/internal/logic/message/builder" + msgutil "lone-services/services/wecom/internal/logic/message/utils" ) -type StoreNotifyApplyHandler struct { -} +type StoreNotifyApplyHandler struct{} -func (h StoreNotifyApplyHandler) Build(job dao.WeComJob) ([]*message.SendRequest, error) { - - store := dao.StoreInfo{} - models.StoreModel{}.Init().GetOne(models.Params{ - Eq: map[string]string{ - "id": strconv.Itoa(job.ObjId), - }, - }, &store) - - var ( - toUser string - content []message.HorizontalContent - ) - - user, err := util.GetActionWecomUser(job.ObjId, job.ObjType) - toUser = user.WecomUserId +func (h StoreNotifyApplyHandler) Build(ctx context.Context, job dao.WeComJob) ([]*message.SendRequest, error) { + change, err := msgutil.GetLatestReviewChange(job.BizType, int64(job.BizId)) if err != nil { return nil, err } + storeName := msgutil.BizFieldFromChange(change, "name") + + user, err := msgutil.GetActionWecomUser(job.BizId, job.BizType) + if err != nil { + return nil, err + } + + var content []message.HorizontalContent switch job.Action { case dao.ActionPass: - - content = util.BuildContent( - struct{ Key, Value string }{"门店名称", store.Name}, + content = msgutil.BuildContent( + struct{ Key, Value string }{"门店名称", storeName}, struct{ Key, Value string }{"审核状态", "已通过"}, ) - case dao.ActionReject: - - content = util.BuildContent( - struct{ Key, Value string }{"门店名称", store.Name}, + content = msgutil.BuildContent( + struct{ Key, Value string }{"门店名称", storeName}, struct{ Key, Value string }{"审核状态", "未通过"}, - struct{ Key, Value string }{"拒绝原因", util.GetExtString(job.Ext, "reason")}, + struct{ Key, Value string }{"拒绝原因", msgutil.GetExtString(job.Ext, "reason")}, ) } - card := builder.TextCardParams{ - ToUser: toUser, + + req, err := builder.TextCard(builder.TextCardParams{ + ToUser: user.WecomUserId, Desc: "门店通知", Title: "门店审核通知", Content: content, - } - - req, err := builder.TextCard(card) - + }) if err != nil { return nil, err } - return []*message.SendRequest{req}, nil } diff --git a/services/wecom/internal/logic/message/handlers/notify_store_first.go b/services/wecom/internal/logic/message/handlers/notify_store_first.go index 44fb909..890034c 100644 --- a/services/wecom/internal/logic/message/handlers/notify_store_first.go +++ b/services/wecom/internal/logic/message/handlers/notify_store_first.go @@ -1,67 +1,56 @@ -package handlers +package handlers import ( - "base-service/app/dao" - "base-service/app/models" - "base-service/app/services/wecom/message/builder" - util "base-service/app/services/wecom/message/utils" - "base-service/pkg/wecom/message" - "base-service/utils" - "strconv" + "context" + + "lone-services/pkg/utils" + "lone-services/pkg/wecom/message" + "lone-services/services/wecom/internal/dao" + "lone-services/services/wecom/internal/logic/message/builder" + msgutil "lone-services/services/wecom/internal/logic/message/utils" ) -type StoreNotifyFirstHandler struct { -} +type StoreNotifyFirstHandler struct{} -func (h StoreNotifyFirstHandler) Build(job dao.WeComJob) ([]*message.SendRequest, error) { - - store := dao.StoreInfo{} - models.StoreModel{}.Init().GetOne(models.Params{ - Eq: map[string]string{ - "id": strconv.Itoa(job.ObjId), - }, - }, &store) +func (h StoreNotifyFirstHandler) Build(ctx context.Context, job dao.WeComJob) ([]*message.SendRequest, error) { + change, err := msgutil.GetLatestReviewChange(job.BizType, int64(job.BizId)) + if err != nil { + return nil, err + } + storeName := msgutil.BizFieldFromChange(change, "name") var ( toUser string content []message.HorizontalContent ) - switch job.Action { case dao.ActionPass: toUser = utils.GetConfigString("wecom.store_notify_second_ids") - content = util.BuildContent( - struct{ Key, Value string }{"门店名称", store.Name}, + content = msgutil.BuildContent( + struct{ Key, Value string }{"门店名称", storeName}, struct{ Key, Value string }{"提醒消息", "您有一个门店需要审核"}, ) - case dao.ActionReject: - user, err := util.GetActionWecomUser(job.ObjId, job.ObjType) - + user, err := msgutil.GetActionWecomUser(job.BizId, job.BizType) if err != nil { return nil, err } - toUser = user.WecomUserId - - content = util.BuildContent( - struct{ Key, Value string }{"门店名称", store.Name}, + content = msgutil.BuildContent( + struct{ Key, Value string }{"门店名称", storeName}, struct{ Key, Value string }{"审核状态", "未通过"}, - struct{ Key, Value string }{"拒绝原因", util.GetExtString(job.Ext, "reason")}, + struct{ Key, Value string }{"拒绝原因", msgutil.GetExtString(job.Ext, "reason")}, ) } - card := builder.TextCardParams{ + + req, err := builder.TextCard(builder.TextCardParams{ ToUser: toUser, Desc: "门店通知", Title: "门店审核通知", Content: content, - } - - req, err := builder.TextCard(card) - + }) if err != nil { return nil, err } - return []*message.SendRequest{req}, nil } diff --git a/services/wecom/internal/logic/message/handlers/notify_store_second.go b/services/wecom/internal/logic/message/handlers/notify_store_second.go index 3408e70..5d6a485 100644 --- a/services/wecom/internal/logic/message/handlers/notify_store_second.go +++ b/services/wecom/internal/logic/message/handlers/notify_store_second.go @@ -1,220 +1,144 @@ -package handlers +package handlers import ( - "base-service/app/dao" - "base-service/app/models" - "base-service/app/services/wecom/message/builder" - util "base-service/app/services/wecom/message/utils" - "base-service/pkg/wecom/message" - "base-service/utils" + "context" "encoding/json" "fmt" - "strconv" + + "lone-services/pkg/utils" + "lone-services/pkg/wecom/message" + "lone-services/services/wecom/internal/dao" + "lone-services/services/wecom/internal/logic/message/builder" + msgutil "lone-services/services/wecom/internal/logic/message/utils" ) -type StoreNotifySecondHandler struct { -} +type StoreNotifySecondHandler struct{} -func (h StoreNotifySecondHandler) Build(job dao.WeComJob) ([]*message.SendRequest, error) { - - store := dao.StoreInfo{} - - models.StoreModel{}.Init().GetOne(models.Params{ - Eq: map[string]string{ - "id": strconv.Itoa(job.ObjId), - }, - }, &store) - - user, err := util.GetApplicantUser(job.ObjId, job.ObjType, dao.NumberTwo) +func (h StoreNotifySecondHandler) Build(ctx context.Context, job dao.WeComJob) ([]*message.SendRequest, error) { + change, err := msgutil.GetLatestReviewChange(job.BizType, int64(job.BizId)) + if err != nil { + return nil, err + } + storeName := msgutil.BizFieldFromChange(change, "name") + user, err := msgutil.GetApplicantUser(job.BizId, job.BizType, dao.UserTypeSale) if err != nil { return nil, err } switch job.Action { - case dao.ActionPass: - req1, err := toStoreReviewer(utils.GetConfigString("wecom.store_reviewer_ids"), job) if err != nil { return nil, err } - reqs := []*message.SendRequest{ - req1, - } - - if user.Id > dao.NumberZero { - req2, err := toStoreApply(user.WecomUserId, store) + reqs := []*message.SendRequest{req1} + if user.Id > utils.NumberZero { + req2, err := toStoreApply(user.WecomUserId, storeName) if err != nil { return nil, err } - reqs = append(reqs, req2) } - return reqs, nil case dao.ActionReject: - - content := util.BuildContent( - struct{ Key, Value string }{"门店名称", store.Name}, + content := msgutil.BuildContent( + struct{ Key, Value string }{"门店名称", storeName}, struct{ Key, Value string }{"审核状态", "未通过"}, - struct{ Key, Value string }{"拒绝原因", util.GetExtString(job.Ext, "reason")}, + struct{ Key, Value string }{"拒绝原因", msgutil.GetExtString(job.Ext, "reason")}, ) - - if user.Id > dao.NumberZero { - card := builder.TextCardParams{ + if user.Id > utils.NumberZero { + req, err := builder.TextCard(builder.TextCardParams{ ToUser: user.WecomUserId, Desc: "门店通知", Title: "门店审核通知", Content: content, - } - req, err := builder.TextCard(card) - + }) if err != nil { return nil, err } - - return []*message.SendRequest{ - req, - }, nil + return []*message.SendRequest{req}, nil } } return nil, nil } -func toStoreApply(toUser string, store dao.StoreInfo) (*message.SendRequest, error) { - - content := util.BuildContent( - struct{ Key, Value string }{"门店名称", store.Name}, +func toStoreApply(toUser, storeName string) (*message.SendRequest, error) { + content := msgutil.BuildContent( + struct{ Key, Value string }{"门店名称", storeName}, struct{ Key, Value string }{"审核状态", "已通过"}, ) - card := builder.TextCardParams{ + return builder.TextCard(builder.TextCardParams{ ToUser: toUser, Desc: "门店通知", Title: "门店审核通知", Content: content, - } - req, err := builder.TextCard(card) - - if err != nil { - return nil, err - } - return req, nil + }) } func toStoreReviewer(toUser string, job dao.WeComJob) (*message.SendRequest, error) { - - logInfo := dao.EditLogInfo{} - - models.EditLogModel{}.Init().GetOne(models.Params{ - Eq: map[string]string{ - "obj_id": strconv.Itoa(job.ObjId), - "obj_type": strconv.Itoa(dao.EditLogTypeStore), - }, - Order: "id desc", - }, &logInfo) - - if logInfo.Id == dao.NumberZero { - return nil, fmt.Errorf("edit log not found") - } - - title := "门店消息通知" - - diffList, err := buildStoreDiff(logInfo.Content) + change, err := msgutil.GetLatestReviewChange(dao.EditLogTypeStore, int64(job.BizId)) if err != nil { return nil, err } + title := "门店消息通知" + diffList, err := buildStoreDiff(msgutil.DiffContent(change)) + if err != nil { + return nil, err + } if len(diffList) > 5 { diffList = diffList[:5] title += "(修改内容过多已自动截取)" } - diffList = append(diffList, message.HorizontalContent{ KeyName: "审核时间", Value: utils.Now().Format(), }) - card := builder.TextCardParams{ + return builder.TextCard(builder.TextCardParams{ ToUser: toUser, Desc: "门店通知", Title: title, Content: diffList, - } - req, err := builder.TextCard(card) - - if err != nil { - return nil, err - } - return req, nil + }) } func buildStoreDiff(content string) ([]message.HorizontalContent, error) { - fields := []dao.FieldConfig{ - { - Field: "name", - Label: "门店名称", - }, - { - Field: "user_name", - Label: "负责人", - }, - { - Field: "store_price", - Label: "门店价格", - }, - { - Field: "sale_price", - Label: "销售底价", - }, - { - Field: "share_price", - Label: "抽成金额", - }, + {Field: "name", Label: "门店名称"}, + {Field: "user_name", Label: "负责人"}, + {Field: "store_price", Label: "门店价格"}, + {Field: "sale_price", Label: "销售底价"}, + {Field: "share_price", Label: "抽成金额"}, } var data struct { Old map[string]interface{} `json:"old"` New map[string]interface{} `json:"new"` } - if err := json.Unmarshal([]byte(content), &data); err != nil { return nil, err } result := make([]message.HorizontalContent, 0) - for _, field := range fields { - if len(result) >= 6 { break } - - oldValue := util.GetMapString(data.Old, field.Field) - newValue := util.GetMapString(data.New, field.Field) - + oldValue := msgutil.GetMapString(data.Old, field.Field) + newValue := msgutil.GetMapString(data.New, field.Field) if oldValue == newValue { continue } - value := newValue - - if oldValue != dao.StringEmpty && - oldValue != dao.StringZero { - - value = fmt.Sprintf( - "%s → %s", - oldValue, - newValue, - ) + if oldValue != utils.StringEmpty && oldValue != utils.StringZero { + value = fmt.Sprintf("%s → %s", oldValue, newValue) } - result = append(result, message.HorizontalContent{ KeyName: field.Label, Value: value, }) } - return result, nil } diff --git a/services/wecom/internal/logic/message/handlers/notify_store_submit.go b/services/wecom/internal/logic/message/handlers/notify_store_submit.go index c7c6b25..92f6e2d 100644 --- a/services/wecom/internal/logic/message/handlers/notify_store_submit.go +++ b/services/wecom/internal/logic/message/handlers/notify_store_submit.go @@ -1,51 +1,34 @@ -package handlers +package handlers import ( - "base-service/app/dao" - "base-service/app/models" - "base-service/app/services/wecom/message/builder" - util "base-service/app/services/wecom/message/utils" - "base-service/pkg/wecom/message" - "base-service/utils" - "strconv" + "context" + + "lone-services/pkg/utils" + "lone-services/pkg/wecom/message" + "lone-services/services/wecom/internal/dao" + "lone-services/services/wecom/internal/logic/message/builder" + msgutil "lone-services/services/wecom/internal/logic/message/utils" ) -type StoreNotifySubmitHandler struct { -} - -func (h StoreNotifySubmitHandler) Build(job dao.WeComJob) ([]*message.SendRequest, error) { - - store := dao.StoreInfo{} - models.StoreModel{}.Init().GetOne(models.Params{ - Eq: map[string]string{ - "id": strconv.Itoa(job.ObjId), - }, - }, &store) - - var ( - toUser string - content []message.HorizontalContent - ) - - toUser = utils.GetConfigString("wecom.store_notify_first_ids") - - content = util.BuildContent( - struct{ Key, Value string }{"门店名称", store.Name}, - struct{ Key, Value string }{"提醒消息", "您有一个门店需要审核"}, - ) - - card := builder.TextCardParams{ - ToUser: toUser, - Desc: "门店通知", - Title: "门店审核通知", - Content: content, - } - - req, err := builder.TextCard(card) +type StoreNotifySubmitHandler struct{} +func (h StoreNotifySubmitHandler) Build(ctx context.Context, job dao.WeComJob) ([]*message.SendRequest, error) { + change, err := msgutil.GetLatestReviewChange(job.BizType, int64(job.BizId)) if err != nil { return nil, err } + req, err := builder.TextCard(builder.TextCardParams{ + ToUser: utils.GetConfigString("wecom.store_notify_first_ids"), + Desc: "门店通知", + Title: "门店审核通知", + Content: msgutil.BuildContent( + struct{ Key, Value string }{"门店名称", msgutil.BizFieldFromChange(change, "name")}, + struct{ Key, Value string }{"提醒消息", "您有一个门店需要审核"}, + ), + }) + if err != nil { + return nil, err + } return []*message.SendRequest{req}, nil } diff --git a/services/wecom/internal/logic/message/handlers/review_address.go b/services/wecom/internal/logic/message/handlers/review_address.go index 1bea656..3e9ced6 100644 --- a/services/wecom/internal/logic/message/handlers/review_address.go +++ b/services/wecom/internal/logic/message/handlers/review_address.go @@ -1,191 +1,66 @@ -package handlers +package handlers import ( - "base-service/app/dao" - "base-service/app/models" - "base-service/app/services/wecom/message/builder" - "base-service/app/services/wecom/message/task" - util "base-service/app/services/wecom/message/utils" - "base-service/pkg/wecom/message" - "base-service/utils" - "encoding/json" + "context" "fmt" - "strconv" + + "lone-services/pkg/utils" + "lone-services/pkg/wecom/message" + "lone-services/services/wecom/internal/dao" + "lone-services/services/wecom/internal/logic/message/builder" + "lone-services/services/wecom/internal/logic/message/task" + msgutil "lone-services/services/wecom/internal/logic/message/utils" "github.com/google/uuid" ) -type AddressReviewHandler struct { -} +type AddressReviewHandler struct{} -func (h AddressReviewHandler) Build(job dao.WeComJob) ([]*message.SendRequest, error) { - - logInfo := dao.EditLogInfo{} - - models.EditLogModel{}.Init().GetOne(models.Params{ - Eq: map[string]string{ - "obj_id": strconv.Itoa(job.ObjId), - "obj_type": strconv.Itoa(int(job.ObjType)), - }, - Order: "id desc", - }, &logInfo) - - if logInfo.Id == dao.NumberZero { - return nil, fmt.Errorf("edit log not found") - } - - // 需要返回的字段 - fields := []dao.FieldConfig{ - { - Field: "type_name", - Label: "门店名称", - }, - { - Field: "name", - Label: "收货人", - }, - { - Field: "address", - Label: "地址", - }, - { - Field: "district", - Label: "地区", - }, - { - Field: "mobile", - Label: "收货人电话", - }, - } - - content, err := BuildAddressDiff(logInfo.Content, fields) +func (h AddressReviewHandler) Build(ctx context.Context, job dao.WeComJob) ([]*message.SendRequest, error) { + change, err := msgutil.GetLatestReviewChange(job.BizType, int64(job.BizId)) if err != nil { return nil, err } - toUser := utils.GetConfigString("wecom.address_reviewer_ids") + fields := []dao.FieldConfig{ + {Field: "type_name", Label: "门店名称"}, + {Field: "name", Label: "收货人"}, + {Field: "address", Label: "地址"}, + {Field: "district", Label: "地区"}, + {Field: "mobile", Label: "收货人电话"}, + } + + content, err := BuildAddressDiff(msgutil.DiffContent(change), fields) + if err != nil { + return nil, err + } taskId := uuid.NewString() - - detailUrl := fmt.Sprintf("https://baidu.com/xxx/review?id=%d", job.ObjId) - - err = task.Service{}.Create(job, taskId, detailUrl) - - if err != nil { + detailUrl := fmt.Sprintf("https://baidu.com/xxx/review?id=%d", job.BizId) + if err = (task.Service{}).Create(job, taskId, detailUrl); err != nil { return nil, err } - req, err := builder.ButtonCard( - builder.ButtonCardParams{ - ToUser: toUser, - TaskId: taskId, - Title: "地址信息变更审核", - Content: content, - Buttons: []message.Button{ - { - Text: "拒绝", - Style: dao.NumberTwo, - Key: fmt.Sprintf("%s:reject:%s", util.GetExtString(job.Ext, "key"), taskId), - }, - { - Text: "通过", - Style: dao.NumberOne, - Key: fmt.Sprintf("%s:agree:%s", util.GetExtString(job.Ext, "key"), taskId), - }, + req, err := builder.ButtonCard(builder.ButtonCardParams{ + ToUser: utils.GetConfigString("wecom.address_reviewer_ids"), + TaskId: taskId, + Title: "地址信息变更审核", + Content: content, + Buttons: []message.Button{ + { + Text: "拒绝", + Style: utils.NumberTwo, + Key: fmt.Sprintf("%s:reject:%s", msgutil.GetExtString(job.Ext, "key"), taskId), + }, + { + Text: "通过", + Style: utils.NumberOne, + Key: fmt.Sprintf("%s:agree:%s", msgutil.GetExtString(job.Ext, "key"), taskId), }, }, - ) - + }) if err != nil { return nil, err } - - return []*message.SendRequest{ - req, - }, nil -} - -func BuildAddressDiff(content string, fields []dao.FieldConfig) ([]message.HorizontalContent, error) { - - var data struct { - Old map[string]interface{} `json:"old"` - New map[string]interface{} `json:"new"` - } - - if err := json.Unmarshal([]byte(content), &data); err != nil { - return nil, err - } - - result := make([]message.HorizontalContent, 0) - - districtOld := util.GetMapString(data.Old, "district") - districtNew := util.GetMapString(data.New, "district") - - for _, field := range fields { - - // district 不单独显示 - if field.Field == "district" { - continue - } - - oldValue := util.GetMapString(data.Old, field.Field) - newValue := util.GetMapString(data.New, field.Field) - - // type_name 新数据可能不存在 - if field.Field == "type_name" && newValue == dao.StringEmpty { - newValue = oldValue - } - - // 地址拼接地区 - if field.Field == "address" { - - if districtOld != dao.StringEmpty { - oldValue = districtOld + oldValue - } - - if districtNew != dao.StringEmpty { - newValue = districtNew + newValue - } - } - - // old 数据,手机号解密 - if field.Field == "mobile" { - - if oldValue != dao.StringEmpty { - - decryptOld, err := utils.Decrypt(oldValue) - if err == nil { - oldValue = decryptOld - } - } - - // if newValue != dao.StringEmpty { - - // decryptNew, err := utils.Decrypt(newValue) - // if err == nil { - // newValue = decryptNew - // } - // } - } - - value := newValue - - if oldValue != dao.StringEmpty && - oldValue != dao.StringZero && - oldValue != newValue { - - value = fmt.Sprintf( - "%s → %s", - oldValue, - newValue, - ) - } - - result = append(result, message.HorizontalContent{ - KeyName: field.Label, - Value: value, - }) - } - - return result, nil + return []*message.SendRequest{req}, nil } diff --git a/services/wecom/internal/logic/message/handlers/review_product.go b/services/wecom/internal/logic/message/handlers/review_product.go index 4ef092f..35ac2cd 100644 --- a/services/wecom/internal/logic/message/handlers/review_product.go +++ b/services/wecom/internal/logic/message/handlers/review_product.go @@ -1,89 +1,66 @@ -package handlers +package handlers import ( - "base-service/app/dao" - "base-service/app/models" - "base-service/app/services/wecom/message/builder" - "base-service/app/services/wecom/message/task" - util "base-service/app/services/wecom/message/utils" - "base-service/pkg/wecom/message" - "base-service/utils" + "context" "fmt" - "strconv" + + "lone-services/pkg/utils" + "lone-services/pkg/wecom/message" + "lone-services/services/wecom/internal/dao" + "lone-services/services/wecom/internal/logic/message/builder" + "lone-services/services/wecom/internal/logic/message/task" + msgutil "lone-services/services/wecom/internal/logic/message/utils" "github.com/google/uuid" ) -type ProductReviewHandler struct { -} +type ProductReviewHandler struct{} -func (h ProductReviewHandler) Build(job dao.WeComJob) ([]*message.SendRequest, error) { +func (h ProductReviewHandler) Build(ctx context.Context, job dao.WeComJob) ([]*message.SendRequest, error) { + product, err := msgutil.GetProductById(ctx, job.BizId) + if err != nil { + return nil, err + } - product := dao.ProductInfo{} - models.ProductModel{}.Init().GetOne(models.Params{ - Eq: map[string]string{ - "id": strconv.Itoa(job.ObjId), - }, - }, &product) - - user, err := util.GetActionUser(job.ObjId, job.ObjType) + user, err := msgutil.GetActionUser(job.BizId, job.BizType) if err != nil { return nil, err } taskId := uuid.NewString() - - detailUrl := fmt.Sprintf("https://baidu.com/xxx/review?id=%d", job.ObjId) - - err = task.Service{}.Create(job, taskId, detailUrl) - - content := []message.HorizontalContent{ - { - KeyName: "产品名称", - Value: product.Name, - }, - { - KeyName: "申请原因", - Value: util.GetExtString(job.Ext, "reason"), - }, - { - KeyName: "申请人", - Value: user.Name, - }, - { - KeyName: "申请时间", - Value: utils.Now().Format(), - }, - } - - toUser := utils.GetConfigString("wecom.product_reviewer_ids") - req, err := builder.ButtonCard( - builder.ButtonCardParams{ - ToUser: toUser, - TaskId: taskId, - Desc: "产品审核", - Title: "产品信息变更审核", - Content: content, - Buttons: []message.Button{ - { - Text: "拒绝", - Style: dao.NumberTwo, - Key: fmt.Sprintf("%s:reject:%s", util.GetExtString(job.Ext, "key"), taskId), - }, - { - Text: "通过", - Style: dao.NumberOne, - Key: fmt.Sprintf("%s:agree:%s", util.GetExtString(job.Ext, "key"), taskId), - }, - }, - }, - ) - - if err != nil { + detailUrl := fmt.Sprintf("https://baidu.com/xxx/review?id=%d", job.BizId) + if err = (task.Service{}).Create(job, taskId, detailUrl); err != nil { return nil, err } - return []*message.SendRequest{ - req, - }, nil + content := []message.HorizontalContent{ + {KeyName: "产品名称", Value: product.GetName()}, + {KeyName: "申请原因", Value: msgutil.GetExtString(job.Ext, "reason")}, + {KeyName: "申请人", Value: user.Name}, + {KeyName: "申请时间", Value: utils.Now().Format()}, + } + + req, err := builder.ButtonCard(builder.ButtonCardParams{ + ToUser: utils.GetConfigString("wecom.product_reviewer_ids"), + TaskId: taskId, + Desc: "产品审核", + Title: "产品信息变更审核", + Content: content, + Buttons: []message.Button{ + { + Text: "拒绝", + Style: utils.NumberTwo, + Key: fmt.Sprintf("%s:reject:%s", msgutil.GetExtString(job.Ext, "key"), taskId), + }, + { + Text: "通过", + Style: utils.NumberOne, + Key: fmt.Sprintf("%s:agree:%s", msgutil.GetExtString(job.Ext, "key"), taskId), + }, + }, + }) + if err != nil { + return nil, err + } + return []*message.SendRequest{req}, nil } diff --git a/services/wecom/internal/logic/message/handlers/review_store.go b/services/wecom/internal/logic/message/handlers/review_store.go index 5b85b74..b9be071 100644 --- a/services/wecom/internal/logic/message/handlers/review_store.go +++ b/services/wecom/internal/logic/message/handlers/review_store.go @@ -1,91 +1,65 @@ -package handlers +package handlers import ( - "base-service/app/dao" - "base-service/app/models" - "base-service/app/services/wecom/message/builder" - "base-service/app/services/wecom/message/task" - util "base-service/app/services/wecom/message/utils" - "base-service/pkg/wecom/message" - "base-service/utils" + "context" "fmt" - "strconv" + + "lone-services/pkg/utils" + "lone-services/pkg/wecom/message" + "lone-services/services/wecom/internal/dao" + "lone-services/services/wecom/internal/logic/message/builder" + "lone-services/services/wecom/internal/logic/message/task" + msgutil "lone-services/services/wecom/internal/logic/message/utils" "github.com/google/uuid" ) -type StoreReviewHandler struct { -} +type StoreReviewHandler struct{} -func (h StoreReviewHandler) Build(job dao.WeComJob) ([]*message.SendRequest, error) { - - store := dao.StoreInfo{} - - models.StoreModel{}.Init().GetOne(models.Params{ - Eq: map[string]string{ - "id": strconv.Itoa(job.ObjId), - }, - }, &store) - - user, err := util.GetActionUser(job.ObjId, job.ObjType) +func (h StoreReviewHandler) Build(ctx context.Context, job dao.WeComJob) ([]*message.SendRequest, error) { + change, err := msgutil.GetLatestReviewChange(job.BizType, int64(job.BizId)) + if err != nil { + return nil, err + } + user, err := msgutil.GetActionUser(job.BizId, job.BizType) if err != nil { return nil, err } content := []message.HorizontalContent{ - { - KeyName: "门店名称", - Value: store.Name, - }, - { - KeyName: "申请原因", - Value: util.GetExtString(job.Ext, "reason"), - }, - { - KeyName: "申请人", - Value: user.Name, - }, - { - KeyName: "申请时间", - Value: utils.Now().Format(), - }, + {KeyName: "门店名称", Value: msgutil.BizFieldFromChange(change, "name")}, + {KeyName: "申请原因", Value: msgutil.GetExtString(job.Ext, "reason")}, + {KeyName: "申请人", Value: user.Name}, + {KeyName: "申请时间", Value: utils.Now().Format()}, } taskId := uuid.NewString() - - detailUrl := fmt.Sprintf("https://baidu.com/xxx/review?id=%d", job.ObjId) - - err = task.Service{}.Create(job, taskId, detailUrl) - - toUser := utils.GetConfigString("wecom.store_reviewer_ids") - - req, err := builder.ButtonCard( - builder.ButtonCardParams{ - ToUser: toUser, - TaskId: taskId, - Desc: "门店审核", - Title: "门店信息变更审核", - Content: content, - Buttons: []message.Button{ - { - Text: "拒绝", - Style: dao.NumberTwo, - Key: fmt.Sprintf("%s:reject:%s", util.GetExtString(job.Ext, "key"), taskId), - }, - { - Text: "通过", - Style: dao.NumberOne, - Key: fmt.Sprintf("%s:agree:%s", util.GetExtString(job.Ext, "key"), taskId), - }, - }, - }, - ) - - if err != nil { + detailUrl := fmt.Sprintf("https://baidu.com/xxx/review?id=%d", job.BizId) + if err = (task.Service{}).Create(job, taskId, detailUrl); err != nil { return nil, err } - return []*message.SendRequest{ - req, - }, nil + req, err := builder.ButtonCard(builder.ButtonCardParams{ + ToUser: utils.GetConfigString("wecom.store_reviewer_ids"), + TaskId: taskId, + Desc: "门店审核", + Title: "门店信息变更审核", + Content: content, + Buttons: []message.Button{ + { + Text: "拒绝", + Style: utils.NumberTwo, + Key: fmt.Sprintf("%s:reject:%s", msgutil.GetExtString(job.Ext, "key"), taskId), + }, + { + Text: "通过", + Style: utils.NumberOne, + Key: fmt.Sprintf("%s:agree:%s", msgutil.GetExtString(job.Ext, "key"), taskId), + }, + }, + }) + if err != nil { + return nil, err + } + return []*message.SendRequest{req}, nil } diff --git a/services/wecom/internal/logic/message/sender/sender.go b/services/wecom/internal/logic/message/sender/sender.go index b6b98a1..e361efa 100644 --- a/services/wecom/internal/logic/message/sender/sender.go +++ b/services/wecom/internal/logic/message/sender/sender.go @@ -1,38 +1,40 @@ package sender import ( - "base-service/app/dao" - "base-service/app/services/wecom/client" - "base-service/app/services/wecom/message/handlers" "context" + + "lone-services/pkg/utils" + "lone-services/services/wecom/internal/client" + "lone-services/services/wecom/internal/dao" + "lone-services/services/wecom/internal/logic/message/handlers" ) type WecomSenderService struct { } -func (s WecomSenderService) Send(job dao.WeComJob) error { +func (s WecomSenderService) Send(ctx context.Context, job dao.WeComJob) error { + if ctx == nil { + ctx = context.Background() + } handler, err := handlers.GetHandler(job) if err != nil { return err } - reqs, err := handler.Build(job) + reqs, err := handler.Build(ctx, job) if err != nil { return err } messageClient := client.NewMessageClient(job.Type) for _, req := range reqs { - - if req == nil || req.ToUser == dao.StringEmpty { + if req == nil || req.ToUser == utils.StringEmpty { continue } - - if err = messageClient.Send(context.Background(), req); err != nil { + if err = messageClient.Send(ctx, req); err != nil { return err } } - return nil } diff --git a/services/wecom/internal/logic/message/task/task.go b/services/wecom/internal/logic/message/task/task.go index ffbb653..b3c1a27 100644 --- a/services/wecom/internal/logic/message/task/task.go +++ b/services/wecom/internal/logic/message/task/task.go @@ -1,34 +1,31 @@ -package task +package task import ( - "base-service/app/dao" - "base-service/app/models" - "base-service/utils" + "lone-services/pkg/utils" + "lone-services/services/wecom/internal/dao" + "lone-services/services/wecom/internal/model" jsoniter "github.com/json-iterator/go" ) -type Service struct { -} +type Service struct{} func (s Service) Create(job dao.WeComJob, taskId string, detailUrl string) error { - payload, err := jsoniter.Marshal(job) if err != nil { return err } task := &dao.WecomReviewTask{ TaskId: taskId, - ObjId: job.ObjId, - ObjType: job.ObjType, + ObjId: job.BizId, + ObjType: job.BizType, Type: job.Type, Payload: string(payload), DetailUrl: detailUrl, ReviewStatus: dao.WecomReviewPending, - ResponseCode: dao.StringEmpty, + ResponseCode: utils.StringEmpty, AgentId: utils.GetConfigInt("wecom.review_agent_id"), CreatedAt: utils.Now(), } - - return models.WecomReviewTask{}.Init().Create(task) + return model.ReviewTaskModel{}.Init().Create(task) } diff --git a/services/wecom/internal/logic/message/utils/helper.go b/services/wecom/internal/logic/message/utils/helper.go index b06acb9..48cbccc 100644 --- a/services/wecom/internal/logic/message/utils/helper.go +++ b/services/wecom/internal/logic/message/utils/helper.go @@ -1,25 +1,21 @@ package utils import ( - "base-service/app/dao" - "base-service/pkg/wecom/message" - "base-service/utils" "fmt" + + "lone-services/pkg/utils" + "lone-services/pkg/wecom/message" ) func GetMapString(data map[string]interface{}, key string) string { - val, ok := data[key] - if !ok || val == nil { - return dao.StringEmpty + return utils.StringEmpty } - return fmt.Sprintf("%v", val) } func GetExtString(ext map[string]any, key string) string { - v, ok := ext[key].(string) if !ok || v == "" { return "无" @@ -38,18 +34,15 @@ func BuildContent(kvPairs ...struct{ Key, Value string }) []message.HorizontalCo } content := make([]message.HorizontalContent, 0, inputCount+fixedItems) - for i := 0; i < inputCount; i++ { content = append(content, message.HorizontalContent{ KeyName: kvPairs[i].Key, Value: kvPairs[i].Value, }) } - content = append(content, message.HorizontalContent{ KeyName: "审核时间", Value: utils.Now().Format(), }) - return content } diff --git a/services/wecom/internal/logic/message/utils/product.go b/services/wecom/internal/logic/message/utils/product.go new file mode 100644 index 0000000..e2e86fc --- /dev/null +++ b/services/wecom/internal/logic/message/utils/product.go @@ -0,0 +1,32 @@ +package utils + +import ( + "context" + "fmt" + + "lone-services/pkg/rpcclient" + "lone-services/pkg/utils" + productpb "lone-services/rpc/product/pb" +) + +// GetProductById 通过产品服务 InfoById 获取产品详情 +func GetProductById(ctx context.Context, id int) (*productpb.Item, error) { + svcName := utils.GetConfigString("services.product") + if svcName == utils.StringEmpty { + return nil, fmt.Errorf("config services.product empty") + } + cli, err := rpcclient.Get(svcName) + if err != nil { + return nil, err + } + item, err := productpb.NewProductClient(cli.Conn()).InfoById(ctx, &productpb.InfoByIdReq{ + Id: int64(id), + }) + if err != nil { + return nil, err + } + if item == nil || item.GetId() < 1 { + return nil, fmt.Errorf("product not found: %d", id) + } + return item, nil +} diff --git a/services/wecom/internal/logic/message/utils/review_change.go b/services/wecom/internal/logic/message/utils/review_change.go new file mode 100644 index 0000000..a7d48fd --- /dev/null +++ b/services/wecom/internal/logic/message/utils/review_change.go @@ -0,0 +1,65 @@ +package utils + +import ( + "fmt" + "strconv" + + jsoniter "github.com/json-iterator/go" + + "lone-services/pkg/modelbase" + "lone-services/pkg/utils" + "lone-services/services/wecom/internal/dao" + "lone-services/services/wecom/internal/model" +) + +// GetLatestReviewChange 按业务类型+业务ID取最新一条变更快照 +func GetLatestReviewChange(bizType uint8, bizId int64) (*dao.ReviewChange, error) { + var change dao.ReviewChange + err := model.ReviewChangeModel{}.Init().GetOne(modelbase.Params{ + Eq: map[string]string{ + "type": strconv.FormatUint(uint64(bizType), 10), + "biz_id": strconv.FormatInt(bizId, 10), + }, + Order: "id desc", + }, &change) + if err != nil { + return nil, err + } + if change.Id < 1 { + return nil, fmt.Errorf("review change not found") + } + return &change, nil +} + +// DiffContent 拼成旧 diff 逻辑使用的 {"old":...,"new":...} JSON +func DiffContent(change *dao.ReviewChange) string { + before := change.BeforeData + after := change.AfterData + if before == utils.StringEmpty { + before = "null" + } + if after == utils.StringEmpty { + after = "null" + } + return fmt.Sprintf(`{"old":%s,"new":%s}`, before, after) +} + +// BizFieldFromChange 从 after/before JSON 中取展示字段(如 name、type_name) +func BizFieldFromChange(change *dao.ReviewChange, field string) string { + if change == nil || field == utils.StringEmpty { + return utils.StringEmpty + } + for _, raw := range []string{change.AfterData, change.BeforeData} { + if raw == utils.StringEmpty { + continue + } + var m map[string]any + if err := jsoniter.Unmarshal([]byte(raw), &m); err != nil { + continue + } + if v, ok := m[field].(string); ok && v != utils.StringEmpty { + return v + } + } + return utils.StringEmpty +} diff --git a/services/wecom/internal/logic/message/utils/user.go b/services/wecom/internal/logic/message/utils/user.go index 3f1709f..a78be09 100644 --- a/services/wecom/internal/logic/message/utils/user.go +++ b/services/wecom/internal/logic/message/utils/user.go @@ -1,149 +1,96 @@ package utils import ( - "base-service/app/dao" - "base-service/app/models" + "fmt" "strconv" "strings" + + "lone-services/pkg/modelbase" + "lone-services/pkg/utils" + "lone-services/services/wecom/internal/dao" + "lone-services/services/wecom/internal/model" ) +// ActionUser 审核相关操作人(姓名来自变更快照) +type ActionUser struct { + Id int64 + Name string +} + func GetApplicantUser(objId int, objType uint8, career uint8) (*dao.WecomUser, error) { - - w := models.Params{ - Eq: map[string]string{ - "obj_id": strconv.Itoa(objId), - "obj_type": strconv.Itoa(int(objType)), - }, - Order: "id desc", - } - - editLog := dao.EditLogInfo{} - err := models.EditLogModel{}.Init().GetOne(w, &editLog) + change, err := GetLatestReviewChange(objType, int64(objId)) if err != nil { return nil, err } - uw := models.Params{ - Eq: map[string]string{ - "obj_id": strconv.Itoa(editLog.AdminId), - "obj_type": strconv.Itoa(int(career)), - "status": strconv.Itoa(int(dao.StatusOk)), - }, - } - user := dao.WecomUser{} - err = models.WecomUserModel{}.Init().GetOne(uw, &user) + err = model.UserModel{}.Init().GetOne(modelbase.Params{ + Eq: map[string]string{ + "user_id": strconv.FormatInt(change.AdminId, 10), + "type": strconv.FormatUint(uint64(career), 10), + "status": strconv.Itoa(int(dao.StatusEnabled)), + }, + }, &user) if err != nil { return nil, err } - return &user, nil } -func GetAdminUser(objId int, objType uint8) (*dao.Admin, error) { - - w := models.Params{ - Eq: map[string]string{ - "obj_id": strconv.Itoa(objId), - "obj_type": strconv.Itoa(int(objType)), - }, - Order: "id desc", - } - - editLog := dao.EditLogInfo{} - err := models.EditLogModel{}.Init().GetOne(w, &editLog) +func GetActionUser(objId int, objType uint8) (*ActionUser, error) { + change, err := GetLatestReviewChange(objType, int64(objId)) if err != nil { return nil, err } - user := dao.Admin{} - - err = models.AdminUserModel{}.Init().GetOne(models.Params{ - Eq: map[string]string{ - "id": strconv.Itoa(editLog.AdminId), - }, - }, &user) - - return &user, nil -} - -func GetActionUser(objId int, objType uint8) (*dao.Admin, error) { - - w := models.Params{ - Eq: map[string]string{ - "obj_id": strconv.Itoa(objId), - "type": strconv.Itoa(int(objType)), - }, - Order: "id desc", - } - - apply := dao.ActionApplyLogInfo{} - err := models.ActionApplyLogModel{}.Init().GetOne(w, &apply) - if err != nil { - return nil, err - } - user := dao.Admin{} - - err = models.AdminUserModel{}.Init().GetOne(models.Params{ - Eq: map[string]string{ - "id": strconv.Itoa(apply.AdminId), - }, - }, &user) - - return &user, nil + return &ActionUser{ + Id: change.AdminId, + Name: change.AdminName, + }, nil } func GetActionWecomUser(objId int, objType uint8) (*dao.WecomUser, error) { - - w := models.Params{ - Eq: map[string]string{ - "obj_id": strconv.Itoa(objId), - "type": strconv.Itoa(int(objType)), - }, - Order: "id desc", - } - - apply := dao.ActionApplyLogInfo{} - err := models.ActionApplyLogModel{}.Init().GetOne(w, &apply) + change, err := GetLatestReviewChange(objType, int64(objId)) if err != nil { return nil, err } - user := dao.Admin{} - err = models.AdminUserModel{}.Init().GetOne(models.Params{ + user := dao.WecomUser{} + err = model.UserModel{}.Init().GetOne(modelbase.Params{ Eq: map[string]string{ - "id": strconv.Itoa(apply.AdminId), + "user_id": strconv.FormatInt(change.AdminId, 10), + "type": strconv.Itoa(int(dao.UserTypeAdmin)), + "status": strconv.Itoa(int(dao.StatusEnabled)), }, }, &user) - - uw := models.Params{ - Eq: map[string]string{ - "obj_id": strconv.Itoa(user.Id), - "obj_type": strconv.Itoa(dao.NumberTwo), - "status": strconv.Itoa(int(dao.StatusOk)), - }, - } - - wecom := dao.WecomUser{} - err = models.WecomUserModel{}.Init().GetOne(uw, &wecom) if err != nil { return nil, err } - - return &wecom, nil + if user.Id < 1 { + // 再试销售类型 + err = model.UserModel{}.Init().GetOne(modelbase.Params{ + Eq: map[string]string{ + "user_id": strconv.FormatInt(change.AdminId, 10), + "type": strconv.Itoa(int(dao.UserTypeSale)), + "status": strconv.Itoa(int(dao.StatusEnabled)), + }, + }, &user) + if err != nil { + return nil, err + } + } + if user.Id < 1 { + return nil, fmt.Errorf("wecom user not found for admin_id=%d", change.AdminId) + } + return &user, nil } func JoinWecomUsers(users ...string) string { - - result := make([]string, 0) - + result := make([]string, 0, len(users)) for _, user := range users { - - if user == "" { + if user == utils.StringEmpty { continue } - result = append(result, user) } - return strings.Join(result, "|") } diff --git a/services/wecom/internal/logic/sendMessageLogic.go b/services/wecom/internal/logic/sendMessageLogic.go new file mode 100644 index 0000000..8ddd0dd --- /dev/null +++ b/services/wecom/internal/logic/sendMessageLogic.go @@ -0,0 +1,57 @@ +package logic + +import ( + "context" + + "lone-services/pkg/utils" + "lone-services/pkg/validate" + wecom "lone-services/rpc/wecom/pb" + "lone-services/services/wecom/internal/dao" + "lone-services/services/wecom/internal/logic/message/sender" + "lone-services/services/wecom/internal/svc" + "lone-services/services/wecom/validator" + + "github.com/zeromicro/go-zero/core/logx" +) + +type SendMessageLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewSendMessageLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SendMessageLogic { + return &SendMessageLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *SendMessageLogic) SendMessage(in *wecom.SendMessageReq) (*wecom.Response, error) { + var req validator.SendMessageValidator + if msg := validate.ValidateFromProto(in, &req); msg != utils.StringEmpty { + return outResponse(utils.ErrorParams, msg), nil + } + + ext := map[string]any{} + if req.Reason != utils.StringEmpty { + ext["reason"] = req.Reason + } + if req.Key != utils.StringEmpty { + ext["key"] = req.Key + } + + job := dao.WeComJob{ + BizId: int(req.BizId), + BizType: uint8(req.BizType), + Type: uint8(req.Type), + Action: uint8(req.Action), + Ext: ext, + } + if err := (sender.WecomSenderService{}).Send(l.ctx, job); err != nil { + l.Errorf("send wecom message: %v", err) + return failResponse(utils.Fail), nil + } + return okResponse(nil), nil +} diff --git a/services/wecom/internal/model/reviewChange.go b/services/wecom/internal/model/reviewChange.go new file mode 100644 index 0000000..707ca2c --- /dev/null +++ b/services/wecom/internal/model/reviewChange.go @@ -0,0 +1,23 @@ +package model + +import ( + "lone-services/pkg/modelbase" + "lone-services/services/wecom/internal/dao" +) + +type ReviewChangeModel struct { + modelbase.Base +} + +func (m ReviewChangeModel) TableName() string { + return modelbase.Prefix() + "review_changes" +} + +func (m ReviewChangeModel) Init() ReviewChangeModel { + m.Table = m.TableName() + return m +} + +func (m ReviewChangeModel) Create(data *dao.ReviewChange) error { + return m.Base.Create(data) +} diff --git a/services/wecom/internal/model/reviewTask.go b/services/wecom/internal/model/reviewTask.go new file mode 100644 index 0000000..cb6575c --- /dev/null +++ b/services/wecom/internal/model/reviewTask.go @@ -0,0 +1,23 @@ +package model + +import ( + "lone-services/pkg/modelbase" + "lone-services/services/wecom/internal/dao" +) + +type ReviewTaskModel struct { + modelbase.Base +} + +func (m ReviewTaskModel) TableName() string { + return modelbase.Prefix() + "review_tasks" +} + +func (m ReviewTaskModel) Init() ReviewTaskModel { + m.Table = m.TableName() + return m +} + +func (m ReviewTaskModel) Create(data *dao.WecomReviewTask) error { + return m.Base.Create(data) +} diff --git a/services/wecom/internal/server/wecomServer.go b/services/wecom/internal/server/wecomServer.go index e99b41f..21811c3 100644 --- a/services/wecom/internal/server/wecomServer.go +++ b/services/wecom/internal/server/wecomServer.go @@ -67,3 +67,15 @@ func (s *WecomServer) ItemsTags(ctx context.Context, in *wecom.ItemsTagsReq) (*w l := logic.NewItemsTagsLogic(ctx, s.svcCtx) return l.ItemsTags(in) } + +// 内部接口:产品/门店/地址新增或修改时写入审核变更快照 +func (s *WecomServer) CreateReviewChange(ctx context.Context, in *wecom.CreateReviewChangeReq) (*wecom.Response, error) { + l := logic.NewCreateReviewChangeLogic(ctx, s.svcCtx) + return l.CreateReviewChange(in) +} + +// 内部接口:发送企微审核/通知消息 +func (s *WecomServer) SendMessage(ctx context.Context, in *wecom.SendMessageReq) (*wecom.Response, error) { + l := logic.NewSendMessageLogic(ctx, s.svcCtx) + return l.SendMessage(in) +} diff --git a/services/wecom/validator/validator.go b/services/wecom/validator/validator.go index a90b18b..f40ed36 100644 --- a/services/wecom/validator/validator.go +++ b/services/wecom/validator/validator.go @@ -95,3 +95,49 @@ func (p DeleteUserValidator) GetMessage() validate.ValidatorMessages { "Id.min": "ID无效", } } + +type CreateReviewChangeValidator struct { + Type uint32 `validate:"required,oneof=1 2 3 4"` + BizId int64 `validate:"required,min=1"` + TaskId string `validate:"omitempty,max=64"` + BeforeData string `validate:"omitempty"` + AfterData string `validate:"required"` + AdminId int64 `validate:"omitempty,min=0"` + AdminName string `validate:"omitempty,max=64"` +} + +func (p CreateReviewChangeValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + "Type.required": "业务类型不能为空", + "Type.oneof": "业务类型不对,1产品 2门店 3地址 4销售", + "BizId.required": "业务ID不能为空", + "BizId.min": "业务ID无效", + "TaskId.max": "任务ID长度不能超过64", + "AfterData.required": "修改后数据不能为空", + "AdminId.min": "操作人ID无效", + "AdminName.max": "操作人姓名长度不能超过64", + } +} + +type SendMessageValidator struct { + BizId int64 `validate:"required,min=1"` + BizType uint32 `validate:"required,oneof=1 2 3 4"` + Type uint32 `validate:"required,min=1"` + Action uint32 `validate:"omitempty,oneof=0 1 2"` + Reason string `validate:"omitempty,max=512"` + Key string `validate:"omitempty,max=128"` +} + +func (p SendMessageValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + "BizId.required": "业务ID不能为空", + "BizId.min": "业务ID无效", + "BizType.required": "业务类型不能为空", + "BizType.oneof": "业务类型不对,1产品 2门店 3地址 4销售", + "Type.required": "消息类型不能为空", + "Type.min": "消息类型无效", + "Action.oneof": "动作不对,0未用 1通过 2拒绝", + "Reason.max": "原因长度不能超过512", + "Key.max": "key长度不能超过128", + } +} diff --git a/services/wecom/wecomClient/wecom.go b/services/wecom/wecomClient/wecom.go index 823a79b..9c56651 100644 --- a/services/wecom/wecomClient/wecom.go +++ b/services/wecom/wecomClient/wecom.go @@ -14,15 +14,17 @@ import ( ) type ( - CreateTagsReq = wecom.CreateTagsReq - CreateUserReq = wecom.CreateUserReq - DeleteUserReq = wecom.DeleteUserReq - EmptyReq = wecom.EmptyReq - ItemsTagsReq = wecom.ItemsTagsReq - ItemsUserReq = wecom.ItemsUserReq - Response = wecom.Response - StatusUserReq = wecom.StatusUserReq - UpdateUserReq = wecom.UpdateUserReq + CreateReviewChangeReq = wecom.CreateReviewChangeReq + CreateTagsReq = wecom.CreateTagsReq + CreateUserReq = wecom.CreateUserReq + DeleteUserReq = wecom.DeleteUserReq + EmptyReq = wecom.EmptyReq + ItemsTagsReq = wecom.ItemsTagsReq + ItemsUserReq = wecom.ItemsUserReq + Response = wecom.Response + SendMessageReq = wecom.SendMessageReq + StatusUserReq = wecom.StatusUserReq + UpdateUserReq = wecom.UpdateUserReq Wecom interface { ItemsUsers(ctx context.Context, in *ItemsUserReq, opts ...grpc.CallOption) (*Response, error) @@ -34,6 +36,10 @@ type ( Types(ctx context.Context, in *EmptyReq, opts ...grpc.CallOption) (*Response, error) CreateTags(ctx context.Context, in *CreateTagsReq, opts ...grpc.CallOption) (*Response, error) ItemsTags(ctx context.Context, in *ItemsTagsReq, opts ...grpc.CallOption) (*Response, error) + // 内部接口:产品/门店/地址新增或修改时写入审核变更快照 + CreateReviewChange(ctx context.Context, in *CreateReviewChangeReq, opts ...grpc.CallOption) (*Response, error) + // 内部接口:发送企微审核/通知消息 + SendMessage(ctx context.Context, in *SendMessageReq, opts ...grpc.CallOption) (*Response, error) } defaultWecom struct { @@ -91,3 +97,15 @@ func (m *defaultWecom) ItemsTags(ctx context.Context, in *ItemsTagsReq, opts ... client := wecom.NewWecomClient(m.cli.Conn()) return client.ItemsTags(ctx, in, opts...) } + +// 内部接口:产品/门店/地址新增或修改时写入审核变更快照 +func (m *defaultWecom) CreateReviewChange(ctx context.Context, in *CreateReviewChangeReq, opts ...grpc.CallOption) (*Response, error) { + client := wecom.NewWecomClient(m.cli.Conn()) + return client.CreateReviewChange(ctx, in, opts...) +} + +// 内部接口:发送企微审核/通知消息 +func (m *defaultWecom) SendMessage(ctx context.Context, in *SendMessageReq, opts ...grpc.CallOption) (*Response, error) { + client := wecom.NewWecomClient(m.cli.Conn()) + return client.SendMessage(ctx, in, opts...) +}