正在显示
29 个修改的文件
包含
1118 行增加
和
0 行删除
| @@ -43,6 +43,7 @@ func (customerValueService *CustomerValueService) CreateCustomerValue(createCust | @@ -43,6 +43,7 @@ func (customerValueService *CustomerValueService) CreateCustomerValue(createCust | ||
| 43 | } | 43 | } |
| 44 | if count, _, err := customerValueRepository.Find(map[string]interface{}{ | 44 | if count, _, err := customerValueRepository.Find(map[string]interface{}{ |
| 45 | "customerValueName": createCustomerValueCommand.CustomerValueName, | 45 | "customerValueName": createCustomerValueCommand.CustomerValueName, |
| 46 | + "companyId": createCustomerValueCommand.CompanyId, | ||
| 46 | }); err != nil { | 47 | }); err != nil { |
| 47 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | 48 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) |
| 48 | } else { | 49 | } else { |
| @@ -129,6 +130,7 @@ func (customerValueService *CustomerValueService) UpdateCustomerValue(updateCust | @@ -129,6 +130,7 @@ func (customerValueService *CustomerValueService) UpdateCustomerValue(updateCust | ||
| 129 | } | 130 | } |
| 130 | if count, customerValues, err := customerValueRepository.Find(map[string]interface{}{ | 131 | if count, customerValues, err := customerValueRepository.Find(map[string]interface{}{ |
| 131 | "customerValueName": updateCustomerValueCommand.CustomerValueName, | 132 | "customerValueName": updateCustomerValueCommand.CustomerValueName, |
| 133 | + "companyId": customerValue.CompanyId, | ||
| 132 | }); err != nil { | 134 | }); err != nil { |
| 133 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | 135 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) |
| 134 | } else { | 136 | } else { |
| @@ -20,3 +20,11 @@ func CreateEmployeeDao(options map[string]interface{}) (*dao.EmployeeDao, error) | @@ -20,3 +20,11 @@ func CreateEmployeeDao(options map[string]interface{}) (*dao.EmployeeDao, error) | ||
| 20 | } | 20 | } |
| 21 | return dao.NewEmployeeDao(transactionContext) | 21 | return dao.NewEmployeeDao(transactionContext) |
| 22 | } | 22 | } |
| 23 | + | ||
| 24 | +func CreateNotificationDao(options map[string]interface{}) (*dao.NotificationDao, error) { | ||
| 25 | + var transactionContext *pg.TransactionContext | ||
| 26 | + if value, ok := options["transactionContext"]; ok { | ||
| 27 | + transactionContext = value.(*pg.TransactionContext) | ||
| 28 | + } | ||
| 29 | + return dao.NewNotificationDao(transactionContext) | ||
| 30 | +} |
| @@ -6,6 +6,22 @@ import ( | @@ -6,6 +6,22 @@ import ( | ||
| 6 | domainService "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/infrastructure/domain_service" | 6 | domainService "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/infrastructure/domain_service" |
| 7 | ) | 7 | ) |
| 8 | 8 | ||
| 9 | +func CreateReadSentNotificationService(options map[string]interface{}) (service.ReadSentNotificationService, error) { | ||
| 10 | + var transactionContext *pgTransaction.TransactionContext | ||
| 11 | + if value, ok := options["transactionContext"]; ok { | ||
| 12 | + transactionContext = value.(*pgTransaction.TransactionContext) | ||
| 13 | + } | ||
| 14 | + return domainService.NewReadSentNotificationService(transactionContext) | ||
| 15 | +} | ||
| 16 | + | ||
| 17 | +func CreateReadAllUnReadSentNotificationService(options map[string]interface{}) (service.ReadAllUnReadSentNotificationService, error) { | ||
| 18 | + var transactionContext *pgTransaction.TransactionContext | ||
| 19 | + if value, ok := options["transactionContext"]; ok { | ||
| 20 | + transactionContext = value.(*pgTransaction.TransactionContext) | ||
| 21 | + } | ||
| 22 | + return domainService.NewReadAllUnReadSentNotificationService(transactionContext) | ||
| 23 | +} | ||
| 24 | + | ||
| 9 | func CreateOperationSuMoneyService(options map[string]interface{}) (service.OperationSuMoneyService, error) { | 25 | func CreateOperationSuMoneyService(options map[string]interface{}) (service.OperationSuMoneyService, error) { |
| 10 | var transactionContext *pgTransaction.TransactionContext | 26 | var transactionContext *pgTransaction.TransactionContext |
| 11 | if value, ok := options["transactionContext"]; ok { | 27 | if value, ok := options["transactionContext"]; ok { |
| @@ -69,3 +69,19 @@ func CreateRejectTaskRecordRepository(options map[string]interface{}) (domain.Re | @@ -69,3 +69,19 @@ func CreateRejectTaskRecordRepository(options map[string]interface{}) (domain.Re | ||
| 69 | } | 69 | } |
| 70 | return repository.NewRejectTaskRecordRepository(transactionContext) | 70 | return repository.NewRejectTaskRecordRepository(transactionContext) |
| 71 | } | 71 | } |
| 72 | + | ||
| 73 | +func CreateNotificationRepository(options map[string]interface{}) (domain.NotificationRepository, error) { | ||
| 74 | + var transactionContext *pg.TransactionContext | ||
| 75 | + if value, ok := options["transactionContext"]; ok { | ||
| 76 | + transactionContext = value.(*pg.TransactionContext) | ||
| 77 | + } | ||
| 78 | + return repository.NewNotificationRepository(transactionContext) | ||
| 79 | +} | ||
| 80 | + | ||
| 81 | +func CreateSentNotificationRepository(options map[string]interface{}) (domain.SentNotificationRepository, error) { | ||
| 82 | + var transactionContext *pg.TransactionContext | ||
| 83 | + if value, ok := options["transactionContext"]; ok { | ||
| 84 | + transactionContext = value.(*pg.TransactionContext) | ||
| 85 | + } | ||
| 86 | + return repository.NewSentNotificationRepository(transactionContext) | ||
| 87 | +} |
| 1 | +package command | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + | ||
| 6 | + "github.com/astaxie/beego/validation" | ||
| 7 | +) | ||
| 8 | + | ||
| 9 | +type ReadAllUnReadSentNotificationCommand struct { | ||
| 10 | + // 通知接收者Uid | ||
| 11 | + ReceiverId int64 `json:"receiverId" valid:"Required"` | ||
| 12 | +} | ||
| 13 | + | ||
| 14 | +func (readAllUnReadSentNotificationCommand *ReadAllUnReadSentNotificationCommand) ValidateCommand() error { | ||
| 15 | + valid := validation.Validation{} | ||
| 16 | + b, err := valid.Valid(readAllUnReadSentNotificationCommand) | ||
| 17 | + if err != nil { | ||
| 18 | + return err | ||
| 19 | + } | ||
| 20 | + if !b { | ||
| 21 | + for _, validErr := range valid.Errors { | ||
| 22 | + return fmt.Errorf("%s %s", validErr.Key, validErr.Message) | ||
| 23 | + } | ||
| 24 | + } | ||
| 25 | + return nil | ||
| 26 | +} |
| 1 | +package command | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + | ||
| 6 | + "github.com/astaxie/beego/validation" | ||
| 7 | +) | ||
| 8 | + | ||
| 9 | +type ReadSentNotificationCommand struct { | ||
| 10 | + // 发送出的通知ID | ||
| 11 | + SentNotificationId int64 `json:"sentNotificationId" valid:"Required"` | ||
| 12 | +} | ||
| 13 | + | ||
| 14 | +func (readSentNotificationCommand *ReadSentNotificationCommand) ValidateCommand() error { | ||
| 15 | + valid := validation.Validation{} | ||
| 16 | + b, err := valid.Valid(readSentNotificationCommand) | ||
| 17 | + if err != nil { | ||
| 18 | + return err | ||
| 19 | + } | ||
| 20 | + if !b { | ||
| 21 | + for _, validErr := range valid.Errors { | ||
| 22 | + return fmt.Errorf("%s %s", validErr.Key, validErr.Message) | ||
| 23 | + } | ||
| 24 | + } | ||
| 25 | + return nil | ||
| 26 | +} |
| 1 | +package query | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + | ||
| 6 | + "github.com/astaxie/beego/validation" | ||
| 7 | +) | ||
| 8 | + | ||
| 9 | +type ListSentNotificationQuery struct { | ||
| 10 | + // 通知接收者Uid | ||
| 11 | + ReceiverId int64 `json:"receiverId" valid:"Required"` | ||
| 12 | + // 通知类型 | ||
| 13 | + NotificationType int `json:"notificationType,omitempty"` | ||
| 14 | + // 查询偏离量 | ||
| 15 | + Offset int `json:"offset,omitempty"` | ||
| 16 | + // 查询限制 | ||
| 17 | + Limit int `json:"limit,omitempty"` | ||
| 18 | +} | ||
| 19 | + | ||
| 20 | +func (listSentNotificationQuery *ListSentNotificationQuery) ValidateQuery() error { | ||
| 21 | + valid := validation.Validation{} | ||
| 22 | + b, err := valid.Valid(listSentNotificationQuery) | ||
| 23 | + if err != nil { | ||
| 24 | + return err | ||
| 25 | + } | ||
| 26 | + if !b { | ||
| 27 | + for _, validErr := range valid.Errors { | ||
| 28 | + return fmt.Errorf("%s %s", validErr.Key, validErr.Message) | ||
| 29 | + } | ||
| 30 | + } | ||
| 31 | + return nil | ||
| 32 | +} |
| 1 | +package service | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "github.com/linmadan/egglib-go/core/application" | ||
| 5 | + "github.com/linmadan/egglib-go/utils/tool_funs" | ||
| 6 | + "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/application/factory" | ||
| 7 | + "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/application/notification/command" | ||
| 8 | + "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/application/notification/query" | ||
| 9 | + "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/domain" | ||
| 10 | + "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/domain/service" | ||
| 11 | +) | ||
| 12 | + | ||
| 13 | +// 通知服务 | ||
| 14 | +type NotificationService struct { | ||
| 15 | +} | ||
| 16 | + | ||
| 17 | +// 读取发送出的通知 | ||
| 18 | +func (notificationService *NotificationService) ReadSentNotification(readSentNotificationCommand *command.ReadSentNotificationCommand) (interface{}, error) { | ||
| 19 | + if err := readSentNotificationCommand.ValidateCommand(); err != nil { | ||
| 20 | + return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | ||
| 21 | + } | ||
| 22 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
| 23 | + if err != nil { | ||
| 24 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 25 | + } | ||
| 26 | + if err := transactionContext.StartTransaction(); err != nil { | ||
| 27 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 28 | + } | ||
| 29 | + defer func() { | ||
| 30 | + transactionContext.RollbackTransaction() | ||
| 31 | + }() | ||
| 32 | + var readSentNotificationService service.ReadSentNotificationService | ||
| 33 | + if value, err := factory.CreateReadSentNotificationService(map[string]interface{}{ | ||
| 34 | + "transactionContext": transactionContext, | ||
| 35 | + }); err != nil { | ||
| 36 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
| 37 | + } else { | ||
| 38 | + readSentNotificationService = value | ||
| 39 | + } | ||
| 40 | + if sentNotification, err := readSentNotificationService.Read(readSentNotificationCommand.SentNotificationId); err != nil { | ||
| 41 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
| 42 | + } else { | ||
| 43 | + if err := transactionContext.CommitTransaction(); err != nil { | ||
| 44 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 45 | + } | ||
| 46 | + return sentNotification, nil | ||
| 47 | + } | ||
| 48 | +} | ||
| 49 | + | ||
| 50 | +// 读取全部未读取的发送出的通知 | ||
| 51 | +func (notificationService *NotificationService) ReadAllUnReadSentNotification(readAllUnReadSentNotificationCommand *command.ReadAllUnReadSentNotificationCommand) (interface{}, error) { | ||
| 52 | + if err := readAllUnReadSentNotificationCommand.ValidateCommand(); err != nil { | ||
| 53 | + return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | ||
| 54 | + } | ||
| 55 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
| 56 | + if err != nil { | ||
| 57 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 58 | + } | ||
| 59 | + if err := transactionContext.StartTransaction(); err != nil { | ||
| 60 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 61 | + } | ||
| 62 | + defer func() { | ||
| 63 | + transactionContext.RollbackTransaction() | ||
| 64 | + }() | ||
| 65 | + var readAllUnReadSentNotificationService service.ReadAllUnReadSentNotificationService | ||
| 66 | + if value, err := factory.CreateReadAllUnReadSentNotificationService(map[string]interface{}{ | ||
| 67 | + "transactionContext": transactionContext, | ||
| 68 | + }); err != nil { | ||
| 69 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
| 70 | + } else { | ||
| 71 | + readAllUnReadSentNotificationService = value | ||
| 72 | + } | ||
| 73 | + if readCount, err := readAllUnReadSentNotificationService.ReadAll(readAllUnReadSentNotificationCommand.ReceiverId); err != nil { | ||
| 74 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
| 75 | + } else { | ||
| 76 | + if err := transactionContext.CommitTransaction(); err != nil { | ||
| 77 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 78 | + } | ||
| 79 | + return readCount, nil | ||
| 80 | + } | ||
| 81 | +} | ||
| 82 | + | ||
| 83 | +// 返回发送出的通知列表 | ||
| 84 | +func (notificationService *NotificationService) ListSentNotification(listSentNotificationQuery *query.ListSentNotificationQuery) (interface{}, error) { | ||
| 85 | + if err := listSentNotificationQuery.ValidateQuery(); err != nil { | ||
| 86 | + return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | ||
| 87 | + } | ||
| 88 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
| 89 | + if err != nil { | ||
| 90 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 91 | + } | ||
| 92 | + if err := transactionContext.StartTransaction(); err != nil { | ||
| 93 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 94 | + } | ||
| 95 | + defer func() { | ||
| 96 | + transactionContext.RollbackTransaction() | ||
| 97 | + }() | ||
| 98 | + var sentNotificationRepository domain.SentNotificationRepository | ||
| 99 | + if value, err := factory.CreateSentNotificationRepository(map[string]interface{}{ | ||
| 100 | + "transactionContext": transactionContext, | ||
| 101 | + }); err != nil { | ||
| 102 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
| 103 | + } else { | ||
| 104 | + sentNotificationRepository = value | ||
| 105 | + } | ||
| 106 | + if count, sentNotifications, err := sentNotificationRepository.Find(tool_funs.SimpleStructToMap(listSentNotificationQuery)); err != nil { | ||
| 107 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
| 108 | + } else { | ||
| 109 | + if err := transactionContext.CommitTransaction(); err != nil { | ||
| 110 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 111 | + } | ||
| 112 | + return map[string]interface{}{ | ||
| 113 | + "count": count, | ||
| 114 | + "sentNotifications": sentNotifications, | ||
| 115 | + }, nil | ||
| 116 | + } | ||
| 117 | +} | ||
| 118 | + | ||
| 119 | +func NewNotificationService(options map[string]interface{}) *NotificationService { | ||
| 120 | + newNotificationService := &NotificationService{} | ||
| 121 | + return newNotificationService | ||
| 122 | +} |
| @@ -43,6 +43,7 @@ func (projectBelongService *ProjectBelongService) CreateProjectBelong(createProj | @@ -43,6 +43,7 @@ func (projectBelongService *ProjectBelongService) CreateProjectBelong(createProj | ||
| 43 | } | 43 | } |
| 44 | if count, _, err := projectBelongRepository.Find(map[string]interface{}{ | 44 | if count, _, err := projectBelongRepository.Find(map[string]interface{}{ |
| 45 | "projectBelongName": createProjectBelongCommand.ProjectBelongName, | 45 | "projectBelongName": createProjectBelongCommand.ProjectBelongName, |
| 46 | + "companyId": createProjectBelongCommand.CompanyId, | ||
| 46 | }); err != nil { | 47 | }); err != nil { |
| 47 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | 48 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) |
| 48 | } else { | 49 | } else { |
| @@ -129,6 +130,7 @@ func (projectBelongService *ProjectBelongService) UpdateProjectBelong(updateProj | @@ -129,6 +130,7 @@ func (projectBelongService *ProjectBelongService) UpdateProjectBelong(updateProj | ||
| 129 | } | 130 | } |
| 130 | if count, projectBelongs, err := projectBelongRepository.Find(map[string]interface{}{ | 131 | if count, projectBelongs, err := projectBelongRepository.Find(map[string]interface{}{ |
| 131 | "projectBelongName": updateProjectBelongCommand.ProjectBelongName, | 132 | "projectBelongName": updateProjectBelongCommand.ProjectBelongName, |
| 133 | + "companyId": projectBelong.CompanyId, | ||
| 132 | }); err != nil { | 134 | }); err != nil { |
| 133 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | 135 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) |
| 134 | } else { | 136 | } else { |
| @@ -43,6 +43,7 @@ func (taskNatureService *TaskNatureService) CreateTaskNature(createTaskNatureCom | @@ -43,6 +43,7 @@ func (taskNatureService *TaskNatureService) CreateTaskNature(createTaskNatureCom | ||
| 43 | } | 43 | } |
| 44 | if count, _, err := taskNatureRepository.Find(map[string]interface{}{ | 44 | if count, _, err := taskNatureRepository.Find(map[string]interface{}{ |
| 45 | "taskNatureName": createTaskNatureCommand.TaskNatureName, | 45 | "taskNatureName": createTaskNatureCommand.TaskNatureName, |
| 46 | + "companyId": createTaskNatureCommand.CompanyId, | ||
| 46 | }); err != nil { | 47 | }); err != nil { |
| 47 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | 48 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) |
| 48 | } else { | 49 | } else { |
| @@ -129,6 +130,7 @@ func (taskNatureService *TaskNatureService) UpdateTaskNature(updateTaskNatureCom | @@ -129,6 +130,7 @@ func (taskNatureService *TaskNatureService) UpdateTaskNature(updateTaskNatureCom | ||
| 129 | } | 130 | } |
| 130 | if count, taskNatures, err := taskNatureRepository.Find(map[string]interface{}{ | 131 | if count, taskNatures, err := taskNatureRepository.Find(map[string]interface{}{ |
| 131 | "taskNatureName": updateTaskNatureCommand.TaskNatureName, | 132 | "taskNatureName": updateTaskNatureCommand.TaskNatureName, |
| 133 | + "companyId": taskNature.CompanyId, | ||
| 132 | }); err != nil { | 134 | }); err != nil { |
| 133 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | 135 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) |
| 134 | } else { | 136 | } else { |
pkg/domain/notification.go
0 → 100644
| 1 | +package domain | ||
| 2 | + | ||
| 3 | +import "time" | ||
| 4 | + | ||
| 5 | +const ( | ||
| 6 | + NOTIFICATION_TYPE_SYSTEM = iota + 1 //系统通知 | ||
| 7 | + NOTIFICATION_TYPE_INTERACTION //互动通知 | ||
| 8 | +) | ||
| 9 | + | ||
| 10 | +const ( | ||
| 11 | + EXTERNAL_RESOURCE_TYPE_TASK = iota + 1 //任务 | ||
| 12 | + EXTERNAL_RESOURCE_TYPE_REJECT_TASK_RECORD //驳回任务记录 | ||
| 13 | +) | ||
| 14 | + | ||
| 15 | +// 通知 | ||
| 16 | +type Notification struct { | ||
| 17 | + // 通知ID | ||
| 18 | + NotificationId int64 `json:"notificationId"` | ||
| 19 | + // 通知类型 | ||
| 20 | + NotificationType int `json:"notificationType"` | ||
| 21 | + // 通知标题 | ||
| 22 | + NotificationTitle string `json:"notificationTitle"` | ||
| 23 | + // 通知内容 | ||
| 24 | + NotificationContent string `json:"notificationContent"` | ||
| 25 | + // 通知时间 | ||
| 26 | + NotificationTime time.Time `json:"notificationTime"` | ||
| 27 | + // 外部资源引用类型(1任务2驳回任务记录) | ||
| 28 | + ExternalResourceType int `json:"externalResourceType"` | ||
| 29 | + // 外部资源引用 | ||
| 30 | + ExternalResource int64 `json:"externalResource"` | ||
| 31 | +} | ||
| 32 | + | ||
| 33 | +type NotificationRepository interface { | ||
| 34 | + Save(notification *Notification) (*Notification, error) | ||
| 35 | + Remove(notification *Notification) (*Notification, error) | ||
| 36 | + FindOne(queryOptions map[string]interface{}) (*Notification, error) | ||
| 37 | + Find(queryOptions map[string]interface{}) (int64, []*Notification, error) | ||
| 38 | +} | ||
| 39 | + | ||
| 40 | +func (notification *Notification) Identify() interface{} { | ||
| 41 | + if notification.NotificationId == 0 { | ||
| 42 | + return nil | ||
| 43 | + } | ||
| 44 | + return notification.NotificationId | ||
| 45 | +} |
pkg/domain/sent_notification.go
0 → 100644
| 1 | +package domain | ||
| 2 | + | ||
| 3 | +import "time" | ||
| 4 | + | ||
| 5 | +// 发送出的通知 | ||
| 6 | +type SentNotification struct { | ||
| 7 | + // 发送出的通知ID | ||
| 8 | + SentNotificationId int64 `json:"sentNotificationId"` | ||
| 9 | + // 通知 | ||
| 10 | + Notification *Notification `json:"notification"` | ||
| 11 | + // 通知接收者 | ||
| 12 | + Receiver *EmployeeInfo `json:"receiver"` | ||
| 13 | + // 是否已读 | ||
| 14 | + IsRead bool `json:"isRead"` | ||
| 15 | + // 通知读取时间 | ||
| 16 | + ReadTime time.Time `json:"readTime"` | ||
| 17 | +} | ||
| 18 | + | ||
| 19 | +type SentNotificationRepository interface { | ||
| 20 | + Save(sentNotification *SentNotification) (*SentNotification, error) | ||
| 21 | + Remove(sentNotification *SentNotification) (*SentNotification, error) | ||
| 22 | + FindOne(queryOptions map[string]interface{}) (*SentNotification, error) | ||
| 23 | + Find(queryOptions map[string]interface{}) (int64, []*SentNotification, error) | ||
| 24 | +} | ||
| 25 | + | ||
| 26 | +func (sentNotification *SentNotification) Identify() interface{} { | ||
| 27 | + if sentNotification.SentNotificationId == 0 { | ||
| 28 | + return nil | ||
| 29 | + } | ||
| 30 | + return sentNotification.SentNotificationId | ||
| 31 | +} | ||
| 32 | + | ||
| 33 | +func (sentNotification *SentNotification) Read() error { | ||
| 34 | + sentNotification.IsRead = true | ||
| 35 | + if sentNotification.ReadTime.IsZero() { | ||
| 36 | + sentNotification.ReadTime = time.Now() | ||
| 37 | + } | ||
| 38 | + return nil | ||
| 39 | +} |
pkg/domain/service/read_sent_notification.go
0 → 100644
| 1 | +package service | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + coreDomain "github.com/linmadan/egglib-go/core/domain" | ||
| 5 | + "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/domain" | ||
| 6 | +) | ||
| 7 | + | ||
| 8 | +type ReadSentNotificationService interface { | ||
| 9 | + coreDomain.DomainEventPublisher | ||
| 10 | + Read(sentNotificationId int64) (*domain.SentNotification, error) | ||
| 11 | +} |
| 1 | +package dao | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + "github.com/go-pg/pg" | ||
| 6 | + pgTransaction "github.com/linmadan/egglib-go/transaction/pg" | ||
| 7 | + "time" | ||
| 8 | +) | ||
| 9 | + | ||
| 10 | +type NotificationDao struct { | ||
| 11 | + transactionContext *pgTransaction.TransactionContext | ||
| 12 | +} | ||
| 13 | + | ||
| 14 | +func (dao *NotificationDao) ReadAllUnReadSentNotification(receiverId int64) (int, error) { | ||
| 15 | + tx := dao.transactionContext.PgTx | ||
| 16 | + result, err := tx.Query( | ||
| 17 | + pg.Scan(), | ||
| 18 | + `UPDATE sent_notifications SET is_read=?, read_time=? WHERE receiver @> '{"uid":?}'`, | ||
| 19 | + true, time.Now(), receiverId) | ||
| 20 | + if err != nil { | ||
| 21 | + return 0, err | ||
| 22 | + } else { | ||
| 23 | + return result.RowsAffected(), nil | ||
| 24 | + } | ||
| 25 | +} | ||
| 26 | + | ||
| 27 | +func NewNotificationDao(transactionContext *pgTransaction.TransactionContext) (*NotificationDao, error) { | ||
| 28 | + if transactionContext == nil { | ||
| 29 | + return nil, fmt.Errorf("transactionContext参数不能为nil") | ||
| 30 | + } else { | ||
| 31 | + return &NotificationDao{ | ||
| 32 | + transactionContext: transactionContext, | ||
| 33 | + }, nil | ||
| 34 | + } | ||
| 35 | +} |
| 1 | +package domain_service | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + coreDomain "github.com/linmadan/egglib-go/core/domain" | ||
| 6 | + pgTransaction "github.com/linmadan/egglib-go/transaction/pg" | ||
| 7 | + "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/domain" | ||
| 8 | + "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/infrastructure/dao" | ||
| 9 | + "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/infrastructure/repository" | ||
| 10 | +) | ||
| 11 | + | ||
| 12 | +type ReadAllUnReadSentNotificationService struct { | ||
| 13 | + coreDomain.BaseEventPublisher | ||
| 14 | + transactionContext *pgTransaction.TransactionContext | ||
| 15 | +} | ||
| 16 | + | ||
| 17 | +func (service *ReadAllUnReadSentNotificationService) ReadAll(receiverUid int64) (int, error) { | ||
| 18 | + var employeeRepository domain.EmployeeRepository | ||
| 19 | + var notificationDao *dao.NotificationDao | ||
| 20 | + if repository, err := repository.NewEmployeeRepository(service.transactionContext); err != nil { | ||
| 21 | + return 0, err | ||
| 22 | + } else { | ||
| 23 | + employeeRepository = repository | ||
| 24 | + } | ||
| 25 | + if dao, err := dao.NewNotificationDao(service.transactionContext); err != nil { | ||
| 26 | + return 0, err | ||
| 27 | + } else { | ||
| 28 | + notificationDao = dao | ||
| 29 | + } | ||
| 30 | + receiver, err := employeeRepository.FindOne(map[string]interface{}{ | ||
| 31 | + "uid": receiverUid, | ||
| 32 | + }) | ||
| 33 | + if err != nil { | ||
| 34 | + return 0, err | ||
| 35 | + } | ||
| 36 | + if receiver == nil { | ||
| 37 | + return 0, fmt.Errorf("无效的通知接收者") | ||
| 38 | + } | ||
| 39 | + readCount, err := notificationDao.ReadAllUnReadSentNotification(receiverUid) | ||
| 40 | + if err != nil { | ||
| 41 | + return 0, err | ||
| 42 | + } else { | ||
| 43 | + return readCount, nil | ||
| 44 | + } | ||
| 45 | +} | ||
| 46 | + | ||
| 47 | +func NewReadAllUnReadSentNotificationService(transactionContext *pgTransaction.TransactionContext) (*ReadAllUnReadSentNotificationService, error) { | ||
| 48 | + if transactionContext == nil { | ||
| 49 | + return nil, fmt.Errorf("transactionContext参数不能为nil") | ||
| 50 | + } else { | ||
| 51 | + return &ReadAllUnReadSentNotificationService{ | ||
| 52 | + transactionContext: transactionContext, | ||
| 53 | + }, nil | ||
| 54 | + } | ||
| 55 | +} |
| 1 | +package domain_service | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + coreDomain "github.com/linmadan/egglib-go/core/domain" | ||
| 6 | + pgTransaction "github.com/linmadan/egglib-go/transaction/pg" | ||
| 7 | + "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/domain" | ||
| 8 | + "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/infrastructure/repository" | ||
| 9 | +) | ||
| 10 | + | ||
| 11 | +type ReadSentNotificationService struct { | ||
| 12 | + coreDomain.BaseEventPublisher | ||
| 13 | + transactionContext *pgTransaction.TransactionContext | ||
| 14 | +} | ||
| 15 | + | ||
| 16 | +func (service *ReadSentNotificationService) Read(sentNotificationId int64) (*domain.SentNotification, error) { | ||
| 17 | + var sentNotificationRepository domain.SentNotificationRepository | ||
| 18 | + if repository, err := repository.NewSentNotificationRepository(service.transactionContext); err != nil { | ||
| 19 | + return nil, err | ||
| 20 | + } else { | ||
| 21 | + sentNotificationRepository = repository | ||
| 22 | + } | ||
| 23 | + sentNotification, err := sentNotificationRepository.FindOne(map[string]interface{}{ | ||
| 24 | + "sentNotificationId": sentNotificationId, | ||
| 25 | + }) | ||
| 26 | + if err != nil { | ||
| 27 | + return nil, err | ||
| 28 | + } | ||
| 29 | + if sentNotification == nil { | ||
| 30 | + return nil, fmt.Errorf("无效的任务") | ||
| 31 | + } | ||
| 32 | + if err := sentNotification.Read(); err != nil { | ||
| 33 | + return nil, err | ||
| 34 | + } | ||
| 35 | + if sentNotification, err := sentNotificationRepository.Save(sentNotification); err != nil { | ||
| 36 | + return nil, err | ||
| 37 | + } else { | ||
| 38 | + return sentNotification, nil | ||
| 39 | + } | ||
| 40 | +} | ||
| 41 | + | ||
| 42 | +func NewReadSentNotificationService(transactionContext *pgTransaction.TransactionContext) (*ReadSentNotificationService, error) { | ||
| 43 | + if transactionContext == nil { | ||
| 44 | + return nil, fmt.Errorf("transactionContext参数不能为nil") | ||
| 45 | + } else { | ||
| 46 | + return &ReadSentNotificationService{ | ||
| 47 | + transactionContext: transactionContext, | ||
| 48 | + }, nil | ||
| 49 | + } | ||
| 50 | +} |
| @@ -34,6 +34,8 @@ func init() { | @@ -34,6 +34,8 @@ func init() { | ||
| 34 | (*models.TaskNature)(nil), | 34 | (*models.TaskNature)(nil), |
| 35 | (*models.ProjectBelong)(nil), | 35 | (*models.ProjectBelong)(nil), |
| 36 | (*models.RejectTaskRecord)(nil), | 36 | (*models.RejectTaskRecord)(nil), |
| 37 | + (*models.Notification)(nil), | ||
| 38 | + (*models.SentNotification)(nil), | ||
| 37 | } { | 39 | } { |
| 38 | err := DB.CreateTable(model, &orm.CreateTableOptions{ | 40 | err := DB.CreateTable(model, &orm.CreateTableOptions{ |
| 39 | Temp: false, | 41 | Temp: false, |
pkg/infrastructure/pg/models/notification.go
0 → 100644
| 1 | +package models | ||
| 2 | + | ||
| 3 | +import "time" | ||
| 4 | + | ||
| 5 | +type Notification struct { | ||
| 6 | + TableName string `pg:"notifications,alias:notification"` | ||
| 7 | + // 通知ID | ||
| 8 | + Id int64 | ||
| 9 | + // 通知类型 | ||
| 10 | + NotificationType int | ||
| 11 | + // 通知标题 | ||
| 12 | + NotificationTitle string | ||
| 13 | + // 通知内容 | ||
| 14 | + NotificationContent string | ||
| 15 | + // 通知时间 | ||
| 16 | + NotificationTime time.Time | ||
| 17 | + // 外部资源引用类型(1任务) | ||
| 18 | + ExternalResourceType int | ||
| 19 | + // 外部资源引用 | ||
| 20 | + ExternalResource int64 | ||
| 21 | +} |
| 1 | +package models | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/domain" | ||
| 5 | + "time" | ||
| 6 | +) | ||
| 7 | + | ||
| 8 | +type SentNotification struct { | ||
| 9 | + TableName string `pg:"sent_notifications,alias:sent_notification"` | ||
| 10 | + // 发送出的通知ID | ||
| 11 | + Id int64 | ||
| 12 | + NotificationId int64 | ||
| 13 | + // 通知 | ||
| 14 | + Notification *Notification | ||
| 15 | + // 通知接收者 | ||
| 16 | + Receiver *domain.EmployeeInfo | ||
| 17 | + // 是否已读 | ||
| 18 | + IsRead bool | ||
| 19 | + // 通知读取时间 | ||
| 20 | + ReadTime time.Time | ||
| 21 | +} |
| 1 | +package repository | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + "github.com/linmadan/egglib-go/utils/snowflake" | ||
| 6 | + | ||
| 7 | + "github.com/go-pg/pg" | ||
| 8 | + pgTransaction "github.com/linmadan/egglib-go/transaction/pg" | ||
| 9 | + "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/domain" | ||
| 10 | + "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/infrastructure/pg/models" | ||
| 11 | +) | ||
| 12 | + | ||
| 13 | +type NotificationRepository struct { | ||
| 14 | + transactionContext *pgTransaction.TransactionContext | ||
| 15 | +} | ||
| 16 | + | ||
| 17 | +func (repository *NotificationRepository) nextIdentify() (int64, error) { | ||
| 18 | + IdWorker, err := snowflake.NewIdWorker(2) | ||
| 19 | + if err != nil { | ||
| 20 | + return 0, err | ||
| 21 | + } | ||
| 22 | + id, err := IdWorker.NextId() | ||
| 23 | + return id, err | ||
| 24 | +} | ||
| 25 | + | ||
| 26 | +func (repository *NotificationRepository) Save(notification *domain.Notification) (*domain.Notification, error) { | ||
| 27 | + tx := repository.transactionContext.PgTx | ||
| 28 | + if notification.Identify() == nil { | ||
| 29 | + if nextId, err := repository.nextIdentify(); err != nil { | ||
| 30 | + return notification, err | ||
| 31 | + } else { | ||
| 32 | + notification.NotificationId = nextId | ||
| 33 | + } | ||
| 34 | + if _, err := tx.QueryOne( | ||
| 35 | + pg.Scan(¬ification.NotificationId, ¬ification.NotificationType, ¬ification.NotificationTitle, ¬ification.NotificationContent, ¬ification.NotificationTime, ¬ification.ExternalResourceType, ¬ification.ExternalResource), | ||
| 36 | + "INSERT INTO notifications (id, notification_type, notification_title, notification_content, notification_time, external_resource_type, external_resource) VALUES (?, ?, ?, ?, ?, ?, ?) RETURNING id, notification_type, notification_title, notification_content, notification_time, external_resource_type, external_resource", | ||
| 37 | + notification.NotificationId, notification.NotificationType, notification.NotificationTitle, notification.NotificationContent, notification.NotificationTime, notification.ExternalResourceType, notification.ExternalResource); err != nil { | ||
| 38 | + return notification, err | ||
| 39 | + } | ||
| 40 | + } else { | ||
| 41 | + if _, err := tx.QueryOne( | ||
| 42 | + pg.Scan(¬ification.NotificationType, ¬ification.NotificationTitle, ¬ification.NotificationContent, ¬ification.NotificationTime, ¬ification.ExternalResourceType, ¬ification.ExternalResource), | ||
| 43 | + "UPDATE notifications SET notification_type=?, notification_title=?, notification_content=?, notification_time=?, external_resource_type=?, external_resource=? WHERE id=? RETURNING notification_type, notification_title, notification_content, notification_time, external_resource_type, external_resource", | ||
| 44 | + notification.NotificationType, notification.NotificationTitle, notification.NotificationContent, notification.NotificationTime, notification.ExternalResourceType, notification.ExternalResource, notification.Identify()); err != nil { | ||
| 45 | + return notification, err | ||
| 46 | + } | ||
| 47 | + } | ||
| 48 | + return notification, nil | ||
| 49 | +} | ||
| 50 | +func (repository *NotificationRepository) Remove(notification *domain.Notification) (*domain.Notification, error) { | ||
| 51 | + tx := repository.transactionContext.PgTx | ||
| 52 | + notificationModel := new(models.Notification) | ||
| 53 | + notificationModel.Id = notification.Identify().(int64) | ||
| 54 | + if _, err := tx.Model(notificationModel).WherePK().Delete(); err != nil { | ||
| 55 | + return notification, err | ||
| 56 | + } | ||
| 57 | + return notification, nil | ||
| 58 | +} | ||
| 59 | +func (repository *NotificationRepository) FindOne(queryOptions map[string]interface{}) (*domain.Notification, error) { | ||
| 60 | + tx := repository.transactionContext.PgTx | ||
| 61 | + notificationModel := new(models.Notification) | ||
| 62 | + query := tx.Model(notificationModel) | ||
| 63 | + if notificationId, ok := queryOptions["notificationId"]; ok { | ||
| 64 | + query = query.Where("notification.id = ?", notificationId) | ||
| 65 | + } | ||
| 66 | + if err := query.First(); err != nil { | ||
| 67 | + if err.Error() == "pg: no rows in result set" { | ||
| 68 | + return nil, fmt.Errorf("没有此资源") | ||
| 69 | + } else { | ||
| 70 | + return nil, err | ||
| 71 | + } | ||
| 72 | + } | ||
| 73 | + if notificationModel.Id == 0 { | ||
| 74 | + return nil, nil | ||
| 75 | + } else { | ||
| 76 | + return repository.transformPgModelToDomainModel(notificationModel) | ||
| 77 | + } | ||
| 78 | +} | ||
| 79 | +func (repository *NotificationRepository) Find(queryOptions map[string]interface{}) (int64, []*domain.Notification, error) { | ||
| 80 | + tx := repository.transactionContext.PgTx | ||
| 81 | + var notificationModels []*models.Notification | ||
| 82 | + notifications := make([]*domain.Notification, 0) | ||
| 83 | + query := tx.Model(¬ificationModels) | ||
| 84 | + if offset, ok := queryOptions["offset"]; ok { | ||
| 85 | + offset := offset.(int) | ||
| 86 | + if offset > -1 { | ||
| 87 | + query = query.Offset(offset) | ||
| 88 | + } | ||
| 89 | + } else { | ||
| 90 | + query = query.Offset(0) | ||
| 91 | + } | ||
| 92 | + if limit, ok := queryOptions["limit"]; ok { | ||
| 93 | + limit := limit.(int) | ||
| 94 | + if limit > -1 { | ||
| 95 | + query = query.Limit(limit) | ||
| 96 | + } | ||
| 97 | + } else { | ||
| 98 | + query = query.Limit(20) | ||
| 99 | + } | ||
| 100 | + if count, err := query.Order("id DESC").SelectAndCount(); err != nil { | ||
| 101 | + return 0, notifications, err | ||
| 102 | + } else { | ||
| 103 | + for _, notificationModel := range notificationModels { | ||
| 104 | + if notification, err := repository.transformPgModelToDomainModel(notificationModel); err != nil { | ||
| 105 | + return 0, notifications, err | ||
| 106 | + } else { | ||
| 107 | + notifications = append(notifications, notification) | ||
| 108 | + } | ||
| 109 | + } | ||
| 110 | + return int64(count), notifications, nil | ||
| 111 | + } | ||
| 112 | +} | ||
| 113 | +func (repository *NotificationRepository) transformPgModelToDomainModel(notificationModel *models.Notification) (*domain.Notification, error) { | ||
| 114 | + return &domain.Notification{ | ||
| 115 | + NotificationId: notificationModel.Id, | ||
| 116 | + NotificationType: notificationModel.NotificationType, | ||
| 117 | + NotificationTitle: notificationModel.NotificationTitle, | ||
| 118 | + NotificationContent: notificationModel.NotificationContent, | ||
| 119 | + NotificationTime: notificationModel.NotificationTime, | ||
| 120 | + ExternalResourceType: notificationModel.ExternalResourceType, | ||
| 121 | + ExternalResource: notificationModel.ExternalResource, | ||
| 122 | + }, nil | ||
| 123 | +} | ||
| 124 | +func NewNotificationRepository(transactionContext *pgTransaction.TransactionContext) (*NotificationRepository, error) { | ||
| 125 | + if transactionContext == nil { | ||
| 126 | + return nil, fmt.Errorf("transactionContext参数不能为nil") | ||
| 127 | + } else { | ||
| 128 | + return &NotificationRepository{ | ||
| 129 | + transactionContext: transactionContext, | ||
| 130 | + }, nil | ||
| 131 | + } | ||
| 132 | +} |
| 1 | +package repository | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + "github.com/linmadan/egglib-go/utils/snowflake" | ||
| 6 | + | ||
| 7 | + "github.com/go-pg/pg" | ||
| 8 | + pgTransaction "github.com/linmadan/egglib-go/transaction/pg" | ||
| 9 | + "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/domain" | ||
| 10 | + "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/infrastructure/pg/models" | ||
| 11 | +) | ||
| 12 | + | ||
| 13 | +type SentNotificationRepository struct { | ||
| 14 | + transactionContext *pgTransaction.TransactionContext | ||
| 15 | +} | ||
| 16 | + | ||
| 17 | +func (repository *SentNotificationRepository) nextIdentify() (int64, error) { | ||
| 18 | + IdWorker, err := snowflake.NewIdWorker(3) | ||
| 19 | + if err != nil { | ||
| 20 | + return 0, err | ||
| 21 | + } | ||
| 22 | + id, err := IdWorker.NextId() | ||
| 23 | + return id, err | ||
| 24 | +} | ||
| 25 | + | ||
| 26 | +func (repository *SentNotificationRepository) Save(sentNotification *domain.SentNotification) (*domain.SentNotification, error) { | ||
| 27 | + tx := repository.transactionContext.PgTx | ||
| 28 | + if sentNotification.Identify() == nil { | ||
| 29 | + if nextId, err := repository.nextIdentify(); err != nil { | ||
| 30 | + return sentNotification, err | ||
| 31 | + } else { | ||
| 32 | + sentNotification.SentNotificationId = nextId | ||
| 33 | + } | ||
| 34 | + if _, err := tx.QueryOne( | ||
| 35 | + pg.Scan(&sentNotification.SentNotificationId, &sentNotification.Notification.NotificationId, &sentNotification.Receiver, &sentNotification.IsRead, &sentNotification.ReadTime), | ||
| 36 | + "INSERT INTO sent_notifications (id, notification_id, receiver, is_read, read_time) VALUES (?, ?, ?, ?, ?) RETURNING id, notification_id, receiver, is_read, read_time", | ||
| 37 | + sentNotification.SentNotificationId, sentNotification.Notification.NotificationId, sentNotification.Receiver, sentNotification.IsRead, sentNotification.ReadTime); err != nil { | ||
| 38 | + return sentNotification, err | ||
| 39 | + } | ||
| 40 | + } else { | ||
| 41 | + if _, err := tx.QueryOne( | ||
| 42 | + pg.Scan(&sentNotification.SentNotificationId, &sentNotification.Notification.NotificationId, &sentNotification.Receiver, &sentNotification.IsRead, &sentNotification.ReadTime), | ||
| 43 | + "UPDATE sent_notifications SET notification_id=?, receiver=?, is_read=?, read_time=? WHERE id=? RETURNING id, notification_id, receiver, is_read, read_time", | ||
| 44 | + sentNotification.Notification.NotificationId, sentNotification.Receiver, sentNotification.IsRead, sentNotification.ReadTime, sentNotification.Identify()); err != nil { | ||
| 45 | + return sentNotification, err | ||
| 46 | + } | ||
| 47 | + } | ||
| 48 | + return sentNotification, nil | ||
| 49 | +} | ||
| 50 | +func (repository *SentNotificationRepository) Remove(sentNotification *domain.SentNotification) (*domain.SentNotification, error) { | ||
| 51 | + tx := repository.transactionContext.PgTx | ||
| 52 | + sentNotificationModel := new(models.SentNotification) | ||
| 53 | + sentNotificationModel.Id = sentNotification.Identify().(int64) | ||
| 54 | + if _, err := tx.Model(sentNotificationModel).WherePK().Delete(); err != nil { | ||
| 55 | + return sentNotification, err | ||
| 56 | + } | ||
| 57 | + return sentNotification, nil | ||
| 58 | +} | ||
| 59 | +func (repository *SentNotificationRepository) FindOne(queryOptions map[string]interface{}) (*domain.SentNotification, error) { | ||
| 60 | + tx := repository.transactionContext.PgTx | ||
| 61 | + sentNotificationModel := new(models.SentNotification) | ||
| 62 | + query := tx.Model(sentNotificationModel).Relation("Notification") | ||
| 63 | + if sentNotificationId, ok := queryOptions["sentNotificationId"]; ok { | ||
| 64 | + query = query.Where("sent_notification.id = ?", sentNotificationId) | ||
| 65 | + } | ||
| 66 | + if err := query.First(); err != nil { | ||
| 67 | + if err.Error() == "pg: no rows in result set" { | ||
| 68 | + return nil, fmt.Errorf("没有此资源") | ||
| 69 | + } else { | ||
| 70 | + return nil, err | ||
| 71 | + } | ||
| 72 | + } | ||
| 73 | + if sentNotificationModel.Id == 0 { | ||
| 74 | + return nil, nil | ||
| 75 | + } else { | ||
| 76 | + return repository.transformPgModelToDomainModel(sentNotificationModel) | ||
| 77 | + } | ||
| 78 | +} | ||
| 79 | +func (repository *SentNotificationRepository) Find(queryOptions map[string]interface{}) (int64, []*domain.SentNotification, error) { | ||
| 80 | + tx := repository.transactionContext.PgTx | ||
| 81 | + var sentNotificationModels []*models.SentNotification | ||
| 82 | + sentNotifications := make([]*domain.SentNotification, 0) | ||
| 83 | + query := tx.Model(&sentNotificationModels).Relation("Notification") | ||
| 84 | + if receiver, ok := queryOptions["receiver"]; ok && (receiver != int64(0)) { | ||
| 85 | + query = query.Where(`sent_notification.receiver @> '{"uid":?}'`, receiver) | ||
| 86 | + } | ||
| 87 | + if notificationType, ok := queryOptions["notificationType"]; ok && (notificationType != int(0)) { | ||
| 88 | + query = query.Where("notification.notification_type = ?", notificationType) | ||
| 89 | + } | ||
| 90 | + if offset, ok := queryOptions["offset"]; ok { | ||
| 91 | + offset := offset.(int) | ||
| 92 | + if offset > -1 { | ||
| 93 | + query = query.Offset(offset) | ||
| 94 | + } | ||
| 95 | + } else { | ||
| 96 | + query = query.Offset(0) | ||
| 97 | + } | ||
| 98 | + if limit, ok := queryOptions["limit"]; ok { | ||
| 99 | + limit := limit.(int) | ||
| 100 | + if limit > -1 { | ||
| 101 | + query = query.Limit(limit) | ||
| 102 | + } | ||
| 103 | + } else { | ||
| 104 | + query = query.Limit(20) | ||
| 105 | + } | ||
| 106 | + if count, err := query.Order("id DESC").SelectAndCount(); err != nil { | ||
| 107 | + return 0, sentNotifications, err | ||
| 108 | + } else { | ||
| 109 | + for _, sentNotificationModel := range sentNotificationModels { | ||
| 110 | + if sentNotification, err := repository.transformPgModelToDomainModel(sentNotificationModel); err != nil { | ||
| 111 | + return 0, sentNotifications, err | ||
| 112 | + } else { | ||
| 113 | + sentNotifications = append(sentNotifications, sentNotification) | ||
| 114 | + } | ||
| 115 | + } | ||
| 116 | + return int64(count), sentNotifications, nil | ||
| 117 | + } | ||
| 118 | +} | ||
| 119 | +func (repository *SentNotificationRepository) transformPgModelToDomainModel(sentNotificationModel *models.SentNotification) (*domain.SentNotification, error) { | ||
| 120 | + var notification *domain.Notification | ||
| 121 | + if sentNotificationModel.Notification == nil { | ||
| 122 | + notification = nil | ||
| 123 | + } else { | ||
| 124 | + notification = &domain.Notification{ | ||
| 125 | + NotificationId: sentNotificationModel.Notification.Id, | ||
| 126 | + NotificationType: sentNotificationModel.Notification.NotificationType, | ||
| 127 | + NotificationTitle: sentNotificationModel.Notification.NotificationTitle, | ||
| 128 | + NotificationContent: sentNotificationModel.Notification.NotificationContent, | ||
| 129 | + NotificationTime: sentNotificationModel.Notification.NotificationTime, | ||
| 130 | + ExternalResourceType: sentNotificationModel.Notification.ExternalResourceType, | ||
| 131 | + ExternalResource: sentNotificationModel.Notification.ExternalResource, | ||
| 132 | + } | ||
| 133 | + } | ||
| 134 | + return &domain.SentNotification{ | ||
| 135 | + SentNotificationId: sentNotificationModel.Id, | ||
| 136 | + Notification: notification, | ||
| 137 | + Receiver: sentNotificationModel.Receiver, | ||
| 138 | + IsRead: sentNotificationModel.IsRead, | ||
| 139 | + ReadTime: sentNotificationModel.ReadTime, | ||
| 140 | + }, nil | ||
| 141 | +} | ||
| 142 | +func NewSentNotificationRepository(transactionContext *pgTransaction.TransactionContext) (*SentNotificationRepository, error) { | ||
| 143 | + if transactionContext == nil { | ||
| 144 | + return nil, fmt.Errorf("transactionContext参数不能为nil") | ||
| 145 | + } else { | ||
| 146 | + return &SentNotificationRepository{ | ||
| 147 | + transactionContext: transactionContext, | ||
| 148 | + }, nil | ||
| 149 | + } | ||
| 150 | +} |
| @@ -23,6 +23,7 @@ func (repository *TaskRepository) nextIdentify() (int64, error) { | @@ -23,6 +23,7 @@ func (repository *TaskRepository) nextIdentify() (int64, error) { | ||
| 23 | id, err := IdWorker.NextId() | 23 | id, err := IdWorker.NextId() |
| 24 | return id, err | 24 | return id, err |
| 25 | } | 25 | } |
| 26 | + | ||
| 26 | func (repository *TaskRepository) Save(task *domain.Task) (*domain.Task, error) { | 27 | func (repository *TaskRepository) Save(task *domain.Task) (*domain.Task, error) { |
| 27 | tx := repository.transactionContext.PgTx | 28 | tx := repository.transactionContext.PgTx |
| 28 | if task.Identify() == nil { | 29 | if task.Identify() == nil { |
| 1 | +package controllers | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "encoding/json" | ||
| 5 | + | ||
| 6 | + "github.com/astaxie/beego" | ||
| 7 | + "github.com/linmadan/egglib-go/web/beego/utils" | ||
| 8 | + "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/application/notification/command" | ||
| 9 | + "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/application/notification/query" | ||
| 10 | + "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/application/notification/service" | ||
| 11 | +) | ||
| 12 | + | ||
| 13 | +type NotificationController struct { | ||
| 14 | + beego.Controller | ||
| 15 | +} | ||
| 16 | + | ||
| 17 | +func (controller *NotificationController) ReadSentNotification() { | ||
| 18 | + notificationService := service.NewNotificationService(nil) | ||
| 19 | + readSentNotificationCommand := &command.ReadSentNotificationCommand{} | ||
| 20 | + json.Unmarshal(controller.Ctx.Input.GetData("requestBody").([]byte), readSentNotificationCommand) | ||
| 21 | + data, err := notificationService.ReadSentNotification(readSentNotificationCommand) | ||
| 22 | + var response utils.JsonResponse | ||
| 23 | + if err != nil { | ||
| 24 | + response = utils.ResponseError(controller.Ctx, err) | ||
| 25 | + } else { | ||
| 26 | + response = utils.ResponseData(controller.Ctx, data) | ||
| 27 | + } | ||
| 28 | + controller.Data["json"] = response | ||
| 29 | + controller.ServeJSON() | ||
| 30 | +} | ||
| 31 | + | ||
| 32 | +func (controller *NotificationController) ReadAllUnReadSentNotification() { | ||
| 33 | + notificationService := service.NewNotificationService(nil) | ||
| 34 | + readAllUnReadSentNotificationCommand := &command.ReadAllUnReadSentNotificationCommand{} | ||
| 35 | + json.Unmarshal(controller.Ctx.Input.GetData("requestBody").([]byte), readAllUnReadSentNotificationCommand) | ||
| 36 | + data, err := notificationService.ReadAllUnReadSentNotification(readAllUnReadSentNotificationCommand) | ||
| 37 | + var response utils.JsonResponse | ||
| 38 | + if err != nil { | ||
| 39 | + response = utils.ResponseError(controller.Ctx, err) | ||
| 40 | + } else { | ||
| 41 | + response = utils.ResponseData(controller.Ctx, data) | ||
| 42 | + } | ||
| 43 | + controller.Data["json"] = response | ||
| 44 | + controller.ServeJSON() | ||
| 45 | +} | ||
| 46 | + | ||
| 47 | +func (controller *NotificationController) ListSentNotification() { | ||
| 48 | + notificationService := service.NewNotificationService(nil) | ||
| 49 | + listSentNotificationQuery := &query.ListSentNotificationQuery{} | ||
| 50 | + receiverId, _ := controller.GetInt64("receiverId") | ||
| 51 | + listSentNotificationQuery.ReceiverId = receiverId | ||
| 52 | + notificationType, _ := controller.GetInt("notificationType") | ||
| 53 | + listSentNotificationQuery.NotificationType = notificationType | ||
| 54 | + offset, _ := controller.GetInt("offset") | ||
| 55 | + listSentNotificationQuery.Offset = offset | ||
| 56 | + limit, _ := controller.GetInt("limit") | ||
| 57 | + listSentNotificationQuery.Limit = limit | ||
| 58 | + data, err := notificationService.ListSentNotification(listSentNotificationQuery) | ||
| 59 | + var response utils.JsonResponse | ||
| 60 | + if err != nil { | ||
| 61 | + response = utils.ResponseError(controller.Ctx, err) | ||
| 62 | + } else { | ||
| 63 | + response = utils.ResponseData(controller.Ctx, data) | ||
| 64 | + } | ||
| 65 | + controller.Data["json"] = response | ||
| 66 | + controller.ServeJSON() | ||
| 67 | +} |
| 1 | +package routers | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "github.com/astaxie/beego" | ||
| 5 | + "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/port/beego/controllers" | ||
| 6 | +) | ||
| 7 | + | ||
| 8 | +func init() { | ||
| 9 | + beego.Router("/notifications/read", &controllers.NotificationController{}, "Post:ReadSentNotification") | ||
| 10 | + beego.Router("/notifications/read-all", &controllers.NotificationController{}, "Post:ReadAllUnReadSentNotification") | ||
| 11 | + beego.Router("/notifications/", &controllers.NotificationController{}, "Get:ListSentNotification") | ||
| 12 | +} |
| 1 | +package notification | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/domain" | ||
| 5 | + "net/http" | ||
| 6 | + "time" | ||
| 7 | + | ||
| 8 | + "github.com/gavv/httpexpect" | ||
| 9 | + "github.com/go-pg/pg" | ||
| 10 | + . "github.com/onsi/ginkgo" | ||
| 11 | + . "github.com/onsi/gomega" | ||
| 12 | + pG "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/infrastructure/pg" | ||
| 13 | +) | ||
| 14 | + | ||
| 15 | +var _ = Describe("返回发送出的通知列表", func() { | ||
| 16 | + var notificationId int64 | ||
| 17 | + var sentNotificationId int64 | ||
| 18 | + BeforeEach(func() { | ||
| 19 | + _, err := pG.DB.QueryOne( | ||
| 20 | + pg.Scan(¬ificationId), | ||
| 21 | + "INSERT INTO notifications (id, notification_type, notification_title, notification_content, notification_time, external_resource_type, external_resource) VALUES (?, ?, ?, ?, ?, ?, ?) RETURNING id", | ||
| 22 | + 1, 1, "testNotificationTitle", "testNotificationContent", time.Now(), 1, 1) | ||
| 23 | + Expect(err).NotTo(HaveOccurred()) | ||
| 24 | + _, err1 := pG.DB.QueryOne( | ||
| 25 | + pg.Scan(&sentNotificationId), | ||
| 26 | + "INSERT INTO sent_notifications (id, notification_id, receiver, is_read, read_time) VALUES (?, ?, ?, ?, ?) RETURNING id", | ||
| 27 | + 1, notificationId, &domain.EmployeeInfo{ | ||
| 28 | + Uid: 2499036607974745088, | ||
| 29 | + }, false, time.Time{}) | ||
| 30 | + Expect(err1).NotTo(HaveOccurred()) | ||
| 31 | + _, err2 := pG.DB.QueryOne( | ||
| 32 | + pg.Scan(), | ||
| 33 | + "INSERT INTO employees (id, company_id, uid, employee_name, employee_account, su_money) VALUES (?, ?, ?, ?, ?, ?)", | ||
| 34 | + 1, 101, 2499036607974745088, "testEmployeeName", "testEmployeeAccount", 0) | ||
| 35 | + Expect(err2).NotTo(HaveOccurred()) | ||
| 36 | + }) | ||
| 37 | + Describe("返回发送出的通知列表", func() { | ||
| 38 | + Context("", func() { | ||
| 39 | + It("", func() { | ||
| 40 | + httpExpect := httpexpect.New(GinkgoT(), server.URL) | ||
| 41 | + httpExpect.GET("/notifications"). | ||
| 42 | + WithQuery("receiverId", 2499036607974745088). | ||
| 43 | + WithQuery("notificationType", 1). | ||
| 44 | + WithQuery("offset", 0). | ||
| 45 | + WithQuery("limit", 20). | ||
| 46 | + Expect(). | ||
| 47 | + Status(http.StatusOK). | ||
| 48 | + JSON(). | ||
| 49 | + Object(). | ||
| 50 | + ContainsKey("code").ValueEqual("code", 0). | ||
| 51 | + ContainsKey("msg").ValueEqual("msg", "ok"). | ||
| 52 | + ContainsKey("data").Value("data").Object() | ||
| 53 | + }) | ||
| 54 | + }) | ||
| 55 | + }) | ||
| 56 | + AfterEach(func() { | ||
| 57 | + _, err := pG.DB.Exec("DELETE FROM sent_notifications WHERE true") | ||
| 58 | + Expect(err).NotTo(HaveOccurred()) | ||
| 59 | + _, err1 := pG.DB.Exec("DELETE FROM notifications WHERE true") | ||
| 60 | + Expect(err1).NotTo(HaveOccurred()) | ||
| 61 | + _, err2 := pG.DB.Exec("DELETE FROM employees WHERE true") | ||
| 62 | + Expect(err2).NotTo(HaveOccurred()) | ||
| 63 | + }) | ||
| 64 | +}) |
| 1 | +package notification | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "net/http" | ||
| 5 | + "net/http/httptest" | ||
| 6 | + "testing" | ||
| 7 | + | ||
| 8 | + "github.com/astaxie/beego" | ||
| 9 | + . "github.com/onsi/ginkgo" | ||
| 10 | + . "github.com/onsi/gomega" | ||
| 11 | + _ "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/infrastructure/pg" | ||
| 12 | + _ "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/port/beego" | ||
| 13 | +) | ||
| 14 | + | ||
| 15 | +func TestNotification(t *testing.T) { | ||
| 16 | + RegisterFailHandler(Fail) | ||
| 17 | + RunSpecs(t, "Beego Port Notification Correlations Test Case Suite") | ||
| 18 | +} | ||
| 19 | + | ||
| 20 | +var handler http.Handler | ||
| 21 | +var server *httptest.Server | ||
| 22 | + | ||
| 23 | +var _ = BeforeSuite(func() { | ||
| 24 | + handler = beego.BeeApp.Handlers | ||
| 25 | + server = httptest.NewServer(handler) | ||
| 26 | +}) | ||
| 27 | + | ||
| 28 | +var _ = AfterSuite(func() { | ||
| 29 | + server.Close() | ||
| 30 | +}) |
| 1 | +package notification | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/domain" | ||
| 5 | + "net/http" | ||
| 6 | + "time" | ||
| 7 | + | ||
| 8 | + "github.com/gavv/httpexpect" | ||
| 9 | + "github.com/go-pg/pg" | ||
| 10 | + . "github.com/onsi/ginkgo" | ||
| 11 | + . "github.com/onsi/gomega" | ||
| 12 | + pG "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/infrastructure/pg" | ||
| 13 | +) | ||
| 14 | + | ||
| 15 | +var _ = Describe("读取全部未读取的发送出的通知", func() { | ||
| 16 | + var notificationId int64 | ||
| 17 | + var sentNotificationId int64 | ||
| 18 | + BeforeEach(func() { | ||
| 19 | + _, err := pG.DB.QueryOne( | ||
| 20 | + pg.Scan(¬ificationId), | ||
| 21 | + "INSERT INTO notifications (id, notification_type, notification_title, notification_content, notification_time, external_resource_type, external_resource) VALUES (?, ?, ?, ?, ?, ?, ?) RETURNING id", | ||
| 22 | + 1, 1, "testNotificationTitle", "testNotificationContent", time.Now(), 1, 1) | ||
| 23 | + Expect(err).NotTo(HaveOccurred()) | ||
| 24 | + _, err1 := pG.DB.QueryOne( | ||
| 25 | + pg.Scan(&sentNotificationId), | ||
| 26 | + "INSERT INTO sent_notifications (id, notification_id, receiver, is_read, read_time) VALUES (?, ?, ?, ?, ?) RETURNING id", | ||
| 27 | + 1, notificationId, &domain.EmployeeInfo{ | ||
| 28 | + Uid: 2499036607974745088, | ||
| 29 | + }, false, time.Time{}) | ||
| 30 | + Expect(err1).NotTo(HaveOccurred()) | ||
| 31 | + _, err2 := pG.DB.QueryOne( | ||
| 32 | + pg.Scan(), | ||
| 33 | + "INSERT INTO employees (id, company_id, uid, employee_name, employee_account, su_money) VALUES (?, ?, ?, ?, ?, ?)", | ||
| 34 | + 1, 101, 2499036607974745088, "testEmployeeName", "testEmployeeAccount", 0) | ||
| 35 | + Expect(err2).NotTo(HaveOccurred()) | ||
| 36 | + }) | ||
| 37 | + Describe("读取全部未读取的发送出的通知", func() { | ||
| 38 | + Context("读取通知接收者全部未读取的发送出的通知", func() { | ||
| 39 | + It("读取成功", func() { | ||
| 40 | + httpExpect := httpexpect.New(GinkgoT(), server.URL) | ||
| 41 | + body := map[string]interface{}{ | ||
| 42 | + "receiverId": 2499036607974745088, | ||
| 43 | + } | ||
| 44 | + httpExpect.POST("/notifications/read-all"). | ||
| 45 | + WithJSON(body). | ||
| 46 | + Expect(). | ||
| 47 | + Status(http.StatusOK). | ||
| 48 | + JSON(). | ||
| 49 | + Object(). | ||
| 50 | + ContainsKey("code").ValueEqual("code", 0). | ||
| 51 | + ContainsKey("msg").ValueEqual("msg", "ok"). | ||
| 52 | + ContainsKey("data").ValueEqual("data", 1) | ||
| 53 | + }) | ||
| 54 | + }) | ||
| 55 | + }) | ||
| 56 | + AfterEach(func() { | ||
| 57 | + _, err := pG.DB.Exec("DELETE FROM sent_notifications WHERE true") | ||
| 58 | + Expect(err).NotTo(HaveOccurred()) | ||
| 59 | + _, err1 := pG.DB.Exec("DELETE FROM notifications WHERE true") | ||
| 60 | + Expect(err1).NotTo(HaveOccurred()) | ||
| 61 | + _, err2 := pG.DB.Exec("DELETE FROM employees WHERE true") | ||
| 62 | + Expect(err2).NotTo(HaveOccurred()) | ||
| 63 | + }) | ||
| 64 | +}) |
| 1 | +package notification | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "github.com/gavv/httpexpect" | ||
| 5 | + "github.com/go-pg/pg" | ||
| 6 | + . "github.com/onsi/ginkgo" | ||
| 7 | + . "github.com/onsi/gomega" | ||
| 8 | + "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/domain" | ||
| 9 | + pG "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/infrastructure/pg" | ||
| 10 | + "net/http" | ||
| 11 | + "time" | ||
| 12 | +) | ||
| 13 | + | ||
| 14 | +var _ = Describe("读取发送出的通知", func() { | ||
| 15 | + var notificationId int64 | ||
| 16 | + var sentNotificationId int64 | ||
| 17 | + BeforeEach(func() { | ||
| 18 | + _, err := pG.DB.QueryOne( | ||
| 19 | + pg.Scan(¬ificationId), | ||
| 20 | + "INSERT INTO notifications (id, notification_type, notification_title, notification_content, notification_time, external_resource_type, external_resource) VALUES (?, ?, ?, ?, ?, ?, ?) RETURNING id", | ||
| 21 | + 1, 1, "testNotificationTitle", "testNotificationContent", time.Now(), 1, 1) | ||
| 22 | + Expect(err).NotTo(HaveOccurred()) | ||
| 23 | + _, err1 := pG.DB.QueryOne( | ||
| 24 | + pg.Scan(&sentNotificationId), | ||
| 25 | + "INSERT INTO sent_notifications (id, notification_id, receiver, is_read, read_time) VALUES (?, ?, ?, ?, ?) RETURNING id", | ||
| 26 | + 1, notificationId, &domain.EmployeeInfo{ | ||
| 27 | + Uid: 2499036607974745088, | ||
| 28 | + }, false, time.Time{}) | ||
| 29 | + Expect(err1).NotTo(HaveOccurred()) | ||
| 30 | + }) | ||
| 31 | + Describe("读取发送出的通知", func() { | ||
| 32 | + Context("读取正确sentNotificationId的发送出的通知", func() { | ||
| 33 | + It("读取成功", func() { | ||
| 34 | + httpExpect := httpexpect.New(GinkgoT(), server.URL) | ||
| 35 | + body := map[string]interface{}{ | ||
| 36 | + "sentNotificationId": sentNotificationId, | ||
| 37 | + } | ||
| 38 | + httpExpect.POST("/notifications/read"). | ||
| 39 | + WithJSON(body). | ||
| 40 | + Expect(). | ||
| 41 | + Status(http.StatusOK). | ||
| 42 | + JSON(). | ||
| 43 | + Object(). | ||
| 44 | + ContainsKey("code").ValueEqual("code", 0). | ||
| 45 | + ContainsKey("msg").ValueEqual("msg", "ok"). | ||
| 46 | + ContainsKey("data").Value("data").Object(). | ||
| 47 | + ContainsKey("isRead").ValueEqual("isRead", true) | ||
| 48 | + }) | ||
| 49 | + }) | ||
| 50 | + }) | ||
| 51 | + AfterEach(func() { | ||
| 52 | + _, err := pG.DB.Exec("DELETE FROM sent_notifications WHERE true") | ||
| 53 | + Expect(err).NotTo(HaveOccurred()) | ||
| 54 | + _, err1 := pG.DB.Exec("DELETE FROM notifications WHERE true") | ||
| 55 | + Expect(err1).NotTo(HaveOccurred()) | ||
| 56 | + }) | ||
| 57 | +}) |
-
请 注册 或 登录 后发表评论