作者 yangfu

用户关注、公司模型

@@ -16,7 +16,20 @@ type ServiceContext struct { @@ -16,7 +16,20 @@ type ServiceContext struct {
16 DB *gorm.DB 16 DB *gorm.DB
17 Redis *redis.Redis 17 Redis *redis.Redis
18 18
19 - CommentRepository domain.CommentRepository 19 + ArticleBackupRepository domain.ArticleBackupRepository
  20 + ArticleCommentRepository domain.ArticleCommentRepository
  21 + ArticleDraftRepository domain.ArticleDraftRepository
  22 + ArticleRepository domain.ArticleRepository
  23 +
  24 + CompanyRepository domain.CompanyRepository
  25 + CommentRepository domain.CommentRepository // 待移除
  26 + DepartmentRepository domain.DepartmentRepository
  27 + MessageBusinessRepository domain.MessageBusinessRepository
  28 + MessageSystemRepository domain.MessageSystemRepository
  29 + RoleRepository domain.RoleRepository
  30 + UserFollowRepository domain.UserFollowRepository
  31 + UserLoveFlagRepository domain.UserLoveFlagRepository
  32 + UserRepository domain.UserRepository
20 } 33 }
21 34
22 func NewServiceContext(c config.Config) *ServiceContext { 35 func NewServiceContext(c config.Config) *ServiceContext {
@@ -26,10 +39,22 @@ func NewServiceContext(c config.Config) *ServiceContext { @@ -26,10 +39,22 @@ func NewServiceContext(c config.Config) *ServiceContext {
26 redis, _ := redis.NewRedis(redis.RedisConf{Host: c.Redis.Host, Pass: c.Redis.Pass, Type: "node"}) 39 redis, _ := redis.NewRedis(redis.RedisConf{Host: c.Redis.Host, Pass: c.Redis.Pass, Type: "node"})
27 40
28 return &ServiceContext{ 41 return &ServiceContext{
29 - Config: c,  
30 - DB: db,  
31 - Redis: redis,  
32 - CommentRepository: repository.NewCommentRepository(cache.NewCachedRepository(mlCache)), 42 + Config: c,
  43 + DB: db,
  44 + Redis: redis,
  45 + CommentRepository: repository.NewCommentRepository(cache.NewCachedRepository(mlCache)),
  46 + ArticleBackupRepository: repository.NewArticleBackupRepository(cache.NewCachedRepository(mlCache)),
  47 + ArticleCommentRepository: repository.NewArticleCommentRepository(cache.NewCachedRepository(mlCache)),
  48 + ArticleDraftRepository: repository.NewArticleDraftRepository(cache.NewCachedRepository(mlCache)),
  49 + ArticleRepository: repository.NewArticleRepository(cache.NewCachedRepository(mlCache)),
  50 + CompanyRepository: repository.NewCompanyRepository(cache.NewCachedRepository(mlCache)),
  51 + DepartmentRepository: repository.NewDepartmentRepository(cache.NewCachedRepository(mlCache)),
  52 + MessageBusinessRepository: repository.NewMessageBusinessRepository(cache.NewCachedRepository(mlCache)),
  53 + MessageSystemRepository: repository.NewMessageSystemRepository(cache.NewCachedRepository(mlCache)),
  54 + RoleRepository: repository.NewRoleRepository(cache.NewCachedRepository(mlCache)),
  55 + UserFollowRepository: repository.NewUserFollowRepository(cache.NewCachedRepository(mlCache)),
  56 + UserLoveFlagRepository: repository.NewUserLoveFlagRepository(cache.NewCachedRepository(mlCache)),
  57 + UserRepository: repository.NewUserRepository(cache.NewCachedRepository(mlCache)),
33 } 58 }
34 } 59 }
35 60
  1 +
  2 +syntax = "v1"
  3 +
  4 +info(
  5 + title: "xx实例"
  6 + desc: "xx实例"
  7 + author: "author"
  8 + email: "email"
  9 + version: "v1"
  10 +)
  11 +
  12 +@server(
  13 + prefix: company/v1
  14 + group: company
  15 + jwt: JwtAuth
  16 +)
  17 +service Core {
  18 + @handler getCompany
  19 + post /company/:id (CompanyGetRequest) returns (CompanyGetResponse)
  20 + @handler saveCompany
  21 + post /company (CompanySaveRequest) returns (CompanySaveResponse)
  22 + @handler deleteCompany
  23 + delete /company/:id (CompanyDeleteRequest) returns (CompanyDeleteResponse)
  24 + @handler updateCompany
  25 + put /company/:id (CompanyUpdateRequest) returns (CompanyUpdateResponse)
  26 + @handler searchCompany
  27 + post /company/search (CompanySearchRequest) returns (CompanySearchResponse)
  28 +}
  29 +
  30 +type (
  31 + CompanyGetRequest {
  32 + Id int64 `path:"id"`
  33 + }
  34 + CompanyGetResponse struct{
  35 + Company CompanyItem `json:"company"`
  36 + }
  37 +
  38 + CompanySaveRequest struct{
  39 + Company CompanyItem `json:"company"`
  40 + }
  41 + CompanySaveResponse struct{}
  42 +
  43 + CompanyDeleteRequest struct{
  44 + Id int64 `path:"id"`
  45 + }
  46 + CompanyDeleteResponse struct{}
  47 +
  48 + CompanyUpdateRequest struct{
  49 + Id int64 `path:"id"`
  50 + Company CompanyItem `json:"company"`
  51 + }
  52 + CompanyUpdateResponse struct{}
  53 +
  54 + CompanySearchRequest struct{
  55 + Page int `json:"page"`
  56 + Size int `json:"size"`
  57 + }
  58 + CompanySearchResponse{
  59 + List []CompanyItem `json:"list"`
  60 + Total int64 `json:"total"`
  61 + }
  62 + CompanyItem struct{
  63 +
  64 + }
  65 +)
  1 +
  2 +syntax = "v1"
  3 +
  4 +info(
  5 + title: "xx实例"
  6 + desc: "xx实例"
  7 + author: "author"
  8 + email: "email"
  9 + version: "v1"
  10 +)
  11 +
  12 +@server(
  13 + prefix: user_follow/v1
  14 + group: user_follow
  15 + jwt: JwtAuth
  16 +)
  17 +service Core {
  18 + @handler getUserFollow
  19 + post /user_follow/:id (UserFollowGetRequest) returns (UserFollowGetResponse)
  20 + @handler saveUserFollow
  21 + post /user_follow (UserFollowSaveRequest) returns (UserFollowSaveResponse)
  22 + @handler deleteUserFollow
  23 + delete /user_follow/:id (UserFollowDeleteRequest) returns (UserFollowDeleteResponse)
  24 + @handler updateUserFollow
  25 + put /user_follow/:id (UserFollowUpdateRequest) returns (UserFollowUpdateResponse)
  26 + @handler searchUserFollow
  27 + post /user_follow/search (UserFollowSearchRequest) returns (UserFollowSearchResponse)
  28 +}
  29 +
  30 +type (
  31 + UserFollowGetRequest {
  32 + Id int64 `path:"id"`
  33 + }
  34 + UserFollowGetResponse struct{
  35 + UserFollow UserFollowItem `json:"user_follow"`
  36 + }
  37 +
  38 + UserFollowSaveRequest struct{
  39 + UserFollow UserFollowItem `json:"user_follow"`
  40 + }
  41 + UserFollowSaveResponse struct{}
  42 +
  43 + UserFollowDeleteRequest struct{
  44 + Id int64 `path:"id"`
  45 + }
  46 + UserFollowDeleteResponse struct{}
  47 +
  48 + UserFollowUpdateRequest struct{
  49 + Id int64 `path:"id"`
  50 + UserFollow UserFollowItem `json:"user_follow"`
  51 + }
  52 + UserFollowUpdateResponse struct{}
  53 +
  54 + UserFollowSearchRequest struct{
  55 + Page int `json:"page"`
  56 + Size int `json:"size"`
  57 + }
  58 + UserFollowSearchResponse{
  59 + List []UserFollowItem `json:"list"`
  60 + Total int64 `json:"total"`
  61 + }
  62 + UserFollowItem struct{
  63 +
  64 + }
  65 +)
  1 +
  2 +syntax = "proto3";
  3 +
  4 +option go_package ="./pb";
  5 +
  6 +package pb;
  7 +
  8 +message CompanyGetReq {
  9 + int64 Id = 1;
  10 +}
  11 +message CompanyGetResp{
  12 + CompanyItem User = 1;
  13 +}
  14 +
  15 +message CompanySaveReq {
  16 +
  17 +}
  18 +message CompanySaveResp{
  19 +
  20 +}
  21 +
  22 +message CompanyDeleteReq {
  23 + int64 Id = 1;
  24 +}
  25 +message CompanyDeleteResp{
  26 +
  27 +}
  28 +
  29 +message CompanyUpdateReq {
  30 + int64 Id = 1;
  31 +}
  32 +message CompanyUpdateResp{
  33 +
  34 +}
  35 +
  36 +message CompanySearchReq {
  37 + int64 PageNumber = 1;
  38 + int64 PageSize = 2;
  39 +}
  40 +message CompanySearchResp{
  41 + repeated CompanyItem List =1;
  42 + int64 Total =2;
  43 +}
  44 +message CompanyItem {
  45 +
  46 +}
  47 +
  48 +service CompanyService {
  49 + rpc CompanyGet(CompanyGetReq) returns(CompanyGetResp);
  50 + rpc CompanySave(CompanySaveReq) returns(CompanySaveResp);
  51 + rpc CompanyDelete(CompanyDeleteReq) returns(CompanyDeleteResp);
  52 + rpc CompanyUpdate(CompanyUpdateReq) returns(CompanyUpdateResp);
  53 + rpc CompanySearch(CompanySearchReq) returns(CompanySearchResp);
  54 +}
  1 +
  2 +syntax = "proto3";
  3 +
  4 +option go_package ="./pb";
  5 +
  6 +package pb;
  7 +
  8 +message UserFollowGetReq {
  9 + int64 Id = 1;
  10 +}
  11 +message UserFollowGetResp{
  12 + UserFollowItem User = 1;
  13 +}
  14 +
  15 +message UserFollowSaveReq {
  16 +
  17 +}
  18 +message UserFollowSaveResp{
  19 +
  20 +}
  21 +
  22 +message UserFollowDeleteReq {
  23 + int64 Id = 1;
  24 +}
  25 +message UserFollowDeleteResp{
  26 +
  27 +}
  28 +
  29 +message UserFollowUpdateReq {
  30 + int64 Id = 1;
  31 +}
  32 +message UserFollowUpdateResp{
  33 +
  34 +}
  35 +
  36 +message UserFollowSearchReq {
  37 + int64 PageNumber = 1;
  38 + int64 PageSize = 2;
  39 +}
  40 +message UserFollowSearchResp{
  41 + repeated UserFollowItem List =1;
  42 + int64 Total =2;
  43 +}
  44 +message UserFollowItem {
  45 +
  46 +}
  47 +
  48 +service UserFollowService {
  49 + rpc UserFollowGet(UserFollowGetReq) returns(UserFollowGetResp);
  50 + rpc UserFollowSave(UserFollowSaveReq) returns(UserFollowSaveResp);
  51 + rpc UserFollowDelete(UserFollowDeleteReq) returns(UserFollowDeleteResp);
  52 + rpc UserFollowUpdate(UserFollowUpdateReq) returns(UserFollowUpdateResp);
  53 + rpc UserFollowSearch(UserFollowSearchReq) returns(UserFollowSearchResp);
  54 +}
  1 +package models
  2 +
  3 +import (
  4 + "fmt"
  5 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
  6 + "gorm.io/gorm"
  7 + "time"
  8 +)
  9 +
  10 +type Company struct {
  11 + Id int64 // 唯一标识
  12 + Name string `json:"name,omitempty"` // 名称
  13 + Code string `json:"code,omitempty"` // 编码(搜索使用,4位字母数字)
  14 + Logo string `json:"logo,omitempty"` // 公司LOGO
  15 +
  16 + CreatedAt int64 `json:"createdAt,omitempty"`
  17 + UpdatedAt int64 `json:"updatedAt,omitempty"`
  18 + DeletedAt int64 `json:"deletedAt,omitempty"`
  19 + Version int `json:"version,omitempty"`
  20 +}
  21 +
  22 +func (m *Company) TableName() string {
  23 + return "company"
  24 +}
  25 +
  26 +func (m *Company) BeforeCreate(tx *gorm.DB) (err error) {
  27 + m.CreatedAt = time.Now().Unix()
  28 + m.UpdatedAt = time.Now().Unix()
  29 + return
  30 +}
  31 +
  32 +func (m *Company) BeforeUpdate(tx *gorm.DB) (err error) {
  33 + m.UpdatedAt = time.Now().Unix()
  34 + return
  35 +}
  36 +
  37 +func (m *Company) CacheKeyFunc() string {
  38 + if m.Id == 0 {
  39 + return ""
  40 + }
  41 + return fmt.Sprintf("%v:cache:%v:id:%v", domain.ProjectName, m.TableName(), m.Id)
  42 +}
  43 +
  44 +func (m *Company) CacheKeyFuncByObject(obj interface{}) string {
  45 + if v, ok := obj.(*Company); ok {
  46 + return v.CacheKeyFunc()
  47 + }
  48 + return ""
  49 +}
  50 +
  51 +func (m *Company) CachePrimaryKeyFunc() string {
  52 + if len("") == 0 {
  53 + return ""
  54 + }
  55 + return fmt.Sprintf("%v:cache:%v:primarykey:%v", domain.ProjectName, m.TableName(), "key")
  56 +}
@@ -8,7 +8,19 @@ import ( @@ -8,7 +8,19 @@ import (
8 ) 8 )
9 9
10 type User struct { 10 type User struct {
11 - Id int64 // 唯一标识 11 + Id int64 // 唯一标识
  12 + CompanyId int64 `json:"companyId,omitempty"` // 公司ID
  13 + DepartmentId int64 `json:"departmentId,omitempty"` // 部门ID
  14 + Roles []int64 `json:"roleId,omitempty"` // 角色
  15 + Flag int `json:"flag"` // 标识 1:管理员 2:普通用户 (有绑定角色是管理员)
  16 + Name string `json:"name,omitempty"` // 名称
  17 + Avatar string `json:"avatar,omitempty"` // 头像
  18 + Phone string `json:"phone,omitempty"` // 手机号 唯一
  19 + Position string `json:"position,omitempty"` // 职位
  20 + Enable int `json:"enable,omitempty"` // 启用状态 1:启用 2:禁用
  21 + AuditStatus int `json:"auditStatus,omitempty"` // 审核状态 0:待审核 1:审核通过 2:拒绝
  22 + Follower []int64 `json:"followers,omitempty"` // 关注我的人 (冗余)
  23 + Following []int64 `json:"following,omitempty"` // 我关注的人 (冗余)
12 24
13 CreatedAt int64 `json:"createdAt,omitempty"` 25 CreatedAt int64 `json:"createdAt,omitempty"`
14 UpdatedAt int64 `json:"updatedAt,omitempty"` 26 UpdatedAt int64 `json:"updatedAt,omitempty"`
  1 +package models
  2 +
  3 +import (
  4 + "fmt"
  5 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
  6 + "gorm.io/gorm"
  7 + "time"
  8 +)
  9 +
  10 +type UserFollow struct {
  11 + Id int64 // 唯一标识
  12 +
  13 + CreatedAt int64 `json:"createdAt,omitempty"`
  14 + UpdatedAt int64 `json:"updatedAt,omitempty"`
  15 + DeletedAt int64 `json:"deletedAt,omitempty"`
  16 + Version int `json:"version,omitempty"`
  17 +}
  18 +
  19 +func (m *UserFollow) TableName() string {
  20 + return "user_follow"
  21 +}
  22 +
  23 +func (m *UserFollow) BeforeCreate(tx *gorm.DB) (err error) {
  24 + m.CreatedAt = time.Now().Unix()
  25 + m.UpdatedAt = time.Now().Unix()
  26 + return
  27 +}
  28 +
  29 +func (m *UserFollow) BeforeUpdate(tx *gorm.DB) (err error) {
  30 + m.UpdatedAt = time.Now().Unix()
  31 + return
  32 +}
  33 +
  34 +func (m *UserFollow) CacheKeyFunc() string {
  35 + //if m.Id == 0 {
  36 + // return ""
  37 + //}
  38 + //return fmt.Sprintf("%v:cache:%v:id:%v", domain.ProjectName, m.TableName(), m.Id)
  39 + return ""
  40 +}
  41 +
  42 +func (m *UserFollow) CacheKeyFuncByObject(obj interface{}) string {
  43 + if v, ok := obj.(*UserFollow); ok {
  44 + return v.CacheKeyFunc()
  45 + }
  46 + return ""
  47 +}
  48 +
  49 +func (m *UserFollow) CachePrimaryKeyFunc() string {
  50 + if len("") == 0 {
  51 + return ""
  52 + }
  53 + return fmt.Sprintf("%v:cache:%v:primarykey:%v", domain.ProjectName, m.TableName(), "key")
  54 +}
  1 +package repository
  2 +
  3 +import (
  4 + "context"
  5 + "github.com/jinzhu/copier"
  6 + "github.com/pkg/errors"
  7 + "github.com/tiptok/gocomm/pkg/cache"
  8 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/models"
  9 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction"
  10 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
  11 + "gorm.io/gorm"
  12 +)
  13 +
  14 +type CompanyRepository struct {
  15 + *cache.CachedRepository
  16 +}
  17 +
  18 +func (repository *CompanyRepository) Insert(ctx context.Context, conn transaction.Conn, dm *domain.Company) (*domain.Company, error) {
  19 + var (
  20 + err error
  21 + m = &models.Company{}
  22 + tx = conn.DB()
  23 + )
  24 + if m, err = repository.DomainModelToModel(dm); err != nil {
  25 + return nil, err
  26 + }
  27 + if tx = tx.Model(m).Save(m); tx.Error != nil {
  28 + return nil, tx.Error
  29 + }
  30 + dm.Id = m.Id
  31 + return repository.ModelToDomainModel(m)
  32 +
  33 +}
  34 +
  35 +func (repository *CompanyRepository) Update(ctx context.Context, conn transaction.Conn, dm *domain.Company) (*domain.Company, error) {
  36 + var (
  37 + err error
  38 + m *models.Company
  39 + tx = conn.DB()
  40 + )
  41 + if m, err = repository.DomainModelToModel(dm); err != nil {
  42 + return nil, err
  43 + }
  44 + queryFunc := func() (interface{}, error) {
  45 + tx = tx.Model(m).Updates(m)
  46 + return nil, tx.Error
  47 + }
  48 + if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
  49 + return nil, err
  50 + }
  51 + return repository.ModelToDomainModel(m)
  52 +}
  53 +
  54 +func (repository *CompanyRepository) UpdateWithVersion(ctx context.Context, transaction transaction.Conn, dm *domain.Company) (*domain.Company, error) {
  55 + var (
  56 + err error
  57 + m *models.Company
  58 + tx = transaction.DB()
  59 + )
  60 + if m, err = repository.DomainModelToModel(dm); err != nil {
  61 + return nil, err
  62 + }
  63 + oldVersion := dm.Version
  64 + m.Version += 1
  65 + queryFunc := func() (interface{}, error) {
  66 + tx = tx.Model(m).Select("*").Where("id = ?", m.Id).Where("version = ?", oldVersion).Updates(m)
  67 + if tx.RowsAffected == 0 {
  68 + return nil, domain.ErrUpdateFail
  69 + }
  70 + return nil, tx.Error
  71 + }
  72 + if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
  73 + return nil, err
  74 + }
  75 + return repository.ModelToDomainModel(m)
  76 +}
  77 +
  78 +func (repository *CompanyRepository) Delete(ctx context.Context, conn transaction.Conn, dm *domain.Company) (*domain.Company, error) {
  79 + var (
  80 + tx = conn.DB()
  81 + m = &models.Company{Id: dm.Identify().(int64)}
  82 + )
  83 + queryFunc := func() (interface{}, error) {
  84 + tx = tx.Where("id = ?", m.Id).Delete(m)
  85 + return m, tx.Error
  86 + }
  87 + if _, err := repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
  88 + return dm, err
  89 + }
  90 + return repository.ModelToDomainModel(m)
  91 +}
  92 +
  93 +func (repository *CompanyRepository) FindOne(ctx context.Context, conn transaction.Conn, id int64) (*domain.Company, error) {
  94 + var (
  95 + err error
  96 + tx = conn.DB()
  97 + m = new(models.Company)
  98 + )
  99 + queryFunc := func() (interface{}, error) {
  100 + tx = tx.Model(m).Where("id = ?", id).First(m)
  101 + if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
  102 + return nil, domain.ErrNotFound
  103 + }
  104 + return m, tx.Error
  105 + }
  106 + cacheModel := new(models.Company)
  107 + cacheModel.Id = id
  108 + if err = repository.QueryCache(cacheModel.CacheKeyFunc, m, queryFunc); err != nil {
  109 + return nil, err
  110 + }
  111 + return repository.ModelToDomainModel(m)
  112 +}
  113 +
  114 +func (repository *CompanyRepository) Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*domain.Company, error) {
  115 + var (
  116 + tx = conn.DB()
  117 + ms []*models.Company
  118 + dms = make([]*domain.Company, 0)
  119 + total int64
  120 + )
  121 + queryFunc := func() (interface{}, error) {
  122 + tx = tx.Model(&ms).Order("id desc")
  123 + if total, tx = transaction.PaginationAndCount(ctx, tx, queryOptions, &ms); tx.Error != nil {
  124 + return dms, tx.Error
  125 + }
  126 + return dms, nil
  127 + }
  128 +
  129 + if _, err := repository.Query(queryFunc); err != nil {
  130 + return 0, nil, err
  131 + }
  132 +
  133 + for _, item := range ms {
  134 + if dm, err := repository.ModelToDomainModel(item); err != nil {
  135 + return 0, dms, err
  136 + } else {
  137 + dms = append(dms, dm)
  138 + }
  139 + }
  140 + return total, dms, nil
  141 +}
  142 +
  143 +func (repository *CompanyRepository) ModelToDomainModel(from *models.Company) (*domain.Company, error) {
  144 + to := &domain.Company{}
  145 + err := copier.Copy(to, from)
  146 + return to, err
  147 +}
  148 +
  149 +func (repository *CompanyRepository) DomainModelToModel(from *domain.Company) (*models.Company, error) {
  150 + to := &models.Company{}
  151 + err := copier.Copy(to, from)
  152 + return to, err
  153 +}
  154 +
  155 +func NewCompanyRepository(cache *cache.CachedRepository) domain.CompanyRepository {
  156 + return &CompanyRepository{CachedRepository: cache}
  157 +}
  1 +package repository
  2 +
  3 +import (
  4 + "context"
  5 + "github.com/jinzhu/copier"
  6 + "github.com/pkg/errors"
  7 + "github.com/tiptok/gocomm/pkg/cache"
  8 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/models"
  9 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction"
  10 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
  11 + "gorm.io/gorm"
  12 +)
  13 +
  14 +type UserFollowRepository struct {
  15 + *cache.CachedRepository
  16 +}
  17 +
  18 +func (repository *UserFollowRepository) Insert(ctx context.Context, conn transaction.Conn, dm *domain.UserFollow) (*domain.UserFollow, error) {
  19 + var (
  20 + err error
  21 + m = &models.UserFollow{}
  22 + tx = conn.DB()
  23 + )
  24 + if m, err = repository.DomainModelToModel(dm); err != nil {
  25 + return nil, err
  26 + }
  27 + if tx = tx.Model(m).Save(m); tx.Error != nil {
  28 + return nil, tx.Error
  29 + }
  30 + dm.Id = m.Id
  31 + return repository.ModelToDomainModel(m)
  32 +
  33 +}
  34 +
  35 +func (repository *UserFollowRepository) Update(ctx context.Context, conn transaction.Conn, dm *domain.UserFollow) (*domain.UserFollow, error) {
  36 + var (
  37 + err error
  38 + m *models.UserFollow
  39 + tx = conn.DB()
  40 + )
  41 + if m, err = repository.DomainModelToModel(dm); err != nil {
  42 + return nil, err
  43 + }
  44 + queryFunc := func() (interface{}, error) {
  45 + tx = tx.Model(m).Updates(m)
  46 + return nil, tx.Error
  47 + }
  48 + if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
  49 + return nil, err
  50 + }
  51 + return repository.ModelToDomainModel(m)
  52 +}
  53 +
  54 +func (repository *UserFollowRepository) UpdateWithVersion(ctx context.Context, transaction transaction.Conn, dm *domain.UserFollow) (*domain.UserFollow, error) {
  55 + var (
  56 + err error
  57 + m *models.UserFollow
  58 + tx = transaction.DB()
  59 + )
  60 + if m, err = repository.DomainModelToModel(dm); err != nil {
  61 + return nil, err
  62 + }
  63 + oldVersion := dm.Version
  64 + m.Version += 1
  65 + queryFunc := func() (interface{}, error) {
  66 + tx = tx.Model(m).Select("*").Where("id = ?", m.Id).Where("version = ?", oldVersion).Updates(m)
  67 + if tx.RowsAffected == 0 {
  68 + return nil, domain.ErrUpdateFail
  69 + }
  70 + return nil, tx.Error
  71 + }
  72 + if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
  73 + return nil, err
  74 + }
  75 + return repository.ModelToDomainModel(m)
  76 +}
  77 +
  78 +func (repository *UserFollowRepository) Delete(ctx context.Context, conn transaction.Conn, dm *domain.UserFollow) (*domain.UserFollow, error) {
  79 + var (
  80 + tx = conn.DB()
  81 + m = &models.UserFollow{Id: dm.Identify().(int64)}
  82 + )
  83 + queryFunc := func() (interface{}, error) {
  84 + tx = tx.Where("id = ?", m.Id).Delete(m)
  85 + return m, tx.Error
  86 + }
  87 + if _, err := repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
  88 + return dm, err
  89 + }
  90 + return repository.ModelToDomainModel(m)
  91 +}
  92 +
  93 +func (repository *UserFollowRepository) FindOne(ctx context.Context, conn transaction.Conn, id int64) (*domain.UserFollow, error) {
  94 + var (
  95 + err error
  96 + tx = conn.DB()
  97 + m = new(models.UserFollow)
  98 + )
  99 + queryFunc := func() (interface{}, error) {
  100 + tx = tx.Model(m).Where("id = ?", id).First(m)
  101 + if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
  102 + return nil, domain.ErrNotFound
  103 + }
  104 + return m, tx.Error
  105 + }
  106 + cacheModel := new(models.UserFollow)
  107 + cacheModel.Id = id
  108 + if err = repository.QueryCache(cacheModel.CacheKeyFunc, m, queryFunc); err != nil {
  109 + return nil, err
  110 + }
  111 + return repository.ModelToDomainModel(m)
  112 +}
  113 +
  114 +func (repository *UserFollowRepository) Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*domain.UserFollow, error) {
  115 + var (
  116 + tx = conn.DB()
  117 + ms []*models.UserFollow
  118 + dms = make([]*domain.UserFollow, 0)
  119 + total int64
  120 + )
  121 + queryFunc := func() (interface{}, error) {
  122 + tx = tx.Model(&ms).Order("id desc")
  123 + if total, tx = transaction.PaginationAndCount(ctx, tx, queryOptions, &ms); tx.Error != nil {
  124 + return dms, tx.Error
  125 + }
  126 + return dms, nil
  127 + }
  128 +
  129 + if _, err := repository.Query(queryFunc); err != nil {
  130 + return 0, nil, err
  131 + }
  132 +
  133 + for _, item := range ms {
  134 + if dm, err := repository.ModelToDomainModel(item); err != nil {
  135 + return 0, dms, err
  136 + } else {
  137 + dms = append(dms, dm)
  138 + }
  139 + }
  140 + return total, dms, nil
  141 +}
  142 +
  143 +func (repository *UserFollowRepository) ModelToDomainModel(from *models.UserFollow) (*domain.UserFollow, error) {
  144 + to := &domain.UserFollow{}
  145 + err := copier.Copy(to, from)
  146 + return to, err
  147 +}
  148 +
  149 +func (repository *UserFollowRepository) DomainModelToModel(from *domain.UserFollow) (*models.UserFollow, error) {
  150 + to := &models.UserFollow{}
  151 + err := copier.Copy(to, from)
  152 + return to, err
  153 +}
  154 +
  155 +func NewUserFollowRepository(cache *cache.CachedRepository) domain.UserFollowRepository {
  156 + return &UserFollowRepository{CachedRepository: cache}
  157 +}
  1 +package domain
  2 +
  3 +import (
  4 + "context"
  5 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction"
  6 +)
  7 +
  8 +type Company struct {
  9 + Id int64 `json:"id,omitempty"` // 唯一标识
  10 + Name string `json:"name,omitempty"` // 名称
  11 + Code string `json:"code,omitempty"` // 编码(搜索使用,4位字母数字)
  12 + Logo string `json:"logo,omitempty"` // 公司LOGO
  13 +
  14 + CreatedAt int64 `json:"createdAt,omitempty"`
  15 + UpdatedAt int64 `json:"updatedAt,omitempty"`
  16 + DeletedAt int64 `json:"deletedAt,omitempty"`
  17 + Version int `json:"version,omitempty"`
  18 +}
  19 +
  20 +type CompanyRepository interface {
  21 + Insert(ctx context.Context, conn transaction.Conn, dm *Company) (*Company, error)
  22 + Update(ctx context.Context, conn transaction.Conn, dm *Company) (*Company, error)
  23 + UpdateWithVersion(ctx context.Context, conn transaction.Conn, dm *Company) (*Company, error)
  24 + Delete(ctx context.Context, conn transaction.Conn, dm *Company) (*Company, error)
  25 + FindOne(ctx context.Context, conn transaction.Conn, id int64) (*Company, error)
  26 + Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*Company, error)
  27 +}
  28 +
  29 +func (m *Company) Identify() interface{} {
  30 + if m.Id == 0 {
  31 + return nil
  32 + }
  33 + return m.Id
  34 +}
