Pārlūkot izejas kodu

增加 RiskControlNtf 风控通知支持

zhou.xiaoning 2 gadi atpakaļ
vecāks
revīzija
3aad1b7dbf
5 mainītis faili ar 242 papildinājumiem un 11 dzēšanām
  1. 1 0
      global/funcode.go
  2. 24 0
      initialize/rabbitmq.go
  3. 195 8
      res/pb/mtp2.pb.go
  4. 16 0
      res/pb/mtp2.proto
  5. 6 3
      service/asign/asign.go

+ 1 - 0
global/funcode.go

@@ -8,6 +8,7 @@ var (
 	PosChangedNtf         = 131075 // 头寸变化通知
 	OrderCanceledNtf      = 131084 // 委托单撤单通知
 	RiskCutNtf            = 131119 // 斩仓通知
+	RiskControlNtf        = 131086 // 风控通知
 
 	AccountFundInfoReq = 262150 // 账户资金信息请求
 	AccountFundInfoRsp = 262151 // 账户资金信息响应

+ 24 - 0
initialize/rabbitmq.go

@@ -268,6 +268,25 @@ func (t *MQProc) onNtf(funcode uint32, sessionId uint32, bytes *[]byte) {
 		if err != nil {
 			return
 		}
+	case global.RiskControlNtf: // 风控通知
+		var p pb.RiskControlNtf
+		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.ListingOrderChangeNtf: // 挂牌委托变更广播通知
 		var p pb.ListingOrderChangeNtf
 		if err = proto.Unmarshal(*bytes, &p); err != nil {
@@ -331,6 +350,7 @@ func (t *MQProc) getRspProtobuf(msg *[]byte) (funcode uint32, sessionId uint32,
 		global.MarketStatusChangeNtf,
 		global.OrderCanceledNtf,
 		global.RiskCutNtf,
+		global.RiskControlNtf,
 		global.LoginRsp,
 		global.LogoutRsp,
 		global.ListingOrderChangeNtf: // 资金变化通知等
@@ -999,6 +1019,10 @@ func RabbitMQSubscribeTopic() (err error) {
 		global.M2A_LOG.Error("rabbitmq subscribe topic failed, err:", zap.Error(err))
 		return
 	}
+	if err = rabbitmq.SubscribeTopic(global.TOPIC_RISK_NOTIFY); err != nil {
+		global.M2A_LOG.Error("rabbitmq subscribe topic failed, err:", zap.Error(err))
+		return
+	}
 	if err = rabbitmq.SubscribeTopic(global.TOPIC_CLIENT_NTF); err != nil {
 		global.M2A_LOG.Error("rabbitmq subscribe topic failed, err:", zap.Error(err))
 		return

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

@@ -14897,6 +14897,150 @@ func (x *RiskCutNtf) GetSafeRate() float64 {
 	return 0
 }
 
+// 风控通知
+type RiskControlNtf 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 账号id
+	AccountStatus     *int32       `protobuf:"varint,4,opt,name=AccountStatus" json:"AccountStatus,omitempty"`           // int32 账户状态
+	AccountType       *int32       `protobuf:"varint,5,opt,name=AccountType" json:"AccountType,omitempty"`               // int32 账户类型
+	AccountCode       *string      `protobuf:"bytes,6,opt,name=AccountCode" json:"AccountCode,omitempty"`                // string 账户名称
+	AccountName       *string      `protobuf:"bytes,7,opt,name=AccountName" json:"AccountName,omitempty"`                // string 账户名称
+	RiskLevel         *int32       `protobuf:"varint,8,opt,name=RiskLevel" json:"RiskLevel,omitempty"`                   // int32 当前风险级别:1:提示,
+	MsgContent        *string      `protobuf:"bytes,9,opt,name=MsgContent" json:"MsgContent,omitempty"`                  // string 风控消息内容
+	Idate             *string      `protobuf:"bytes,10,opt,name=Idate" json:"Idate,omitempty"`                           // datetime 时间
+	RiskRate          *float64     `protobuf:"fixed64,11,opt,name=RiskRate" json:"RiskRate,omitempty"`                   // double 风险率
+	CurrentNetBalance *float64     `protobuf:"fixed64,12,opt,name=CurrentNetBalance" json:"CurrentNetBalance,omitempty"` // double 净值
+	RiskType          *int32       `protobuf:"varint,13,opt,name=RiskType" json:"RiskType,omitempty"`                    // int32 风控类型:0:默认风险率监控,1:安全度风控
+}
+
+func (x *RiskControlNtf) Reset() {
+	*x = RiskControlNtf{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_mtp2_proto_msgTypes[130]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *RiskControlNtf) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RiskControlNtf) ProtoMessage() {}
+
+func (x *RiskControlNtf) ProtoReflect() protoreflect.Message {
+	mi := &file_mtp2_proto_msgTypes[130]
+	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 RiskControlNtf.ProtoReflect.Descriptor instead.
+func (*RiskControlNtf) Descriptor() ([]byte, []int) {
+	return file_mtp2_proto_rawDescGZIP(), []int{130}
+}
+
+func (x *RiskControlNtf) GetHeader() *MessageHead {
+	if x != nil {
+		return x.Header
+	}
+	return nil
+}
+
+func (x *RiskControlNtf) GetNtfHeader() *NotifyHead {
+	if x != nil {
+		return x.NtfHeader
+	}
+	return nil
+}
+
+func (x *RiskControlNtf) GetAccountId() uint64 {
+	if x != nil && x.AccountId != nil {
+		return *x.AccountId
+	}
+	return 0
+}
+
+func (x *RiskControlNtf) GetAccountStatus() int32 {
+	if x != nil && x.AccountStatus != nil {
+		return *x.AccountStatus
+	}
+	return 0
+}
+
+func (x *RiskControlNtf) GetAccountType() int32 {
+	if x != nil && x.AccountType != nil {
+		return *x.AccountType
+	}
+	return 0
+}
+
+func (x *RiskControlNtf) GetAccountCode() string {
+	if x != nil && x.AccountCode != nil {
+		return *x.AccountCode
+	}
+	return ""
+}
+
+func (x *RiskControlNtf) GetAccountName() string {
+	if x != nil && x.AccountName != nil {
+		return *x.AccountName
+	}
+	return ""
+}
+
+func (x *RiskControlNtf) GetRiskLevel() int32 {
+	if x != nil && x.RiskLevel != nil {
+		return *x.RiskLevel
+	}
+	return 0
+}
+
+func (x *RiskControlNtf) GetMsgContent() string {
+	if x != nil && x.MsgContent != nil {
+		return *x.MsgContent
+	}
+	return ""
+}
+
+func (x *RiskControlNtf) GetIdate() string {
+	if x != nil && x.Idate != nil {
+		return *x.Idate
+	}
+	return ""
+}
+
+func (x *RiskControlNtf) GetRiskRate() float64 {
+	if x != nil && x.RiskRate != nil {
+		return *x.RiskRate
+	}
+	return 0
+}
+
+func (x *RiskControlNtf) GetCurrentNetBalance() float64 {
+	if x != nil && x.CurrentNetBalance != nil {
+		return *x.CurrentNetBalance
+	}
+	return 0
+}
+
+func (x *RiskControlNtf) GetRiskType() int32 {
+	if x != nil && x.RiskType != nil {
+		return *x.RiskType
+	}
+	return 0
+}
+
 var File_mtp2_proto protoreflect.FileDescriptor
 
 var file_mtp2_proto_rawDesc = []byte{
@@ -17629,7 +17773,35 @@ var file_mtp2_proto_rawDesc = []byte{
 	0x43, 0x75, 0x74, 0x52, 0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x01, 0x52, 0x07, 0x43,
 	0x75, 0x74, 0x52, 0x61, 0x74, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x53, 0x61, 0x66, 0x65, 0x52, 0x61,
 	0x74, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, 0x53, 0x61, 0x66, 0x65, 0x52, 0x61,
-	0x74, 0x65,
+	0x74, 0x65, 0x22, 0xcb, 0x03, 0x0a, 0x0e, 0x52, 0x69, 0x73, 0x6b, 0x43, 0x6f, 0x6e, 0x74, 0x72,
+	0x6f, 0x6c, 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, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52,
+	0x09, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x41, 0x63,
+	0x63, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28,
+	0x05, 0x52, 0x0d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
+	0x12, 0x20, 0x0a, 0x0b, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18,
+	0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79,
+	0x70, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x6f, 0x64,
+	0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74,
+	0x43, 0x6f, 0x64, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4e,
+	0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x41, 0x63, 0x63, 0x6f, 0x75,
+	0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x52, 0x69, 0x73, 0x6b, 0x4c, 0x65,
+	0x76, 0x65, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x52, 0x69, 0x73, 0x6b, 0x4c,
+	0x65, 0x76, 0x65, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x4d, 0x73, 0x67, 0x43, 0x6f, 0x6e, 0x74, 0x65,
+	0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x4d, 0x73, 0x67, 0x43, 0x6f, 0x6e,
+	0x74, 0x65, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x49, 0x64, 0x61, 0x74, 0x65, 0x18, 0x0a, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x05, 0x49, 0x64, 0x61, 0x74, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x52, 0x69,
+	0x73, 0x6b, 0x52, 0x61, 0x74, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, 0x52, 0x69,
+	0x73, 0x6b, 0x52, 0x61, 0x74, 0x65, 0x12, 0x2c, 0x0a, 0x11, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e,
+	0x74, 0x4e, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28,
+	0x01, 0x52, 0x11, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x4e, 0x65, 0x74, 0x42, 0x61, 0x6c,
+	0x61, 0x6e, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x52, 0x69, 0x73, 0x6b, 0x54, 0x79, 0x70, 0x65,
+	0x18, 0x0d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x52, 0x69, 0x73, 0x6b, 0x54, 0x79, 0x70, 0x65,
 }
 
 var (
@@ -17644,7 +17816,7 @@ func file_mtp2_proto_rawDescGZIP() []byte {
 	return file_mtp2_proto_rawDescData
 }
 
-var file_mtp2_proto_msgTypes = make([]protoimpl.MessageInfo, 130)
+var file_mtp2_proto_msgTypes = make([]protoimpl.MessageInfo, 131)
 var file_mtp2_proto_goTypes = []interface{}{
 	(*MessageHead)(nil),                         // 0: pb.MessageHead
 	(*NotifyHead)(nil),                          // 1: pb.NotifyHead
@@ -17776,6 +17948,7 @@ var file_mtp2_proto_goTypes = []interface{}{
 	(*T2BSMSVerificationCodeReq)(nil),           // 127: pb.t2bSMSVerificationCodeReq
 	(*T2BSMSVerificationCodeRsp)(nil),           // 128: pb.t2bSMSVerificationCodeRsp
 	(*RiskCutNtf)(nil),                          // 129: pb.RiskCutNtf
+	(*RiskControlNtf)(nil),                      // 130: pb.RiskControlNtf
 }
 var file_mtp2_proto_depIdxs = []int32{
 	0,   // 0: pb.MoneyChangedNtf.Header:type_name -> pb.MessageHead
@@ -17916,11 +18089,13 @@ var file_mtp2_proto_depIdxs = []int32{
 	0,   // 135: pb.t2bSMSVerificationCodeRsp.Header:type_name -> pb.MessageHead
 	0,   // 136: pb.RiskCutNtf.Header:type_name -> pb.MessageHead
 	1,   // 137: pb.RiskCutNtf.NtfHeader:type_name -> pb.NotifyHead
-	138, // [138:138] is the sub-list for method output_type
-	138, // [138:138] is the sub-list for method input_type
-	138, // [138:138] is the sub-list for extension type_name
-	138, // [138:138] is the sub-list for extension extendee
-	0,   // [0:138] is the sub-list for field type_name
+	0,   // 138: pb.RiskControlNtf.Header:type_name -> pb.MessageHead
+	1,   // 139: pb.RiskControlNtf.NtfHeader:type_name -> pb.NotifyHead
+	140, // [140:140] is the sub-list for method output_type
+	140, // [140:140] is the sub-list for method input_type
+	140, // [140:140] is the sub-list for extension type_name
+	140, // [140:140] is the sub-list for extension extendee
+	0,   // [0:140] is the sub-list for field type_name
 }
 
 func init() { file_mtp2_proto_init() }
@@ -19489,6 +19664,18 @@ func file_mtp2_proto_init() {
 				return nil
 			}
 		}
+		file_mtp2_proto_msgTypes[130].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*RiskControlNtf); 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{
@@ -19496,7 +19683,7 @@ func file_mtp2_proto_init() {
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_mtp2_proto_rawDesc,
 			NumEnums:      0,
-			NumMessages:   130,
+			NumMessages:   131,
 			NumExtensions: 0,
 			NumServices:   0,
 		},

+ 16 - 0
res/pb/mtp2.proto

@@ -1690,4 +1690,20 @@ message RiskCutNtf {
 		optional double CurRate = 6; // double 实时风险率
 		optional double CutRate = 7; // double 斩仓触发风险率
 		optional double SafeRate = 8; // double 斩仓恢复风险率
+}
+// 风控通知
+message RiskControlNtf {
+	optional MessageHead Header = 1; // 消息头
+		optional NotifyHead NtfHeader = 2; // NotifyHead 公共消息头
+		optional uint64 AccountId = 3; // uint64 账号id
+		optional int32 AccountStatus = 4; // int32 账户状态
+		optional int32 AccountType = 5; // int32 账户类型
+		optional string AccountCode = 6; // string 账户名称
+		optional string AccountName = 7; // string 账户名称
+		optional int32 RiskLevel = 8; // int32 当前风险级别:1:提示,
+		optional string MsgContent = 9; // string 风控消息内容
+		optional string Idate = 10; // datetime 时间
+		optional double RiskRate = 11; // double 风险率
+		optional double CurrentNetBalance = 12; // double 净值
+		optional int32 RiskType = 13; // int32 风控类型:0:默认风险率监控,1:安全度风控
 }

+ 6 - 3
service/asign/asign.go

@@ -209,14 +209,17 @@ type AddPersonalUserData struct {
 // https://preweb.asign.cn/platform/openDoc/docDetail?mid=addPersonalUser
 // 添加个人用户(https://{host}/user/addPersonalUser)
 // 错误码	错误描述
+// 100020	认证记录尚未完成/失败
 // 100021	用户已存在
-// 100156	手机号码格式错误
-// 100157	邮箱格式错误
 // 100571	参数错误,唯一识别码Account为空
 // 100577	参数错误,{param}长度超过限制:{length}
 // 100579	参数错误,{param}不能为空
+// 100580	参数错误,{param1}、{param2}不能同时为空
 // 100598	参数错误,身份证号码格式不正确
-// 100639	参数错误,名字点号格式不正确
+// 100721	参数错误,根据序列号未查询到对应认证记录
+// 100722	参数错误,该实名记录已核销,请重新实名认证
+// 100726	该条实名记录为核验记录,无法用于添加用户
+// 100727	实名认证类型和添加用户类型不匹配
 func AddPersonalUserBy(account, name, idCard, mobile string, idCardType *int) (rspData AsignRsp[AddPersonalUserData], err error) {
 	apiUrl := global.M2A_CONFIG.Asign.URL + "user/addPersonalUser"