作者 tangxvhui
... ... @@ -16,7 +16,20 @@ type ServiceContext struct {
DB *gorm.DB
Redis *redis.Redis
CommentRepository domain.CommentRepository
ArticleBackupRepository domain.ArticleBackupRepository
ArticleCommentRepository domain.ArticleCommentRepository
ArticleDraftRepository domain.ArticleDraftRepository
ArticleRepository domain.ArticleRepository
CompanyRepository domain.CompanyRepository
CommentRepository domain.CommentRepository // 待移除
DepartmentRepository domain.DepartmentRepository
MessageBusinessRepository domain.MessageBusinessRepository
MessageSystemRepository domain.MessageSystemRepository
RoleRepository domain.RoleRepository
UserFollowRepository domain.UserFollowRepository
UserLoveFlagRepository domain.UserLoveFlagRepository
UserRepository domain.UserRepository
}
func NewServiceContext(c config.Config) *ServiceContext {
... ... @@ -26,10 +39,22 @@ func NewServiceContext(c config.Config) *ServiceContext {
redis, _ := redis.NewRedis(redis.RedisConf{Host: c.Redis.Host, Pass: c.Redis.Pass, Type: "node"})
return &ServiceContext{
Config: c,
DB: db,
Redis: redis,
CommentRepository: repository.NewCommentRepository(cache.NewCachedRepository(mlCache)),
Config: c,
DB: db,
Redis: redis,
CommentRepository: repository.NewCommentRepository(cache.NewCachedRepository(mlCache)),
ArticleBackupRepository: repository.NewArticleBackupRepository(cache.NewCachedRepository(mlCache)),
ArticleCommentRepository: repository.NewArticleCommentRepository(cache.NewCachedRepository(mlCache)),
ArticleDraftRepository: repository.NewArticleDraftRepository(cache.NewCachedRepository(mlCache)),
ArticleRepository: repository.NewArticleRepository(cache.NewCachedRepository(mlCache)),
CompanyRepository: repository.NewCompanyRepository(cache.NewCachedRepository(mlCache)),
DepartmentRepository: repository.NewDepartmentRepository(cache.NewCachedRepository(mlCache)),
MessageBusinessRepository: repository.NewMessageBusinessRepository(cache.NewCachedRepository(mlCache)),
MessageSystemRepository: repository.NewMessageSystemRepository(cache.NewCachedRepository(mlCache)),
RoleRepository: repository.NewRoleRepository(cache.NewCachedRepository(mlCache)),
UserFollowRepository: repository.NewUserFollowRepository(cache.NewCachedRepository(mlCache)),
UserLoveFlagRepository: repository.NewUserLoveFlagRepository(cache.NewCachedRepository(mlCache)),
UserRepository: repository.NewUserRepository(cache.NewCachedRepository(mlCache)),
}
}
... ...
syntax = "v1"
info(
title: "xx实例"
desc: "xx实例"
author: "author"
email: "email"
version: "v1"
)
@server(
prefix: company/v1
group: company
jwt: JwtAuth
)
service Core {
@handler getCompany
post /company/:id (CompanyGetRequest) returns (CompanyGetResponse)
@handler saveCompany
post /company (CompanySaveRequest) returns (CompanySaveResponse)
@handler deleteCompany
delete /company/:id (CompanyDeleteRequest) returns (CompanyDeleteResponse)
@handler updateCompany
put /company/:id (CompanyUpdateRequest) returns (CompanyUpdateResponse)
@handler searchCompany
post /company/search (CompanySearchRequest) returns (CompanySearchResponse)
}
type (
CompanyGetRequest {
Id int64 `path:"id"`
}
CompanyGetResponse struct{
Company CompanyItem `json:"company"`
}
CompanySaveRequest struct{
Company CompanyItem `json:"company"`
}
CompanySaveResponse struct{}
CompanyDeleteRequest struct{
Id int64 `path:"id"`
}
CompanyDeleteResponse struct{}
CompanyUpdateRequest struct{
Id int64 `path:"id"`
Company CompanyItem `json:"company"`
}
CompanyUpdateResponse struct{}
CompanySearchRequest struct{
Page int `json:"page"`
Size int `json:"size"`
}
CompanySearchResponse{
List []CompanyItem `json:"list"`
Total int64 `json:"total"`
}
CompanyItem struct{
}
)
... ...
syntax = "v1"
info(
title: "xx实例"
desc: "xx实例"
author: "author"
email: "email"
version: "v1"
)
@server(
prefix: user_follow/v1
group: user_follow
jwt: JwtAuth
)
service Core {
@handler getUserFollow
post /user_follow/:id (UserFollowGetRequest) returns (UserFollowGetResponse)
@handler saveUserFollow
post /user_follow (UserFollowSaveRequest) returns (UserFollowSaveResponse)
@handler deleteUserFollow
delete /user_follow/:id (UserFollowDeleteRequest) returns (UserFollowDeleteResponse)
@handler updateUserFollow
put /user_follow/:id (UserFollowUpdateRequest) returns (UserFollowUpdateResponse)
@handler searchUserFollow
post /user_follow/search (UserFollowSearchRequest) returns (UserFollowSearchResponse)
}
type (
UserFollowGetRequest {
Id int64 `path:"id"`
}
UserFollowGetResponse struct{
UserFollow UserFollowItem `json:"user_follow"`
}
UserFollowSaveRequest struct{
UserFollow UserFollowItem `json:"user_follow"`
}
UserFollowSaveResponse struct{}
UserFollowDeleteRequest struct{
Id int64 `path:"id"`
}
UserFollowDeleteResponse struct{}
UserFollowUpdateRequest struct{
Id int64 `path:"id"`
UserFollow UserFollowItem `json:"user_follow"`
}
UserFollowUpdateResponse struct{}
UserFollowSearchRequest struct{
Page int `json:"page"`
Size int `json:"size"`
}
UserFollowSearchResponse{
List []UserFollowItem `json:"list"`
Total int64 `json:"total"`
}
UserFollowItem struct{
}
)
... ...
syntax = "proto3";
option go_package ="./pb";
package pb;
message CompanyGetReq {
int64 Id = 1;
}
message CompanyGetResp{
CompanyItem User = 1;
}
message CompanySaveReq {
}
message CompanySaveResp{
}
message CompanyDeleteReq {
int64 Id = 1;
}
message CompanyDeleteResp{
}
message CompanyUpdateReq {
int64 Id = 1;
}
message CompanyUpdateResp{
}
message CompanySearchReq {
int64 PageNumber = 1;
int64 PageSize = 2;
}
message CompanySearchResp{
repeated CompanyItem List =1;
int64 Total =2;
}
message CompanyItem {
}
service CompanyService {
rpc CompanyGet(CompanyGetReq) returns(CompanyGetResp);
rpc CompanySave(CompanySaveReq) returns(CompanySaveResp);
rpc CompanyDelete(CompanyDeleteReq) returns(CompanyDeleteResp);
rpc CompanyUpdate(CompanyUpdateReq) returns(CompanyUpdateResp);
rpc CompanySearch(CompanySearchReq) returns(CompanySearchResp);
}
... ...
syntax = "proto3";
option go_package ="./pb";
package pb;
message UserFollowGetReq {
int64 Id = 1;
}
message UserFollowGetResp{
UserFollowItem User = 1;
}
message UserFollowSaveReq {
}
message UserFollowSaveResp{
}
message UserFollowDeleteReq {
int64 Id = 1;
}
message UserFollowDeleteResp{
}
message UserFollowUpdateReq {
int64 Id = 1;
}
message UserFollowUpdateResp{
}
message UserFollowSearchReq {
int64 PageNumber = 1;
int64 PageSize = 2;
}
message UserFollowSearchResp{
repeated UserFollowItem List =1;
int64 Total =2;
}
message UserFollowItem {
}
service UserFollowService {
rpc UserFollowGet(UserFollowGetReq) returns(UserFollowGetResp);
rpc UserFollowSave(UserFollowSaveReq) returns(UserFollowSaveResp);
rpc UserFollowDelete(UserFollowDeleteReq) returns(UserFollowDeleteResp);
rpc UserFollowUpdate(UserFollowUpdateReq) returns(UserFollowUpdateResp);
rpc UserFollowSearch(UserFollowSearchReq) returns(UserFollowSearchResp);
}
... ...
package models
import (
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
"gorm.io/gorm"
"time"
)
type Company struct {
Id int64 // 唯一标识
Name string `json:"name,omitempty"` // 名称
Code string `json:"code,omitempty"` // 编码(搜索使用,4位字母数字)
Logo string `json:"logo,omitempty"` // 公司LOGO
CreatedAt int64 `json:"createdAt,omitempty"`
UpdatedAt int64 `json:"updatedAt,omitempty"`
DeletedAt int64 `json:"deletedAt,omitempty"`
Version int `json:"version,omitempty"`
}
func (m *Company) TableName() string {
return "company"
}
func (m *Company) BeforeCreate(tx *gorm.DB) (err error) {
m.CreatedAt = time.Now().Unix()
m.UpdatedAt = time.Now().Unix()
return
}
func (m *Company) BeforeUpdate(tx *gorm.DB) (err error) {
m.UpdatedAt = time.Now().Unix()
return
}
func (m *Company) CacheKeyFunc() string {
if m.Id == 0 {
return ""
}
return fmt.Sprintf("%v:cache:%v:id:%v", domain.ProjectName, m.TableName(), m.Id)
}
func (m *Company) CacheKeyFuncByObject(obj interface{}) string {
if v, ok := obj.(*Company); ok {
return v.CacheKeyFunc()
}
return ""
}
func (m *Company) CachePrimaryKeyFunc() string {
if len("") == 0 {
return ""
}
return fmt.Sprintf("%v:cache:%v:primarykey:%v", domain.ProjectName, m.TableName(), "key")
}
... ...
... ... @@ -8,7 +8,19 @@ import (
)
type User struct {
Id int64 // 唯一标识
Id int64 // 唯一标识
CompanyId int64 `json:"companyId,omitempty"` // 公司ID
DepartmentId int64 `json:"departmentId,omitempty"` // 部门ID
Roles []int64 `json:"roleId,omitempty"` // 角色
Flag int `json:"flag"` // 标识 1:管理员 2:普通用户 (有绑定角色是管理员)
Name string `json:"name,omitempty"` // 名称
Avatar string `json:"avatar,omitempty"` // 头像
Phone string `json:"phone,omitempty"` // 手机号 唯一
Position string `json:"position,omitempty"` // 职位
Enable int `json:"enable,omitempty"` // 启用状态 1:启用 2:禁用
AuditStatus int `json:"auditStatus,omitempty"` // 审核状态 0:待审核 1:审核通过 2:拒绝
Follower []int64 `json:"followers,omitempty"` // 关注我的人 (冗余)
Following []int64 `json:"following,omitempty"` // 我关注的人 (冗余)
CreatedAt int64 `json:"createdAt,omitempty"`
UpdatedAt int64 `json:"updatedAt,omitempty"`
... ...
package models
import (
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
"gorm.io/gorm"
"time"
)
type UserFollow struct {
Id int64 // 唯一标识
CreatedAt int64 `json:"createdAt,omitempty"`
UpdatedAt int64 `json:"updatedAt,omitempty"`
DeletedAt int64 `json:"deletedAt,omitempty"`
Version int `json:"version,omitempty"`
}
func (m *UserFollow) TableName() string {
return "user_follow"
}
func (m *UserFollow) BeforeCreate(tx *gorm.DB) (err error) {
m.CreatedAt = time.Now().Unix()
m.UpdatedAt = time.Now().Unix()
return
}
func (m *UserFollow) BeforeUpdate(tx *gorm.DB) (err error) {
m.UpdatedAt = time.Now().Unix()
return
}
func (m *UserFollow) CacheKeyFunc() string {
//if m.Id == 0 {
// return ""
//}
//return fmt.Sprintf("%v:cache:%v:id:%v", domain.ProjectName, m.TableName(), m.Id)
return ""
}
func (m *UserFollow) CacheKeyFuncByObject(obj interface{}) string {
if v, ok := obj.(*UserFollow); ok {
return v.CacheKeyFunc()
}
return ""
}
func (m *UserFollow) 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"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/models"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
"gorm.io/gorm"
)
type CompanyRepository struct {
*cache.CachedRepository
}
func (repository *CompanyRepository) Insert(ctx context.Context, conn transaction.Conn, dm *domain.Company) (*domain.Company, error) {
var (
err error
m = &models.Company{}
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 *CompanyRepository) Update(ctx context.Context, conn transaction.Conn, dm *domain.Company) (*domain.Company, error) {
var (
err error
m *models.Company
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 *CompanyRepository) UpdateWithVersion(ctx context.Context, transaction transaction.Conn, dm *domain.Company) (*domain.Company, error) {
var (
err error
m *models.Company
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 *CompanyRepository) Delete(ctx context.Context, conn transaction.Conn, dm *domain.Company) (*domain.Company, error) {
var (
tx = conn.DB()
m = &models.Company{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 *CompanyRepository) FindOne(ctx context.Context, conn transaction.Conn, id int64) (*domain.Company, error) {
var (
err error
tx = conn.DB()
m = new(models.Company)
)
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.Company)
cacheModel.Id = id
if err = repository.QueryCache(cacheModel.CacheKeyFunc, m, queryFunc); err != nil {
return nil, err
}
return repository.ModelToDomainModel(m)
}
func (repository *CompanyRepository) Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*domain.Company, error) {
var (
tx = conn.DB()
ms []*models.Company
dms = make([]*domain.Company, 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 *CompanyRepository) ModelToDomainModel(from *models.Company) (*domain.Company, error) {
to := &domain.Company{}
err := copier.Copy(to, from)
return to, err
}
func (repository *CompanyRepository) DomainModelToModel(from *domain.Company) (*models.Company, error) {
to := &models.Company{}
err := copier.Copy(to, from)
return to, err
}
func NewCompanyRepository(cache *cache.CachedRepository) domain.CompanyRepository {
return &CompanyRepository{CachedRepository: cache}
}
... ...
package repository
import (
"context"
"github.com/jinzhu/copier"
"github.com/pkg/errors"
"github.com/tiptok/gocomm/pkg/cache"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/models"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
"gorm.io/gorm"
)
type UserFollowRepository struct {
*cache.CachedRepository
}
func (repository *UserFollowRepository) Insert(ctx context.Context, conn transaction.Conn, dm *domain.UserFollow) (*domain.UserFollow, error) {
var (
err error
m = &models.UserFollow{}
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 *UserFollowRepository) Update(ctx context.Context, conn transaction.Conn, dm *domain.UserFollow) (*domain.UserFollow, error) {
var (
err error
m *models.UserFollow
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 *UserFollowRepository) UpdateWithVersion(ctx context.Context, transaction transaction.Conn, dm *domain.UserFollow) (*domain.UserFollow, error) {
var (
err error
m *models.UserFollow
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 *UserFollowRepository) Delete(ctx context.Context, conn transaction.Conn, dm *domain.UserFollow) (*domain.UserFollow, error) {
var (
tx = conn.DB()
m = &models.UserFollow{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 *UserFollowRepository) FindOne(ctx context.Context, conn transaction.Conn, id int64) (*domain.UserFollow, error) {
var (
err error
tx = conn.DB()
m = new(models.UserFollow)
)
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.UserFollow)
cacheModel.Id = id
if err = repository.QueryCache(cacheModel.CacheKeyFunc, m, queryFunc); err != nil {
return nil, err
}
return repository.ModelToDomainModel(m)
}
func (repository *UserFollowRepository) Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*domain.UserFollow, error) {
var (
tx = conn.DB()
ms []*models.UserFollow
dms = make([]*domain.UserFollow, 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 *UserFollowRepository) ModelToDomainModel(from *models.UserFollow) (*domain.UserFollow, error) {
to := &domain.UserFollow{}
err := copier.Copy(to, from)
return to, err
}
func (repository *UserFollowRepository) DomainModelToModel(from *domain.UserFollow) (*models.UserFollow, error) {
to := &models.UserFollow{}
err := copier.Copy(to, from)
return to, err
}
func NewUserFollowRepository(cache *cache.CachedRepository) domain.UserFollowRepository {
return &UserFollowRepository{CachedRepository: cache}
}
... ...
package domain
import (
"context"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction"
)
type Company struct {
Id int64 `json:"id,omitempty"` // 唯一标识
Name string `json:"name,omitempty"` // 名称
Code string `json:"code,omitempty"` // 编码(搜索使用,4位字母数字)
Logo string `json:"logo,omitempty"` // 公司LOGO
CreatedAt int64 `json:"createdAt,omitempty"`
UpdatedAt int64 `json:"updatedAt,omitempty"`
DeletedAt int64 `json:"deletedAt,omitempty"`
Version int `json:"version,omitempty"`
}
type CompanyRepository interface {
Insert(ctx context.Context, conn transaction.Conn, dm *Company) (*Company, error)
Update(ctx context.Context, conn transaction.Conn, dm *Company) (*Company, error)
UpdateWithVersion(ctx context.Context, conn transaction.Conn, dm *Company) (*Company, error)
Delete(ctx context.Context, conn transaction.Conn, dm *Company) (*Company, error)
FindOne(ctx context.Context, conn transaction.Conn, id int64) (*Company, error)
Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*Company, error)
}
func (m *Company) Identify() interface{} {
if m.Id == 0 {
return nil
}
return m.Id
}
... ...
... ... @@ -17,6 +17,8 @@ type User struct {
Position string `json:"position,omitempty"` // 职位
Enable int `json:"enable,omitempty"` // 启用状态 1:启用 2:禁用
AuditStatus int `json:"auditStatus,omitempty"` // 审核状态 0:待审核 1:审核通过 2:拒绝
Follower []int64 `json:"followers,omitempty"` // 关注我的人 (冗余)
Following []int64 `json:"following,omitempty"` // 我关注的人 (冗余)
CreatedAt int64 `json:"createdAt,omitempty"`
UpdatedAt int64 `json:"updatedAt,omitempty"`
... ...
package domain
import (
"context"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction"
)
type UserFollow struct {
Id int64 `json:"id,omitempty"` // 唯一标识
FromUserId int64 `json:"fromUserId,omitempty"` /// 发起关注的人
ToUserId int64 `json:"toUserId,omitempty"` /// 被关注的人
CreatedAt int64 `json:"createdAt,omitempty"`
UpdatedAt int64 `json:"updatedAt,omitempty"`
DeletedAt int64 `json:"deletedAt,omitempty"`
Version int `json:"version,omitempty"`
}
type UserFollowRepository interface {
Insert(ctx context.Context, conn transaction.Conn, dm *UserFollow) (*UserFollow, error)
Update(ctx context.Context, conn transaction.Conn, dm *UserFollow) (*UserFollow, error)
UpdateWithVersion(ctx context.Context, conn transaction.Conn, dm *UserFollow) (*UserFollow, error)
Delete(ctx context.Context, conn transaction.Conn, dm *UserFollow) (*UserFollow, error)
FindOne(ctx context.Context, conn transaction.Conn, id int64) (*UserFollow, error)
Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*UserFollow, error)
}
func (m *UserFollow) Identify() interface{} {
if m.Id == 0 {
return nil
}
return m.Id
}
... ...
... ... @@ -16,4 +16,14 @@ CREATE TABLE `role` (
CREATE TABLE `user` (
`id` int(0) NOT NULL COMMENT '唯一标识',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
CREATE TABLE `company` (
`id` int(0) NOT NULL COMMENT '唯一标识',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
CREATE TABLE `user_follow` (
`id` int(0) NOT NULL COMMENT '唯一标识',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
\ No newline at end of file
... ...
package contextdata
import (
"context"
)
func GetTenantFromCtx(ctx context.Context) int64 {
userToken := GetUserTokenFromCtx(ctx)
if userToken.CompanyId == 0 {
return 0
}
return userToken.CompanyId
}
... ... @@ -5,7 +5,6 @@ import (
"encoding/json"
"github.com/golang-jwt/jwt/v4"
"github.com/zeromicro/go-zero/core/logx"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/config"
"time"
)
... ... @@ -63,22 +62,13 @@ type UserToken struct {
CompanyId int64 `json:"companyId"`
}
func (tk UserToken) GenerateToken(jwtConfig config.JwtAuth) (string, error) {
func (tk UserToken) GenerateToken(secret string, expire int64) (string, error) {
claims := make(jwt.MapClaims)
claims["exp"] = time.Now().Unix() + jwtConfig.Expire
claims["exp"] = time.Now().Unix() + expire
claims["iat"] = time.Now().Unix()
claims["UserId"] = tk.UserId
token := jwt.New(jwt.SigningMethodHS256)
token.Claims = claims
return token.SignedString([]byte(jwtConfig.AccessSecret))
}
func (tk *UserToken) ParseToken(jwtConfig config.JWT, str string) error {
return nil
}
// CheckUserInfo 如果UserToken有效 返回:true 否则返回false
func (tk *UserToken) CheckUserInfo() bool {
return !(tk.UserId > 100000000 || tk.UserId <= 0)
return token.SignedString([]byte(secret))
}
... ...
package result
import (
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr"
"net/http"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/rest/httpx"
"google.golang.org/grpc/status"
)
// http返回
func HttpResult(r *http.Request, w http.ResponseWriter, resp interface{}, err error) {
if err == nil {
//成功返回
r := Success(resp)
httpx.WriteJson(w, http.StatusOK, r)
} else {
//错误返回
errcode := xerr.SERVER_COMMON_ERROR
errmsg := "服务器开小差啦,稍后再来试一试"
internalErr := ""
causeErr := errors.Cause(err) // err类型
if e, ok := causeErr.(*xerr.CodeError); ok { //自定义错误类型
//自定义CodeError
errcode = e.GetErrCode()
errmsg = e.GetErrMsg()
if e.InternalError != nil {
internalErr = e.InternalError.Error()
}
} else {
if gstatus, ok := status.FromError(causeErr); ok { // grpc err错误
grpcCode := uint32(gstatus.Code())
if xerr.IsCodeErr(grpcCode) { //区分自定义错误跟系统底层、db等错误,底层、db错误不能返回给前端
errcode = grpcCode
errmsg = gstatus.Message()
}
}
}
logx.WithContext(r.Context()).Errorf("【API-ERR】 : %+v ", err)
response := Error(errcode, errmsg)
response.Error = internalErr
httpx.WriteJson(w, http.StatusOK, response)
}
}
// 授权的http方法
func AuthHttpResult(r *http.Request, w http.ResponseWriter, resp interface{}, err error) {
if err == nil {
//成功返回
r := Success(resp)
httpx.WriteJson(w, http.StatusOK, r)
} else {
//错误返回
errcode := xerr.SERVER_COMMON_ERROR
errmsg := "服务器开小差啦,稍后再来试一试"
causeErr := errors.Cause(err) // err类型
if e, ok := causeErr.(*xerr.CodeError); ok { //自定义错误类型
//自定义CodeError
errcode = e.GetErrCode()
errmsg = e.GetErrMsg()
} else {
if gstatus, ok := status.FromError(causeErr); ok { // grpc err错误
grpcCode := uint32(gstatus.Code())
if xerr.IsCodeErr(grpcCode) { //区分自定义错误跟系统底层、db等错误,底层、db错误不能返回给前端
errcode = grpcCode
errmsg = gstatus.Message()
}
}
}
logx.WithContext(r.Context()).Errorf("【GATEWAY-ERR】 : %+v ", err)
httpx.WriteJson(w, http.StatusUnauthorized, Error(errcode, errmsg))
}
}
// http 参数错误返回
func ParamErrorResult(r *http.Request, w http.ResponseWriter, err error) {
errMsg := fmt.Sprintf("%s ,%s", xerr.MapErrMsg(xerr.REUQEST_PARAM_ERROR), err.Error())
httpx.WriteJson(w, http.StatusBadRequest, Error(xerr.REUQEST_PARAM_ERROR, errMsg))
}
package result
import (
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr"
"net/http"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/rest/httpx"
"google.golang.org/grpc/status"
)
// HttpResult http响应结果返回
func HttpResult(r *http.Request, w http.ResponseWriter, resp interface{}, err error) {
// 成功返回
if err == nil {
r := Success(resp)
httpx.WriteJson(w, http.StatusOK, r)
return
}
//错误返回
errCode := xerr.ServerCommonError
errMsg := "服务器开小差啦,稍后再来试一试"
internalErr := ""
causeErr := errors.Cause(err)
codeError := &xerr.CodeError{}
if ok := errors.As(causeErr, codeError); ok { // 自定义错误类型
errCode = codeError.GetErrCode()
errMsg = codeError.GetErrMsg()
if codeError.InternalError != nil {
internalErr = codeError.InternalError.Error()
}
} else {
if grpcStatus, ok := status.FromError(causeErr); ok { // grpc err错误
grpcCode := uint32(grpcStatus.Code())
if xerr.IsCodeErr(grpcCode) {
errCode = grpcCode
errMsg = grpcStatus.Message()
}
}
}
// TODO:区分自定义错误跟系统底层、db等错误,底层、db错误不能返回给前端
logx.WithContext(r.Context()).Errorf("【API-ERR】 : %+v ", err)
response := Error(errCode, errMsg)
response.Error = internalErr
httpx.WriteJson(w, http.StatusOK, response)
}
// ParamErrorResult http参数错误返回
func ParamErrorResult(r *http.Request, w http.ResponseWriter, err error) {
errMsg := fmt.Sprintf("%s ,%s", xerr.MapErrMsg(xerr.RequestParamError), err.Error())
httpx.WriteJson(w, http.StatusBadRequest, Error(xerr.RequestParamError, errMsg))
}
... ...
package result
import (
"context"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
"google.golang.org/grpc/status"
)
// job返回
func JobResult(ctx context.Context, resp interface{}, err error) {
if err == nil {
// 成功返回 ,只有dev环境下才会打印info,线上不显示
if resp != nil {
logx.Infof("resp: %+v", resp)
}
return
} else {
errCode := xerr.SERVER_COMMON_ERROR
errMsg := "服务器开小差啦,稍后再来试一试"
// 错误返回
causeErr := errors.Cause(err) // err类型
if e, ok := causeErr.(*xerr.CodeError); ok { // 自定义错误类型
// 自定义CodeError
errCode = e.GetErrCode()
errMsg = e.GetErrMsg()
} else {
if gstatus, ok := status.FromError(causeErr); ok { // grpc err错误
grpcCode := uint32(gstatus.Code())
if xerr.IsCodeErr(grpcCode) { // 区分自定义错误跟系统底层、db等错误,底层、db错误不能返回给前端
errCode = grpcCode
errMsg = gstatus.Message()
}
}
}
logx.WithContext(ctx).Errorf("【JOB-ERR】 : %+v ,errCode:%d , errMsg:%s ", err, errCode, errMsg)
return
}
}
... ... @@ -2,52 +2,26 @@ package tool
import (
jwt "github.com/golang-jwt/jwt/v4"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/config"
"time"
)
type UserToken struct {
UserId int64 `json:"userId"`
CoachId int64 `json:"coach_id"`
AdminId int64 `json:"adminId"`
ClientType string `json:"clientType"`
AccessShops []int64 `json:"accessShops"`
UserId int64 `json:"userId"`
AdminId int64 `json:"adminId"`
CompanyId int64 `json:"companyId"`
ClientType string `json:"clientType"`
}
func (tk UserToken) GenerateToken(jwtConfig config.JwtAuth) (string, error) {
func (tk UserToken) GenerateToken(secret string, expire int64) (string, error) {
claims := make(jwt.MapClaims)
claims["exp"] = time.Now().Unix() + jwtConfig.Expire
claims["exp"] = time.Now().Unix() + expire
claims["iat"] = time.Now().Unix()
claims["UserId"] = tk.UserId
claims["CoachId"] = tk.CoachId
claims["AdminId"] = tk.AdminId
claims["CompanyId"] = tk.CompanyId
claims["ClientType"] = tk.ClientType
claims["AccessShops"] = tk.AccessShops
token := jwt.New(jwt.SigningMethodHS256)
token.Claims = claims
return token.SignedString([]byte(jwtConfig.AccessSecret))
}
func (tk *UserToken) ParseToken(jwtConfig config.JWT, str string) error {
//tokenClaims, err := jwt.ParseWithClaims(
// str,
// tk,
// func(token *jwt.Token) (interface{}, error) {
// return []byte(jwtConfig.Secret), nil
// })
//if err != nil {
// return err
//}
//if claim, ok := tokenClaims.Claims.(*UserToken); ok && tokenClaims.Valid {
// *tk = *claim
// return nil
//}
//return errors.New("token 解析失败")
return nil
}
// CheckUserInfo 如果UserToken有效 返回:true 否则返回false
func (tk *UserToken) CheckUserInfo() bool {
return !(tk.UserId > 100000000 || tk.UserId <= 0)
return token.SignedString([]byte(secret))
}
... ...
package xerr
/**默认的服务错误**/
func NewErr(err error) *CodeError {
return &CodeError{errCode: ServerCommonError, InternalError: err}
}
func NewErrMsg(errMsg string) *CodeError {
return &CodeError{errCode: ServerCommonError, errMsg: errMsg}
}
func NewErrMsgErr(errMsg string, internalError error) *CodeError {
return &CodeError{errCode: ServerCommonError, errMsg: errMsg, InternalError: internalError}
}
/**指定错误码的错误**/
func NewCodeErr(errCode uint32, err error) *CodeError {
return &CodeError{errCode: errCode, errMsg: MapErrMsg(errCode), InternalError: err}
}
func NewCodeErrMsg(errCode uint32, err error, msg string) *CodeError {
return &CodeError{errCode: errCode, errMsg: msg, InternalError: err}
}
... ...
package xerr
// 成功返回
const OK uint32 = 200
/**(前3位代表业务,后三位代表具体功能)**/
// 全局错误码
const SERVER_COMMON_ERROR uint32 = 100001
const REUQEST_PARAM_ERROR uint32 = 100002
const TOKEN_EXPIRE_ERROR uint32 = 100003
const TOKEN_GENERATE_ERROR uint32 = 100004
const DB_ERROR uint32 = 100005
const DB_UPDATE_AFFECTED_ZERO_ERROR uint32 = 100006
const REQUEST_ARGS_ERROR = 200001
// 微信模块
const ErrWxMiniAuthFailError uint32 = 500001
const ErrUserNoAuth uint32 = 500002
package xerr
import (
"fmt"
import "fmt"
const (
// OK 成功返回
OK uint32 = 200
)
// 全局错误码
// 系统错误前3位代表业务,后三位代表具体功能
const (
ServerCommonError uint32 = 100001 // 系统错误
RequestParamError uint32 = 100002 // 参数请求错误
TokenExpireError uint32 = 100003 // token失效
TokenGenerateError uint32 = 100004 // 生成token失败
DbError uint32 = 100005 // 数据库错误
DbUpdateAffectedZeroError uint32 = 100006 // 数据库更新错误
)
/**
常用通用固定错误
*/
/**微信模块**/
const (
ErrWxMiniAuthFailError uint32 = 500001
ErrUserNoAuth uint32 = 500002
)
type CodeError struct {
errCode uint32
... ... @@ -33,31 +49,3 @@ func (e *CodeError) Error() string {
}
return fmt.Sprintf("ErrCode:%d,ErrMsg:%s", e.errCode, e.errMsg)
}
/*
指定错误码的错误
*/
func NewCodeErr(errCode uint32, err error) *CodeError {
return &CodeError{errCode: errCode, errMsg: MapErrMsg(errCode), InternalError: err}
}
func NewCodeErrMsg(errCode uint32, err error, msg string) *CodeError {
return &CodeError{errCode: errCode, errMsg: msg, InternalError: err}
}
/*
默认的服务错误
*/
func NewErr(err error) *CodeError {
return &CodeError{errCode: SERVER_COMMON_ERROR, InternalError: err}
}
func NewErrMsg(errMsg string) *CodeError {
return &CodeError{errCode: SERVER_COMMON_ERROR, errMsg: errMsg}
}
func NewErrMsgErr(errMsg string, err error) *CodeError {
return &CodeError{errCode: SERVER_COMMON_ERROR, errMsg: errMsg, InternalError: err}
}
... ...
... ... @@ -5,26 +5,26 @@ var message map[uint32]string
func init() {
message = make(map[uint32]string)
message[OK] = "SUCCESS"
message[SERVER_COMMON_ERROR] = "服务器开小差啦,稍后再来试一试"
message[REUQEST_PARAM_ERROR] = "参数错误"
message[TOKEN_EXPIRE_ERROR] = "token失效,请重新登陆"
message[TOKEN_GENERATE_ERROR] = "生成token失败"
message[DB_ERROR] = "数据库繁忙,请稍后再试"
message[DB_UPDATE_AFFECTED_ZERO_ERROR] = "更新数据影响行数为0"
message[ServerCommonError] = "服务器开小差啦,稍后再来试一试"
message[RequestParamError] = "参数错误"
message[TokenExpireError] = "token失效,请重新登陆"
message[TokenGenerateError] = "生成token失败"
message[DbError] = "数据库繁忙,请稍后再试"
message[DbUpdateAffectedZeroError] = "更新数据影响行数为0"
message[ErrUserNoAuth] = "无权限"
message[ErrWxMiniAuthFailError] = "微信授权失败"
}
func MapErrMsg(errcode uint32) string {
if msg, ok := message[errcode]; ok {
func MapErrMsg(errCode uint32) string {
if msg, ok := message[errCode]; ok {
return msg
} else {
return "服务器开小差啦,稍后再来试一试"
}
}
func IsCodeErr(errcode uint32) bool {
if _, ok := message[errcode]; ok {
func IsCodeErr(errCode uint32) bool {
if _, ok := message[errCode]; ok {
return true
} else {
return false
... ...