xy 2 days ago
parent
commit
3a1f005b91

+ 20 - 4
bin/client_msg/mail.proto

@@ -3,6 +3,24 @@ syntax = "proto3";
 option go_package = "./msg";
 
 import "common.proto";          // 直接引入
+
+
+enum OptMailType {
+  ROLE_TYPE_UNKNOWN = 0;
+  CHECK        = 1;  // 查看
+  RECEIVE   = 2; //领取
+  DELETE   = 3; //删除
+}
+
+//邮箱信息
+message MailInfo{
+  string mail_json_info = 1;
+  int32 mail_type = 2;
+  int32 check_status = 3;
+  int32 receive_status = 4;
+  string create_time = 5;
+}
+
 //请求获取邮箱
 message ReqMail{
   string userid = 1;
@@ -12,12 +30,10 @@ message ReqMail{
 message ResMail{
   bool success = 1;
   common_pack.MsgError err_msg = 2;
-  repeated common_pack.ChatMessage list = 3;
+  repeated MailInfo list = 3;
 }
 //操作邮箱
 message OptMail{
   int32 mail_id =1;
-  int32 check_status = 2;
-  int32 receive_status = 3;
-  bool is_delete = 4;
+  OptMailType opt =2;
 }

+ 60 - 4
src/server/datacenter/mail_db/mail.go

@@ -6,6 +6,7 @@ import (
 	"errors"
 	"fmt"
 	mysqlmgr "server/db/mysql"
+	"server/msg"
 )
 
 type Mail struct {
@@ -96,8 +97,7 @@ func UpdateReceiveStatus(mailID int, status int) (int64, error) {
 	return result, err
 }
 
-func GetMailsByType(mailType int, userID string) ([]Mail, error) {
-	var mails []Mail
+func GetMailsByType(mailType int, userID string) ([]*msg.MailInfo, error) {
 	var rows *sql.Rows
 	var err error
 
@@ -120,6 +120,8 @@ func GetMailsByType(mailType int, userID string) ([]Mail, error) {
 	}
 	defer rows.Close()
 
+	var mailList []*msg.MailInfo
+
 	for rows.Next() {
 		var mail Mail
 		err := rows.Scan(
@@ -134,12 +136,66 @@ func GetMailsByType(mailType int, userID string) ([]Mail, error) {
 		if err != nil {
 			return nil, fmt.Errorf("scan failed: %v", err)
 		}
-		mails = append(mails, mail)
+		mailList = append(mailList, &msg.MailInfo{
+			MailJsonInfo:  string(mail.MailInfo),
+			MailType:      int32(mail.MailType),
+			CheckStatus:   int32(mail.CheckStatus),
+			ReceiveStatus: int32(mail.ReceiveStatus),
+			CreateTime:    mail.CreateTime.Time.GoString(),
+		})
 	}
 
 	if err = rows.Err(); err != nil {
 		return nil, fmt.Errorf("rows error: %v", err)
 	}
 
-	return mails, nil
+	return mailList, nil
+}
+
+// DeleteMail 删除邮件
+// 参数:
+// - mailID: 要删除的邮件ID
+// - userID: 执行删除操作的用户ID(用于验证个人邮件所有权)
+// 返回:
+// - 删除的行数
+// - 错误信息
+func DeleteMail(mailID int, userID string) (int64, error) {
+	// 首先查询邮件信息以确定类型和所有权
+	var mail Mail
+	query := "SELECT mail_type, user_id FROM mail WHERE id = ?"
+	err := mysqlmgr.QueryRow(query, mailID).Scan(&mail.MailType, &mail.UserID)
+	if err != nil {
+		if err == sql.ErrNoRows {
+			return 0, errors.New("mail not found")
+		}
+		return 0, fmt.Errorf("failed to query mail info: %v", err)
+	}
+
+	// 检查是否为系统邮件
+	if mail.MailType == 1 {
+		return 0, errors.New("system mail cannot be deleted")
+	}
+
+	// 检查个人邮件所有权
+	if mail.MailType == 2 {
+		// 验证userID是否匹配
+		if !mail.UserID.Valid || mail.UserID.String != userID {
+			return 0, errors.New("you can only delete your own mail")
+		}
+	}
+
+	// 执行删除操作
+	deleteQuery := "DELETE FROM mail WHERE id = ?"
+	if mail.MailType == 2 {
+		// 个人邮件需要验证用户ID
+		deleteQuery += " AND user_id = ?"
+		result, err := mysqlmgr.Delete(deleteQuery, mailID, userID)
+		if err != nil {
+			return 0, fmt.Errorf("failed to delete mail: %v", err)
+		}
+		return result, err
+	}
+
+	// 理论上不会执行到这里,因为前面已经处理了所有情况
+	return 0, errors.New("invalid mail type")
 }

+ 41 - 1
src/server/hall/mail/mail.go

@@ -1,9 +1,49 @@
 package mail
 
+import (
+	maildb "server/datacenter/mail_db"
+	"server/msg"
+
+	"github.com/name5566/leaf/gate"
+)
+
 func GetMail(args []interface{}) {
+	m := args[0].(*msg.ReqMail)
+	a := args[1].(gate.Agent)
+	FromUserInfo := a.UserData().(*msg.UserInfo)
+	var mailList []*msg.MailInfo
+	var err error
+	if m.MailType == 1 { //系统
+		mailList, err = maildb.GetMailsByType(int(m.MailType), "")
+	} else if m.MailType == 1 { //个人
+		mailList, err = maildb.GetMailsByType(int(m.MailType), FromUserInfo.UserId)
+	}
 
+	if err != nil {
+		a.WriteMsg(&msg.ResMail{
+			Success: false,
+			ErrMsg: &msg.MsgError{
+				ErrorCode: 101,
+				ErrorMsg:  err.Error(),
+			},
+		})
+	} else {
+		a.WriteMsg(&msg.ResMail{
+			Success: true,
+			List:    mailList,
+		})
+	}
 }
 
 func OptMail(args []interface{}) {
-
+	m := args[0].(*msg.OptMail)
+	a := args[1].(gate.Agent)
+	FromUserInfo := a.UserData().(*msg.UserInfo)
+	if m.Opt == msg.OptMailType_CHECK { //查看
+		maildb.UpdateCheckStatus(int(m.MailId), 1)
+	} else if m.Opt == msg.OptMailType_DELETE { //删除
+		maildb.DeleteMail(int(m.MailId), FromUserInfo.UserId)
+	} else if m.Opt == msg.OptMailType_RECEIVE { //领取
+		maildb.UpdateReceiveStatus(int(m.MailId), 1)
+	}
 }

+ 182 - 54
src/server/msg/mail.pb.go

@@ -21,6 +21,135 @@ const (
 	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
 )
 
+type OptMailType int32
+
+const (
+	OptMailType_ROLE_TYPE_UNKNOWN OptMailType = 0
+	OptMailType_CHECK             OptMailType = 1 // 查看
+	OptMailType_RECEIVE           OptMailType = 2 //领取
+	OptMailType_DELETE            OptMailType = 3 //删除
+)
+
+// Enum value maps for OptMailType.
+var (
+	OptMailType_name = map[int32]string{
+		0: "ROLE_TYPE_UNKNOWN",
+		1: "CHECK",
+		2: "RECEIVE",
+		3: "DELETE",
+	}
+	OptMailType_value = map[string]int32{
+		"ROLE_TYPE_UNKNOWN": 0,
+		"CHECK":             1,
+		"RECEIVE":           2,
+		"DELETE":            3,
+	}
+)
+
+func (x OptMailType) Enum() *OptMailType {
+	p := new(OptMailType)
+	*p = x
+	return p
+}
+
+func (x OptMailType) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (OptMailType) Descriptor() protoreflect.EnumDescriptor {
+	return file_mail_proto_enumTypes[0].Descriptor()
+}
+
+func (OptMailType) Type() protoreflect.EnumType {
+	return &file_mail_proto_enumTypes[0]
+}
+
+func (x OptMailType) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use OptMailType.Descriptor instead.
+func (OptMailType) EnumDescriptor() ([]byte, []int) {
+	return file_mail_proto_rawDescGZIP(), []int{0}
+}
+
+// 邮箱信息
+type MailInfo struct {
+	state         protoimpl.MessageState `protogen:"open.v1"`
+	MailJsonInfo  string                 `protobuf:"bytes,1,opt,name=mail_json_info,json=mailJsonInfo,proto3" json:"mail_json_info,omitempty"`
+	MailType      int32                  `protobuf:"varint,2,opt,name=mail_type,json=mailType,proto3" json:"mail_type,omitempty"`
+	CheckStatus   int32                  `protobuf:"varint,3,opt,name=check_status,json=checkStatus,proto3" json:"check_status,omitempty"`
+	ReceiveStatus int32                  `protobuf:"varint,4,opt,name=receive_status,json=receiveStatus,proto3" json:"receive_status,omitempty"`
+	CreateTime    string                 `protobuf:"bytes,5,opt,name=create_time,json=createTime,proto3" json:"create_time,omitempty"`
+	unknownFields protoimpl.UnknownFields
+	sizeCache     protoimpl.SizeCache
+}
+
+func (x *MailInfo) Reset() {
+	*x = MailInfo{}
+	mi := &file_mail_proto_msgTypes[0]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *MailInfo) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MailInfo) ProtoMessage() {}
+
+func (x *MailInfo) ProtoReflect() protoreflect.Message {
+	mi := &file_mail_proto_msgTypes[0]
+	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 MailInfo.ProtoReflect.Descriptor instead.
+func (*MailInfo) Descriptor() ([]byte, []int) {
+	return file_mail_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *MailInfo) GetMailJsonInfo() string {
+	if x != nil {
+		return x.MailJsonInfo
+	}
+	return ""
+}
+
+func (x *MailInfo) GetMailType() int32 {
+	if x != nil {
+		return x.MailType
+	}
+	return 0
+}
+
+func (x *MailInfo) GetCheckStatus() int32 {
+	if x != nil {
+		return x.CheckStatus
+	}
+	return 0
+}
+
+func (x *MailInfo) GetReceiveStatus() int32 {
+	if x != nil {
+		return x.ReceiveStatus
+	}
+	return 0
+}
+
+func (x *MailInfo) GetCreateTime() string {
+	if x != nil {
+		return x.CreateTime
+	}
+	return ""
+}
+
 // 请求获取邮箱
 type ReqMail struct {
 	state         protoimpl.MessageState `protogen:"open.v1"`
@@ -32,7 +161,7 @@ type ReqMail struct {
 
 func (x *ReqMail) Reset() {
 	*x = ReqMail{}
-	mi := &file_mail_proto_msgTypes[0]
+	mi := &file_mail_proto_msgTypes[1]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -44,7 +173,7 @@ func (x *ReqMail) String() string {
 func (*ReqMail) ProtoMessage() {}
 
 func (x *ReqMail) ProtoReflect() protoreflect.Message {
-	mi := &file_mail_proto_msgTypes[0]
+	mi := &file_mail_proto_msgTypes[1]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -57,7 +186,7 @@ func (x *ReqMail) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ReqMail.ProtoReflect.Descriptor instead.
 func (*ReqMail) Descriptor() ([]byte, []int) {
-	return file_mail_proto_rawDescGZIP(), []int{0}
+	return file_mail_proto_rawDescGZIP(), []int{1}
 }
 
 func (x *ReqMail) GetUserid() string {
@@ -79,14 +208,14 @@ type ResMail struct {
 	state         protoimpl.MessageState `protogen:"open.v1"`
 	Success       bool                   `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"`
 	ErrMsg        *MsgError              `protobuf:"bytes,2,opt,name=err_msg,json=errMsg,proto3" json:"err_msg,omitempty"`
-	List          []*ChatMessage         `protobuf:"bytes,3,rep,name=list,proto3" json:"list,omitempty"`
+	List          []*MailInfo            `protobuf:"bytes,3,rep,name=list,proto3" json:"list,omitempty"`
 	unknownFields protoimpl.UnknownFields
 	sizeCache     protoimpl.SizeCache
 }
 
 func (x *ResMail) Reset() {
 	*x = ResMail{}
-	mi := &file_mail_proto_msgTypes[1]
+	mi := &file_mail_proto_msgTypes[2]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -98,7 +227,7 @@ func (x *ResMail) String() string {
 func (*ResMail) ProtoMessage() {}
 
 func (x *ResMail) ProtoReflect() protoreflect.Message {
-	mi := &file_mail_proto_msgTypes[1]
+	mi := &file_mail_proto_msgTypes[2]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -111,7 +240,7 @@ func (x *ResMail) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ResMail.ProtoReflect.Descriptor instead.
 func (*ResMail) Descriptor() ([]byte, []int) {
-	return file_mail_proto_rawDescGZIP(), []int{1}
+	return file_mail_proto_rawDescGZIP(), []int{2}
 }
 
 func (x *ResMail) GetSuccess() bool {
@@ -128,7 +257,7 @@ func (x *ResMail) GetErrMsg() *MsgError {
 	return nil
 }
 
-func (x *ResMail) GetList() []*ChatMessage {
+func (x *ResMail) GetList() []*MailInfo {
 	if x != nil {
 		return x.List
 	}
@@ -139,16 +268,14 @@ func (x *ResMail) GetList() []*ChatMessage {
 type OptMail struct {
 	state         protoimpl.MessageState `protogen:"open.v1"`
 	MailId        int32                  `protobuf:"varint,1,opt,name=mail_id,json=mailId,proto3" json:"mail_id,omitempty"`
-	CheckStatus   int32                  `protobuf:"varint,2,opt,name=check_status,json=checkStatus,proto3" json:"check_status,omitempty"`
-	ReceiveStatus int32                  `protobuf:"varint,3,opt,name=receive_status,json=receiveStatus,proto3" json:"receive_status,omitempty"`
-	IsDelete      bool                   `protobuf:"varint,4,opt,name=is_delete,json=isDelete,proto3" json:"is_delete,omitempty"`
+	Opt           OptMailType            `protobuf:"varint,2,opt,name=opt,proto3,enum=OptMailType" json:"opt,omitempty"`
 	unknownFields protoimpl.UnknownFields
 	sizeCache     protoimpl.SizeCache
 }
 
 func (x *OptMail) Reset() {
 	*x = OptMail{}
-	mi := &file_mail_proto_msgTypes[2]
+	mi := &file_mail_proto_msgTypes[3]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -160,7 +287,7 @@ func (x *OptMail) String() string {
 func (*OptMail) ProtoMessage() {}
 
 func (x *OptMail) ProtoReflect() protoreflect.Message {
-	mi := &file_mail_proto_msgTypes[2]
+	mi := &file_mail_proto_msgTypes[3]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -173,7 +300,7 @@ func (x *OptMail) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use OptMail.ProtoReflect.Descriptor instead.
 func (*OptMail) Descriptor() ([]byte, []int) {
-	return file_mail_proto_rawDescGZIP(), []int{2}
+	return file_mail_proto_rawDescGZIP(), []int{3}
 }
 
 func (x *OptMail) GetMailId() int32 {
@@ -183,25 +310,11 @@ func (x *OptMail) GetMailId() int32 {
 	return 0
 }
 
-func (x *OptMail) GetCheckStatus() int32 {
+func (x *OptMail) GetOpt() OptMailType {
 	if x != nil {
-		return x.CheckStatus
+		return x.Opt
 	}
-	return 0
-}
-
-func (x *OptMail) GetReceiveStatus() int32 {
-	if x != nil {
-		return x.ReceiveStatus
-	}
-	return 0
-}
-
-func (x *OptMail) GetIsDelete() bool {
-	if x != nil {
-		return x.IsDelete
-	}
-	return false
+	return OptMailType_ROLE_TYPE_UNKNOWN
 }
 
 var File_mail_proto protoreflect.FileDescriptor
@@ -209,19 +322,30 @@ var File_mail_proto protoreflect.FileDescriptor
 const file_mail_proto_rawDesc = "" +
 	"\n" +
 	"\n" +
-	"mail.proto\x1a\fcommon.proto\">\n" +
+	"mail.proto\x1a\fcommon.proto\"\xb8\x01\n" +
+	"\bMailInfo\x12$\n" +
+	"\x0email_json_info\x18\x01 \x01(\tR\fmailJsonInfo\x12\x1b\n" +
+	"\tmail_type\x18\x02 \x01(\x05R\bmailType\x12!\n" +
+	"\fcheck_status\x18\x03 \x01(\x05R\vcheckStatus\x12%\n" +
+	"\x0ereceive_status\x18\x04 \x01(\x05R\rreceiveStatus\x12\x1f\n" +
+	"\vcreate_time\x18\x05 \x01(\tR\n" +
+	"createTime\">\n" +
 	"\aReqMail\x12\x16\n" +
 	"\x06userid\x18\x01 \x01(\tR\x06userid\x12\x1b\n" +
-	"\tmail_type\x18\x02 \x01(\x05R\bmailType\"\x81\x01\n" +
+	"\tmail_type\x18\x02 \x01(\x05R\bmailType\"r\n" +
 	"\aResMail\x12\x18\n" +
 	"\asuccess\x18\x01 \x01(\bR\asuccess\x12.\n" +
-	"\aerr_msg\x18\x02 \x01(\v2\x15.common_pack.MsgErrorR\x06errMsg\x12,\n" +
-	"\x04list\x18\x03 \x03(\v2\x18.common_pack.ChatMessageR\x04list\"\x89\x01\n" +
+	"\aerr_msg\x18\x02 \x01(\v2\x15.common_pack.MsgErrorR\x06errMsg\x12\x1d\n" +
+	"\x04list\x18\x03 \x03(\v2\t.MailInfoR\x04list\"B\n" +
 	"\aOptMail\x12\x17\n" +
-	"\amail_id\x18\x01 \x01(\x05R\x06mailId\x12!\n" +
-	"\fcheck_status\x18\x02 \x01(\x05R\vcheckStatus\x12%\n" +
-	"\x0ereceive_status\x18\x03 \x01(\x05R\rreceiveStatus\x12\x1b\n" +
-	"\tis_delete\x18\x04 \x01(\bR\bisDeleteB\aZ\x05./msgb\x06proto3"
+	"\amail_id\x18\x01 \x01(\x05R\x06mailId\x12\x1e\n" +
+	"\x03opt\x18\x02 \x01(\x0e2\f.OptMailTypeR\x03opt*H\n" +
+	"\vOptMailType\x12\x15\n" +
+	"\x11ROLE_TYPE_UNKNOWN\x10\x00\x12\t\n" +
+	"\x05CHECK\x10\x01\x12\v\n" +
+	"\aRECEIVE\x10\x02\x12\n" +
+	"\n" +
+	"\x06DELETE\x10\x03B\aZ\x05./msgb\x06proto3"
 
 var (
 	file_mail_proto_rawDescOnce sync.Once
@@ -235,22 +359,25 @@ func file_mail_proto_rawDescGZIP() []byte {
 	return file_mail_proto_rawDescData
 }
 
-var file_mail_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
+var file_mail_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
+var file_mail_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
 var file_mail_proto_goTypes = []any{
-	(*ReqMail)(nil),     // 0: ReqMail
-	(*ResMail)(nil),     // 1: ResMail
-	(*OptMail)(nil),     // 2: OptMail
-	(*MsgError)(nil),    // 3: common_pack.MsgError
-	(*ChatMessage)(nil), // 4: common_pack.ChatMessage
+	(OptMailType)(0), // 0: OptMailType
+	(*MailInfo)(nil), // 1: MailInfo
+	(*ReqMail)(nil),  // 2: ReqMail
+	(*ResMail)(nil),  // 3: ResMail
+	(*OptMail)(nil),  // 4: OptMail
+	(*MsgError)(nil), // 5: common_pack.MsgError
 }
 var file_mail_proto_depIdxs = []int32{
-	3, // 0: ResMail.err_msg:type_name -> common_pack.MsgError
-	4, // 1: ResMail.list:type_name -> common_pack.ChatMessage
-	2, // [2:2] is the sub-list for method output_type
-	2, // [2:2] is the sub-list for method input_type
-	2, // [2:2] is the sub-list for extension type_name
-	2, // [2:2] is the sub-list for extension extendee
-	0, // [0:2] is the sub-list for field type_name
+	5, // 0: ResMail.err_msg:type_name -> common_pack.MsgError
+	1, // 1: ResMail.list:type_name -> MailInfo
+	0, // 2: OptMail.opt:type_name -> OptMailType
+	3, // [3:3] is the sub-list for method output_type
+	3, // [3:3] is the sub-list for method input_type
+	3, // [3:3] is the sub-list for extension type_name
+	3, // [3:3] is the sub-list for extension extendee
+	0, // [0:3] is the sub-list for field type_name
 }
 
 func init() { file_mail_proto_init() }
@@ -264,13 +391,14 @@ func file_mail_proto_init() {
 		File: protoimpl.DescBuilder{
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: unsafe.Slice(unsafe.StringData(file_mail_proto_rawDesc), len(file_mail_proto_rawDesc)),
-			NumEnums:      0,
-			NumMessages:   3,
+			NumEnums:      1,
+			NumMessages:   4,
 			NumExtensions: 0,
 			NumServices:   0,
 		},
 		GoTypes:           file_mail_proto_goTypes,
 		DependencyIndexes: file_mail_proto_depIdxs,
+		EnumInfos:         file_mail_proto_enumTypes,
 		MessageInfos:      file_mail_proto_msgTypes,
 	}.Build()
 	File_mail_proto = out.File