作者 yangfu
... ... @@ -723,6 +723,24 @@
]
}
},
"v1/mini/show/home_page": {
"get": {
"summary": "小程序首页数据展示",
"operationId": "MiniShowHomePage",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/MiniHomePageRespose"
}
}
},
"requestBody": {},
"tags": [
"article"
]
}
},
"v1/mini/user/apply-join-company": {
"post": {
"summary": "用户申请加入公司",
... ... @@ -1361,6 +1379,34 @@
]
}
},
"v1/system/article_comment/search": {
"post": {
"summary": "管理后台文章评论列表",
"operationId": "SystemArticleCommentSearch",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/SystemArticleCommentSearchResponse"
}
}
},
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/SystemArticleCommentSearchRequest"
}
}
],
"requestBody": {},
"tags": [
"comment"
]
}
},
"v1/system/article_comment/search/me": {
"post": {
"summary": "小程序获取回复@人可选列表",
... ... @@ -1443,6 +1489,24 @@
]
}
},
"v1/system/article_tag/options": {
"get": {
"summary": "后台标签下拉列表",
"operationId": "Options",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/TagOptionsResponse"
}
}
},
"requestBody": {},
"tags": [
"tags"
]
}
},
"v1/system/article_tag/search": {
"post": {
"summary": "后台搜索标签",
... ... @@ -2308,6 +2372,52 @@
"totalComment"
]
},
"ArticleTagCount": {
"type": "object",
"properties": {
"tagGroup": {
"type": "string",
"description": " 标签分组"
},
"tagId": {
"type": "integer",
"format": "int64",
"description": " 标签id"
},
"tagImage": {
"type": "string",
"description": " 对应的图标"
},
"tagName": {
"type": "string",
"description": " 标签名称"
},
"tagRemark": {
"type": "string",
"description": " 标签备注"
},
"totalArticle": {
"type": "integer",
"format": "int32",
"description": " 总的文章数量"
},
"readArticle": {
"type": "integer",
"format": "int32",
"description": " 已读的标签数量"
}
},
"title": "ArticleTagCount",
"required": [
"tagGroup",
"tagId",
"tagImage",
"tagName",
"tagRemark",
"totalArticle",
"readArticle"
]
},
"ArticleTagGroup": {
"type": "object",
"properties": {
... ... @@ -4033,6 +4143,35 @@
},
"title": "MiniGetArticleCommentResponse"
},
"MiniHomePageRequest": {
"type": "object",
"properties": {
"": {
"type": "integer",
"format": "int64"
},
"": {
"type": "integer",
"format": "int64"
}
},
"title": "MiniHomePageRequest"
},
"MiniHomePageRespose": {
"type": "object",
"properties": {
"tags": {
"type": "array",
"items": {
"$ref": "#/definitions/ArticleTagCount"
}
}
},
"title": "MiniHomePageRespose",
"required": [
"tags"
]
},
"MiniListArticleCommentRequest": {
"type": "object",
"properties": {
... ... @@ -4330,21 +4469,6 @@
"$ref": "#/definitions/UserItem",
"description": " 用户信息"
},
"totalArticle": {
"type": "integer",
"format": "int64",
"description": " 累计信息发布"
},
"totalLoved": {
"type": "integer",
"format": "int64",
"description": " 累计收到的赞"
},
"totalAccepted": {
"type": "integer",
"format": "int64",
"description": " 累计被采纳"
},
"accounts": {
"type": "array",
"items": {
... ... @@ -4363,9 +4487,6 @@
"title": "MiniUserInfoResponse",
"required": [
"user",
"totalArticle",
"totalLoved",
"totalAccepted",
"accounts",
"auths"
]
... ... @@ -4891,6 +5012,87 @@
"value"
]
},
"SystemArticleCommentSearchItem": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"pid": {
"type": "integer",
"format": "int64"
},
"topId": {
"type": "integer",
"format": "int64"
},
"articleId": {
"type": "integer",
"format": "int64",
"description": " 文章id"
},
"sectionId": {
"type": "integer",
"format": "int64",
"description": " 段落id"
},
"fromUserId": {
"type": "integer",
"format": "int64",
"description": " 填写评论的人"
},
"fromUser": {
"$ref": "#/definitions/CommentAuthor",
"description": " 填写评论的人"
},
"countReply": {
"type": "integer",
"format": "int32",
"description": " 回复数量"
},
"countUserLove": {
"type": "integer",
"format": "int32",
"description": " 用户点赞数量"
},
"countAdminLove": {
"type": "integer",
"format": "int32",
"description": " 运营点赞数量"
},
"createdAt": {
"type": "integer",
"format": "int64",
"description": " 评论时间"
},
"content": {
"type": "string",
"description": " 评论的内容"
},
"show": {
"type": "integer",
"format": "int32",
"description": " 显示状态"
}
},
"title": "SystemArticleCommentSearchItem",
"required": [
"id",
"pid",
"topId",
"articleId",
"sectionId",
"fromUserId",
"fromUser",
"countReply",
"countUserLove",
"countAdminLove",
"createdAt",
"content",
"show"
]
},
"SystemArticleCommentSearchMeRequest": {
"type": "object",
"properties": {
... ... @@ -4945,6 +5147,76 @@
"total"
]
},
"SystemArticleCommentSearchRequest": {
"type": "object",
"properties": {
"page": {
"type": "integer",
"format": "int32"
},
"size": {
"type": "integer",
"format": "int32"
},
"articleId": {
"type": "integer",
"format": "int64",
"description": " 文章ID"
},
"topId": {
"type": "integer",
"format": "int64",
"description": " 文章顶层ID"
},
"authorId": {
"type": "integer",
"format": "int64",
"description": " 用户"
},
"show": {
"type": "integer",
"format": "int32",
"description": " 显示状态"
},
"beginTime": {
"type": "integer",
"format": "int64",
"description": " 开始时间"
},
"endTime": {
"type": "integer",
"format": "int64",
"description": " 结束时间"
}
},
"title": "SystemArticleCommentSearchRequest",
"required": [
"page",
"size",
"articleId",
"topId"
]
},
"SystemArticleCommentSearchResponse": {
"type": "object",
"properties": {
"total": {
"type": "integer",
"format": "int64"
},
"list": {
"type": "array",
"items": {
"$ref": "#/definitions/SystemArticleCommentSearchItem"
}
}
},
"title": "SystemArticleCommentSearchResponse",
"required": [
"total",
"list"
]
},
"SystemArticleGetHistoryRequest": {
"type": "object",
"properties": {
... ... @@ -5578,14 +5850,10 @@
},
"description": " 评论人"
},
"location": {
"$ref": "#/definitions/Location",
"description": " 坐标"
},
"targetUser": {
"type": "integer",
"format": "int32",
"description": "分发方式 [0分发给所有人、1分发给指定的人]"
"description": " 分发方式 [0分发给所有人、1分发给指定的人]"
},
"tags": {
"type": "array",
... ... @@ -5594,6 +5862,10 @@
"format": "int64"
},
"description": " 标签"
},
"AccessToken": {
"type": "string",
"description": " 授权token"
}
},
"title": "SystemArticleUpdateRequest",
... ... @@ -5605,9 +5877,9 @@
"images",
"whoRead",
"whoReview",
"location",
"targetUser",
"tags"
"tags",
"x-mmm-accesstoken"
]
},
"SystemArticleUpdateResponse": {
... ... @@ -5643,7 +5915,7 @@
"format": "int32",
"description": "点赞数量"
},
"CountComment": {
"countComment": {
"type": "integer",
"format": "int32",
"description": "评论数量"
... ... @@ -5675,7 +5947,7 @@
"images",
"createdAt",
"countLove",
"CountComment",
"countComment",
"show",
"tags",
"targetUser"
... ... @@ -6368,6 +6640,71 @@
"list"
]
},
"TagOptionValue": {
"type": "object",
"properties": {
"label": {
"type": "string",
"description": " 名称"
},
"value": {
"type": "integer",
"format": "int64",
"description": " 标签ID"
}
},
"title": "TagOptionValue",
"required": [
"label",
"value"
]
},
"TagOptions": {
"type": "object",
"properties": {
"label": {
"type": "string",
"description": " 分组名称"
},
"options": {
"type": "array",
"items": {
"$ref": "#/definitions/TagOptionValue"
}
}
},
"title": "TagOptions",
"required": [
"label",
"options"
]
},
"TagOptionsRequest": {
"type": "object",
"properties": {
"": {
"type": "integer",
"format": "int64",
"description": " 公司ID"
}
},
"title": "TagOptionsRequest"
},
"TagOptionsResponse": {
"type": "object",
"properties": {
"options": {
"type": "array",
"items": {
"$ref": "#/definitions/TagOptions"
}
}
},
"title": "TagOptionsResponse",
"required": [
"options"
]
},
"UserFollowItem": {
"type": "object",
"properties": {
... ...
... ... @@ -32,7 +32,11 @@ service Core {
@doc "后台搜索标签"
@handler SearchTag
post/article_tag/search (TagListRequest) returns (TagListResponse)
post /article_tag/search (TagListRequest) returns (TagListResponse)
@doc "后台标签下拉列表"
@handler Options
get /article_tag/options (TagOptionsRequest) returns (TagOptionsResponse)
}
// 创建标签
... ... @@ -117,4 +121,22 @@ type (
TagDeleteResponse {
Id int64 `json:"id"`
}
)
//标签下拉列表
type (
TagOptionsRequest {
CompanyId int64 `path:",optional"` // 公司ID
}
TagOptionsResponse {
Options []TagOptions `json:"options"`
}
TagOptions {
Label string `json:"label"` // 分组名称
Options []TagOptionValue `json:"options"`
}
TagOptionValue {
Label string `json:"label"` // 名称
Value int64 `json:"value"` // 标签ID
}
)
\ No newline at end of file
... ...
... ... @@ -388,6 +388,9 @@ type (
Tags []string `json:"tags"` //标签
TargetUser int `json:"targetUser"` //分发方式 [0分发给所有人、1分发给指定的人]
}
)
// 管理后台编辑文章
type (
//编辑
SystemArticleUpdateRequest {
Id int64 `json:"id"`
... ... @@ -398,7 +401,6 @@ type (
Images []string `json:"images"` // 图片
WhoRead []int64 `json:"whoRead"` // 谁可以看
WhoReview []int64 `json:"whoReview"` // 评论人
Location Location `json:"location"` // 坐标
TargetUser int `json:"targetUser"` // 分发方式 [0分发给所有人、1分发给指定的人]
Tags []int64 `json:"tags"` // 标签
AccessToken string `header:"x-mmm-accesstoken"` // 授权token
... ... @@ -415,6 +417,9 @@ type (
Tags []int64 `json:"tags"` //标签
TargetUser int `json:"targetUser"` //分发方式 [0分发给所有人、1分发给指定的人]
}
)
// 管理后台编辑历史列表
type (
//历史
SystemArticleHistoryRequest {
ArticleId int64 `json:"articleId"` //文章ID
... ... @@ -434,6 +439,9 @@ type (
Action string `json:"action"` //编辑类型
UpdatedAt int64 `json:"updatedAt"` //编辑时间
}
)
// 管理后台历史记录详情
type (
SystemArticleGetHistoryRequest {
Id int64 `path:"id"` //id
CompanyId int64 `path:",optional"`
... ... @@ -453,6 +461,9 @@ type (
TargetUser int `json:"targetUser"` // 分发方式 [0分发给所有人、1分发给指定的人]
Tags []int64 `json:"tags"` // 标签
}
)
// 管理后台文章恢复
type (
SystemArticleRestoreRequest {
Id int64 `json:"id"` //ID
AccessToken string `header:"x-mmm-accesstoken"` // 授权token
... ... @@ -488,19 +499,19 @@ type (
//小程序首页搜索文章
type (
MiniSearchArticleRequest {
Page int `json:"page"`
Size int `json:"size"`
CompanyId int64 `json:",optional"`
UserId int64 `json:",optional"`
TagGroup string `json:"tagGroup"`
TagId int64 `json:"tagId"`
BeginTime int64 `json:"beginTime"`
EndTime int `json:"endTime"`
SearchWord string `json:"searchWord"`
Page int `json:"page"`
Size int `json:"size"`
CompanyId int64 `json:",optional"`
UserId int64 `json:",optional"`
TagCategory string `json:"tagCategory"`
TagId int64 `json:"tagId"`
BeginTime int64 `json:"beginTime"`
EndTime int64 `json:"endTime"`
SearchWord string `json:"searchWord"`
}
//
MiniSearchArticleResponse {
Total int `json:"total"`
Total int `json:"total"`
List []MiniSearchArticleItem `json:"list"`
}
//
... ...
... ... @@ -15,7 +15,6 @@ info(
jwt: MiniAuth
)
service Core {
@doc "小程序填写文章的评论"
@handler MiniCreateArticleComment
post /article_comment (MiniCreateArticleCommentRequest) returns (MiniCreateArticleCommentResponse)
... ... @@ -52,6 +51,11 @@ service Core {
@doc "小程序获取回复@人可选列表"
@handler SystemArticleCommentSearchMe
post /article_comment/search/me (SystemArticleCommentSearchMeRequest) returns (SystemArticleCommentSearchMeResponse)
@doc "管理后台文章评论列表"
@handler SystemArticleCommentSearch
post /article_comment/search (SystemArticleCommentSearchRequest) returns (SystemArticleCommentSearchResponse)
}
//评论的填写人
... ... @@ -203,4 +207,36 @@ type (
List []ArticleCommentItem `json:"list"`
Total int64 `json:"total"`
}
)
// 文章里的评论列表
type (
SystemArticleCommentSearchRequest {
Page int `json:"page"`
Size int `json:"size"`
ArticleId int64 `json:"articleId"` // 文章ID
TopId int64 `json:"topId"` // 文章顶层ID
AuthorId int64 `json:"authorId,optional"` // 用户
Show int `json:"show,optional"` // 显示状态
BeginTime int64 `json:"beginTime,optional"` // 开始时间
EndTime int64 `json:"endTime,optional"` // 结束时间
}
SystemArticleCommentSearchResponse {
Total int64 `json:"total"`
List []SystemArticleCommentSearchItem `json:"list"`
}
SystemArticleCommentSearchItem {
Id int64 `json:"id"`
Pid int64 `json:"pid"`
TopId int64 `json:"topId"`
ArtitcleId int64 `json:"articleId"` // 文章id
SectionId int64 `json:"sectionId"` // 段落id
FromUserId int64 `json:"fromUserId"` // 填写评论的人
FromUser CommentAuthor `json:"fromUser"` // 填写评论的人
CountReply int `json:"countReply"` // 回复数量
CountUserLove int `json:"countUserLove"` // 用户点赞数量
CountAdminLove int `json:"countAdminLove"` // 运营点赞数量
CreatedAt int64 `json:"createdAt"` // 评论时间
Content string `json:"content"` // 评论的内容
Show int `json:"show"` // 显示状态
}
)
\ No newline at end of file
... ...
... ... @@ -7,8 +7,11 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/logic/article"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/contextdata"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/result"
)
// 小程序端搜索
func MiniSearchArticlePageHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.MiniSearchArticleRequest
... ... @@ -18,11 +21,10 @@ func MiniSearchArticlePageHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
}
l := article.NewMiniSearchArticlePageLogic(r.Context(), svcCtx)
token := contextdata.GetUserTokenFromCtx(r.Context())
req.UserId = token.UserId
req.CompanyId = token.CompanyId
resp, err := l.MiniSearchArticlePage(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
result.HttpResult(r, w, resp, err)
}
}
... ...
package comment
import (
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/result"
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/logic/comment"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types"
)
func SystemArticleCommentSearchHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.SystemArticleCommentSearchRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := comment.NewSystemArticleCommentSearchLogic(r.Context(), svcCtx)
resp, err := l.SystemArticleCommentSearch(&req)
result.HttpResult(r, w, resp, err)
}
}
... ...
... ... @@ -64,6 +64,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
Path: "/article_comment/search/me",
Handler: comment.SystemArticleCommentSearchMeHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/article_comment/search",
Handler: comment.SystemArticleCommentSearchHandler(serverCtx),
},
}...,
),
rest.WithJwt(serverCtx.Config.SystemAuth.AccessSecret),
... ... @@ -114,6 +119,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
Path: "/article_tag/search",
Handler: tags.SearchTagHandler(serverCtx),
},
{
Method: http.MethodGet,
Path: "/article_tag/options",
Handler: tags.OptionsHandler(serverCtx),
},
},
rest.WithJwt(serverCtx.Config.SystemAuth.AccessSecret),
rest.WithPrefix("/v1/system"),
... ...
package tags
import (
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/contextdata"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/result"
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/logic/tags"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types"
)
func OptionsHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.TagOptionsRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := tags.NewOptionsLogic(r.Context(), svcCtx)
token := contextdata.GetUserTokenFromCtx(r.Context())
req.CompanyId = token.CompanyId
resp, err := l.Options(&req)
result.HttpResult(r, w, resp, err)
}
}
... ...
... ... @@ -5,6 +5,8 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr"
"github.com/zeromicro/go-zero/core/logx"
)
... ... @@ -23,8 +25,59 @@ func NewMiniSearchArticlePageLogic(ctx context.Context, svcCtx *svc.ServiceConte
}
}
// 小程序端搜索展示文章列表
func (l *MiniSearchArticlePageLogic) MiniSearchArticlePage(req *types.MiniSearchArticleRequest) (resp *types.MiniSearchArticleResponse, err error) {
// todo: add your logic here and delete this line
return
var conn = l.svcCtx.DefaultDBConn()
cnt, articleList, err := l.svcCtx.ArticleRepository.CustomSearchBy(l.ctx, conn, req.UserId, req.CompanyId,
req.TagCategory, req.TagId, [2]int64{req.BeginTime, req.EndTime}, req.SearchWord, req.Page, req.Size)
if err != nil {
return nil, xerr.NewErrMsgErr("获取文章列表失败", err)
}
articleIds := []int64{}
for _, val := range articleList {
articleIds = append(articleIds, val.Id)
}
readFlag := map[int64]struct{}{}
if len(articleIds) > 0 {
queryOption := domain.NewQueryOptions().WithFindOnly().
MustWithKV("userId", req.UserId).MustWithKV("articleIds", articleIds)
_, userReadFlag, err := l.svcCtx.UserReadArticleRepository.Find(l.ctx, conn, queryOption)
if err != nil {
return nil, xerr.NewErrMsgErr("获取文章列表失败", err)
}
for _, val := range userReadFlag {
readFlag[val.ArticleId] = struct{}{}
}
}
resp = &types.MiniSearchArticleResponse{
Total: int(cnt),
List: make([]types.MiniSearchArticleItem, len(articleList)),
}
for i, val := range articleList {
item := types.MiniSearchArticleItem{
ArticleId: val.Id,
Title: val.Title,
Author: val.Author.Name,
Images: []string{},
CreatedAt: val.CreatedAt,
MeReadFlag: 0,
}
if _, ok := readFlag[val.Id]; ok {
item.MeReadFlag = 1
}
for _, img := range val.Images {
item.Images = append(item.Images, img.Url)
}
resp.List[i] = item
}
return resp, nil
}
... ...
... ... @@ -11,6 +11,7 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/contextdata"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/tool/oss"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr"
"strings"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types"
... ... @@ -39,7 +40,7 @@ func (l *SystemUpdateArticleLogic) SystemUpdateArticle(req *types.SystemArticleU
if err != nil {
return nil, xerr.NewErrMsgErr("帖子不存在", err)
}
//获取图片的尺寸大小
// 获取图片的尺寸大小
images := []domain.Image{}
for _, val := range req.Images {
fInfo, _ := oss.GetImageInfo(val)
... ... @@ -51,29 +52,98 @@ func (l *SystemUpdateArticleLogic) SystemUpdateArticle(req *types.SystemArticleU
Height: h,
})
}
//检查文章可被哪些人查看
whoRead := []int64{}
if len(req.WhoRead) > 0 {
whoRead = lo.Uniq(req.WhoRead)
var u *domain.User
for _, val := range whoRead {
u, err = l.svcCtx.UserRepository.FindOne(l.ctx, conn, val)
if err != nil {
return nil, xerr.NewErrMsgErr("文章可查看人设置错误", err)
}
if u.CompanyId != article.CompanyId {
return nil, xerr.NewErrMsg("文章可查看人设置错误")
}
}
}
//检查文章可被哪些人评论
whoReview := []int64{}
if len(req.WhoReview) > 0 {
whoReview = lo.Uniq(req.WhoReview)
}
//有指定可查看人的情况
if len(whoRead) > 0 {
if len(whoReview) > 0 {
// 检查 whoRead 是否 完全包含 whoReview
ok := lo.Every(whoRead, whoReview)
if !ok {
return nil, xerr.NewErrMsg("文章可评论人设置错误")
}
}
if len(whoReview) == 0 {
//有指定可查看人 ,但未指定可评论人
return nil, xerr.NewErrMsg("文章可评论人设置错误")
}
}
//没有指定可查看人的情况
if len(whoRead) == 0 {
if len(whoReview) > 0 {
// 未指定可查看人(全员可看),有指定可评论人,
var u *domain.User
for _, val := range whoReview {
u, err = l.svcCtx.UserRepository.FindOne(l.ctx, conn, val)
if err != nil {
return nil, xerr.NewErrMsgErr("文章可评论人设置错误", err)
}
if u.CompanyId != article.CompanyId {
return nil, xerr.NewErrMsg("文章可评论人设置错误")
}
}
}
}
//验证tag
if len(req.Tags) > 0 {
req.Tags = lo.Uniq(req.Tags)
for _, value := range req.Tags {
t, err := l.svcCtx.ArticleTagRepository.FindOne(l.ctx, conn, value)
if err != nil {
return nil, xerr.NewErrMsgErr("文章标签设置错误", err)
}
if t.CompanyId != article.CompanyId {
return nil, xerr.NewErrMsgErr("文章标签设置错误", err)
}
}
}
article.Title = req.Title
article.Version = article.Version + 1
article.Images = images
article.WhoRead = req.WhoRead
article.WhoReview = req.WhoReview
article.WhoRead = whoRead
article.WhoReview = whoReview
article.TargetUser = domain.ArticleTarget(req.TargetUser)
article.Location = domain.Location{
Longitude: req.Location.Longitude,
Latitude: req.Location.Latitude,
Descript: req.Location.Descript,
}
article.Tags = req.Tags
//文章内容
articleSections := []domain.ArticleSection{}
sortBy := 1
lo.ForEach(req.Section, func(item types.ArticleSection, index int) {
articleSections = append(articleSections, domain.ArticleSection{
Id: item.Id,
CompanyId: article.CompanyId,
Version: article.Version,
ArticleId: article.Id,
Content: item.Content,
SortBy: index + 1,
})
strList := strings.Split(item.Content, "\n")
for key, value := range strList {
if value == "" {
continue
}
section := domain.ArticleSection{
CompanyId: article.CompanyId,
Version: article.Version,
ArticleId: article.Id,
Content: value,
SortBy: sortBy,
}
if key == 0 {
section.Id = item.Id
}
articleSections = append(articleSections, section)
sortBy++
}
})
//设置内容概要
if len(req.Section) > 0 {
... ...
package comment
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/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"
"github.com/zeromicro/go-zero/core/logx"
)
type SystemArticleCommentSearchLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewSystemArticleCommentSearchLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SystemArticleCommentSearchLogic {
return &SystemArticleCommentSearchLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *SystemArticleCommentSearchLogic) SystemArticleCommentSearch(req *types.SystemArticleCommentSearchRequest) (resp *types.SystemArticleCommentSearchResponse, err error) {
var conn = l.svcCtx.DefaultDBConn()
queryOptions := domain.NewQueryOptions().
WithOffsetLimit(req.Page, req.Size).
WithKV("articleId", req.ArticleId).
WithKV("topId", req.TopId).
WithKV("fromUserId", req.AuthorId).
WithKV("beginCreatedAt", req.BeginTime).
WithKV("endCreatedAt", req.EndTime)
total, comments, err := l.svcCtx.ArticleCommentRepository.Find(l.ctx, conn, queryOptions)
if err != nil {
return nil, xerr.NewErrMsgErr("获取文章评论失败", err)
}
resp = &types.SystemArticleCommentSearchResponse{
Total: total,
List: make([]types.SystemArticleCommentSearchItem, 0),
}
lo.ForEach(comments, func(item *domain.ArticleComment, index int) {
resp.List = append(resp.List, types.SystemArticleCommentSearchItem{
Id: item.Id,
Pid: item.Pid,
TopId: item.TopId,
ArtitcleId: item.ArticleId,
SectionId: item.SectionId,
FromUserId: item.FromUserId,
FromUser: types.CommentAuthor{
Id: item.FromUser.Id,
Name: item.FromUser.Name,
Avatar: item.FromUser.Avatar,
Company: item.FromUser.Company,
Position: item.FromUser.Position,
},
CountReply: item.CountReply,
CountUserLove: item.CountUserLove,
CountAdminLove: item.CountAdminLove,
CreatedAt: item.CreatedAt,
Content: item.Content,
Show: int(item.Show),
})
})
return
}
... ...
... ... @@ -48,7 +48,7 @@ func (l *MiniBusinessLogic) MiniBusiness(req *types.MessageBusinessRequest) (res
var companyIdMap = map[int64]*domain.Company{}
var userIdMap = map[int64]*domain.User{}
var articleIdMap = map[int64]*domain.Article{}
var commentIdMap = map[int64]*domain.Comment{}
var commentIdMap = map[int64]*domain.ArticleComment{}
//var discussionIdMap = map[int64]int{}
//var discussionOpinionIdMap = map[int64]int{}
for _, item := range list {
... ... @@ -126,7 +126,7 @@ func (l *MiniBusinessLogic) MiniBusiness(req *types.MessageBusinessRequest) (res
// 获取评论
if len(commentIds) > 0 {
_, commentList, err := l.svcCtx.CommentRepository.Find(l.ctx, conn, domain.NewQueryOptions().
_, commentList, err := l.svcCtx.ArticleCommentRepository.Find(l.ctx, conn, domain.NewQueryOptions().
WithFindOnly().
WithKV("ids", commentIds).
WithKV("limit", len(commentIds)))
... ... @@ -192,12 +192,12 @@ func (l *MiniBusinessLogic) MiniBusiness(req *types.MessageBusinessRequest) (res
}
}
if _, ok := commentIdMap[item.CommentId]; ok {
if v, ok := commentIdMap[item.CommentId]; ok {
to.Comment = &types.SimpleComment{
//Id: v.Id,
//Title: v.Title,
//CountLove: v.CountLove,
//CountComment: v.CountComment,
Id: v.Id,
Content: v.Content,
CountLove: v.CountUserLove,
CountComment: v.CountReply,
}
}
... ...
package tags
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/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"
"github.com/zeromicro/go-zero/core/logx"
)
type OptionsLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewOptionsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *OptionsLogic {
return &OptionsLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *OptionsLogic) Options(req *types.TagOptionsRequest) (resp *types.TagOptionsResponse, err error) {
var conn = l.svcCtx.DefaultDBConn()
queryOption := domain.NewQueryOptions().WithFindOnly()
_, tagList, err := l.svcCtx.ArticleTagRepository.Find(l.ctx, conn, req.CompanyId, queryOption)
if err != nil {
return nil, xerr.NewErrMsgErr("获取标签列表失败", err)
}
var group []string
options := make(map[string][]types.TagOptionValue)
lo.ForEach(tagList, func(tag *domain.ArticleTag, index int) {
if _, ok := options[tag.Category]; !ok {
options[tag.Category] = make([]types.TagOptionValue, 0)
group = append(group, tag.Category)
}
options[tag.Category] = append(options[tag.Category], types.TagOptionValue{
Label: tag.Name,
Value: tag.Id,
})
})
resp = &types.TagOptionsResponse{Options: []types.TagOptions{}}
for _, value := range group {
ops := []types.TagOptionValue{}
if _, ok := options[value]; ok {
ops = options[value]
}
resp.Options = append(resp.Options, types.TagOptions{
Label: value,
Options: ops,
})
}
return
}
... ...
... ... @@ -46,19 +46,19 @@ func (l *MiniMyLikeLogic) MiniMyLike(req *types.MiniMyLikeRequest) (resp *types.
var userMap = make(map[int64]*domain.User)
var articleMap = make(map[int64]*domain.Article)
var commentMap = make(map[int64]*domain.Comment)
var commentMap = make(map[int64]*domain.ArticleComment)
lo.ForEach(list, func(item *domain.UserLoveFlag, index int) {
var (
user *domain.User
article *domain.Article
comment *domain.Comment
comment *domain.ArticleComment
)
if item.CommentId != 0 { // 点赞评论
user, _ = domain.LazyLoad(userMap, l.ctx, conn, item.CommentAuthor, l.svcCtx.UserRepository.FindOne)
article, _ = domain.LazyLoad(articleMap, l.ctx, conn, item.ArticleId, l.svcCtx.ArticleRepository.FindOne)
comment, _ = domain.LazyLoad(commentMap, l.ctx, conn, item.CommentId, l.svcCtx.CommentRepository.FindOne)
comment, _ = domain.LazyLoad(commentMap, l.ctx, conn, item.CommentId, l.svcCtx.ArticleCommentRepository.FindOne)
} else {
user, _ = domain.LazyLoad(userMap, l.ctx, conn, item.ArticleAuthor, l.svcCtx.UserRepository.FindOne)
article, _ = domain.LazyLoad(articleMap, l.ctx, conn, item.ArticleId, l.svcCtx.ArticleRepository.FindOne)
... ... @@ -70,7 +70,7 @@ func (l *MiniMyLikeLogic) MiniMyLike(req *types.MiniMyLikeRequest) (resp *types.
return
}
func NewItemSimple(love *domain.UserLoveFlag, user *domain.User, article *domain.Article, comment *domain.Comment) types.MyLikeItem {
func NewItemSimple(love *domain.UserLoveFlag, user *domain.User, article *domain.Article, comment *domain.ArticleComment) types.MyLikeItem {
item := types.MyLikeItem{
UserId: love.UserId,
ArticleId: love.ArticleId,
... ... @@ -101,10 +101,11 @@ func NewItemSimple(love *domain.UserLoveFlag, user *domain.User, article *domain
if comment != nil {
item.Comment = &types.SimpleComment{
Id: comment.Id,
//Content: comment.Content,
//CountLove: comment.CountLove,
//CountComment: comment.CountComment,
Id: comment.Id,
Content: comment.Content,
CountLove: comment.CountUserLove,
CountComment: comment.CountReply,
Show: int(comment.Show),
}
}
... ...
... ... @@ -29,7 +29,6 @@ type ServiceContext struct {
ArticleAndTagRepository domain.ArticleAndTagRepository
CompanyRepository domain.CompanyRepository
CommentRepository domain.CommentRepository // 待移除
DepartmentRepository domain.DepartmentRepository
MessageBusinessRepository domain.MessageBusinessRepository
MessageSystemRepository domain.MessageSystemRepository
... ... @@ -60,7 +59,6 @@ func NewServiceContext(c config.Config) *ServiceContext {
ApiAuthService: apiAuth,
LoginStatusCheck: middleware.NewLoginStatusCheckMiddleware(apiAuth).Handle,
CommentRepository: repository.NewCommentRepository(cache.NewCachedRepository(mlCache)),
ArticleBackupRepository: repository.NewArticleBackupRepository(cache.NewCachedRepository(mlCache)),
ArticleCommentRepository: repository.NewArticleCommentRepository(cache.NewCachedRepository(mlCache)),
ArticleDraftRepository: repository.NewArticleDraftRepository(cache.NewCachedRepository(mlCache)),
... ...
... ... @@ -136,6 +136,38 @@ type SystemArticleCommentSearchMeResponse struct {
Total int64 `json:"total"`
}
type SystemArticleCommentSearchRequest struct {
Page int `json:"page"`
Size int `json:"size"`
ArticleId int64 `json:"articleId"` // 文章ID
TopId int64 `json:"topId"` // 文章顶层ID
AuthorId int64 `json:"authorId,optional"` // 用户
Show int `json:"show,optional"` // 显示状态
BeginTime int64 `json:"beginTime,optional"` // 开始时间
EndTime int64 `json:"endTime,optional"` // 结束时间
}
type SystemArticleCommentSearchResponse struct {
Total int64 `json:"total"`
List []SystemArticleCommentSearchItem `json:"list"`
}
type SystemArticleCommentSearchItem struct {
Id int64 `json:"id"`
Pid int64 `json:"pid"`
TopId int64 `json:"topId"`
ArtitcleId int64 `json:"articleId"` // 文章id
SectionId int64 `json:"sectionId"` // 段落id
FromUserId int64 `json:"fromUserId"` // 填写评论的人
FromUser CommentAuthor `json:"fromUser"` // 填写评论的人
CountReply int `json:"countReply"` // 回复数量
CountUserLove int `json:"countUserLove"` // 用户点赞数量
CountAdminLove int `json:"countAdminLove"` // 运营点赞数量
CreatedAt int64 `json:"createdAt"` // 评论时间
Content string `json:"content"` // 评论的内容
Show int `json:"show"` // 显示状态
}
type MessageSystemRequest struct {
Page int `json:"page"`
Size int `json:"size"`
... ... @@ -274,6 +306,24 @@ type TagDeleteResponse struct {
Id int64 `json:"id"`
}
type TagOptionsRequest struct {
CompanyId int64 `path:",optional"` // 公司ID
}
type TagOptionsResponse struct {
Options []TagOptions `json:"options"`
}
type TagOptions struct {
Label string `json:"label"` // 分组名称
Options []TagOptionValue `json:"options"`
}
type TagOptionValue struct {
Label string `json:"label"` // 名称
Value int64 `json:"value"` // 标签ID
}
type MiniUserLoginRequest struct {
LoginType string `json:"loginType"` // 登录类型 wechat-login whchat-phone-login phone-password-login phone-smscode-login
WechatAuthCode string `json:"wechatAuthcode,optional"` // 微信登录 授权码
... ... @@ -960,7 +1010,6 @@ type SystemArticleUpdateRequest struct {
Images []string `json:"images"` // 图片
WhoRead []int64 `json:"whoRead"` // 谁可以看
WhoReview []int64 `json:"whoReview"` // 评论人
Location Location `json:"location"` // 坐标
TargetUser int `json:"targetUser"` // 分发方式 [0分发给所有人、1分发给指定的人]
Tags []int64 `json:"tags"` // 标签
AccessToken string `header:"x-mmm-accesstoken"` // 授权token
... ... @@ -1052,15 +1101,15 @@ type ArticleTagCount struct {
}
type MiniSearchArticleRequest struct {
Page int `json:"page"`
Size int `json:"size"`
CompanyId int64 `json:",optional"`
UserId int64 `json:",optional"`
TagGroup string `json:"tagGroup"`
TagId int64 `json:"tagId"`
BeginTime int64 `json:"beginTime"`
EndTime int `json:"endTime"`
SearchWord string `json:"searchWord"`
Page int `json:"page"`
Size int `json:"size"`
CompanyId int64 `json:",optional"`
UserId int64 `json:",optional"`
TagCategory string `json:"tagCategory"`
TagId int64 `json:"tagId"`
BeginTime int64 `json:"beginTime"`
EndTime int64 `json:"endTime"`
SearchWord string `json:"searchWord"`
}
type MiniSearchArticleResponse struct {
... ...
package models
import (
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
"gorm.io/gorm"
"gorm.io/plugin/soft_delete"
"time"
)
type Comment struct {
Id int64 // 唯一标识
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 *Comment) TableName() string {
return "t_comment"
}
func (m *Comment) BeforeCreate(tx *gorm.DB) (err error) {
m.CreatedAt = time.Now().Unix()
m.UpdatedAt = time.Now().Unix()
return
}
func (m *Comment) BeforeUpdate(tx *gorm.DB) (err error) {
m.UpdatedAt = time.Now().Unix()
return
}
func (m *Comment) CacheKeyFunc() string {
if m.Id == 0 {
return ""
}
return fmt.Sprintf("%v:cache:%v:id:%v", domain.ProjectName, m.TableName(), m.Id)
}
func (m *Comment) CacheKeyFuncByObject(obj interface{}) string {
if v, ok := obj.(*Comment); ok {
return v.CacheKeyFunc()
}
return ""
}
func (m *Comment) CachePrimaryKeyFunc() string {
if len("") == 0 {
return ""
}
return fmt.Sprintf("%v:cache:%v:primarykey:%v", domain.ProjectName, m.TableName(), "key")
}
... ... @@ -133,11 +133,10 @@ func (repository *ArticleAndTagRepository) DomainModelToModel(from *domain.Artic
return to, err
}
// 以TagId作为分组,统计所有已有标签的文章和人员已读的文章
// 小程序端 以TagId作为分组,统计所有已有标签的文章和人员已读的文章
func (repository *ArticleAndTagRepository) CountArticleReadGroupByTag(ctx context.Context, conn transaction.Conn, userId int64, companyId int64) ([]*domain.CountArticleTagRead, error) {
sqlStr := `
-- 首页统计数据
sqlStr := `-- 首页统计数据
with
-- 按查看权限查询文章
-- 获取有标签的文章
... ...
... ... @@ -2,6 +2,7 @@ package repository
import (
"context"
"fmt"
"github.com/pkg/errors"
"github.com/tiptok/gocomm/pkg/cache"
... ... @@ -399,27 +400,75 @@ func NewArticleRepository(cache *cache.CachedRepository) domain.ArticleRepositor
return &ArticleRepository{CachedRepository: cache}
}
// -- 首页统计数据
// with
// -- 按查看权限查询文章
// -- 获取有标签的文章
// -- 过滤出可展示的文章id
// t_article_and_tag_2 as (
// select article_and_tag.article_id , article_and_tag.tag_id
// from article_and_tag
// join article on article_and_tag.article_id = article.id
// where article.deleted_at=0
// and article.company_id =1598224576532189184
// and article."show" =0
// and (article.target_user =0 or article.who_read @>'[1]')
// ),
// -- 查询人员已查看的文章
// t_user_read as(
// select user_read_article.article_id from user_read_article where user_read_article.user_id =1
// )
// -- 汇总统计 cnt_1符合条件的文章总数,cnt_2 已浏览的数量
// select count(t_article_and_tag_2.article_id) as cnt_1 ,count(t_user_read.article_id) as cnt_2, t_article_and_tag_2.tag_id
// from t_article_and_tag_2
// left join t_user_read on t_article_and_tag_2.article_id=t_user_read.article_id
// group by t_article_and_tag_2.tag_id
// ;
// 小程序端搜索查询文章
// userId 人员id,谁查看文章
// companyId 公司id
// tagCategory 标签分类
// tagId 标签id
// createdAt 文章的发布时间,按范围查询 [开始时间,结束时间]
// titleLike 搜索标题
func (repository *ArticleRepository) CustomSearchBy(ctx context.Context, conn transaction.Conn, userId int64, companyId int64,
tagCategory string, tagId int64, createdAt [2]int64, titleLike string, page int, size int) (int64, []*domain.Article, error) {
var (
tx = conn.DB()
ms []*models.Article
dms = make([]*domain.Article, 0)
total int64
)
tx = tx.Model(&ms).
Where(`article."show" =?`, domain.ArticleShowEnable).
Where(`article."deleted_at" = 0`).
Where(`article."company_id"=?`, companyId).
Where(
fmt.Sprintf(`(article.target_user = 0 or article.who_read @> '[%d]' )`, userId),
)
if createdAt[0] > 0 {
tx = tx.Where("article.created_at >=?", createdAt[0])
}
if createdAt[1] > 0 {
tx = tx.Where("article.created_at <=?", createdAt[1])
}
if tagId > 0 {
tx = tx.Joins(`join article_and_tag on article.id = article_and_tag.article_id`)
tx = tx.Where("article_and_tag.tag_id=?", tagId)
} else if len(tagCategory) > 0 {
tx = tx.Joins(`join article_and_tag on article.id = article_and_tag.article_id`)
tx = tx.Where(`article_and_tag.tag_id =any(select article_tag.id from article_tag where category =%s )`, tagCategory)
}
if len(titleLike) > 0 {
tx = tx.Where("article.title like ?", "%"+titleLike+"%")
}
result := tx.Count(&total)
if result.Error != nil {
return 0, nil, result.Error
}
if size <= 0 {
size = 20
}
if page <= 0 {
page = 1
}
result = tx.Limit(size).Offset((page - 1) * size).Order("id desc").Find(&ms)
if result.Error != nil {
return 0, nil, result.Error
}
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
}
// select *
// from article
// join article_and_tag on article.id = article_and_tag.article_id
// where article."show" =1
// and article_and_tag.tag_id =any(select article_tag.id from article_tag where category ='分组三' )
// and article_and_tag.tag_id =0
// and article.created_at >=0 and article.created_at <=9000000000
// and article.title like '%%'
... ...
... ... @@ -96,7 +96,6 @@ func (repository *ArticleSectionRepository) DeleteBy(ctx context.Context, conn t
m = &models.ArticleSection{}
)
queryFunc := func() (interface{}, error) {
tx = tx.Where("id = ?", m.Id)
if v, ok := queryOptions["articleId"]; ok {
tx = tx.Where("article_id = ?", v)
}
... ... @@ -141,7 +140,7 @@ func (repository *ArticleSectionRepository) Find(ctx context.Context, conn trans
total int64
)
queryFunc := func() (interface{}, error) {
tx = tx.Model(&ms).Order("id desc")
tx = tx.Model(&ms).Order("sort_by")
if v, ok := queryOptions["articleId"]; ok {
tx = tx.Where("article_id = ?", v)
... ...
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 CommentRepository struct {
*cache.CachedRepository
}
func (repository *CommentRepository) Insert(ctx context.Context, conn transaction.Conn, dm *domain.Comment) (*domain.Comment, error) {
var (
err error
m = &models.Comment{}
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 *CommentRepository) Update(ctx context.Context, conn transaction.Conn, dm *domain.Comment) (*domain.Comment, error) {
var (
err error
m *models.Comment
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 *CommentRepository) UpdateWithVersion(ctx context.Context, transaction transaction.Conn, dm *domain.Comment) (*domain.Comment, error) {
var (
err error
m *models.Comment
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 *CommentRepository) Delete(ctx context.Context, conn transaction.Conn, dm *domain.Comment) (*domain.Comment, error) {
var (
tx = conn.DB()
m = &models.Comment{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 *CommentRepository) FindOne(ctx context.Context, conn transaction.Conn, id int64) (*domain.Comment, error) {
var (
err error
tx = conn.DB()
m = new(models.Comment)
)
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.Comment)
cacheModel.Id = id
if err = repository.QueryCache(cacheModel.CacheKeyFunc, m, queryFunc); err != nil {
return nil, err
}
return repository.ModelToDomainModel(m)
}
func (repository *CommentRepository) Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*domain.Comment, error) {
var (
tx = conn.DB()
ms []*models.Comment
dms = make([]*domain.Comment, 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 *CommentRepository) ModelToDomainModel(from *models.Comment) (*domain.Comment, error) {
to := &domain.Comment{}
err := copier.Copy(to, from)
return to, err
}
func (repository *CommentRepository) DomainModelToModel(from *domain.Comment) (*models.Comment, error) {
to := &models.Comment{}
err := copier.Copy(to, from)
return to, err
}
func NewCommentRepository(cache *cache.CachedRepository) domain.CommentRepository {
return &CommentRepository{CachedRepository: cache}
}
... ... @@ -127,6 +127,9 @@ func (repository *UserReadArticleRepository) Find(ctx context.Context, conn tran
if v, ok := queryOptions["articleId"]; ok {
tx = tx.Where("article_id=?", v)
}
if v, ok := queryOptions["articleIds"]; ok {
tx = tx.Where("article_id in (?)", v)
}
if total, tx = transaction.PaginationAndCount(ctx, tx, queryOptions, &ms); tx.Error != nil {
return dms, tx.Error
}
... ...
... ... @@ -43,6 +43,16 @@ type ArticleRepository interface {
IncreaseCountLove(ctx context.Context, conn transaction.Conn, incr int, articleId int64) error //点赞数量变动
IncreaseCountComment(ctx context.Context, conn transaction.Conn, incr int, articleId int64) error //评论数量变动
IncreaseCountRead(ctx context.Context, conn transaction.Conn, incr int, articleId int64) error //浏览数量变动
// 小程序端搜索查询文章
// userId 人员id,谁查看文章
// companyId 公司id
// tagCategory 标签分类
// tagId 标签id
// createdAt 文章的发布时间,按范围查询 [开始时间,结束时间]
// titleLike 搜索标题
CustomSearchBy(ctx context.Context, conn transaction.Conn, userId int64, companyId int64,
tagCategory string, tagId int64, createdAt [2]int64, titleLike string, page int, size int) (int64, []*Article, error)
}
type ArticleTarget int
... ...
package domain
import (
"context"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction"
)
type Comment struct {
Id int64 // 唯一标识
CreatedAt int64 `json:",omitempty"`
UpdatedAt int64 `json:",omitempty"`
DeletedAt int64 `json:",omitempty"`
Version int `json:",omitempty"`
}
type CommentRepository interface {
Insert(ctx context.Context, conn transaction.Conn, dm *Comment) (*Comment, error)
Update(ctx context.Context, conn transaction.Conn, dm *Comment) (*Comment, error)
UpdateWithVersion(ctx context.Context, conn transaction.Conn, dm *Comment) (*Comment, error)
Delete(ctx context.Context, conn transaction.Conn, dm *Comment) (*Comment, error)
FindOne(ctx context.Context, conn transaction.Conn, id int64) (*Comment, error)
Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*Comment, error)
}
func (m *Comment) Identify() interface{} {
if m.Id == 0 {
return nil
}
return m.Id
}
... ... @@ -41,7 +41,7 @@ func GetImageInfo(url string) (info FileInfo, err error) {
return info, err
}
httpclient := http.Client{
Timeout: 30 * time.Second,
Timeout: 5 * time.Second,
}
resp, err := httpclient.Do(req)
if err != nil {
... ... @@ -70,7 +70,10 @@ func GetVideoCover(videoUrl string) (coverUrl string, w int, h int, err error) {
return
}
videoUrl = videoUrl + "?x-oss-process=video/snapshot,t_100,f_jpg,m_fast"
res, err := http.Get(videoUrl)
httpclient := http.Client{
Timeout: 5 * time.Second,
}
res, err := httpclient.Get(videoUrl)
if err != nil || res.StatusCode != http.StatusOK {
return videoUrl, 600, 600, fmt.Errorf("获取图片失败:%s", err)
}
... ...