作者 tangxvhui
... ... @@ -41,10 +41,10 @@ service Core {
post /mini/user/department-users (MiniUserDepartmentUsersRequest)returns (MiniUserInfoResponse)
@doc "关注我的人"
@handler miniUserFollower
post /mini/user/follower (UserSearchRequest)returns(UserSearchResponse)
post /mini/user/follower (MiniUserFollowedSearchRequest)returns(MiniUserFollowedSearchResponse)
@doc "我关注的人"
@handler miniUserFollowing
post /mini/user/following (UserSearchRequest)returns(UserSearchResponse)
post /mini/user/following (MiniUserFollowedSearchRequest)returns(MiniUserFollowedSearchResponse)
@doc "关注"
@handler miniUserFollow
post /mini/user/follow (FollowRequest)
... ... @@ -97,6 +97,14 @@ type(
Departments []*Department `json:"departments"`
Users []*UserItem `json:"users"`
}
MiniUserFollowedSearchRequest{
Page int `json:"page,optional"`
Size int `json:"size,optional"`
}
MiniUserFollowedSearchResponse{
List []*UserFollowItem `json:"users"`
Total int64 `json:"total"`
}
UserItem {
Id int64 `json:"id,omitempty"` // 用户ID
CompanyId int64 `json:"companyId,omitempty"` // 公司ID
... ... @@ -133,6 +141,15 @@ type(
FollowRequest{
UserId int64 `json:"userId"`
}
UserFollowItem struct {
Id int64 `json:"id"` // 用户ID
Name string `json:"name"` // 名称
CompanyName string `json:"companyName"` // 公司名称
Avatar string `json:"avatar"` // 头像
Position string `json:"position"` // 职位
Followed bool `json:"followed"` // 关注
MutualFollowed bool `json:"mutualFollowed"` // 互相关注标识
}
)
... ...
... ... @@ -12,7 +12,7 @@ import (
func MiniUserFollowerHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.UserSearchRequest
var req types.MiniUserFollowedSearchRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
... ...
... ... @@ -12,7 +12,7 @@ import (
func MiniUserFollowingHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.UserSearchRequest
var req types.MiniUserFollowedSearchRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
... ...
... ... @@ -27,9 +27,11 @@ func NewMiniBusinessLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Mini
}
func (l *MiniBusinessLogic) MiniBusiness(req *types.MessageBusinessRequest) (resp *types.MessageBusinessResponse, err error) {
var userToken = contextdata.GetUserTokenFromCtx(l.ctx)
var conn = l.svcCtx.DefaultDBConn()
var msgType = req.Type
total, list, err := l.svcCtx.MessageBusinessRepository.Find(l.ctx, l.svcCtx.DefaultDBConn(), domain.NewQueryOptions().
total, list, err := l.svcCtx.MessageBusinessRepository.Find(l.ctx, conn, domain.NewQueryOptions().
WithOffsetLimit(req.Page, req.Size).
WithKV("type", msgType))
if err != nil {
... ... @@ -96,11 +98,10 @@ func (l *MiniBusinessLogic) MiniBusiness(req *types.MessageBusinessRequest) (res
// 获取公司
if len(companyIds) > 0 {
_, companyList, err := l.svcCtx.CompanyRepository.Find(l.ctx, l.svcCtx.DefaultDBConn(),
domain.NewQueryOptions().
WithFindOnly().
WithKV("ids", userIds).
WithKV("limit", len(userIds)))
_, companyList, err := l.svcCtx.CompanyRepository.Find(l.ctx, conn, domain.NewQueryOptions().
WithFindOnly().
WithKV("ids", userIds).
WithKV("limit", len(userIds)))
if err != nil {
return nil, err
}
... ... @@ -111,11 +112,10 @@ func (l *MiniBusinessLogic) MiniBusiness(req *types.MessageBusinessRequest) (res
// 获取用户
if len(userIds) > 0 {
_, userList, err := l.svcCtx.UserRepository.Find(l.ctx, l.svcCtx.DefaultDBConn(),
domain.NewQueryOptions().
WithFindOnly().
WithKV("ids", userIds).
WithKV("limit", len(userIds)))
_, userList, err := l.svcCtx.UserRepository.Find(l.ctx, conn, domain.NewQueryOptions().
WithFindOnly().
WithKV("ids", userIds).
WithKV("limit", len(userIds)))
if err != nil {
return nil, err
}
... ... @@ -126,11 +126,10 @@ func (l *MiniBusinessLogic) MiniBusiness(req *types.MessageBusinessRequest) (res
// 获取评论
if len(commentIds) > 0 {
_, commentList, err := l.svcCtx.CommentRepository.Find(l.ctx, l.svcCtx.DefaultDBConn(),
domain.NewQueryOptions().
WithFindOnly().
WithKV("ids", commentIds).
WithKV("limit", len(commentIds)))
_, commentList, err := l.svcCtx.CommentRepository.Find(l.ctx, conn, domain.NewQueryOptions().
WithFindOnly().
WithKV("ids", commentIds).
WithKV("limit", len(commentIds)))
if err != nil {
return nil, err
}
... ... @@ -141,11 +140,10 @@ func (l *MiniBusinessLogic) MiniBusiness(req *types.MessageBusinessRequest) (res
// 获取文章数据
if len(articleIds) > 0 {
_, articleList, err := l.svcCtx.ArticleRepository.Find(l.ctx, l.svcCtx.DefaultDBConn(), 0,
domain.NewQueryOptions().
WithFindOnly().
WithKV("ids", articleIds).
WithKV("limit", len(articleIds)))
_, articleList, err := l.svcCtx.ArticleRepository.Find(l.ctx, conn, userToken.CompanyId, domain.NewQueryOptions().
WithFindOnly().
WithKV("ids", articleIds).
WithKV("limit", len(articleIds)))
if err != nil {
return nil, err
}
... ... @@ -156,18 +154,18 @@ func (l *MiniBusinessLogic) MiniBusiness(req *types.MessageBusinessRequest) (res
for _, item := range list {
to := types.MessageBusinessItem{
Id: item.Id,
Type: int(item.Type),
OptType: int(item.OptType),
CompanyId: item.CompanyId,
UserId: item.UserId,
RecipientId: item.RecipientId,
ArticleId: item.ArticleId,
CommentId: item.CommentId,
DiscussionId: item.DiscussionId,
DiscussionOpinionId: item.DiscussionOpinionId,
Content: item.Content,
CreatedAt: item.CreatedAt,
Id: item.Id,
Type: int(item.Type),
OptType: int(item.OptType),
CompanyId: item.CompanyId,
UserId: item.UserId,
RecipientId: item.RecipientId,
ArticleId: item.ArticleId,
CommentId: item.CommentId,
//DiscussionId: item.DiscussionId,
//DiscussionOpinionId: item.DiscussionOpinionId,
Content: item.Content,
CreatedAt: item.CreatedAt,
}
if v, ok := userIdMap[item.UserId]; ok {
... ...
... ... @@ -2,6 +2,10 @@ package user
import (
"context"
"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"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/contextdata"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types"
... ... @@ -23,8 +27,32 @@ func NewMiniUserFollowLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Mi
}
}
func (l *MiniUserFollowLogic) MiniUserFollow(req *types.FollowRequest) error {
// todo: add your logic here and delete this line
func (l *MiniUserFollowLogic) MiniUserFollow(req *types.FollowRequest) (err error) {
var (
conn = l.svcCtx.DefaultDBConn()
user *domain.User
targetUser *domain.User
userToken = contextdata.GetUserTokenFromCtx(l.ctx)
)
if user, err = l.svcCtx.UserRepository.FindOne(l.ctx, conn, userToken.UserId); err != nil {
return xerr.NewErrMsgErr("用户不存在", err)
}
if targetUser, err = l.svcCtx.UserRepository.FindOne(l.ctx, conn, req.UserId); err != nil {
return xerr.NewErrMsgErr("关注的用户不存在", err)
}
if err = transaction.UseTrans(l.ctx, l.svcCtx.DB, func(ctx context.Context, conn transaction.Conn) error {
if err = user.Follow(targetUser); err != nil {
return err
}
if user, err = l.svcCtx.UserRepository.UpdateWithVersion(ctx, conn, user); err != nil {
return err
}
if targetUser, err = l.svcCtx.UserRepository.UpdateWithVersion(ctx, conn, targetUser); err != nil {
return err
}
return nil
}, true); err != nil {
return xerr.NewErrMsgErr("关注用户失败", err)
}
return nil
}
... ...
... ... @@ -2,6 +2,10 @@ package user
import (
"context"
"github.com/samber/lo"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/contextdata"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types"
... ... @@ -23,8 +27,42 @@ func NewMiniUserFollowerLogic(ctx context.Context, svcCtx *svc.ServiceContext) *
}
}
func (l *MiniUserFollowerLogic) MiniUserFollower(req *types.UserSearchRequest) (resp *types.UserSearchResponse, err error) {
// todo: add your logic here and delete this line
func (l *MiniUserFollowerLogic) MiniUserFollower(req *types.MiniUserFollowedSearchRequest) (resp *types.MiniUserFollowedSearchResponse, err error) {
var (
conn = l.svcCtx.DefaultDBConn()
user *domain.User
userToken = contextdata.GetUserTokenFromCtx(l.ctx)
companyMap = make(map[int64]*domain.Company)
)
if user, err = l.svcCtx.UserRepository.FindOne(l.ctx, conn, userToken.UserId); err != nil {
return nil, xerr.NewErrMsgErr("用户不存在", err)
}
var (
users = user.Follower
total = int64(len(users))
offset, limit = domain.OffsetLimit(req.Page, req.Size)
)
users = lo.Slice(users, offset, offset+limit)
resp = &types.MiniUserFollowedSearchResponse{
Total: total,
List: make([]*types.UserFollowItem, 0),
}
lo.ForEach(users, func(item int64, index int) {
if foundUser, _ := l.svcCtx.UserRepository.FindOne(l.ctx, conn, item); foundUser != nil {
var companyName = ""
if company, _ := domain.LazyLoad(companyMap, l.ctx, conn, foundUser.CompanyId, l.svcCtx.CompanyRepository.FindOne); company != nil {
companyName = company.Name
}
resp.List = append(resp.List, &types.UserFollowItem{
Id: foundUser.Id,
Name: foundUser.Name,
CompanyName: companyName,
Avatar: foundUser.Avatar,
Position: foundUser.Position,
Followed: true,
MutualFollowed: lo.Contains(user.Following, item),
})
}
})
return
}
... ...
... ... @@ -2,6 +2,10 @@ package user
import (
"context"
"github.com/samber/lo"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/contextdata"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types"
... ... @@ -23,8 +27,42 @@ func NewMiniUserFollowingLogic(ctx context.Context, svcCtx *svc.ServiceContext)
}
}
func (l *MiniUserFollowingLogic) MiniUserFollowing(req *types.UserSearchRequest) (resp *types.UserSearchResponse, err error) {
// todo: add your logic here and delete this line
func (l *MiniUserFollowingLogic) MiniUserFollowing(req *types.MiniUserFollowedSearchRequest) (resp *types.MiniUserFollowedSearchResponse, err error) {
var (
conn = l.svcCtx.DefaultDBConn()
user *domain.User
userToken = contextdata.GetUserTokenFromCtx(l.ctx)
companyMap = make(map[int64]*domain.Company)
)
if user, err = l.svcCtx.UserRepository.FindOne(l.ctx, conn, userToken.UserId); err != nil {
return nil, xerr.NewErrMsgErr("用户不存在", err)
}
var (
users = user.Following
total = int64(len(users))
offset, limit = domain.OffsetLimit(req.Page, req.Size)
)
users = lo.Slice(users, offset, offset+limit)
resp = &types.MiniUserFollowedSearchResponse{
Total: total,
List: make([]*types.UserFollowItem, 0),
}
lo.ForEach(users, func(item int64, index int) {
if foundUser, _ := l.svcCtx.UserRepository.FindOne(l.ctx, conn, item); foundUser != nil {
var companyName = ""
if company, _ := domain.LazyLoad(companyMap, l.ctx, conn, foundUser.CompanyId, l.svcCtx.CompanyRepository.FindOne); company != nil {
companyName = company.Name
}
resp.List = append(resp.List, &types.UserFollowItem{
Id: foundUser.Id,
Name: foundUser.Name,
CompanyName: companyName,
Avatar: foundUser.Avatar,
Position: foundUser.Position,
Followed: true,
//MutualFollowed: lo.Contains(user.Following, foundUser.Id),
})
}
})
return
}
... ...
... ... @@ -2,6 +2,10 @@ package user
import (
"context"
"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"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/contextdata"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types"
... ... @@ -23,8 +27,32 @@ func NewMiniUserUnFollowLogic(ctx context.Context, svcCtx *svc.ServiceContext) *
}
}
func (l *MiniUserUnFollowLogic) MiniUserUnFollow(req *types.FollowRequest) error {
// todo: add your logic here and delete this line
func (l *MiniUserUnFollowLogic) MiniUserUnFollow(req *types.FollowRequest) (err error) {
var (
conn = l.svcCtx.DefaultDBConn()
user *domain.User
targetUser *domain.User
userToken = contextdata.GetUserTokenFromCtx(l.ctx)
)
if user, err = l.svcCtx.UserRepository.FindOne(l.ctx, conn, userToken.UserId); err != nil {
return xerr.NewErrMsgErr("用户不存在", err)
}
if targetUser, err = l.svcCtx.UserRepository.FindOne(l.ctx, conn, req.UserId); err != nil {
return xerr.NewErrMsgErr("关注的用户不存在", err)
}
if err = transaction.UseTrans(l.ctx, l.svcCtx.DB, func(ctx context.Context, conn transaction.Conn) error {
if err = user.Unfollow(targetUser); err != nil {
return err
}
if user, err = l.svcCtx.UserRepository.UpdateWithVersion(ctx, conn, user); err != nil {
return err
}
if targetUser, err = l.svcCtx.UserRepository.UpdateWithVersion(ctx, conn, targetUser); err != nil {
return err
}
return nil
}, true); err != nil {
return xerr.NewErrMsgErr("关注用户失败", err)
}
return nil
}
... ...
... ... @@ -192,6 +192,16 @@ type MiniUserDepartmentUsersResponse struct {
Users []*UserItem `json:"users"`
}
type MiniUserFollowedSearchRequest struct {
Page int `json:"page,optional"`
Size int `json:"size,optional"`
}
type MiniUserFollowedSearchResponse struct {
List []*UserFollowItem `json:"users"`
Total int64 `json:"total"`
}
type UserItem struct {
Id int64 `json:"id,omitempty"` // 用户ID
CompanyId int64 `json:"companyId,omitempty"` // 公司ID
... ... @@ -231,6 +241,16 @@ type FollowRequest struct {
UserId int64 `json:"userId"`
}
type UserFollowItem struct {
Id int64 `json:"id"` // 用户ID
Name string `json:"name"` // 名称
CompanyName string `json:"companyName"` // 公司名称
Avatar string `json:"avatar"` // 头像
Position string `json:"position"` // 职位
Followed bool `json:"followed"` // 关注
MutualFollowed bool `json:"mutualFollowed"` // 互相关注标识
}
type CompanySearchRequest struct {
Page int `json:"page"`
Size int `json:"size"`
... ...
... ... @@ -10,22 +10,22 @@ import (
// MessageBusiness 消息中心业务
type MessageBusiness struct {
Id int64 // 唯一标识
Type int `json:"type"` // 分类 (1回复 2点赞 3被采纳)
OptType int `json:"optType"` // 操作类型(1针对文章、1针对评论、2针对圆桌)
CompanyId int64 `json:"companyId"` // 操作人公司ID
UserId int64 `json:"userId"` // 操作人用户ID
RecipientId int64 `json:"recipientId"` // 接收人用户ID
ArticleId int64 `json:"articleId"` // 文章ID
CommentId int64 `json:"commentId,omitempty"` // 评论ID
DiscussionId int64 `json:"discussionId,omitempty"` // 圆桌ID
DiscussionOpinionId int64 `json:"discussionOpinionId,omitempty"` // 观点ID
Content string `json:"content,omitempty"` // 消息内容
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"`
Id int64 // 唯一标识
Type int `json:"type"` // 分类 (1回复 2点赞 3被采纳)
OptType int `json:"optType"` // 操作类型(1针对文章、1针对评论、2针对圆桌)
CompanyId int64 `json:"companyId"` // 操作人公司ID
UserId int64 `json:"userId"` // 操作人用户ID
RecipientId int64 `json:"recipientId"` // 接收人用户ID
ArticleId int64 `json:"articleId,omitempty"` // 文章ID
CommentId int64 `json:"commentId,omitempty"` // 评论ID
Content string `json:"content,omitempty"` // 消息内容
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"`
//DiscussionId int64 `json:"discussionId,omitempty"` // 圆桌ID
//DiscussionOpinionId int64 `json:"discussionOpinionId,omitempty"` // 观点ID
}
func (m *MessageBusiness) TableName() string {
... ...
... ... @@ -9,7 +9,11 @@ import (
)
type Role struct {
Id int64 // 唯一标识
Id int64 // 唯一标识
Name string `json:"name"` // 角色名称
Auths []int64 `gorm:"type:jsonb;serializer:json"` // 角色权限列表
Remark string `json:"remark"` // 备注
Users []int64 `gorm:"type:jsonb;serializer:json"` // 绑定的用户
CreatedAt int64
UpdatedAt int64
... ...
... ... @@ -121,6 +121,9 @@ func (repository *MessageBusinessRepository) Find(ctx context.Context, conn tran
)
queryFunc := func() (interface{}, error) {
tx = tx.Model(&ms).Order("created_at desc")
if v, ok := queryOptions["companyId"]; ok {
tx.Where("company_id = ?", v)
}
if total, tx = transaction.PaginationAndCount(ctx, tx, queryOptions, &ms); tx.Error != nil {
return dms, tx.Error
}
... ...
... ... @@ -6,21 +6,22 @@ import (
)
type MessageBusiness struct {
Id int64 // 唯一标识
Type MsgBusinessType `json:"type"` // 分类 (1回复 2点赞 3被采纳)
OptType MsgBusinessOpt `json:"optType"` // 操作类型(1针对文章、1针对评论、2针对圆桌)
CompanyId int64 `json:"companyId"` // 操作人公司ID
UserId int64 `json:"userId"` // 操作人用户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"`
Id int64 // 唯一标识
Type MsgBusinessType `json:"type"` // 分类 (1回复 2点赞 3被采纳)
OptType MsgBusinessOpt `json:"optType"` // 操作类型(1针对文章、1针对评论、2针对圆桌)
CompanyId int64 `json:"companyId"` // 操作人公司ID
UserId int64 `json:"userId"` // 操作人用户ID
RecipientId int64 `json:"recipientId"` // 接收人用户ID
ArticleId int64 `json:"articleId"` // 文章ID
CommentId int64 `json:"commentId"` // 评论ID
Content string `json:"content"` // 消息内容
CreatedAt int64 `json:",omitempty"`
UpdatedAt int64 `json:",omitempty"`
DeletedAt int64 `json:",omitempty"`
Version int `json:",omitempty"`
//DiscussionId int64 `json:"discussionId"` // 圆桌ID
//DiscussionOpinionId int64 `json:"discussionOpinionId"` // 观点ID
}
type MsgBusinessType int
... ...
... ... @@ -85,6 +85,23 @@ func (m *User) Audit(status int) error {
return nil
}
func (m *User) Follow(targetUser *User) error {
if lo.Contains(m.Following, targetUser.Id) {
return fmt.Errorf("已关注用户%v", targetUser.Name)
}
m.Following = append(m.Following, targetUser.Id)
if !lo.Contains(targetUser.Follower, m.Id) {
targetUser.Follower = append(targetUser.Follower, m.Id)
}
return nil
}
func (m *User) Unfollow(targetUser *User) error {
m.Following = lo.Without(m.Following, targetUser.Id)
targetUser.Follower = lo.Without(targetUser.Follower, m.Id)
return nil
}
type (
LoginCreator interface {
WechatLogin(r WechatLoginRequest) (*LoginInfo, error)
... ...