ソースを参照

增加 PosChangedNtf= 131075 // 头寸变化通知

zhou.xiaoning 2 年 前
コミット
e33a4804d5
5 ファイル変更194 行追加21 行削除
  1. 1 0
      global/funcode.go
  2. 20 1
      initialize/rabbitmq.go
  3. 105 8
      res/pb/mtp2.pb.go
  4. 7 0
      res/pb/mtp2.proto
  5. 61 12
      service/asign/sign.go

+ 1 - 0
global/funcode.go

@@ -5,6 +5,7 @@ var (
 	OrderDealedNtf        = 131081 // 委托单成交通知
 	MarketStatusChangeNtf = 131089 // 市场状态变更通知
 	ListingOrderChangeNtf = 131176 // 挂牌委托变更广播通知
+	PosChangedNtf         = 131075 // 头寸变化通知
 
 	AccountFundInfoReq = 262150 // 账户资金信息请求
 	AccountFundInfoRsp = 262151 // 账户资金信息响应

+ 20 - 1
initialize/rabbitmq.go

@@ -164,6 +164,24 @@ func (t *MQProc) onNtf(funcode uint32, sessionId uint32, bytes *[]byte) {
 		if err != nil {
 			return
 		}
+	case global.PosChangedNtf: // 头寸变化通知
+		var p pb.PosChangedNtf
+		if err = proto.Unmarshal(*bytes, &p); err != nil {
+			global.M2A_LOG.Error("总线数据反序列化失败", zap.Error(err))
+			return
+		}
+		if bs, e := protojson.Marshal(&p); e != nil {
+			global.M2A_LOG.Error("总线数据序列化JSON失败", zap.Error(err))
+			return
+		} else {
+			sendBytes = &bs
+		}
+
+		// 获取目标客户
+		clients, err = accountSrv.GetClientsByAccountID(*p.AccountID)
+		if err != nil {
+			return
+		}
 	case global.OrderDealedNtf: // 委托单成交通知
 		var p pb.OrderDealedNtf
 		if err = proto.Unmarshal(*bytes, &p); err != nil {
@@ -251,7 +269,8 @@ func (t *MQProc) getRspProtobuf(msg *[]byte) (funcode uint32, sessionId uint32,
 	global.M2A_LOG.Info("收到总线消息", zap.Any("funcode", funcode), zap.Any("sessionId", sessionId), zap.Any("len", len(b)))
 
 	switch int(funcode) {
-	case global.MoneyChangedNtf,
+	case global.PosChangedNtf,
+		global.MoneyChangedNtf,
 		global.OrderDealedNtf,
 		global.MarketStatusChangeNtf,
 		global.LoginRsp,

+ 105 - 8
res/pb/mtp2.pb.go

@@ -14193,6 +14193,78 @@ func (x *LogoutRsp) GetRetDesc() string {
 	return ""
 }
 
+// 头寸变化通知
+type PosChangedNtf struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Header    *MessageHead `protobuf:"bytes,1,opt,name=Header" json:"Header,omitempty"`        // 消息头
+	NtfHeader *NotifyHead  `protobuf:"bytes,2,opt,name=NtfHeader" json:"NtfHeader,omitempty"`  // NotifyHead 公共消息头
+	AccountID *uint64      `protobuf:"varint,3,opt,name=AccountID" json:"AccountID,omitempty"` // uint64 交易账号
+	GoodsID   *uint32      `protobuf:"varint,4,opt,name=GoodsID" json:"GoodsID,omitempty"`     // uint32 商品
+}
+
+func (x *PosChangedNtf) Reset() {
+	*x = PosChangedNtf{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_mtp2_proto_msgTypes[123]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *PosChangedNtf) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*PosChangedNtf) ProtoMessage() {}
+
+func (x *PosChangedNtf) ProtoReflect() protoreflect.Message {
+	mi := &file_mtp2_proto_msgTypes[123]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use PosChangedNtf.ProtoReflect.Descriptor instead.
+func (*PosChangedNtf) Descriptor() ([]byte, []int) {
+	return file_mtp2_proto_rawDescGZIP(), []int{123}
+}
+
+func (x *PosChangedNtf) GetHeader() *MessageHead {
+	if x != nil {
+		return x.Header
+	}
+	return nil
+}
+
+func (x *PosChangedNtf) GetNtfHeader() *NotifyHead {
+	if x != nil {
+		return x.NtfHeader
+	}
+	return nil
+}
+
+func (x *PosChangedNtf) GetAccountID() uint64 {
+	if x != nil && x.AccountID != nil {
+		return *x.AccountID
+	}
+	return 0
+}
+
+func (x *PosChangedNtf) GetGoodsID() uint32 {
+	if x != nil && x.GoodsID != nil {
+		return *x.GoodsID
+	}
+	return 0
+}
+
 var File_mtp2_proto protoreflect.FileDescriptor
 
 var file_mtp2_proto_rawDesc = []byte{
@@ -16804,7 +16876,17 @@ var file_mtp2_proto_rawDesc = []byte{
 	0x12, 0x18, 0x0a, 0x07, 0x52, 0x65, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
 	0x05, 0x52, 0x07, 0x52, 0x65, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x52, 0x65,
 	0x74, 0x44, 0x65, 0x73, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x52, 0x65, 0x74,
-	0x44, 0x65, 0x73, 0x63,
+	0x44, 0x65, 0x73, 0x63, 0x22, 0x9e, 0x01, 0x0a, 0x0d, 0x50, 0x6f, 0x73, 0x43, 0x68, 0x61, 0x6e,
+	0x67, 0x65, 0x64, 0x4e, 0x74, 0x66, 0x12, 0x27, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73,
+	0x61, 0x67, 0x65, 0x48, 0x65, 0x61, 0x64, 0x52, 0x06, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12,
+	0x2c, 0x0a, 0x09, 0x4e, 0x74, 0x66, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x48, 0x65,
+	0x61, 0x64, 0x52, 0x09, 0x4e, 0x74, 0x66, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x1c, 0x0a,
+	0x09, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04,
+	0x52, 0x09, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x47,
+	0x6f, 0x6f, 0x64, 0x73, 0x49, 0x44, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x47, 0x6f,
+	0x6f, 0x64, 0x73, 0x49, 0x44,
 }
 
 var (
@@ -16819,7 +16901,7 @@ func file_mtp2_proto_rawDescGZIP() []byte {
 	return file_mtp2_proto_rawDescData
 }
 
-var file_mtp2_proto_msgTypes = make([]protoimpl.MessageInfo, 123)
+var file_mtp2_proto_msgTypes = make([]protoimpl.MessageInfo, 124)
 var file_mtp2_proto_goTypes = []interface{}{
 	(*MessageHead)(nil),                         // 0: pb.MessageHead
 	(*NotifyHead)(nil),                          // 1: pb.NotifyHead
@@ -16944,6 +17026,7 @@ var file_mtp2_proto_goTypes = []interface{}{
 	(*CustOfflineNtf)(nil),                      // 120: pb.CustOfflineNtf
 	(*LogoutReq)(nil),                           // 121: pb.LogoutReq
 	(*LogoutRsp)(nil),                           // 122: pb.LogoutRsp
+	(*PosChangedNtf)(nil),                       // 123: pb.PosChangedNtf
 }
 var file_mtp2_proto_depIdxs = []int32{
 	0,   // 0: pb.MoneyChangedNtf.Header:type_name -> pb.MessageHead
@@ -17074,11 +17157,13 @@ var file_mtp2_proto_depIdxs = []int32{
 	0,   // 125: pb.CustOfflineNtf.Header:type_name -> pb.MessageHead
 	0,   // 126: pb.LogoutReq.Header:type_name -> pb.MessageHead
 	0,   // 127: pb.LogoutRsp.Header:type_name -> pb.MessageHead
-	128, // [128:128] is the sub-list for method output_type
-	128, // [128:128] is the sub-list for method input_type
-	128, // [128:128] is the sub-list for extension type_name
-	128, // [128:128] is the sub-list for extension extendee
-	0,   // [0:128] is the sub-list for field type_name
+	0,   // 128: pb.PosChangedNtf.Header:type_name -> pb.MessageHead
+	1,   // 129: pb.PosChangedNtf.NtfHeader:type_name -> pb.NotifyHead
+	130, // [130:130] is the sub-list for method output_type
+	130, // [130:130] is the sub-list for method input_type
+	130, // [130:130] is the sub-list for extension type_name
+	130, // [130:130] is the sub-list for extension extendee
+	0,   // [0:130] is the sub-list for field type_name
 }
 
 func init() { file_mtp2_proto_init() }
@@ -18563,6 +18648,18 @@ func file_mtp2_proto_init() {
 				return nil
 			}
 		}
+		file_mtp2_proto_msgTypes[123].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*PosChangedNtf); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
 	}
 	type x struct{}
 	out := protoimpl.TypeBuilder{
@@ -18570,7 +18667,7 @@ func file_mtp2_proto_init() {
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_mtp2_proto_rawDesc,
 			NumEnums:      0,
-			NumMessages:   123,
+			NumMessages:   124,
 			NumExtensions: 0,
 			NumServices:   0,
 		},

+ 7 - 0
res/pb/mtp2.proto

@@ -1616,4 +1616,11 @@ message LogoutRsp {
 	optional MessageHead Header = 1; // 消息头
 	optional int32 RetCode = 2; // 返回码
 	optional string RetDesc = 3; // 描述信息
+}
+// 头寸变化通知
+message PosChangedNtf {
+	optional MessageHead Header = 1; // 消息头
+		optional NotifyHead NtfHeader = 2; // NotifyHead 公共消息头
+		optional uint64 AccountID = 3; // uint64 交易账号
+		optional uint32 GoodsID = 4; // uint32 商品
 }

+ 61 - 12
service/asign/sign.go

@@ -1,18 +1,67 @@
 package asign
 
+import (
+	"crypto"
+	"crypto/rand"
+	"crypto/rsa"
+	"crypto/sha1"
+	"crypto/x509"
+	"encoding/pem"
+	"errors"
+	"fmt"
+	"strconv"
+	"time"
+)
+
 // 签名规范:
-//     1、表单提交方式:form-data
-//     2、请求头部参数
-//         参数1:sign(签名值,具体算法参考一下的前面算法)
-//         参数2:timestamp(时间戳,13位)
-//     3、请求体参数:
-//         参数1:appId(appId值,每个接入者唯一一个)
-//         参数2:timestamp(时间戳,13位,与上述一致)
-//         参数3:bizData(json字符串,举个例子,比方说要传合同编号如:{"contractNo":"0001"})
-//     4、签名算法:
-//         4.1、将上述3所属的bizData(json字符串),按照阿拉伯字母排序(如:{"ba":1,"ac":2}--->{"ac":2,"ba":1}),
-//         4.2、将4.1排序后的字符串,将【bizData+md5(bizData)+ appId + timestatmp】拼接后利用RSA非对称加密算法(SHA1withRSA),计算出最后的签名sign,对其base64编码,放入head的key(sign)中。
-func GetSign(bizData map[string]interface{}) (sign string, err error) {
+//
+//	1、表单提交方式:form-data
+//	2、请求头部参数
+//	    参数1:sign(签名值,具体算法参考一下的前面算法)
+//	    参数2:timestamp(时间戳,13位)
+//	3、请求体参数:
+//	    参数1:appId(appId值,每个接入者唯一一个)
+//	    参数2:timestamp(时间戳,13位,与上述一致)
+//	    参数3:bizData(json字符串,举个例子,比方说要传合同编号如:{"contractNo":"0001"})
+//	4、签名算法:
+//	    4.1、将上述3所属的bizData(json字符串),按照阿拉伯字母排序(如:{"ba":1,"ac":2}--->{"ac":2,"ba":1}),
+//	    4.2、将4.1排序后的字符串,将【bizData+md5(bizData)+ appId + timestatmp】拼接后利用RSA非对称加密算法(SHA1withRSA),计算出最后的签名sign,对其base64编码,放入head的key(sign)中。
+func GetSignature(bizData map[string]interface{}, appId string, privateKeyPEM string) (signatureBase64 string, timestamp string, err error) {
+	timestamp = strconv.FormatInt(time.Now().UnixMilli(), 10)
+	// Parse the privateKeyPEM into an RSA private key
+	privateKeyBlock, _ := pem.Decode([]byte(privateKeyPEM))
+	if privateKeyBlock == nil || privateKeyBlock.Type != "RSA PRIVATE KEY" {
+		err = errors.New("签名失败: Error decoding private key PEM")
+		return
+	}
+	privateKey, err := x509.ParsePKCS1PrivateKey(privateKeyBlock.Bytes)
+	if err != nil {
+		return
+	}
+
+	// Message to be signed
+	message := ""
+
+	// Sign the message using SHA1withRSA
+	signature, err := signMessage(message, privateKey)
+	if err != nil {
+		fmt.Println("Error signing the message:", err)
+		return
+	}
+	fmt.Println(signature)
 
 	return
 }
+
+// signMessage signs the given message using SHA1withRSA
+func signMessage(message string, privateKey *rsa.PrivateKey) ([]byte, error) {
+	hashed := sha1.Sum([]byte(message))
+	return rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA1, hashed[:])
+}
+
+// verifySignature verifies the given signature for the message using SHA1withRSA
+func verifySignature(message string, signature []byte, publicKey *rsa.PublicKey) bool {
+	hashed := sha1.Sum([]byte(message))
+	err := rsa.VerifyPKCS1v15(publicKey, crypto.SHA1, hashed[:], signature)
+	return err == nil
+}