作者 郑周

1.系统消息模型

2.业务消息模型
syntax = "v1"
info(
title: "xx实例"
desc: "xx实例"
author: "author"
email: "email"
version: "v1"
)
@server(
prefix: message_business/v1
group: message_business
jwt: JwtAuth
)
service Core {
@handler getMessageBusiness
post /message_business/:id (MessageBusinessGetRequest) returns (MessageBusinessGetResponse)
@handler saveMessageBusiness
post /message_business (MessageBusinessSaveRequest) returns (MessageBusinessSaveResponse)
@handler deleteMessageBusiness
delete /message_business/:id (MessageBusinessDeleteRequest) returns (MessageBusinessDeleteResponse)
@handler updateMessageBusiness
put /message_business/:id (MessageBusinessUpdateRequest) returns (MessageBusinessUpdateResponse)
@handler searchMessageBusiness
post /message_business/search (MessageBusinessSearchRequest) returns (MessageBusinessSearchResponse)
}
type (
MessageBusinessGetRequest {
Id int64 `path:"id"`
}
MessageBusinessGetResponse struct{
MessageBusiness MessageBusinessItem `json:"message_business"`
}
MessageBusinessSaveRequest struct{
MessageBusiness MessageBusinessItem `json:"message_business"`
}
MessageBusinessSaveResponse struct{}
MessageBusinessDeleteRequest struct{
Id int64 `path:"id"`
}
MessageBusinessDeleteResponse struct{}
MessageBusinessUpdateRequest struct{
Id int64 `path:"id"`
MessageBusiness MessageBusinessItem `json:"message_business"`
}
MessageBusinessUpdateResponse struct{}
MessageBusinessSearchRequest struct{
Page int `json:"page"`
Size int `json:"size"`
}
MessageBusinessSearchResponse{
List []MessageBusinessItem `json:"list"`
Total int64 `json:"total"`
}
MessageBusinessItem struct{
}
)
... ...
syntax = "v1"
info(
title: "xx实例"
desc: "xx实例"
author: "author"
email: "email"
version: "v1"
)
@server(
prefix: message_system/v1
group: message_system
jwt: JwtAuth
)
service Core {
@handler getMessageSystem
post /message_system/:id (MessageSystemGetRequest) returns (MessageSystemGetResponse)
@handler saveMessageSystem
post /message_system (MessageSystemSaveRequest) returns (MessageSystemSaveResponse)
@handler deleteMessageSystem
delete /message_system/:id (MessageSystemDeleteRequest) returns (MessageSystemDeleteResponse)
@handler updateMessageSystem
put /message_system/:id (MessageSystemUpdateRequest) returns (MessageSystemUpdateResponse)
@handler searchMessageSystem
post /message_system/search (MessageSystemSearchRequest) returns (MessageSystemSearchResponse)
}
type (
MessageSystemGetRequest {
Id int64 `path:"id"`
}
MessageSystemGetResponse struct{
MessageSystem MessageSystemItem `json:"message_system"`
}
MessageSystemSaveRequest struct{
MessageSystem MessageSystemItem `json:"message_system"`
}
MessageSystemSaveResponse struct{}
MessageSystemDeleteRequest struct{
Id int64 `path:"id"`
}
MessageSystemDeleteResponse struct{}
MessageSystemUpdateRequest struct{
Id int64 `path:"id"`
MessageSystem MessageSystemItem `json:"message_system"`
}
MessageSystemUpdateResponse struct{}
MessageSystemSearchRequest struct{
Page int `json:"page"`
Size int `json:"size"`
}
MessageSystemSearchResponse{
List []MessageSystemItem `json:"list"`
Total int64 `json:"total"`
}
MessageSystemItem struct{
}
)
... ...
syntax = "proto3";
option go_package ="./pb";
package pb;
message MessageBusinessGetReq {
int64 Id = 1;
}
message MessageBusinessGetResp{
MessageBusinessItem User = 1;
}
message MessageBusinessSaveReq {
}
message MessageBusinessSaveResp{
}
message MessageBusinessDeleteReq {
int64 Id = 1;
}
message MessageBusinessDeleteResp{
}
message MessageBusinessUpdateReq {
int64 Id = 1;
}
message MessageBusinessUpdateResp{
}
message MessageBusinessSearchReq {
int64 PageNumber = 1;
int64 PageSize = 2;
}
message MessageBusinessSearchResp{
repeated MessageBusinessItem List =1;
int64 Total =2;
}
message MessageBusinessItem {
}
service MessageBusinessService {
rpc MessageBusinessGet(MessageBusinessGetReq) returns(MessageBusinessGetResp);
rpc MessageBusinessSave(MessageBusinessSaveReq) returns(MessageBusinessSaveResp);
rpc MessageBusinessDelete(MessageBusinessDeleteReq) returns(MessageBusinessDeleteResp);
rpc MessageBusinessUpdate(MessageBusinessUpdateReq) returns(MessageBusinessUpdateResp);
rpc MessageBusinessSearch(MessageBusinessSearchReq) returns(MessageBusinessSearchResp);
}
... ...
syntax = "proto3";
option go_package ="./pb";
package pb;
message MessageSystemGetReq {
int64 Id = 1;
}
message MessageSystemGetResp{
MessageSystemItem User = 1;
}
message MessageSystemSaveReq {
}
message MessageSystemSaveResp{
}
message MessageSystemDeleteReq {
int64 Id = 1;
}
message MessageSystemDeleteResp{
}
message MessageSystemUpdateReq {
int64 Id = 1;
}
message MessageSystemUpdateResp{
}
message MessageSystemSearchReq {
int64 PageNumber = 1;
int64 PageSize = 2;
}
message MessageSystemSearchResp{
repeated MessageSystemItem List =1;
int64 Total =2;
}
message MessageSystemItem {
}
service MessageSystemService {
rpc MessageSystemGet(MessageSystemGetReq) returns(MessageSystemGetResp);
rpc MessageSystemSave(MessageSystemSaveReq) returns(MessageSystemSaveResp);
rpc MessageSystemDelete(MessageSystemDeleteReq) returns(MessageSystemDeleteResp);
rpc MessageSystemUpdate(MessageSystemUpdateReq) returns(MessageSystemUpdateResp);
rpc MessageSystemSearch(MessageSystemSearchReq) returns(MessageSystemSearchResp);
}
... ...
package models
import (
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
"gorm.io/gorm"
"gorm.io/plugin/soft_delete"
)
type MessageBusiness struct {
Id int64 // 唯一标识
Type int `json:"type"` // 分类 (1回复 2点赞 3被采纳)
OptType int `json:"optType"` // 操作类型(1针对文章、1针对评论、2针对圆桌)
TriggerId int64 `json:"triggerId"` // 触发者ID
RecipientId int64 `json:"recipientId"` // 接收者ID
ArticleId int64 `json:"articleId"` // 文章ID
CommentId int64 `json:"commentId"` // 评论ID
DiscussionId int64 `json:"discussionId"` // 圆桌ID
DiscussionOpinionId int64 `json:"discussionOpinionId"` // 观点ID
Content string `json:"content"` // 消息内容
CreatedAt int64 `json:",omitempty"`
UpdatedAt int64 `json:",omitempty"`
DeletedAt int64 `json:",omitempty"`
Version int `json:",omitempty"`
IsDel soft_delete.DeletedAt `gorm:"softDelete:flag,DeletedAtField:DeletedAt"`
}
func (m *MessageBusiness) TableName() string {
return "message_business"
}
func (m *MessageBusiness) BeforeCreate(tx *gorm.DB) (err error) {
// m.CreatedAt = time.Now().Unix()
// m.UpdatedAt = time.Now().Unix()
return
}
func (m *MessageBusiness) BeforeUpdate(tx *gorm.DB) (err error) {
// m.UpdatedAt = time.Now().Unix()
return
}
func (m *MessageBusiness) CacheKeyFunc() string {
if m.Id == 0 {
return ""
}
return fmt.Sprintf("%v:cache:%v:id:%v", domain.ProjectName, m.TableName(), m.Id)
}
func (m *MessageBusiness) CacheKeyFuncByObject(obj interface{}) string {
if v, ok := obj.(*MessageBusiness); ok {
return v.CacheKeyFunc()
}
return ""
}
func (m *MessageBusiness) CachePrimaryKeyFunc() string {
if len("") == 0 {
return ""
}
return fmt.Sprintf("%v:cache:%v:primarykey:%v", domain.ProjectName, m.TableName(), "key")
}
... ...
package models
import (
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
"gorm.io/gorm"
"gorm.io/plugin/soft_delete"
)
type MessageSystem struct {
Id int64 // 唯一标识
RecipientId int64 `json:"recipientId"` // 接收者ID
Type int `json:"type"` // 系统分类(0待定、1业务正常通知、2业务异常通知)
Title string `json:"title"` // 标题
Content string `json:"content"` // 内容
CreatedAt int64 `json:",omitempty"`
UpdatedAt int64 `json:",omitempty"`
DeletedAt int64 `json:",omitempty"`
Version int `json:",omitempty"`
IsDel soft_delete.DeletedAt `gorm:"softDelete:flag,DeletedAtField:DeletedAt"`
}
func (m *MessageSystem) TableName() string {
return "message_system"
}
func (m *MessageSystem) BeforeCreate(tx *gorm.DB) (err error) {
// m.CreatedAt = time.Now().Unix()
// m.UpdatedAt = time.Now().Unix()
return
}
func (m *MessageSystem) BeforeUpdate(tx *gorm.DB) (err error) {
// m.UpdatedAt = time.Now().Unix()
return
}
func (m *MessageSystem) CacheKeyFunc() string {
if m.Id == 0 {
return ""
}
return fmt.Sprintf("%v:cache:%v:id:%v", domain.ProjectName, m.TableName(), m.Id)
}
func (m *MessageSystem) CacheKeyFuncByObject(obj interface{}) string {
if v, ok := obj.(*MessageSystem); ok {
return v.CacheKeyFunc()
}
return ""
}
func (m *MessageSystem) CachePrimaryKeyFunc() string {
if len("") == 0 {
return ""
}
return fmt.Sprintf("%v:cache:%v:primarykey:%v", domain.ProjectName, m.TableName(), "key")
}
... ...
package repository
import (
"context"
"github.com/jinzhu/copier"
"github.com/pkg/errors"
"github.com/tiptok/gocomm/pkg/cache"
"gorm.io/gorm"
)
type MessageBusinessRepository struct {
*cache.CachedRepository
}
func (repository *MessageBusinessRepository) Insert(ctx context.Context, conn transaction.Conn, dm *domain.MessageBusiness) (*domain.MessageBusiness, error) {
var (
err error
m = &models.MessageBusiness{}
tx = conn.DB()
)
if m, err = repository.DomainModelToModel(dm); err != nil {
return nil, err
}
if tx = tx.Model(m).Save(m); tx.Error != nil {
return nil, tx.Error
}
dm.Id = m.Id
return repository.ModelToDomainModel(m)
}
func (repository *MessageBusinessRepository) Update(ctx context.Context, conn transaction.Conn, dm *domain.MessageBusiness) (*domain.MessageBusiness, error) {
var (
err error
m *models.MessageBusiness
tx = conn.DB()
)
if m, err = repository.DomainModelToModel(dm); err != nil {
return nil, err
}
queryFunc := func() (interface{}, error) {
tx = tx.Model(m).Updates(m)
return nil, tx.Error
}
if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
return nil, err
}
return repository.ModelToDomainModel(m)
}
func (repository *MessageBusinessRepository) UpdateWithVersion(ctx context.Context, transaction transaction.Conn, dm *domain.MessageBusiness) (*domain.MessageBusiness, error) {
var (
err error
m *models.MessageBusiness
tx = transaction.DB()
)
if m, err = repository.DomainModelToModel(dm); err != nil {
return nil, err
}
oldVersion := dm.Version
m.Version += 1
queryFunc := func() (interface{}, error) {
tx = tx.Model(m).Select("*").Where("id = ?", m.Id).Where("version = ?", oldVersion).Updates(m)
if tx.RowsAffected == 0 {
return nil, domain.ErrUpdateFail
}
return nil, tx.Error
}
if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
return nil, err
}
return repository.ModelToDomainModel(m)
}
func (repository *MessageBusinessRepository) Delete(ctx context.Context, conn transaction.Conn, dm *domain.MessageBusiness) (*domain.MessageBusiness, error) {
var (
tx = conn.DB()
m = &models.MessageBusiness{Id: dm.Identify().(int64)}
)
queryFunc := func() (interface{}, error) {
tx = tx.Where("id = ?", m.Id).Delete(m)
return m, tx.Error
}
if _, err := repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
return dm, err
}
return repository.ModelToDomainModel(m)
}
func (repository *MessageBusinessRepository) FindOne(ctx context.Context, conn transaction.Conn, id int64) (*domain.MessageBusiness, error) {
var (
err error
tx = conn.DB()
m = new(models.MessageBusiness)
)
queryFunc := func() (interface{}, error) {
tx = tx.Model(m).Where("id = ?", id).First(m)
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, domain.ErrNotFound
}
return m, tx.Error
}
cacheModel := new(models.MessageBusiness)
cacheModel.Id = id
if err = repository.QueryCache(cacheModel.CacheKeyFunc, m, queryFunc); err != nil {
return nil, err
}
return repository.ModelToDomainModel(m)
}
func (repository *MessageBusinessRepository) Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*domain.MessageBusiness, error) {
var (
tx = conn.DB()
ms []*models.MessageBusiness
dms = make([]*domain.MessageBusiness, 0)
total int64
)
queryFunc := func() (interface{}, error) {
tx = tx.Model(&ms).Order("id desc")
if total, tx = transaction.PaginationAndCount(ctx, tx, queryOptions, &ms); tx.Error != nil {
return dms, tx.Error
}
return dms, nil
}
if _, err := repository.Query(queryFunc); err != nil {
return 0, nil, err
}
for _, item := range ms {
if dm, err := repository.ModelToDomainModel(item); err != nil {
return 0, dms, err
} else {
dms = append(dms, dm)
}
}
return total, dms, nil
}
func (repository *MessageBusinessRepository) ModelToDomainModel(from *models.MessageBusiness) (*domain.MessageBusiness, error) {
to := &domain.MessageBusiness{}
err := copier.Copy(to, from)
return to, err
}
func (repository *MessageBusinessRepository) DomainModelToModel(from *domain.MessageBusiness) (*models.MessageBusiness, error) {
to := &models.MessageBusiness{}
err := copier.Copy(to, from)
return to, err
}
func NewMessageBusinessRepository(cache *cache.CachedRepository) domain.MessageBusinessRepository {
return &MessageBusinessRepository{CachedRepository: cache}
}
... ...
package repository
import (
"context"
"github.com/jinzhu/copier"
"github.com/pkg/errors"
"github.com/tiptok/gocomm/pkg/cache"
"gorm.io/gorm"
)
type MessageSystemRepository struct {
*cache.CachedRepository
}
func (repository *MessageSystemRepository) Insert(ctx context.Context, conn transaction.Conn, dm *domain.MessageSystem) (*domain.MessageSystem, error) {
var (
err error
m = &models.MessageSystem{}
tx = conn.DB()
)
if m, err = repository.DomainModelToModel(dm); err != nil {
return nil, err
}
if tx = tx.Model(m).Save(m); tx.Error != nil {
return nil, tx.Error
}
dm.Id = m.Id
return repository.ModelToDomainModel(m)
}
func (repository *MessageSystemRepository) Update(ctx context.Context, conn transaction.Conn, dm *domain.MessageSystem) (*domain.MessageSystem, error) {
var (
err error
m *models.MessageSystem
tx = conn.DB()
)
if m, err = repository.DomainModelToModel(dm); err != nil {
return nil, err
}
queryFunc := func() (interface{}, error) {
tx = tx.Model(m).Updates(m)
return nil, tx.Error
}
if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
return nil, err
}
return repository.ModelToDomainModel(m)
}
func (repository *MessageSystemRepository) UpdateWithVersion(ctx context.Context, transaction transaction.Conn, dm *domain.MessageSystem) (*domain.MessageSystem, error) {
var (
err error
m *models.MessageSystem
tx = transaction.DB()
)
if m, err = repository.DomainModelToModel(dm); err != nil {
return nil, err
}
oldVersion := dm.Version
m.Version += 1
queryFunc := func() (interface{}, error) {
tx = tx.Model(m).Select("*").Where("id = ?", m.Id).Where("version = ?", oldVersion).Updates(m)
if tx.RowsAffected == 0 {
return nil, domain.ErrUpdateFail
}
return nil, tx.Error
}
if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
return nil, err
}
return repository.ModelToDomainModel(m)
}
func (repository *MessageSystemRepository) Delete(ctx context.Context, conn transaction.Conn, dm *domain.MessageSystem) (*domain.MessageSystem, error) {
var (
tx = conn.DB()
m = &models.MessageSystem{Id: dm.Identify().(int64)}
)
queryFunc := func() (interface{}, error) {
tx = tx.Where("id = ?", m.Id).Delete(m)
return m, tx.Error
}
if _, err := repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
return dm, err
}
return repository.ModelToDomainModel(m)
}
func (repository *MessageSystemRepository) FindOne(ctx context.Context, conn transaction.Conn, id int64) (*domain.MessageSystem, error) {
var (
err error
tx = conn.DB()
m = new(models.MessageSystem)
)
queryFunc := func() (interface{}, error) {
tx = tx.Model(m).Where("id = ?", id).First(m)
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, domain.ErrNotFound
}
return m, tx.Error
}
cacheModel := new(models.MessageSystem)
cacheModel.Id = id
if err = repository.QueryCache(cacheModel.CacheKeyFunc, m, queryFunc); err != nil {
return nil, err
}
return repository.ModelToDomainModel(m)
}
func (repository *MessageSystemRepository) Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*domain.MessageSystem, error) {
var (
tx = conn.DB()
ms []*models.MessageSystem
dms = make([]*domain.MessageSystem, 0)
total int64
)
queryFunc := func() (interface{}, error) {
tx = tx.Model(&ms).Order("id desc")
if total, tx = transaction.PaginationAndCount(ctx, tx, queryOptions, &ms); tx.Error != nil {
return dms, tx.Error
}
return dms, nil
}
if _, err := repository.Query(queryFunc); err != nil {
return 0, nil, err
}
for _, item := range ms {
if dm, err := repository.ModelToDomainModel(item); err != nil {
return 0, dms, err
} else {
dms = append(dms, dm)
}
}
return total, dms, nil
}
func (repository *MessageSystemRepository) ModelToDomainModel(from *models.MessageSystem) (*domain.MessageSystem, error) {
to := &domain.MessageSystem{}
err := copier.Copy(to, from)
return to, err
}
func (repository *MessageSystemRepository) DomainModelToModel(from *domain.MessageSystem) (*models.MessageSystem, error) {
to := &models.MessageSystem{}
err := copier.Copy(to, from)
return to, err
}
func NewMessageSystemRepository(cache *cache.CachedRepository) domain.MessageSystemRepository {
return &MessageSystemRepository{CachedRepository: cache}
}
... ...
package domain
import (
"context"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction"
)
type MessageBusiness struct {
Id int64 // 唯一标识
Type int `json:"type"` // 分类 (1回复 2点赞 3被采纳)
OptType int `json:"optType"` // 操作类型(1针对文章、1针对评论、2针对圆桌)
TriggerId int64 `json:"triggerId"` // 触发者ID
RecipientId int64 `json:"recipientId"` // 接收者ID
ArticleId int64 `json:"articleId"` // 文章ID
CommentId int64 `json:"commentId"` // 评论ID
DiscussionId int64 `json:"discussionId"` // 圆桌ID
DiscussionOpinionId int64 `json:"discussionOpinionId"` // 观点ID
Content string `json:"content"` // 消息内容
CreatedAt int64 `json:",omitempty"`
UpdatedAt int64 `json:",omitempty"`
DeletedAt int64 `json:",omitempty"`
Version int `json:",omitempty"`
}
type MessageBusinessRepository interface {
Insert(ctx context.Context, conn transaction.Conn, dm *MessageBusiness) (*MessageBusiness, error)
Update(ctx context.Context, conn transaction.Conn, dm *MessageBusiness) (*MessageBusiness, error)
UpdateWithVersion(ctx context.Context, conn transaction.Conn, dm *MessageBusiness) (*MessageBusiness, error)
Delete(ctx context.Context, conn transaction.Conn, dm *MessageBusiness) (*MessageBusiness, error)
FindOne(ctx context.Context, conn transaction.Conn, id int64) (*MessageBusiness, error)
Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*MessageBusiness, error)
}
func (m *MessageBusiness) Identify() interface{} {
if m.Id == 0 {
return nil
}
return m.Id
}
... ...
package domain
import (
"context"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction"
)
type MessageSystem struct {
Id int64 // 唯一标识
RecipientId int64 `json:"recipientId"` // 接收者ID
Type int `json:"type"` // 系统分类(0待定、1业务正常通知、2业务异常通知)
Title string `json:"title"` // 标题
Content string `json:"content"` // 内容
CreatedAt int64 `json:",omitempty"`
UpdatedAt int64 `json:",omitempty"`
DeletedAt int64 `json:",omitempty"`
Version int `json:",omitempty"`
}
type MessageSystemRepository interface {
Insert(ctx context.Context, conn transaction.Conn, dm *MessageSystem) (*MessageSystem, error)
Update(ctx context.Context, conn transaction.Conn, dm *MessageSystem) (*MessageSystem, error)
UpdateWithVersion(ctx context.Context, conn transaction.Conn, dm *MessageSystem) (*MessageSystem, error)
Delete(ctx context.Context, conn transaction.Conn, dm *MessageSystem) (*MessageSystem, error)
FindOne(ctx context.Context, conn transaction.Conn, id int64) (*MessageSystem, error)
Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*MessageSystem, error)
}
func (m *MessageSystem) Identify() interface{} {
if m.Id == 0 {
return nil
}
return m.Id
}
... ...