@@ -17,6 +17,8 @@ type User struct { @@ -17,6 +17,8 @@ type User struct {
17 Position string `json:"position,omitempty"` // 职位 17 Position string `json:"position,omitempty"` // 职位
18 Enable int `json:"enable,omitempty"` // 启用状态 1:启用 2:禁用 18 Enable int `json:"enable,omitempty"` // 启用状态 1:启用 2:禁用
19 AuditStatus int `json:"auditStatus,omitempty"` // 审核状态 0:待审核 1:审核通过 2:拒绝 19 AuditStatus int `json:"auditStatus,omitempty"` // 审核状态 0:待审核 1:审核通过 2:拒绝
  20 + Follower []int64 `json:"followers,omitempty"` // 关注我的人 (冗余)
  21 + Following []int64 `json:"following,omitempty"` // 我关注的人 (冗余)
20 22
21 CreatedAt int64 `json:"createdAt,omitempty"` 23 CreatedAt int64 `json:"createdAt,omitempty"`
22 UpdatedAt int64 `json:"updatedAt,omitempty"` 24 UpdatedAt int64 `json:"updatedAt,omitempty"`
  1 +package domain
  2 +
  3 +import (
  4 + "context"
  5 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction"
  6 +)
  7 +
  8 +type UserFollow struct {
  9 + Id int64 `json:"id,omitempty"` // 唯一标识
  10 + FromUserId int64 `json:"fromUserId,omitempty"` /// 发起关注的人
  11 + ToUserId int64 `json:"toUserId,omitempty"` /// 被关注的人
  12 + CreatedAt int64 `json:"createdAt,omitempty"`
  13 + UpdatedAt int64 `json:"updatedAt,omitempty"`
  14 + DeletedAt int64 `json:"deletedAt,omitempty"`
  15 + Version int `json:"version,omitempty"`
  16 +}
  17 +
  18 +type UserFollowRepository interface {
  19 + Insert(ctx context.Context, conn transaction.Conn, dm *UserFollow) (*UserFollow, error)
  20 + Update(ctx context.Context, conn transaction.Conn, dm *UserFollow) (*UserFollow, error)
  21 + UpdateWithVersion(ctx context.Context, conn transaction.Conn, dm *UserFollow) (*UserFollow, error)
  22 + Delete(ctx context.Context, conn transaction.Conn, dm *UserFollow) (*UserFollow, error)
  23 + FindOne(ctx context.Context, conn transaction.Conn, id int64) (*UserFollow, error)
  24 + Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*UserFollow, error)
  25 +}
  26 +
  27 +func (m *UserFollow) Identify() interface{} {
  28 + if m.Id == 0 {
  29 + return nil
  30 + }
  31 + return m.Id
  32 +}
@@ -16,4 +16,14 @@ CREATE TABLE `role` ( @@ -16,4 +16,14 @@ CREATE TABLE `role` (
16 CREATE TABLE `user` ( 16 CREATE TABLE `user` (
17 `id` int(0) NOT NULL COMMENT '唯一标识', 17 `id` int(0) NOT NULL COMMENT '唯一标识',
18 PRIMARY KEY (`id`) USING BTREE 18 PRIMARY KEY (`id`) USING BTREE
  19 +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
  20 +
  21 +CREATE TABLE `company` (
  22 + `id` int(0) NOT NULL COMMENT '唯一标识',
  23 + PRIMARY KEY (`id`) USING BTREE
  24 +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
  25 +
  26 +CREATE TABLE `user_follow` (
  27 + `id` int(0) NOT NULL COMMENT '唯一标识',
  28 + PRIMARY KEY (`id`) USING BTREE
19 ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; 29 ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;