合并分支 'test' 到 'master'
Test 查看合并请求 !13
正在显示
48 个修改的文件
包含
2295 行增加
和
140 行删除
@@ -60,6 +60,7 @@ type ( | @@ -60,6 +60,7 @@ type ( | ||
60 | Page int `json:"page"` | 60 | Page int `json:"page"` |
61 | Size int `json:"size"` | 61 | Size int `json:"size"` |
62 | IncludeRootCompany bool `json:"includeRootCompany,optional"` // 包含公司(把公司当作部门作为顶级节点 部门ID:0) | 62 | IncludeRootCompany bool `json:"includeRootCompany,optional"` // 包含公司(把公司当作部门作为顶级节点 部门ID:0) |
63 | + IncludeDefaultDepartment bool `json:"includeDefaultDepartment,optional"` // 包含默认分组 | ||
63 | } | 64 | } |
64 | 65 | ||
65 | DepartmentListResponse { | 66 | DepartmentListResponse { |
@@ -26,6 +26,14 @@ service Core { | @@ -26,6 +26,14 @@ service Core { | ||
26 | @doc "点赞消息" | 26 | @doc "点赞消息" |
27 | @handler miniLike | 27 | @handler miniLike |
28 | post /mini/message/like (MessageRequest) returns (MessageBusinessResponse) | 28 | post /mini/message/like (MessageRequest) returns (MessageBusinessResponse) |
29 | + | ||
30 | + @doc "增加订阅消息次数" | ||
31 | + @handler miniMessageSubscribeAdd | ||
32 | + post /mini/message/subscribe/add (MessageSubscribeAddRequest) returns (MessageSubscribeAddResponse) | ||
33 | + | ||
34 | + @doc "获取订阅消息次数" | ||
35 | + @handler miniMessageSubscribeList | ||
36 | + post /mini/message/subscribe/list (MessageSubscribeListRequest) returns (MessageSubscribeListResponse) | ||
29 | } | 37 | } |
30 | 38 | ||
31 | type ( | 39 | type ( |
@@ -86,4 +94,25 @@ type ( | @@ -86,4 +94,25 @@ type ( | ||
86 | CountComment int `json:"countComment"` // 评论数量 | 94 | CountComment int `json:"countComment"` // 评论数量 |
87 | Show int `json:"show"` // 文章的展示状态(0显示、1不显示) | 95 | Show int `json:"show"` // 文章的展示状态(0显示、1不显示) |
88 | } | 96 | } |
97 | + | ||
98 | + // 增加消息订阅次数 | ||
99 | + MessageSubscribeAddRequest { | ||
100 | + Types []int `json:"types"` // 订阅消息类型 | ||
101 | + } | ||
102 | + MessageSubscribeAddResponse { | ||
103 | + Items []MessageSubscribeItem `json:"items"` | ||
104 | + } | ||
105 | + MessageSubscribeItem { | ||
106 | + Type int `json:"type"` // 订阅消息类型 | ||
107 | + Count int `json:"count"` // 订阅次数 | ||
108 | + UserId int64 `json:"userId"` // 用户ID | ||
109 | + CompanyId int64 `json:"companyId"` // 公司ID | ||
110 | + } | ||
111 | + //订阅消息次数详情 | ||
112 | + MessageSubscribeListRequest { | ||
113 | + | ||
114 | + } | ||
115 | + MessageSubscribeListResponse { | ||
116 | + Items []MessageSubscribeItem `json:"items"` | ||
117 | + } | ||
89 | ) | 118 | ) |
@@ -95,6 +95,13 @@ service Core { | @@ -95,6 +95,13 @@ service Core { | ||
95 | @doc "个人主页-用户发布的信息" | 95 | @doc "个人主页-用户发布的信息" |
96 | @handler miniHomepageUserNews | 96 | @handler miniHomepageUserNews |
97 | post /mini/homepage/user_news (MiniHomepageUserNewsRequest)returns(MiniHomepageUserNewsResposne) | 97 | post /mini/homepage/user_news (MiniHomepageUserNewsRequest)returns(MiniHomepageUserNewsResposne) |
98 | + | ||
99 | + @doc "检测是否绑定微信" | ||
100 | + @handler miniWechatInfo | ||
101 | + get /mini/wechat/info (MiniWechatInfoRequest) returns (MiniWechatInfoResponse) | ||
102 | + @doc "绑定微信" | ||
103 | + @handler miniWechatBind | ||
104 | + post /mini/wechat/bind (MiniWechatBindRequest) returns (MiniWechatBindResponse) | ||
98 | } | 105 | } |
99 | 106 | ||
100 | type( | 107 | type( |
@@ -279,6 +286,7 @@ type( | @@ -279,6 +286,7 @@ type( | ||
279 | ParentId int64 `json:"parentId"` // 父级ID | 286 | ParentId int64 `json:"parentId"` // 父级ID |
280 | Name string `json:"name"` // 部门名称 | 287 | Name string `json:"name"` // 部门名称 |
281 | UserIds []int64 `json:"userIds"` // 部门下的用户 | 288 | UserIds []int64 `json:"userIds"` // 部门下的用户 |
289 | + TotalUser int `json:"totalUser"` // 累计用户 | ||
282 | } | 290 | } |
283 | UserSearchRequest{ | 291 | UserSearchRequest{ |
284 | Page int `json:"page,optional"` | 292 | Page int `json:"page,optional"` |
@@ -471,7 +479,7 @@ type( | @@ -471,7 +479,7 @@ type( | ||
471 | Phone string `json:"phone,optional"` // 手机号 唯一 | 479 | Phone string `json:"phone,optional"` // 手机号 唯一 |
472 | Position string `json:"position,optional"` // 职位 | 480 | Position string `json:"position,optional"` // 职位 |
473 | Enable int `json:"enable,optional"` // 启用状态 1:启用 2:禁用 | 481 | Enable int `json:"enable,optional"` // 启用状态 1:启用 2:禁用 |
474 | - DepartmentId int64 `json:"departmentId,optional"` // 所属部门 | 482 | + DepartmentId *int64 `json:"departmentId,optional"` // 所属部门 |
475 | } | 483 | } |
476 | SystemUserSearchResponse{ | 484 | SystemUserSearchResponse{ |
477 | List []SystemUser `json:"list"` | 485 | List []SystemUser `json:"list"` |
@@ -523,4 +531,30 @@ type( | @@ -523,4 +531,30 @@ type( | ||
523 | List []SystemUser `json:"list"` | 531 | List []SystemUser `json:"list"` |
524 | Total int64 `json:"total"` | 532 | Total int64 `json:"total"` |
525 | } | 533 | } |
534 | +) | ||
535 | + | ||
536 | +// 检测微信绑定信息 | ||
537 | +type ( | ||
538 | + MiniWechatInfoRequest { | ||
539 | + | ||
540 | + } | ||
541 | + MiniWechatInfoResponse { | ||
542 | + Bind bool `json:"bind"` // 绑定结果 true-已绑定 false-未绑定 | ||
543 | + OpenId string `json:"openId"` // 绑定的微信openId | ||
544 | + Phone string `json:"phone"` // 绑定手机号 | ||
545 | + } | ||
546 | +) | ||
547 | + | ||
548 | +// 绑定微信账号 | ||
549 | +type ( | ||
550 | + MiniWechatBindRequest { | ||
551 | + WechatAuthCode string `json:"wechatAuthcode"` // 微信登录 授权码 | ||
552 | + WechatEncryptedData string `json:"wechatEncryptedData"` // 微信登录 加密数据 | ||
553 | + WechatIV string `json:"wechatIV"` // 微信登录 加密算法初始向量 | ||
554 | + } | ||
555 | + MiniWechatBindResponse { | ||
556 | + Bind bool `json:"bind"` // 绑定结果 true-已绑定 false-未绑定 | ||
557 | + OpenId string `json:"openId"` // 绑定的微信openId | ||
558 | + Phone string `json:"phone"` // 绑定手机号 | ||
559 | + } | ||
526 | ) | 560 | ) |
1 | +package message | ||
2 | + | ||
3 | +import ( | ||
4 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/result" | ||
5 | + "net/http" | ||
6 | + | ||
7 | + "github.com/zeromicro/go-zero/rest/httpx" | ||
8 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/logic/message" | ||
9 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc" | ||
10 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types" | ||
11 | +) | ||
12 | + | ||
13 | +func MiniMessageSubscribeAddHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { | ||
14 | + return func(w http.ResponseWriter, r *http.Request) { | ||
15 | + var req types.MessageSubscribeAddRequest | ||
16 | + if err := httpx.Parse(r, &req); err != nil { | ||
17 | + httpx.ErrorCtx(r.Context(), w, err) | ||
18 | + return | ||
19 | + } | ||
20 | + | ||
21 | + l := message.NewMiniMessageSubscribeAddLogic(r.Context(), svcCtx) | ||
22 | + resp, err := l.MiniMessageSubscribeAdd(&req) | ||
23 | + result.HttpResult(r, w, resp, err) | ||
24 | + } | ||
25 | +} |
1 | +package message | ||
2 | + | ||
3 | +import ( | ||
4 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/result" | ||
5 | + "net/http" | ||
6 | + | ||
7 | + "github.com/zeromicro/go-zero/rest/httpx" | ||
8 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/logic/message" | ||
9 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc" | ||
10 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types" | ||
11 | +) | ||
12 | + | ||
13 | +func MiniMessageSubscribeListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { | ||
14 | + return func(w http.ResponseWriter, r *http.Request) { | ||
15 | + var req types.MessageSubscribeListRequest | ||
16 | + if err := httpx.Parse(r, &req); err != nil { | ||
17 | + httpx.ErrorCtx(r.Context(), w, err) | ||
18 | + return | ||
19 | + } | ||
20 | + | ||
21 | + l := message.NewMiniMessageSubscribeListLogic(r.Context(), svcCtx) | ||
22 | + resp, err := l.MiniMessageSubscribeList(&req) | ||
23 | + result.HttpResult(r, w, resp, err) | ||
24 | + } | ||
25 | +} |
@@ -163,6 +163,16 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { | @@ -163,6 +163,16 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { | ||
163 | Path: "/mini/message/like", | 163 | Path: "/mini/message/like", |
164 | Handler: message.MiniLikeHandler(serverCtx), | 164 | Handler: message.MiniLikeHandler(serverCtx), |
165 | }, | 165 | }, |
166 | + { | ||
167 | + Method: http.MethodPost, | ||
168 | + Path: "/mini/message/subscribe/add", | ||
169 | + Handler: message.MiniMessageSubscribeAddHandler(serverCtx), | ||
170 | + }, | ||
171 | + { | ||
172 | + Method: http.MethodPost, | ||
173 | + Path: "/mini/message/subscribe/list", | ||
174 | + Handler: message.MiniMessageSubscribeListHandler(serverCtx), | ||
175 | + }, | ||
166 | }..., | 176 | }..., |
167 | ), | 177 | ), |
168 | rest.WithJwt(serverCtx.Config.MiniAuth.AccessSecret), | 178 | rest.WithJwt(serverCtx.Config.MiniAuth.AccessSecret), |
@@ -339,6 +349,16 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { | @@ -339,6 +349,16 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { | ||
339 | Path: "/mini/homepage/user_news", | 349 | Path: "/mini/homepage/user_news", |
340 | Handler: user.MiniHomepageUserNewsHandler(serverCtx), | 350 | Handler: user.MiniHomepageUserNewsHandler(serverCtx), |
341 | }, | 351 | }, |
352 | + { | ||
353 | + Method: http.MethodGet, | ||
354 | + Path: "/mini/wechat/info", | ||
355 | + Handler: user.MiniWechatInfoHandler(serverCtx), | ||
356 | + }, | ||
357 | + { | ||
358 | + Method: http.MethodPost, | ||
359 | + Path: "/mini/wechat/bind", | ||
360 | + Handler: user.MiniWechatBindHandler(serverCtx), | ||
361 | + }, | ||
342 | }..., | 362 | }..., |
343 | ), | 363 | ), |
344 | rest.WithJwt(serverCtx.Config.MiniAuth.AccessSecret), | 364 | rest.WithJwt(serverCtx.Config.MiniAuth.AccessSecret), |
1 | +package user | ||
2 | + | ||
3 | +import ( | ||
4 | + "net/http" | ||
5 | + | ||
6 | + "github.com/zeromicro/go-zero/rest/httpx" | ||
7 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/logic/user" | ||
8 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc" | ||
9 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types" | ||
10 | +) | ||
11 | + | ||
12 | +func MiniWechatBindHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { | ||
13 | + return func(w http.ResponseWriter, r *http.Request) { | ||
14 | + var req types.MiniWechatBindRequest | ||
15 | + if err := httpx.Parse(r, &req); err != nil { | ||
16 | + httpx.ErrorCtx(r.Context(), w, err) | ||
17 | + return | ||
18 | + } | ||
19 | + | ||
20 | + l := user.NewMiniWechatBindLogic(r.Context(), svcCtx) | ||
21 | + resp, err := l.MiniWechatBind(&req) | ||
22 | + if err != nil { | ||
23 | + httpx.ErrorCtx(r.Context(), w, err) | ||
24 | + } else { | ||
25 | + httpx.OkJsonCtx(r.Context(), w, resp) | ||
26 | + } | ||
27 | + } | ||
28 | +} |
1 | +package user | ||
2 | + | ||
3 | +import ( | ||
4 | + "net/http" | ||
5 | + | ||
6 | + "github.com/zeromicro/go-zero/rest/httpx" | ||
7 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/logic/user" | ||
8 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc" | ||
9 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types" | ||
10 | +) | ||
11 | + | ||
12 | +func MiniWechatInfoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { | ||
13 | + return func(w http.ResponseWriter, r *http.Request) { | ||
14 | + var req types.MiniWechatInfoRequest | ||
15 | + if err := httpx.Parse(r, &req); err != nil { | ||
16 | + httpx.ErrorCtx(r.Context(), w, err) | ||
17 | + return | ||
18 | + } | ||
19 | + | ||
20 | + l := user.NewMiniWechatInfoLogic(r.Context(), svcCtx) | ||
21 | + resp, err := l.MiniWechatInfo(&req) | ||
22 | + if err != nil { | ||
23 | + httpx.ErrorCtx(r.Context(), w, err) | ||
24 | + } else { | ||
25 | + httpx.OkJsonCtx(r.Context(), w, resp) | ||
26 | + } | ||
27 | + } | ||
28 | +} |
@@ -87,6 +87,7 @@ func (l *MiniArticleBackupSearchLogic) MiniArticleBackupSearch(req *types.MiniAr | @@ -87,6 +87,7 @@ func (l *MiniArticleBackupSearchLogic) MiniArticleBackupSearch(req *types.MiniAr | ||
87 | changeFiled = append(changeFiled, "修改了评论范围") | 87 | changeFiled = append(changeFiled, "修改了评论范围") |
88 | case "Section": | 88 | case "Section": |
89 | { | 89 | { |
90 | + changeFiled = append(changeFiled, "修改了文章内容") | ||
90 | item.Title = backupList[i].Title | 91 | item.Title = backupList[i].Title |
91 | item.Content = content.String() | 92 | item.Content = content.String() |
92 | item.Images = images | 93 | item.Images = images |
@@ -2,6 +2,7 @@ package article | @@ -2,6 +2,7 @@ package article | ||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "context" | 4 | "context" |
5 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/logic/message" | ||
5 | "strconv" | 6 | "strconv" |
6 | "strings" | 7 | "strings" |
7 | "text/template" | 8 | "text/template" |
@@ -198,6 +199,12 @@ func (l *MiniCreateArticleLogic) MiniCreateArticle(req *types.MiniArticleCreateR | @@ -198,6 +199,12 @@ func (l *MiniCreateArticleLogic) MiniCreateArticle(req *types.MiniArticleCreateR | ||
198 | if err != nil { | 199 | if err != nil { |
199 | return xerr.NewErrMsgErr("创建文章失败", err) | 200 | return xerr.NewErrMsgErr("创建文章失败", err) |
200 | } | 201 | } |
202 | + | ||
203 | + //发送订阅消息 | ||
204 | + err = message.NewMiniSubscribeLogic(l.ctx, l.svcCtx).FollowArticle(conn, newArticle) | ||
205 | + if err != nil { | ||
206 | + return xerr.NewErrMsgErr("创建文章失败", err) | ||
207 | + } | ||
201 | return nil | 208 | return nil |
202 | }, true) | 209 | }, true) |
203 | if err != nil { | 210 | if err != nil { |
@@ -271,6 +271,11 @@ func (l *MiniSetUserLikeLogic) setUserLikeArticle(req *types.MiniSetUserLikeRequ | @@ -271,6 +271,11 @@ func (l *MiniSetUserLikeLogic) setUserLikeArticle(req *types.MiniSetUserLikeRequ | ||
271 | return err | 271 | return err |
272 | } | 272 | } |
273 | 273 | ||
274 | + //发送订阅消息 | ||
275 | + err = message.NewMiniSubscribeLogic(l.ctx, l.svcCtx).LikeArticle(c, articleInfo, userInfo) | ||
276 | + if err != nil { | ||
277 | + return err | ||
278 | + } | ||
274 | return nil | 279 | return nil |
275 | }, true) | 280 | }, true) |
276 | if err != nil { | 281 | if err != nil { |
@@ -362,6 +367,11 @@ func (l *MiniSetUserLikeLogic) setUserLikeComment(req *types.MiniSetUserLikeRequ | @@ -362,6 +367,11 @@ func (l *MiniSetUserLikeLogic) setUserLikeComment(req *types.MiniSetUserLikeRequ | ||
362 | return err | 367 | return err |
363 | } | 368 | } |
364 | 369 | ||
370 | + // 订阅消息 | ||
371 | + err = message.NewMiniSubscribeLogic(l.ctx, l.svcCtx).LikeComment(c, commentInfo, userInfo) | ||
372 | + if err != nil { | ||
373 | + return err | ||
374 | + } | ||
365 | return nil | 375 | return nil |
366 | }, true) | 376 | }, true) |
367 | if err != nil { | 377 | if err != nil { |
@@ -4,6 +4,7 @@ import ( | @@ -4,6 +4,7 @@ import ( | ||
4 | "context" | 4 | "context" |
5 | "github.com/pkg/errors" | 5 | "github.com/pkg/errors" |
6 | "github.com/samber/lo" | 6 | "github.com/samber/lo" |
7 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/logic/message" | ||
7 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction" | 8 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction" |
8 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain" | 9 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain" |
9 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/gateway/authlib" | 10 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/gateway/authlib" |
@@ -154,6 +155,11 @@ func (l *SystemCreateArticleLogic) SystemCreateArticle(req *types.SystemArticleC | @@ -154,6 +155,11 @@ func (l *SystemCreateArticleLogic) SystemCreateArticle(req *types.SystemArticleC | ||
154 | return xerr.NewErrMsg("删除草稿失败") | 155 | return xerr.NewErrMsg("删除草稿失败") |
155 | } | 156 | } |
156 | } | 157 | } |
158 | + //发送订阅消息 | ||
159 | + err = message.NewMiniSubscribeLogic(l.ctx, l.svcCtx).FollowArticle(conn, article) | ||
160 | + if err != nil { | ||
161 | + return xerr.NewErrMsgErr("创建文章失败", err) | ||
162 | + } | ||
157 | return nil | 163 | return nil |
158 | }, true) | 164 | }, true) |
159 | if err != nil { | 165 | if err != nil { |
@@ -206,7 +206,11 @@ func (l *MiniCreateArticleCommentLogic) MiniCreateArticleComment(req *types.Mini | @@ -206,7 +206,11 @@ func (l *MiniCreateArticleCommentLogic) MiniCreateArticleComment(req *types.Mini | ||
206 | if err != nil { | 206 | if err != nil { |
207 | return err | 207 | return err |
208 | } | 208 | } |
209 | - | 209 | + // 发送订阅消息 |
210 | + err = message.NewMiniSubscribeLogic(l.ctx, l.svcCtx).ReplyComment(c, articleInfo, &newComment) | ||
211 | + if err != nil { | ||
212 | + return err | ||
213 | + } | ||
210 | return nil | 214 | return nil |
211 | }, true) | 215 | }, true) |
212 | 216 |
@@ -2,6 +2,7 @@ package department | @@ -2,6 +2,7 @@ package department | ||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "context" | 4 | "context" |
5 | + "github.com/samber/lo" | ||
5 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc" | 6 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc" |
6 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types" | 7 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types" |
7 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain" | 8 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain" |
@@ -39,6 +40,30 @@ func (l *SystemListLogic) SystemList(req *types.DepartmentListRequest) (resp *ty | @@ -39,6 +40,30 @@ func (l *SystemListLogic) SystemList(req *types.DepartmentListRequest) (resp *ty | ||
39 | Total: total, | 40 | Total: total, |
40 | List: make([]types.Department, 0), | 41 | List: make([]types.Department, 0), |
41 | } | 42 | } |
43 | + | ||
44 | + _, users, _ := l.svcCtx.UserRepository.Find(l.ctx, conn, domain.NewQueryOptions(). | ||
45 | + MustWithKV("companyId", userToken.CompanyId). | ||
46 | + WithKV("auditStatus", []int{domain.UserAuditStatusPassed})) | ||
47 | + | ||
48 | + // 统计部门用户数量 | ||
49 | + var counterByDepartment = make(map[int64]int) | ||
50 | + lo.ForEach(users, func(item *domain.User, index int) { | ||
51 | + if len(item.Departments) == 0 { | ||
52 | + if _, ok := counterByDepartment[domain.DefaultDepartmentId]; ok { | ||
53 | + counterByDepartment[domain.DefaultDepartmentId]++ | ||
54 | + } else { | ||
55 | + counterByDepartment[domain.DefaultDepartmentId] = 1 | ||
56 | + } | ||
57 | + return | ||
58 | + } | ||
59 | + for _, dep := range item.Departments { | ||
60 | + if _, ok := counterByDepartment[dep]; ok { | ||
61 | + counterByDepartment[dep]++ | ||
62 | + } else { | ||
63 | + counterByDepartment[dep] = 1 | ||
64 | + } | ||
65 | + } | ||
66 | + }) | ||
42 | if req.IncludeRootCompany { | 67 | if req.IncludeRootCompany { |
43 | company, _ := l.svcCtx.CompanyRepository.FindOne(l.ctx, conn, userToken.CompanyId) | 68 | company, _ := l.svcCtx.CompanyRepository.FindOne(l.ctx, conn, userToken.CompanyId) |
44 | if company != nil { | 69 | if company != nil { |
@@ -47,9 +72,24 @@ func (l *SystemListLogic) SystemList(req *types.DepartmentListRequest) (resp *ty | @@ -47,9 +72,24 @@ func (l *SystemListLogic) SystemList(req *types.DepartmentListRequest) (resp *ty | ||
47 | CompanyId: company.Id, | 72 | CompanyId: company.Id, |
48 | ParentId: -1, | 73 | ParentId: -1, |
49 | Name: company.Name, | 74 | Name: company.Name, |
75 | + TotalUser: len(users), | ||
50 | }) | 76 | }) |
51 | } | 77 | } |
52 | } | 78 | } |
79 | + | ||
80 | + if req.IncludeDefaultDepartment { | ||
81 | + to := types.Department{ | ||
82 | + Id: domain.DefaultDepartmentId, | ||
83 | + CompanyId: userToken.CompanyId, | ||
84 | + ParentId: 0, | ||
85 | + Name: "未分组", | ||
86 | + } | ||
87 | + if v, ok := counterByDepartment[domain.DefaultDepartmentId]; ok { | ||
88 | + to.TotalUser = v | ||
89 | + } | ||
90 | + resp.List = append(resp.List, to) | ||
91 | + } | ||
92 | + | ||
53 | for _, item := range list { | 93 | for _, item := range list { |
54 | to := types.Department{ | 94 | to := types.Department{ |
55 | Id: item.Id, | 95 | Id: item.Id, |
@@ -57,6 +97,9 @@ func (l *SystemListLogic) SystemList(req *types.DepartmentListRequest) (resp *ty | @@ -57,6 +97,9 @@ func (l *SystemListLogic) SystemList(req *types.DepartmentListRequest) (resp *ty | ||
57 | ParentId: item.ParentId, | 97 | ParentId: item.ParentId, |
58 | Name: item.Name, | 98 | Name: item.Name, |
59 | } | 99 | } |
100 | + if v, ok := counterByDepartment[item.Id]; ok { | ||
101 | + to.TotalUser = v | ||
102 | + } | ||
60 | resp.List = append(resp.List, to) | 103 | resp.List = append(resp.List, to) |
61 | } | 104 | } |
62 | return resp, nil | 105 | return resp, nil |
1 | +package message | ||
2 | + | ||
3 | +import ( | ||
4 | + "context" | ||
5 | + "github.com/samber/lo" | ||
6 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction" | ||
7 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain" | ||
8 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/contextdata" | ||
9 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr" | ||
10 | + | ||
11 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc" | ||
12 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types" | ||
13 | + | ||
14 | + "github.com/zeromicro/go-zero/core/logx" | ||
15 | +) | ||
16 | + | ||
17 | +type MiniMessageSubscribeAddLogic struct { | ||
18 | + logx.Logger | ||
19 | + ctx context.Context | ||
20 | + svcCtx *svc.ServiceContext | ||
21 | +} | ||
22 | + | ||
23 | +func NewMiniMessageSubscribeAddLogic(ctx context.Context, svcCtx *svc.ServiceContext) *MiniMessageSubscribeAddLogic { | ||
24 | + return &MiniMessageSubscribeAddLogic{ | ||
25 | + Logger: logx.WithContext(ctx), | ||
26 | + ctx: ctx, | ||
27 | + svcCtx: svcCtx, | ||
28 | + } | ||
29 | +} | ||
30 | + | ||
31 | +func (l *MiniMessageSubscribeAddLogic) MiniMessageSubscribeAdd(req *types.MessageSubscribeAddRequest) (resp *types.MessageSubscribeAddResponse, err error) { | ||
32 | + var userToken = contextdata.GetUserTokenFromCtx(l.ctx) | ||
33 | + userId := userToken.UserId | ||
34 | + companyId := userToken.CompanyId | ||
35 | + var conn = l.svcCtx.DefaultDBConn() | ||
36 | + //验证类型 | ||
37 | + for _, item := range req.Types { | ||
38 | + if !lo.Contains([]int{domain.SubscribeTypeReplyComment, domain.SubscribeTypeLike, domain.SubscribeTypeFollow}, item) { | ||
39 | + return nil, xerr.NewErrMsg("请订阅正确的消息类型") | ||
40 | + } | ||
41 | + } | ||
42 | + resp = &types.MessageSubscribeAddResponse{Items: make([]types.MessageSubscribeItem, 0)} | ||
43 | + err = transaction.UseTrans(l.ctx, conn.DB(), func(ctx context.Context, conn transaction.Conn) error { | ||
44 | + for _, item := range req.Types { | ||
45 | + userSubscribe, err := l.svcCtx.UserSubscribeRepository.FindOneByType(l.ctx, conn, companyId, userId, item) | ||
46 | + if err == nil { //已有数据增加次数 | ||
47 | + userSubscribe.Count += 1 | ||
48 | + _, err = l.svcCtx.UserSubscribeRepository.Update(l.ctx, conn, userSubscribe) | ||
49 | + if err != nil { | ||
50 | + return err | ||
51 | + } | ||
52 | + } else { //新增 | ||
53 | + userSubscribe, err = l.svcCtx.UserSubscribeRepository.Insert(l.ctx, conn, &domain.UserSubscribe{ | ||
54 | + Type: item, | ||
55 | + UserId: userId, | ||
56 | + CompanyId: companyId, | ||
57 | + Count: 1, | ||
58 | + }) | ||
59 | + if err != nil { | ||
60 | + return err | ||
61 | + } | ||
62 | + } | ||
63 | + resp.Items = append(resp.Items, types.MessageSubscribeItem{ | ||
64 | + Type: userSubscribe.Type, | ||
65 | + Count: userSubscribe.Count, | ||
66 | + UserId: userSubscribe.UserId, | ||
67 | + CompanyId: userSubscribe.CompanyId, | ||
68 | + }) | ||
69 | + } | ||
70 | + return nil | ||
71 | + }, true) | ||
72 | + if err != nil { | ||
73 | + return nil, xerr.NewErrMsgErr("增加订阅消息次数失败", err) | ||
74 | + } | ||
75 | + return | ||
76 | +} |
1 | +package message | ||
2 | + | ||
3 | +import ( | ||
4 | + "context" | ||
5 | + "github.com/samber/lo" | ||
6 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain" | ||
7 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/contextdata" | ||
8 | + | ||
9 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc" | ||
10 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types" | ||
11 | + | ||
12 | + "github.com/zeromicro/go-zero/core/logx" | ||
13 | +) | ||
14 | + | ||
15 | +type MiniMessageSubscribeListLogic struct { | ||
16 | + logx.Logger | ||
17 | + ctx context.Context | ||
18 | + svcCtx *svc.ServiceContext | ||
19 | +} | ||
20 | + | ||
21 | +func NewMiniMessageSubscribeListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *MiniMessageSubscribeListLogic { | ||
22 | + return &MiniMessageSubscribeListLogic{ | ||
23 | + Logger: logx.WithContext(ctx), | ||
24 | + ctx: ctx, | ||
25 | + svcCtx: svcCtx, | ||
26 | + } | ||
27 | +} | ||
28 | + | ||
29 | +func (l *MiniMessageSubscribeListLogic) MiniMessageSubscribeList(req *types.MessageSubscribeListRequest) (resp *types.MessageSubscribeListResponse, err error) { | ||
30 | + var userToken = contextdata.GetUserTokenFromCtx(l.ctx) | ||
31 | + userId := userToken.UserId | ||
32 | + companyId := userToken.CompanyId | ||
33 | + var conn = l.svcCtx.DefaultDBConn() | ||
34 | + resp = &types.MessageSubscribeListResponse{Items: make([]types.MessageSubscribeItem, 0)} | ||
35 | + _, list, err := l.svcCtx.UserSubscribeRepository.Find(l.ctx, conn, domain.NewQueryOptions().WithKV("companyId", companyId).WithKV("userId", userId)) | ||
36 | + lo.ForEach(list, func(item *domain.UserSubscribe, index int) { | ||
37 | + resp.Items = append(resp.Items, types.MessageSubscribeItem{ | ||
38 | + Type: item.Type, | ||
39 | + Count: item.Count, | ||
40 | + UserId: item.UserId, | ||
41 | + CompanyId: item.CompanyId, | ||
42 | + }) | ||
43 | + }) | ||
44 | + return | ||
45 | +} |
1 | +package message | ||
2 | + | ||
3 | +import ( | ||
4 | + "context" | ||
5 | + "fmt" | ||
6 | + "github.com/jinzhu/copier" | ||
7 | + "github.com/silenceper/wechat/v2" | ||
8 | + "github.com/silenceper/wechat/v2/cache" | ||
9 | + miniConfig "github.com/silenceper/wechat/v2/miniprogram/config" | ||
10 | + "github.com/silenceper/wechat/v2/miniprogram/subscribe" | ||
11 | + "github.com/zeromicro/go-zero/core/logx" | ||
12 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc" | ||
13 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction" | ||
14 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain" | ||
15 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr" | ||
16 | + "strings" | ||
17 | + "time" | ||
18 | +) | ||
19 | + | ||
20 | +type MiniSubscribeLogic struct { | ||
21 | + logx.Logger | ||
22 | + ctx context.Context | ||
23 | + svcCtx *svc.ServiceContext | ||
24 | +} | ||
25 | + | ||
26 | +func NewMiniSubscribeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *MiniSubscribeLogic { | ||
27 | + return &MiniSubscribeLogic{ | ||
28 | + Logger: logx.WithContext(ctx), | ||
29 | + ctx: ctx, | ||
30 | + svcCtx: svcCtx, | ||
31 | + } | ||
32 | +} | ||
33 | + | ||
34 | +func (l *MiniSubscribeLogic) getSubScribe() *subscribe.Subscribe { | ||
35 | + miniprogram := wechat.NewWechat().GetMiniProgram(&miniConfig.Config{ | ||
36 | + AppID: l.svcCtx.Config.Wechat.AppID, | ||
37 | + AppSecret: l.svcCtx.Config.Wechat.AppSecret, | ||
38 | + Cache: cache.NewMemory(), | ||
39 | + }) | ||
40 | + return miniprogram.GetSubscribe() | ||
41 | +} | ||
42 | + | ||
43 | +// getOpenId 获取绑定用户openID | ||
44 | +func (l *MiniSubscribeLogic) getOpenId(conn transaction.Conn, userId int64) (string, error) { | ||
45 | + userInfo, err := l.svcCtx.UserRepository.FindOne(l.ctx, conn, userId) | ||
46 | + if err != nil { | ||
47 | + return "", err | ||
48 | + } | ||
49 | + //获取微信绑定 | ||
50 | + userWechat, err := l.svcCtx.UserWechatRepository.FindOneByPhone(l.ctx, conn, userInfo.Phone) | ||
51 | + if err != nil { | ||
52 | + return "", err | ||
53 | + } | ||
54 | + return userWechat.OpenId, nil | ||
55 | +} | ||
56 | + | ||
57 | +// sendAndDecrease 保存并扣减订阅消息 | ||
58 | +func (l *MiniSubscribeLogic) sendAndDecrease(conn transaction.Conn, companyId, userId int64, mType int, msg *subscribe.Message) error { | ||
59 | + templateData := make(map[string]interface{}) | ||
60 | + _ = copier.Copy(&templateData, msg.Data) | ||
61 | + subscribeMessage := &domain.MessageSubscribe{ | ||
62 | + Type: mType, | ||
63 | + CompanyId: companyId, | ||
64 | + UserId: userId, | ||
65 | + OpenId: msg.ToUser, | ||
66 | + TemplateId: msg.TemplateID, | ||
67 | + TemplateData: templateData, | ||
68 | + } | ||
69 | + //获取订阅次数 | ||
70 | + userSubscribe, err := l.svcCtx.UserSubscribeRepository.FindOneByType(l.ctx, conn, companyId, userId, mType) | ||
71 | + if err != nil || userSubscribe.Count <= 0 { | ||
72 | + subscribeMessage.Result = "fail" | ||
73 | + subscribeMessage.Error = "订阅次数已用完" | ||
74 | + } else { | ||
75 | + //扣减订阅次数 | ||
76 | + userSubscribe.Count = userSubscribe.Count - 1 | ||
77 | + _, err = l.svcCtx.UserSubscribeRepository.Update(l.ctx, conn, userSubscribe) | ||
78 | + if err != nil { | ||
79 | + return err | ||
80 | + } | ||
81 | + //发送订阅消息 | ||
82 | + subCtx := l.getSubScribe() | ||
83 | + sendErr := subCtx.Send(msg) | ||
84 | + if sendErr != nil { | ||
85 | + subscribeMessage.Result = "fail" | ||
86 | + subscribeMessage.Error = sendErr.Error() | ||
87 | + } else { | ||
88 | + subscribeMessage.Result = "ok" | ||
89 | + } | ||
90 | + } | ||
91 | + //保存订阅结果 | ||
92 | + _, err = l.svcCtx.MessageSubscribeRepository.Insert(l.ctx, conn, subscribeMessage) | ||
93 | + if err != nil { | ||
94 | + return err | ||
95 | + } | ||
96 | + return nil | ||
97 | +} | ||
98 | + | ||
99 | +func (l *MiniSubscribeLogic) messageSubscribe(companyId, userId int64, mType int) *domain.MessageSubscribe { | ||
100 | + return &domain.MessageSubscribe{ | ||
101 | + Type: mType, | ||
102 | + CompanyId: companyId, | ||
103 | + UserId: userId, | ||
104 | + } | ||
105 | +} | ||
106 | + | ||
107 | +// getReplyCommentUserInfo 获取评论消息用户信息 用户名称+职位 例:张三-董事办 | ||
108 | +func (l *MiniSubscribeLogic) getReplyCommentUserInfo(conn transaction.Conn, companyId, userId int64) (string, error) { | ||
109 | + userInfo, err := l.svcCtx.UserRepository.FindOne(l.ctx, conn, userId) | ||
110 | + if err != nil { | ||
111 | + return "", xerr.NewErrMsgErr("获取评论用户信息失败", err) | ||
112 | + } | ||
113 | + users := []string{userInfo.Name} | ||
114 | + if len(userInfo.Roles) > 0 { | ||
115 | + _, roles, err := l.svcCtx.RoleRepository.Find(l.ctx, conn, domain.IndexCompanyId(companyId)().MustWithKV("ids", userInfo.Roles)) | ||
116 | + if err == nil && len(roles) > 0 { | ||
117 | + roleNames := make([]string, 0) | ||
118 | + for _, item := range roles { | ||
119 | + roleNames = append(roleNames, item.Name) | ||
120 | + } | ||
121 | + users = append(users, strings.Join(roleNames, "、")) | ||
122 | + } | ||
123 | + } | ||
124 | + return strings.Join(users, "-"), nil | ||
125 | +} | ||
126 | + | ||
127 | +// ReplyComment 发送评论订阅消息 | ||
128 | +// @param conn 数据库连接 | ||
129 | +// @param article 文章 | ||
130 | +// @param comment 评论 | ||
131 | +func (l *MiniSubscribeLogic) ReplyComment(conn transaction.Conn, article *domain.Article, comment *domain.ArticleComment) error { | ||
132 | + //评论用户+职位 例: 张三-董事办 | ||
133 | + fromUserName, err := l.getReplyCommentUserInfo(conn, comment.CompanyId, comment.FromUserId) | ||
134 | + if err != nil { | ||
135 | + return xerr.NewErrMsgErr("发送消息失败", err) | ||
136 | + } | ||
137 | + //评论消息 | ||
138 | + msg := &subscribe.Message{ | ||
139 | + TemplateID: domain.SubscribeTemplateComment, | ||
140 | + Data: map[string]*subscribe.DataItem{ | ||
141 | + //文章标题 | ||
142 | + "thing1": &subscribe.DataItem{Value: article.GetSubscribeMessageTitle()}, | ||
143 | + //评论内容 | ||
144 | + "thing2": &subscribe.DataItem{Value: comment.GetSubscribeMessageContent()}, | ||
145 | + //评论时间 | ||
146 | + "time3": &subscribe.DataItem{Value: time.Now().Format("2006-01-02 15:04:05")}, | ||
147 | + //评论用户 | ||
148 | + "thing5": &subscribe.DataItem{Value: fromUserName}, | ||
149 | + //备注 | ||
150 | + "thing9": &subscribe.DataItem{Value: ""}, | ||
151 | + }, | ||
152 | + MiniprogramState: l.svcCtx.Config.Wechat.QrcodeEnv, | ||
153 | + } | ||
154 | + //发帖人接收消息 | ||
155 | + openId, err := l.getOpenId(conn, article.AuthorId) | ||
156 | + //未绑定微信号,直接返回 | ||
157 | + if err == nil && openId != "" { | ||
158 | + msg.ToUser = openId | ||
159 | + msg.Page = fmt.Sprintf("/pages/detail/more-comment?id=%v", article.Id) //跳转页面 帖子评论聚合页 | ||
160 | + //备注 | ||
161 | + userCount, err := l.svcCtx.ArticleCommentRepository.CommentUserCount(l.ctx, conn, comment.CompanyId, comment.ArticleId) | ||
162 | + msg.Data["thing9"] = &subscribe.DataItem{Value: fmt.Sprintf("您的帖子最近已有%v人评论,点击查看详情", userCount)} | ||
163 | + //发送微信订阅消息 | ||
164 | + err = l.sendAndDecrease(conn, comment.CompanyId, article.AuthorId, domain.SubscribeTypeReplyComment, msg) | ||
165 | + if err != nil { | ||
166 | + return xerr.NewErrMsgErr("评论失败", err) | ||
167 | + } | ||
168 | + } | ||
169 | + //评论回复 | ||
170 | + if comment.Pid > 0 { | ||
171 | + toOpenId, err := l.getOpenId(conn, comment.ToUserId) | ||
172 | + if err == nil && toOpenId != "" { | ||
173 | + msg.ToUser = toOpenId | ||
174 | + msg.Page = fmt.Sprintf("/pages/detail/reply-comment?id=%v&commentId=%v", article.Id, comment.Pid) //跳转页面评论聚合页 | ||
175 | + //备注 | ||
176 | + replyCount, err := l.svcCtx.ArticleCommentRepository.ReplyUserCount(l.ctx, conn, comment.CompanyId, comment.Pid) | ||
177 | + if err == nil { | ||
178 | + msg.Data["thing9"] = &subscribe.DataItem{Value: fmt.Sprintf("您的评论最近已有%v人回复,点击查看详情", replyCount)} | ||
179 | + //发送微信订阅消息 | ||
180 | + err = l.sendAndDecrease(conn, comment.CompanyId, comment.ToUserId, domain.SubscribeTypeReplyComment, msg) | ||
181 | + if err != nil { | ||
182 | + return xerr.NewErrMsgErr("评论失败", err) | ||
183 | + } | ||
184 | + } | ||
185 | + } | ||
186 | + } | ||
187 | + //@消息 | ||
188 | + if len(comment.AtWho) > 0 { | ||
189 | + for _, at := range comment.AtWho { | ||
190 | + atOpenId, err := l.getOpenId(conn, at.Id) | ||
191 | + //未绑定微信跳过 | ||
192 | + if err != nil || atOpenId == "" { | ||
193 | + continue | ||
194 | + } | ||
195 | + msg.ToUser = atOpenId | ||
196 | + msg.Page = fmt.Sprintf("/pages/detail/reply-comment?id=%v&commentId=%v", article.Id, comment.Pid) //跳转页面 评论详情页 | ||
197 | + //备注 | ||
198 | + msg.Data["thing9"] = &subscribe.DataItem{Value: fmt.Sprintf("%v在评论中提到了你", comment.FromUser.Name)} | ||
199 | + //发送微信订阅消息 | ||
200 | + err = l.sendAndDecrease(conn, comment.CompanyId, at.Id, domain.SubscribeTypeReplyComment, msg) | ||
201 | + if err != nil { | ||
202 | + return xerr.NewErrMsgErr("评论失败", err) | ||
203 | + } | ||
204 | + } | ||
205 | + } | ||
206 | + return nil | ||
207 | +} | ||
208 | + | ||
209 | +// LikeArticle 帖子点赞订阅消息 | ||
210 | +func (l *MiniSubscribeLogic) LikeArticle(conn transaction.Conn, article *domain.Article, userInfo *domain.User) error { | ||
211 | + openId, err := l.getOpenId(conn, article.AuthorId) | ||
212 | + if err != nil || openId == "" { | ||
213 | + return nil | ||
214 | + } | ||
215 | + newArticle, err := l.svcCtx.ArticleRepository.FindOne(l.ctx, conn, article.Id) | ||
216 | + if err != nil { | ||
217 | + return xerr.NewErrMsgErr("未获取到帖子信息", err) | ||
218 | + } | ||
219 | + msg := &subscribe.Message{ | ||
220 | + ToUser: openId, | ||
221 | + TemplateID: domain.SubscribeTemplateLike, | ||
222 | + Page: fmt.Sprintf("/pages/detail/detail?id=%v", article.Id), | ||
223 | + Data: map[string]*subscribe.DataItem{ | ||
224 | + //点赞用户 | ||
225 | + "name1": &subscribe.DataItem{Value: userInfo.Name}, | ||
226 | + //点赞时间 | ||
227 | + "date2": &subscribe.DataItem{Value: time.Now().Format("2006-01-02 15:04:05")}, | ||
228 | + //动态内容 | ||
229 | + "thing8": &subscribe.DataItem{Value: article.GetSubscribeMessageTitle()}, | ||
230 | + //被赞次数 | ||
231 | + "number4": &subscribe.DataItem{Value: newArticle.CountLove}, | ||
232 | + //温馨提示 | ||
233 | + "thing5": &subscribe.DataItem{Value: "这条内容很受欢迎哦,快来看看吧"}, | ||
234 | + }, | ||
235 | + MiniprogramState: l.svcCtx.Config.Wechat.QrcodeEnv, | ||
236 | + } | ||
237 | + err = l.sendAndDecrease(conn, article.CompanyId, article.AuthorId, domain.SubscribeTypeLike, msg) | ||
238 | + if err != nil { | ||
239 | + return xerr.NewErrMsgErr("点赞失败", err) | ||
240 | + } | ||
241 | + return nil | ||
242 | +} | ||
243 | + | ||
244 | +// LikeComment 点赞评论订阅消息 | ||
245 | +func (l *MiniSubscribeLogic) LikeComment(conn transaction.Conn, comment *domain.ArticleComment, userInfo *domain.User) error { | ||
246 | + openId, err := l.getOpenId(conn, comment.FromUserId) | ||
247 | + if err != nil || openId == "" { | ||
248 | + return nil | ||
249 | + } | ||
250 | + //获取被赞次数 | ||
251 | + newComment, err := l.svcCtx.ArticleCommentRepository.FindOne(l.ctx, conn, comment.Id) | ||
252 | + if err != nil { | ||
253 | + return xerr.NewErrMsgErr("未获取到评论信息", err) | ||
254 | + } | ||
255 | + msg := &subscribe.Message{ | ||
256 | + ToUser: openId, | ||
257 | + TemplateID: domain.SubscribeTemplateLike, | ||
258 | + Page: fmt.Sprintf("/pages/detail/reply-comment?id=%v&commentId=%v", comment.ArticleId, comment.Id), | ||
259 | + Data: map[string]*subscribe.DataItem{ | ||
260 | + //点赞用户 | ||
261 | + "name1": &subscribe.DataItem{Value: userInfo.Name}, | ||
262 | + //点赞时间 | ||
263 | + "date2": &subscribe.DataItem{Value: time.Now().Format("2006-01-02 15:04:05")}, | ||
264 | + //动态内容 | ||
265 | + "thing8": &subscribe.DataItem{Value: comment.GetSubscribeMessageContent()}, | ||
266 | + //被赞次数 | ||
267 | + "number4": &subscribe.DataItem{Value: newComment.CountUserLove}, | ||
268 | + //温馨提示 | ||
269 | + "thing5": &subscribe.DataItem{Value: "这条内容很受欢迎哦,快来看看吧"}, | ||
270 | + }, | ||
271 | + MiniprogramState: l.svcCtx.Config.Wechat.QrcodeEnv, | ||
272 | + } | ||
273 | + err = l.sendAndDecrease(conn, comment.CompanyId, comment.FromUserId, domain.SubscribeTypeLike, msg) | ||
274 | + if err != nil { | ||
275 | + return xerr.NewErrMsgErr("点赞失败", err) | ||
276 | + } | ||
277 | + return nil | ||
278 | +} | ||
279 | + | ||
280 | +// FollowArticle 发帖关注更新提醒 | ||
281 | +func (l *MiniSubscribeLogic) FollowArticle(conn transaction.Conn, article *domain.Article) error { | ||
282 | + //获取关注帖子作者的人员 | ||
283 | + _, userInfo, err := l.svcCtx.UserFollowRepository.Find(l.ctx, conn, domain.NewQueryOptions().WithKV("toUserIds", []int64{article.AuthorId})) | ||
284 | + if err == nil && len(userInfo) > 0 { | ||
285 | + for _, item := range userInfo { | ||
286 | + openId, err := l.getOpenId(conn, item.FromUserId) | ||
287 | + if err != nil || openId == "" { | ||
288 | + continue | ||
289 | + } | ||
290 | + msg := &subscribe.Message{ | ||
291 | + ToUser: openId, | ||
292 | + TemplateID: domain.SubscribeTemplateFollow, | ||
293 | + Page: fmt.Sprintf("/pages/detail/detail?id=%v", article.Id), | ||
294 | + Data: map[string]*subscribe.DataItem{ | ||
295 | + //创作者 | ||
296 | + "thing1": &subscribe.DataItem{Value: article.Author.Name}, | ||
297 | + //作品名称 | ||
298 | + "thing2": &subscribe.DataItem{Value: article.Title}, | ||
299 | + //内容摘要 | ||
300 | + "thing5": &subscribe.DataItem{Value: ""}, | ||
301 | + //发布时间 | ||
302 | + "time6": &subscribe.DataItem{Value: time.Now().Format("2006-01-02 15:04:05")}, | ||
303 | + //温馨提示 | ||
304 | + "thing3": &subscribe.DataItem{Value: "你关注的人发布了新的帖子"}, | ||
305 | + }, | ||
306 | + MiniprogramState: l.svcCtx.Config.Wechat.QrcodeEnv, | ||
307 | + } | ||
308 | + err = l.sendAndDecrease(conn, article.CompanyId, item.FromUserId, domain.SubscribeTypeFollow, msg) | ||
309 | + if err != nil { | ||
310 | + return xerr.NewErrMsgErr("保存订阅消息失败", err) | ||
311 | + } | ||
312 | + } | ||
313 | + } | ||
314 | + return nil | ||
315 | +} |
@@ -40,7 +40,7 @@ func (l *MiniUserDepartmentUsersLogic) MiniUserDepartmentUsers(req *types.MiniUs | @@ -40,7 +40,7 @@ func (l *MiniUserDepartmentUsersLogic) MiniUserDepartmentUsers(req *types.MiniUs | ||
40 | "list": groups, | 40 | "list": groups, |
41 | } | 41 | } |
42 | company, err = l.svcCtx.CompanyRepository.FindOne(l.ctx, conn, userToken.CompanyId) | 42 | company, err = l.svcCtx.CompanyRepository.FindOne(l.ctx, conn, userToken.CompanyId) |
43 | - if err != nil { | 43 | + if err != nil || company == nil { |
44 | return nil, xerr.NewErrMsgErr("查找部门用户失败", err) | 44 | return nil, xerr.NewErrMsgErr("查找部门用户失败", err) |
45 | } | 45 | } |
46 | _, departments, err = l.svcCtx.DepartmentRepository.Find(l.ctx, conn, domain.IndexCompanyId(userToken.CompanyId)().WithFindOnly()) | 46 | _, departments, err = l.svcCtx.DepartmentRepository.Find(l.ctx, conn, domain.IndexCompanyId(userToken.CompanyId)().WithFindOnly()) |
@@ -51,7 +51,7 @@ func (l *MiniUserDepartmentUsersLogic) MiniUserDepartmentUsers(req *types.MiniUs | @@ -51,7 +51,7 @@ func (l *MiniUserDepartmentUsersLogic) MiniUserDepartmentUsers(req *types.MiniUs | ||
51 | if err != nil { | 51 | if err != nil { |
52 | return nil, xerr.NewErrMsgErr("查找部门用户失败", err) | 52 | return nil, xerr.NewErrMsgErr("查找部门用户失败", err) |
53 | } | 53 | } |
54 | - departments = append([]*domain.Department{&domain.Department{Id: 0, Name: company.Name}}, departments...) | 54 | + departments = append([]*domain.Department{&domain.Department{Id: 0, Name: "未分组"}}, departments...) |
55 | lo.ForEach(departments, func(item *domain.Department, index int) { | 55 | lo.ForEach(departments, func(item *domain.Department, index int) { |
56 | group := DepartmentUser{ | 56 | group := DepartmentUser{ |
57 | Id: item.Id, | 57 | Id: item.Id, |
@@ -61,7 +61,7 @@ func (l *MiniUserDepartmentUsersLogic) MiniUserDepartmentUsers(req *types.MiniUs | @@ -61,7 +61,7 @@ func (l *MiniUserDepartmentUsersLogic) MiniUserDepartmentUsers(req *types.MiniUs | ||
61 | groupUserSet := collection.NewSet() | 61 | groupUserSet := collection.NewSet() |
62 | for _, user := range users { | 62 | for _, user := range users { |
63 | // 未分配部门的归类到公司底下 | 63 | // 未分配部门的归类到公司底下 |
64 | - if len(user.Departments) == 0 { | 64 | + if item.Id == 0 && len(user.Departments) == 0 { |
65 | if !groupUserSet.Contains(user.Id) { | 65 | if !groupUserSet.Contains(user.Id) { |
66 | group.Users = append(group.Users, &domain.User{ | 66 | group.Users = append(group.Users, &domain.User{ |
67 | Id: user.Id, | 67 | Id: user.Id, |
@@ -35,7 +35,7 @@ func (l *MiniUserLoginLogic) MiniUserLogin(req *types.MiniUserLoginRequest) (res | @@ -35,7 +35,7 @@ func (l *MiniUserLoginLogic) MiniUserLogin(req *types.MiniUserLoginRequest) (res | ||
35 | var ( | 35 | var ( |
36 | loginInfo *domain.LoginInfo | 36 | loginInfo *domain.LoginInfo |
37 | token string | 37 | token string |
38 | - loginCreator domain.LoginCreator = WxClientLogin{l: l} | 38 | + loginCreator domain.LoginCreator = WxClientLogin{svcCtx: l.svcCtx, ctx: l.ctx} |
39 | ) | 39 | ) |
40 | switch req.LoginType { | 40 | switch req.LoginType { |
41 | case domain.LoginTypeWechatLogin: | 41 | case domain.LoginTypeWechatLogin: |
@@ -102,7 +102,8 @@ func generateToken(svcCtx *svc.ServiceContext, user *domain.User) (token string, | @@ -102,7 +102,8 @@ func generateToken(svcCtx *svc.ServiceContext, user *domain.User) (token string, | ||
102 | } | 102 | } |
103 | 103 | ||
104 | type WxClientLogin struct { | 104 | type WxClientLogin struct { |
105 | - l *MiniUserLoginLogic | 105 | + svcCtx *svc.ServiceContext |
106 | + ctx context.Context | ||
106 | } | 107 | } |
107 | 108 | ||
108 | func (c WxClientLogin) WechatPhoneLogin(r domain.WechatLoginRequest) (*domain.LoginInfo, error) { | 109 | func (c WxClientLogin) WechatPhoneLogin(r domain.WechatLoginRequest) (*domain.LoginInfo, error) { |
@@ -111,8 +112,8 @@ func (c WxClientLogin) WechatPhoneLogin(r domain.WechatLoginRequest) (*domain.Lo | @@ -111,8 +112,8 @@ func (c WxClientLogin) WechatPhoneLogin(r domain.WechatLoginRequest) (*domain.Lo | ||
111 | Phone: "", | 112 | Phone: "", |
112 | } | 113 | } |
113 | miniprogram := wechat.NewWechat().GetMiniProgram(&miniConfig.Config{ | 114 | miniprogram := wechat.NewWechat().GetMiniProgram(&miniConfig.Config{ |
114 | - AppID: c.l.svcCtx.Config.Wechat.AppID, | ||
115 | - AppSecret: c.l.svcCtx.Config.Wechat.AppSecret, | 115 | + AppID: c.svcCtx.Config.Wechat.AppID, |
116 | + AppSecret: c.svcCtx.Config.Wechat.AppSecret, | ||
116 | Cache: cache.NewMemory(), | 117 | Cache: cache.NewMemory(), |
117 | }) | 118 | }) |
118 | authResult, err := miniprogram.GetAuth().GetPhoneNumber(code) | 119 | authResult, err := miniprogram.GetAuth().GetPhoneNumber(code) |
@@ -130,6 +131,23 @@ func (c WxClientLogin) WechatLogin(r domain.WechatLoginRequest) (*domain.LoginIn | @@ -130,6 +131,23 @@ func (c WxClientLogin) WechatLogin(r domain.WechatLoginRequest) (*domain.LoginIn | ||
130 | return nil, nil | 131 | return nil, nil |
131 | } | 132 | } |
132 | 133 | ||
134 | +func (c WxClientLogin) GetOpenId(r domain.WechatLoginRequest) (string, error) { | ||
135 | + miniprogram := wechat.NewWechat().GetMiniProgram(&miniConfig.Config{ | ||
136 | + AppID: c.svcCtx.Config.Wechat.AppID, | ||
137 | + AppSecret: c.svcCtx.Config.Wechat.AppSecret, | ||
138 | + Cache: cache.NewMemory(), | ||
139 | + }) | ||
140 | + result, err := miniprogram.GetAuth().Code2Session(r.Code) | ||
141 | + if err != nil { | ||
142 | + return "", xerr.NewErrMsgErr("发起授权请求失败", err) | ||
143 | + } | ||
144 | + plainData, err := miniprogram.GetEncryptor().Decrypt(result.SessionKey, r.EncryptedData, r.IV) | ||
145 | + if err != nil { | ||
146 | + return "", xerr.NewErrMsgErr("获取授权用户失败", err) | ||
147 | + } | ||
148 | + return plainData.OpenID, nil | ||
149 | +} | ||
150 | + | ||
133 | func (c WxClientLogin) PhonePasswordLogin(phone string, password string) (*domain.LoginInfo, error) { | 151 | func (c WxClientLogin) PhonePasswordLogin(phone string, password string) (*domain.LoginInfo, error) { |
134 | panic("implement me") | 152 | panic("implement me") |
135 | } | 153 | } |
@@ -139,10 +157,10 @@ func (c WxClientLogin) PhoneSmsCodeLogin(phone string, code string) (*domain.Log | @@ -139,10 +157,10 @@ func (c WxClientLogin) PhoneSmsCodeLogin(phone string, code string) (*domain.Log | ||
139 | err error | 157 | err error |
140 | skipCheckSmsCode bool = false | 158 | skipCheckSmsCode bool = false |
141 | ) | 159 | ) |
142 | - if c.l.svcCtx.Config.DebugSmsCode != "" && c.l.svcCtx.Config.DebugSmsCode == code { | 160 | + if c.svcCtx.Config.DebugSmsCode != "" && c.svcCtx.Config.DebugSmsCode == code { |
143 | skipCheckSmsCode = true | 161 | skipCheckSmsCode = true |
144 | } | 162 | } |
145 | - if _, err = c.l.svcCtx.SmsService.CheckSmsCode(c.l.ctx, smslib.RequestCheckSmsCode{Phone: phone, Code: code}); err != nil && !skipCheckSmsCode { | 163 | + if _, err = c.svcCtx.SmsService.CheckSmsCode(c.ctx, smslib.RequestCheckSmsCode{Phone: phone, Code: code}); err != nil && !skipCheckSmsCode { |
146 | return nil, xerr.NewErrMsgErr(err.Error(), err) | 164 | return nil, xerr.NewErrMsgErr(err.Error(), err) |
147 | } | 165 | } |
148 | response := &domain.LoginInfo{ | 166 | response := &domain.LoginInfo{ |
1 | +package user | ||
2 | + | ||
3 | +import ( | ||
4 | + "context" | ||
5 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain" | ||
6 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/contextdata" | ||
7 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr" | ||
8 | + | ||
9 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc" | ||
10 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types" | ||
11 | + | ||
12 | + "github.com/zeromicro/go-zero/core/logx" | ||
13 | +) | ||
14 | + | ||
15 | +type MiniWechatBindLogic struct { | ||
16 | + logx.Logger | ||
17 | + ctx context.Context | ||
18 | + svcCtx *svc.ServiceContext | ||
19 | +} | ||
20 | + | ||
21 | +func NewMiniWechatBindLogic(ctx context.Context, svcCtx *svc.ServiceContext) *MiniWechatBindLogic { | ||
22 | + return &MiniWechatBindLogic{ | ||
23 | + Logger: logx.WithContext(ctx), | ||
24 | + ctx: ctx, | ||
25 | + svcCtx: svcCtx, | ||
26 | + } | ||
27 | +} | ||
28 | + | ||
29 | +func (l *MiniWechatBindLogic) MiniWechatBind(req *types.MiniWechatBindRequest) (resp *types.MiniWechatBindResponse, err error) { | ||
30 | + var loginCreator domain.LoginCreator = WxClientLogin{svcCtx: l.svcCtx, ctx: l.ctx} | ||
31 | + openId, err := loginCreator.GetOpenId(domain.WechatLoginRequest{ | ||
32 | + Code: req.WechatAuthCode, | ||
33 | + EncryptedData: req.WechatEncryptedData, | ||
34 | + IV: req.WechatIV, | ||
35 | + }) | ||
36 | + if err != nil { | ||
37 | + return nil, xerr.NewErrMsgErr("授权失败", err) | ||
38 | + } | ||
39 | + var userToken = contextdata.GetUserTokenFromCtx(l.ctx) | ||
40 | + userId := userToken.UserId | ||
41 | + var conn = l.svcCtx.DefaultDBConn() | ||
42 | + //获取用户信息 | ||
43 | + userInfo, err := l.svcCtx.UserRepository.FindOne(l.ctx, conn, userId) | ||
44 | + if err != nil { | ||
45 | + return nil, xerr.NewErrMsgErr("获取用户信息失败", err) | ||
46 | + } | ||
47 | + _, err = l.svcCtx.UserWechatRepository.FindOneByPhone(l.ctx, conn, userInfo.Phone) | ||
48 | + if err != nil { // 未存储 | ||
49 | + _, err = l.svcCtx.UserWechatRepository.Insert(l.ctx, conn, &domain.UserWechat{ | ||
50 | + Phone: userInfo.Phone, | ||
51 | + OpenId: openId, | ||
52 | + }) | ||
53 | + if err != nil { | ||
54 | + return nil, xerr.NewErrMsgErr("授权失败", err) | ||
55 | + } | ||
56 | + } | ||
57 | + if err != nil { | ||
58 | + return nil, xerr.NewErrMsg("保存用户信息失败") | ||
59 | + } | ||
60 | + return &types.MiniWechatBindResponse{ | ||
61 | + Bind: true, | ||
62 | + Phone: userInfo.Phone, | ||
63 | + OpenId: openId, | ||
64 | + }, nil | ||
65 | +} |
1 | +package user | ||
2 | + | ||
3 | +import ( | ||
4 | + "context" | ||
5 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/contextdata" | ||
6 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr" | ||
7 | + | ||
8 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc" | ||
9 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types" | ||
10 | + | ||
11 | + "github.com/zeromicro/go-zero/core/logx" | ||
12 | +) | ||
13 | + | ||
14 | +type MiniWechatInfoLogic struct { | ||
15 | + logx.Logger | ||
16 | + ctx context.Context | ||
17 | + svcCtx *svc.ServiceContext | ||
18 | +} | ||
19 | + | ||
20 | +func NewMiniWechatInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *MiniWechatInfoLogic { | ||
21 | + return &MiniWechatInfoLogic{ | ||
22 | + Logger: logx.WithContext(ctx), | ||
23 | + ctx: ctx, | ||
24 | + svcCtx: svcCtx, | ||
25 | + } | ||
26 | +} | ||
27 | + | ||
28 | +func (l *MiniWechatInfoLogic) MiniWechatInfo(req *types.MiniWechatInfoRequest) (resp *types.MiniWechatInfoResponse, err error) { | ||
29 | + var userToken = contextdata.GetUserTokenFromCtx(l.ctx) | ||
30 | + userId := userToken.UserId | ||
31 | + var conn = l.svcCtx.DefaultDBConn() | ||
32 | + user, err := l.svcCtx.UserRepository.FindOne(l.ctx, conn, userId) | ||
33 | + if err != nil { | ||
34 | + return nil, xerr.NewErrMsg("未获取到用户信息") | ||
35 | + } | ||
36 | + userWechat, err := l.svcCtx.UserWechatRepository.FindOneByPhone(l.ctx, conn, user.Phone) | ||
37 | + if err != nil { | ||
38 | + return &types.MiniWechatInfoResponse{ | ||
39 | + Bind: false, | ||
40 | + }, nil | ||
41 | + } else { | ||
42 | + return &types.MiniWechatInfoResponse{ | ||
43 | + Bind: true, | ||
44 | + OpenId: userWechat.OpenId, | ||
45 | + Phone: userWechat.Phone, | ||
46 | + }, nil | ||
47 | + } | ||
48 | +} |
@@ -41,8 +41,11 @@ func (l *SystemUserSearchLogic) SystemUserSearch(req *types.SystemUserSearchRequ | @@ -41,8 +41,11 @@ func (l *SystemUserSearchLogic) SystemUserSearch(req *types.SystemUserSearchRequ | ||
41 | WithKV("likePhone", req.Phone). | 41 | WithKV("likePhone", req.Phone). |
42 | WithKV("position", req.Position). | 42 | WithKV("position", req.Position). |
43 | WithKV("enable", req.Enable). | 43 | WithKV("enable", req.Enable). |
44 | - WithKV("departmentId", req.DepartmentId). | ||
45 | WithKV("auditStatus", []int{domain.UserAuditStatusPassed}) | 44 | WithKV("auditStatus", []int{domain.UserAuditStatusPassed}) |
45 | + | ||
46 | + if req.DepartmentId != nil { | ||
47 | + queryOptions.MustWithKV("departmentId", *req.DepartmentId) | ||
48 | + } | ||
46 | if total, users, err = l.svcCtx.UserRepository.Find(l.ctx, conn, queryOptions); err != nil { | 49 | if total, users, err = l.svcCtx.UserRepository.Find(l.ctx, conn, queryOptions); err != nil { |
47 | return nil, xerr.NewErr(err) | 50 | return nil, xerr.NewErr(err) |
48 | } | 51 | } |
@@ -37,16 +37,19 @@ type ServiceContext struct { | @@ -37,16 +37,19 @@ type ServiceContext struct { | ||
37 | ArticleAndTagRepository domain.ArticleAndTagRepository | 37 | ArticleAndTagRepository domain.ArticleAndTagRepository |
38 | ArticleDraftOperationRepository domain.ArticleDraftOperationRepository | 38 | ArticleDraftOperationRepository domain.ArticleDraftOperationRepository |
39 | 39 | ||
40 | - CompanyRepository domain.CompanyRepository | ||
41 | - DepartmentRepository domain.DepartmentRepository | ||
42 | - MessageBusinessRepository domain.MessageBusinessRepository | ||
43 | - MessageSystemRepository domain.MessageSystemRepository | ||
44 | - RoleRepository domain.RoleRepository | ||
45 | - UserFollowRepository domain.UserFollowRepository | ||
46 | - UserLoveFlagRepository domain.UserLoveFlagRepository | ||
47 | - UserReadArticleRepository domain.UserReadArticleRepository | ||
48 | - UserRepository domain.UserRepository | ||
49 | - UserRoleRepository domain.UserRoleRepository | 40 | + CompanyRepository domain.CompanyRepository |
41 | + DepartmentRepository domain.DepartmentRepository | ||
42 | + MessageBusinessRepository domain.MessageBusinessRepository | ||
43 | + MessageSystemRepository domain.MessageSystemRepository | ||
44 | + MessageSubscribeRepository domain.MessageSubscribeRepository | ||
45 | + RoleRepository domain.RoleRepository | ||
46 | + UserFollowRepository domain.UserFollowRepository | ||
47 | + UserLoveFlagRepository domain.UserLoveFlagRepository | ||
48 | + UserReadArticleRepository domain.UserReadArticleRepository | ||
49 | + UserRepository domain.UserRepository | ||
50 | + UserRoleRepository domain.UserRoleRepository | ||
51 | + UserSubscribeRepository domain.UserSubscribeRepository | ||
52 | + UserWechatRepository domain.UserWechatRepository | ||
50 | 53 | ||
51 | ApiAuthService authlib.ApiAuthService | 54 | ApiAuthService authlib.ApiAuthService |
52 | SmsService smslib.SMSService | 55 | SmsService smslib.SMSService |
@@ -92,17 +95,20 @@ func NewServiceContext(c config.Config) *ServiceContext { | @@ -92,17 +95,20 @@ func NewServiceContext(c config.Config) *ServiceContext { | ||
92 | ArticleCategoryRepository: repository.NewArticleCategoryRepository(cache.NewCachedRepository(mlCache)), | 95 | ArticleCategoryRepository: repository.NewArticleCategoryRepository(cache.NewCachedRepository(mlCache)), |
93 | ArticleDraftOperationRepository: repository.NewArticleDraftOperationRepository(cache.NewCachedRepository(mlCache)), | 96 | ArticleDraftOperationRepository: repository.NewArticleDraftOperationRepository(cache.NewCachedRepository(mlCache)), |
94 | 97 | ||
95 | - CompanyRepository: repository.NewCompanyRepository(cache.NewCachedRepository(mlCache)), | ||
96 | - DepartmentRepository: repository.NewDepartmentRepository(cache.NewCachedRepository(mlCache)), | ||
97 | - MessageBusinessRepository: repository.NewMessageBusinessRepository(cache.NewCachedRepository(mlCache)), | ||
98 | - MessageSystemRepository: repository.NewMessageSystemRepository(cache.NewCachedRepository(mlCache)), | ||
99 | - RoleRepository: repository.NewRoleRepository(cache.NewCachedRepository(mlCache)), | ||
100 | - UserFollowRepository: repository.NewUserFollowRepository(cache.NewCachedRepository(mlCache)), | ||
101 | - UserLoveFlagRepository: repository.NewUserLoveFlagRepository(cache.NewCachedRepository(mlCache)), | ||
102 | - UserRepository: repository.NewUserRepository(cache.NewCachedRepository(mlCache)), | ||
103 | - UserReadArticleRepository: repository.NewUserReadArticleRepository(cache.NewCachedRepository(mlCache)), | ||
104 | - ArticleTagRepository: repository.NewArticleTagRepository(cache.NewCachedRepository(mlCache)), | ||
105 | - UserRoleRepository: repository.NewUserRoleRepository(cache.NewCachedRepository(mlCache)), | 98 | + CompanyRepository: repository.NewCompanyRepository(cache.NewCachedRepository(mlCache)), |
99 | + DepartmentRepository: repository.NewDepartmentRepository(cache.NewCachedRepository(mlCache)), | ||
100 | + MessageBusinessRepository: repository.NewMessageBusinessRepository(cache.NewCachedRepository(mlCache)), | ||
101 | + MessageSystemRepository: repository.NewMessageSystemRepository(cache.NewCachedRepository(mlCache)), | ||
102 | + MessageSubscribeRepository: repository.NewMessageSubscribeRepository(cache.NewCachedRepository(mlCache)), | ||
103 | + RoleRepository: repository.NewRoleRepository(cache.NewCachedRepository(mlCache)), | ||
104 | + UserFollowRepository: repository.NewUserFollowRepository(cache.NewCachedRepository(mlCache)), | ||
105 | + UserLoveFlagRepository: repository.NewUserLoveFlagRepository(cache.NewCachedRepository(mlCache)), | ||
106 | + UserRepository: repository.NewUserRepository(cache.NewCachedRepository(mlCache)), | ||
107 | + UserReadArticleRepository: repository.NewUserReadArticleRepository(cache.NewCachedRepository(mlCache)), | ||
108 | + ArticleTagRepository: repository.NewArticleTagRepository(cache.NewCachedRepository(mlCache)), | ||
109 | + UserRoleRepository: repository.NewUserRoleRepository(cache.NewCachedRepository(mlCache)), | ||
110 | + UserSubscribeRepository: repository.NewUserSubscribeRepository(cache.NewCachedRepository(mlCache)), | ||
111 | + UserWechatRepository: repository.NewUserWechatRepository(cache.NewCachedRepository(mlCache)), | ||
106 | } | 112 | } |
107 | } | 113 | } |
108 | 114 |
@@ -347,6 +347,28 @@ type SimpleArticle struct { | @@ -347,6 +347,28 @@ type SimpleArticle struct { | ||
347 | Show int `json:"show"` // 文章的展示状态(0显示、1不显示) | 347 | Show int `json:"show"` // 文章的展示状态(0显示、1不显示) |
348 | } | 348 | } |
349 | 349 | ||
350 | +type MessageSubscribeAddRequest struct { | ||
351 | + Types []int `json:"types"` // 订阅消息类型 | ||
352 | +} | ||
353 | + | ||
354 | +type MessageSubscribeAddResponse struct { | ||
355 | + Items []MessageSubscribeItem `json:"items"` | ||
356 | +} | ||
357 | + | ||
358 | +type MessageSubscribeItem struct { | ||
359 | + Type int `json:"type"` // 订阅消息类型 | ||
360 | + Count int `json:"count"` // 订阅次数 | ||
361 | + UserId int64 `json:"userId"` // 用户ID | ||
362 | + CompanyId int64 `json:"companyId"` // 公司ID | ||
363 | +} | ||
364 | + | ||
365 | +type MessageSubscribeListRequest struct { | ||
366 | +} | ||
367 | + | ||
368 | +type MessageSubscribeListResponse struct { | ||
369 | + Items []MessageSubscribeItem `json:"items"` | ||
370 | +} | ||
371 | + | ||
350 | type TagCreateRequest struct { | 372 | type TagCreateRequest struct { |
351 | CompanyId int64 `json:",optional"` | 373 | CompanyId int64 `json:",optional"` |
352 | Image string `json:"image"` | 374 | Image string `json:"image"` |
@@ -637,6 +659,7 @@ type Department struct { | @@ -637,6 +659,7 @@ type Department struct { | ||
637 | ParentId int64 `json:"parentId"` // 父级ID | 659 | ParentId int64 `json:"parentId"` // 父级ID |
638 | Name string `json:"name"` // 部门名称 | 660 | Name string `json:"name"` // 部门名称 |
639 | UserIds []int64 `json:"userIds"` // 部门下的用户 | 661 | UserIds []int64 `json:"userIds"` // 部门下的用户 |
662 | + TotalUser int `json:"totalUser"` // 累计用户 | ||
640 | } | 663 | } |
641 | 664 | ||
642 | type UserSearchRequest struct { | 665 | type UserSearchRequest struct { |
@@ -786,7 +809,7 @@ type SystemUserSearchRequest struct { | @@ -786,7 +809,7 @@ type SystemUserSearchRequest struct { | ||
786 | Phone string `json:"phone,optional"` // 手机号 唯一 | 809 | Phone string `json:"phone,optional"` // 手机号 唯一 |
787 | Position string `json:"position,optional"` // 职位 | 810 | Position string `json:"position,optional"` // 职位 |
788 | Enable int `json:"enable,optional"` // 启用状态 1:启用 2:禁用 | 811 | Enable int `json:"enable,optional"` // 启用状态 1:启用 2:禁用 |
789 | - DepartmentId int64 `json:"departmentId,optional"` // 所属部门 | 812 | + DepartmentId *int64 `json:"departmentId,optional"` // 所属部门 |
790 | } | 813 | } |
791 | 814 | ||
792 | type SystemUserSearchResponse struct { | 815 | type SystemUserSearchResponse struct { |
@@ -846,6 +869,27 @@ type SystemUserAccountSearchResponse struct { | @@ -846,6 +869,27 @@ type SystemUserAccountSearchResponse struct { | ||
846 | Total int64 `json:"total"` | 869 | Total int64 `json:"total"` |
847 | } | 870 | } |
848 | 871 | ||
872 | +type MiniWechatInfoRequest struct { | ||
873 | +} | ||
874 | + | ||
875 | +type MiniWechatInfoResponse struct { | ||
876 | + Bind bool `json:"bind"` // 绑定结果 true-已绑定 false-未绑定 | ||
877 | + OpenId string `json:"openId"` // 绑定的微信openId | ||
878 | + Phone string `json:"phone"` // 绑定手机号 | ||
879 | +} | ||
880 | + | ||
881 | +type MiniWechatBindRequest struct { | ||
882 | + WechatAuthCode string `json:"wechatAuthcode"` // 微信登录 授权码 | ||
883 | + WechatEncryptedData string `json:"wechatEncryptedData"` // 微信登录 加密数据 | ||
884 | + WechatIV string `json:"wechatIV"` // 微信登录 加密算法初始向量 | ||
885 | +} | ||
886 | + | ||
887 | +type MiniWechatBindResponse struct { | ||
888 | + Bind bool `json:"bind"` // 绑定结果 true-已绑定 false-未绑定 | ||
889 | + OpenId string `json:"openId"` // 绑定的微信openId | ||
890 | + Phone string `json:"phone"` // 绑定手机号 | ||
891 | +} | ||
892 | + | ||
849 | type CompanySearchRequest struct { | 893 | type CompanySearchRequest struct { |
850 | Page int `json:"page,optional"` | 894 | Page int `json:"page,optional"` |
851 | Size int `json:"size,optional"` | 895 | Size int `json:"size,optional"` |
@@ -1727,9 +1771,10 @@ type DepartmentUpdateRequest struct { | @@ -1727,9 +1771,10 @@ type DepartmentUpdateRequest struct { | ||
1727 | } | 1771 | } |
1728 | 1772 | ||
1729 | type DepartmentListRequest struct { | 1773 | type DepartmentListRequest struct { |
1730 | - Page int `json:"page"` | ||
1731 | - Size int `json:"size"` | ||
1732 | - IncludeRootCompany bool `json:"includeRootCompany,optional"` // 包含公司(把公司当作部门作为顶级节点 部门ID:0) | 1774 | + Page int `json:"page"` |
1775 | + Size int `json:"size"` | ||
1776 | + IncludeRootCompany bool `json:"includeRootCompany,optional"` // 包含公司(把公司当作部门作为顶级节点 部门ID:0) | ||
1777 | + IncludeDefaultDepartment bool `json:"includeDefaultDepartment,optional"` // 包含默认分组 | ||
1733 | } | 1778 | } |
1734 | 1779 | ||
1735 | type DepartmentListResponse struct { | 1780 | type DepartmentListResponse struct { |
1 | + | ||
2 | +syntax = "v1" | ||
3 | + | ||
4 | +info( | ||
5 | + title: "xx实例" | ||
6 | + desc: "xx实例" | ||
7 | + author: "author" | ||
8 | + email: "email" | ||
9 | + version: "v1" | ||
10 | +) | ||
11 | + | ||
12 | +@server( | ||
13 | + prefix: message_subscribe/v1 | ||
14 | + group: message_subscribe | ||
15 | + jwt: JwtAuth | ||
16 | +) | ||
17 | +service Core { | ||
18 | + @handler getMessageSubscribe | ||
19 | + post /message_subscribe/:id (MessageSubscribeGetRequest) returns (MessageSubscribeGetResponse) | ||
20 | + @handler saveMessageSubscribe | ||
21 | + post /message_subscribe (MessageSubscribeSaveRequest) returns (MessageSubscribeSaveResponse) | ||
22 | + @handler deleteMessageSubscribe | ||
23 | + delete /message_subscribe/:id (MessageSubscribeDeleteRequest) returns (MessageSubscribeDeleteResponse) | ||
24 | + @handler updateMessageSubscribe | ||
25 | + put /message_subscribe/:id (MessageSubscribeUpdateRequest) returns (MessageSubscribeUpdateResponse) | ||
26 | + @handler searchMessageSubscribe | ||
27 | + post /message_subscribe/search (MessageSubscribeSearchRequest) returns (MessageSubscribeSearchResponse) | ||
28 | +} | ||
29 | + | ||
30 | +type ( | ||
31 | + MessageSubscribeGetRequest { | ||
32 | + Id int64 `path:"id"` | ||
33 | + } | ||
34 | + MessageSubscribeGetResponse struct{ | ||
35 | + MessageSubscribe MessageSubscribeItem `json:"message_subscribe"` | ||
36 | + } | ||
37 | + | ||
38 | + MessageSubscribeSaveRequest struct{ | ||
39 | + MessageSubscribe MessageSubscribeItem `json:"message_subscribe"` | ||
40 | + } | ||
41 | + MessageSubscribeSaveResponse struct{} | ||
42 | + | ||
43 | + MessageSubscribeDeleteRequest struct{ | ||
44 | + Id int64 `path:"id"` | ||
45 | + } | ||
46 | + MessageSubscribeDeleteResponse struct{} | ||
47 | + | ||
48 | + MessageSubscribeUpdateRequest struct{ | ||
49 | + Id int64 `path:"id"` | ||
50 | + MessageSubscribe MessageSubscribeItem `json:"message_subscribe"` | ||
51 | + } | ||
52 | + MessageSubscribeUpdateResponse struct{} | ||
53 | + | ||
54 | + MessageSubscribeSearchRequest struct{ | ||
55 | + Page int `json:"page"` | ||
56 | + Size int `json:"size"` | ||
57 | + } | ||
58 | + MessageSubscribeSearchResponse{ | ||
59 | + List []MessageSubscribeItem `json:"list"` | ||
60 | + Total int64 `json:"total"` | ||
61 | + } | ||
62 | + MessageSubscribeItem struct{ | ||
63 | + | ||
64 | + } | ||
65 | +) |
cmd/discuss/doc/dsl/api/user_subscribe.api
0 → 100755
1 | + | ||
2 | +syntax = "v1" | ||
3 | + | ||
4 | +info( | ||
5 | + title: "xx实例" | ||
6 | + desc: "xx实例" | ||
7 | + author: "author" | ||
8 | + email: "email" | ||
9 | + version: "v1" | ||
10 | +) | ||
11 | + | ||
12 | +@server( | ||
13 | + prefix: user_subscribe/v1 | ||
14 | + group: user_subscribe | ||
15 | + jwt: JwtAuth | ||
16 | +) | ||
17 | +service Core { | ||
18 | + @handler getUserSubscribe | ||
19 | + post /user_subscribe/:id (UserSubscribeGetRequest) returns (UserSubscribeGetResponse) | ||
20 | + @handler saveUserSubscribe | ||
21 | + post /user_subscribe (UserSubscribeSaveRequest) returns (UserSubscribeSaveResponse) | ||
22 | + @handler deleteUserSubscribe | ||
23 | + delete /user_subscribe/:id (UserSubscribeDeleteRequest) returns (UserSubscribeDeleteResponse) | ||
24 | + @handler updateUserSubscribe | ||
25 | + put /user_subscribe/:id (UserSubscribeUpdateRequest) returns (UserSubscribeUpdateResponse) | ||
26 | + @handler searchUserSubscribe | ||
27 | + post /user_subscribe/search (UserSubscribeSearchRequest) returns (UserSubscribeSearchResponse) | ||
28 | +} | ||
29 | + | ||
30 | +type ( | ||
31 | + UserSubscribeGetRequest { | ||
32 | + Id int64 `path:"id"` | ||
33 | + } | ||
34 | + UserSubscribeGetResponse struct{ | ||
35 | + UserSubscribe UserSubscribeItem `json:"user_subscribe"` | ||
36 | + } | ||
37 | + | ||
38 | + UserSubscribeSaveRequest struct{ | ||
39 | + UserSubscribe UserSubscribeItem `json:"user_subscribe"` | ||
40 | + } | ||
41 | + UserSubscribeSaveResponse struct{} | ||
42 | + | ||
43 | + UserSubscribeDeleteRequest struct{ | ||
44 | + Id int64 `path:"id"` | ||
45 | + } | ||
46 | + UserSubscribeDeleteResponse struct{} | ||
47 | + | ||
48 | + UserSubscribeUpdateRequest struct{ | ||
49 | + Id int64 `path:"id"` | ||
50 | + UserSubscribe UserSubscribeItem `json:"user_subscribe"` | ||
51 | + } | ||
52 | + UserSubscribeUpdateResponse struct{} | ||
53 | + | ||
54 | + UserSubscribeSearchRequest struct{ | ||
55 | + Page int `json:"page"` | ||
56 | + Size int `json:"size"` | ||
57 | + } | ||
58 | + UserSubscribeSearchResponse{ | ||
59 | + List []UserSubscribeItem `json:"list"` | ||
60 | + Total int64 `json:"total"` | ||
61 | + } | ||
62 | + UserSubscribeItem struct{ | ||
63 | + | ||
64 | + } | ||
65 | +) |
cmd/discuss/doc/dsl/api/user_wechat.api
0 → 100755
1 | + | ||
2 | +syntax = "v1" | ||
3 | + | ||
4 | +info( | ||
5 | + title: "xx实例" | ||
6 | + desc: "xx实例" | ||
7 | + author: "author" | ||
8 | + email: "email" | ||
9 | + version: "v1" | ||
10 | +) | ||
11 | + | ||
12 | +@server( | ||
13 | + prefix: user_wechat/v1 | ||
14 | + group: user_wechat | ||
15 | + jwt: JwtAuth | ||
16 | +) | ||
17 | +service Core { | ||
18 | + @handler getUserWechat | ||
19 | + post /user_wechat/:id (UserWechatGetRequest) returns (UserWechatGetResponse) | ||
20 | + @handler saveUserWechat | ||
21 | + post /user_wechat (UserWechatSaveRequest) returns (UserWechatSaveResponse) | ||
22 | + @handler deleteUserWechat | ||
23 | + delete /user_wechat/:id (UserWechatDeleteRequest) returns (UserWechatDeleteResponse) | ||
24 | + @handler updateUserWechat | ||
25 | + put /user_wechat/:id (UserWechatUpdateRequest) returns (UserWechatUpdateResponse) | ||
26 | + @handler searchUserWechat | ||
27 | + post /user_wechat/search (UserWechatSearchRequest) returns (UserWechatSearchResponse) | ||
28 | +} | ||
29 | + | ||
30 | +type ( | ||
31 | + UserWechatGetRequest { | ||
32 | + Id int64 `path:"id"` | ||
33 | + } | ||
34 | + UserWechatGetResponse struct{ | ||
35 | + UserWechat UserWechatItem `json:"user_wechat"` | ||
36 | + } | ||
37 | + | ||
38 | + UserWechatSaveRequest struct{ | ||
39 | + UserWechat UserWechatItem `json:"user_wechat"` | ||
40 | + } | ||
41 | + UserWechatSaveResponse struct{} | ||
42 | + | ||
43 | + UserWechatDeleteRequest struct{ | ||
44 | + Id int64 `path:"id"` | ||
45 | + } | ||
46 | + UserWechatDeleteResponse struct{} | ||
47 | + | ||
48 | + UserWechatUpdateRequest struct{ | ||
49 | + Id int64 `path:"id"` | ||
50 | + UserWechat UserWechatItem `json:"user_wechat"` | ||
51 | + } | ||
52 | + UserWechatUpdateResponse struct{} | ||
53 | + | ||
54 | + UserWechatSearchRequest struct{ | ||
55 | + Page int `json:"page"` | ||
56 | + Size int `json:"size"` | ||
57 | + } | ||
58 | + UserWechatSearchResponse{ | ||
59 | + List []UserWechatItem `json:"list"` | ||
60 | + Total int64 `json:"total"` | ||
61 | + } | ||
62 | + UserWechatItem struct{ | ||
63 | + | ||
64 | + } | ||
65 | +) |
1 | + | ||
2 | +syntax = "proto3"; | ||
3 | + | ||
4 | +option go_package ="./pb"; | ||
5 | + | ||
6 | +package pb; | ||
7 | + | ||
8 | +message MessageSubscribeGetReq { | ||
9 | + int64 Id = 1; | ||
10 | +} | ||
11 | +message MessageSubscribeGetResp{ | ||
12 | + MessageSubscribeItem User = 1; | ||
13 | +} | ||
14 | + | ||
15 | +message MessageSubscribeSaveReq { | ||
16 | + | ||
17 | +} | ||
18 | +message MessageSubscribeSaveResp{ | ||
19 | + | ||
20 | +} | ||
21 | + | ||
22 | +message MessageSubscribeDeleteReq { | ||
23 | + int64 Id = 1; | ||
24 | +} | ||
25 | +message MessageSubscribeDeleteResp{ | ||
26 | + | ||
27 | +} | ||
28 | + | ||
29 | +message MessageSubscribeUpdateReq { | ||
30 | + int64 Id = 1; | ||
31 | +} | ||
32 | +message MessageSubscribeUpdateResp{ | ||
33 | + | ||
34 | +} | ||
35 | + | ||
36 | +message MessageSubscribeSearchReq { | ||
37 | + int64 PageNumber = 1; | ||
38 | + int64 PageSize = 2; | ||
39 | +} | ||
40 | +message MessageSubscribeSearchResp{ | ||
41 | + repeated MessageSubscribeItem List =1; | ||
42 | + int64 Total =2; | ||
43 | +} | ||
44 | +message MessageSubscribeItem { | ||
45 | + | ||
46 | +} | ||
47 | + | ||
48 | +service MessageSubscribeService { | ||
49 | + rpc MessageSubscribeGet(MessageSubscribeGetReq) returns(MessageSubscribeGetResp); | ||
50 | + rpc MessageSubscribeSave(MessageSubscribeSaveReq) returns(MessageSubscribeSaveResp); | ||
51 | + rpc MessageSubscribeDelete(MessageSubscribeDeleteReq) returns(MessageSubscribeDeleteResp); | ||
52 | + rpc MessageSubscribeUpdate(MessageSubscribeUpdateReq) returns(MessageSubscribeUpdateResp); | ||
53 | + rpc MessageSubscribeSearch(MessageSubscribeSearchReq) returns(MessageSubscribeSearchResp); | ||
54 | +} |
cmd/discuss/doc/dsl/rpc/user_subscribe.proto
0 → 100755
1 | + | ||
2 | +syntax = "proto3"; | ||
3 | + | ||
4 | +option go_package ="./pb"; | ||
5 | + | ||
6 | +package pb; | ||
7 | + | ||
8 | +message UserSubscribeGetReq { | ||
9 | + int64 Id = 1; | ||
10 | +} | ||
11 | +message UserSubscribeGetResp{ | ||
12 | + UserSubscribeItem User = 1; | ||
13 | +} | ||
14 | + | ||
15 | +message UserSubscribeSaveReq { | ||
16 | + | ||
17 | +} | ||
18 | +message UserSubscribeSaveResp{ | ||
19 | + | ||
20 | +} | ||
21 | + | ||
22 | +message UserSubscribeDeleteReq { | ||
23 | + int64 Id = 1; | ||
24 | +} | ||
25 | +message UserSubscribeDeleteResp{ | ||
26 | + | ||
27 | +} | ||
28 | + | ||
29 | +message UserSubscribeUpdateReq { | ||
30 | + int64 Id = 1; | ||
31 | +} | ||
32 | +message UserSubscribeUpdateResp{ | ||
33 | + | ||
34 | +} | ||
35 | + | ||
36 | +message UserSubscribeSearchReq { | ||
37 | + int64 PageNumber = 1; | ||
38 | + int64 PageSize = 2; | ||
39 | +} | ||
40 | +message UserSubscribeSearchResp{ | ||
41 | + repeated UserSubscribeItem List =1; | ||
42 | + int64 Total =2; | ||
43 | +} | ||
44 | +message UserSubscribeItem { | ||
45 | + | ||
46 | +} | ||
47 | + | ||
48 | +service UserSubscribeService { | ||
49 | + rpc UserSubscribeGet(UserSubscribeGetReq) returns(UserSubscribeGetResp); | ||
50 | + rpc UserSubscribeSave(UserSubscribeSaveReq) returns(UserSubscribeSaveResp); | ||
51 | + rpc UserSubscribeDelete(UserSubscribeDeleteReq) returns(UserSubscribeDeleteResp); | ||
52 | + rpc UserSubscribeUpdate(UserSubscribeUpdateReq) returns(UserSubscribeUpdateResp); | ||
53 | + rpc UserSubscribeSearch(UserSubscribeSearchReq) returns(UserSubscribeSearchResp); | ||
54 | +} |
cmd/discuss/doc/dsl/rpc/user_wechat.proto
0 → 100755
1 | + | ||
2 | +syntax = "proto3"; | ||
3 | + | ||
4 | +option go_package ="./pb"; | ||
5 | + | ||
6 | +package pb; | ||
7 | + | ||
8 | +message UserWechatGetReq { | ||
9 | + int64 Id = 1; | ||
10 | +} | ||
11 | +message UserWechatGetResp{ | ||
12 | + UserWechatItem User = 1; | ||
13 | +} | ||
14 | + | ||
15 | +message UserWechatSaveReq { | ||
16 | + | ||
17 | +} | ||
18 | +message UserWechatSaveResp{ | ||
19 | + | ||
20 | +} | ||
21 | + | ||
22 | +message UserWechatDeleteReq { | ||
23 | + int64 Id = 1; | ||
24 | +} | ||
25 | +message UserWechatDeleteResp{ | ||
26 | + | ||
27 | +} | ||
28 | + | ||
29 | +message UserWechatUpdateReq { | ||
30 | + int64 Id = 1; | ||
31 | +} | ||
32 | +message UserWechatUpdateResp{ | ||
33 | + | ||
34 | +} | ||
35 | + | ||
36 | +message UserWechatSearchReq { | ||
37 | + int64 PageNumber = 1; | ||
38 | + int64 PageSize = 2; | ||
39 | +} | ||
40 | +message UserWechatSearchResp{ | ||
41 | + repeated UserWechatItem List =1; | ||
42 | + int64 Total =2; | ||
43 | +} | ||
44 | +message UserWechatItem { | ||
45 | + | ||
46 | +} | ||
47 | + | ||
48 | +service UserWechatService { | ||
49 | + rpc UserWechatGet(UserWechatGetReq) returns(UserWechatGetResp); | ||
50 | + rpc UserWechatSave(UserWechatSaveReq) returns(UserWechatSaveResp); | ||
51 | + rpc UserWechatDelete(UserWechatDeleteReq) returns(UserWechatDeleteResp); | ||
52 | + rpc UserWechatUpdate(UserWechatUpdateReq) returns(UserWechatUpdateResp); | ||
53 | + rpc UserWechatSearch(UserWechatSearchReq) returns(UserWechatSearchResp); | ||
54 | +} |
@@ -24,8 +24,11 @@ func Migrate(db *gorm.DB) { | @@ -24,8 +24,11 @@ func Migrate(db *gorm.DB) { | ||
24 | //&models.MessageBusiness{}, | 24 | //&models.MessageBusiness{}, |
25 | //&models.Department{}, | 25 | //&models.Department{}, |
26 | //&models.ArticleAndTag{}, | 26 | //&models.ArticleAndTag{}, |
27 | - &models.ArticleDraftOperation{}, | ||
28 | - &models.ArticleCategory{}, | 27 | + //&models.ArticleDraftOperation{}, |
28 | + //&models.ArticleCategory{}, | ||
29 | + &models.UserSubscribe{}, | ||
30 | + &models.MessageSubscribe{}, | ||
31 | + &models.UserWechat{}, | ||
29 | } | 32 | } |
30 | 33 | ||
31 | db.AutoMigrate(modelsList...) | 34 | db.AutoMigrate(modelsList...) |
1 | +package models | ||
2 | + | ||
3 | +import ( | ||
4 | + "fmt" | ||
5 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain" | ||
6 | + "gorm.io/gorm" | ||
7 | + "gorm.io/plugin/soft_delete" | ||
8 | +) | ||
9 | + | ||
10 | +type MessageSubscribe struct { | ||
11 | + Id int64 `json:"id"` // 唯一标识 | ||
12 | + Type int `json:"type"` // 分类(1评论回复 2获赞 3关注人更新) | ||
13 | + CompanyId int64 `json:"companyId"` // 公司ID | ||
14 | + UserId int64 `json:"userId"` // 用户ID | ||
15 | + OpenId string `json:"openId"` // 微信openID | ||
16 | + TemplateId string `json:"templateId"` // 模板ID | ||
17 | + TemplateData map[string]interface{} `json:"templateData" gorm:"serializer:json;type:text;"` // 模板参数 | ||
18 | + Result string `json:"result"` // 发送结果 | ||
19 | + Error string `json:"error"` // 调用接口错误信息 | ||
20 | + CreatedAt int64 `json:",omitempty"` // 创建时间 | ||
21 | + UpdatedAt int64 `json:",omitempty"` // 更新时间 | ||
22 | + DeletedAt int64 `json:",omitempty"` // 删除时间 | ||
23 | + Version int `json:",omitempty"` // 版本 | ||
24 | + IsDel soft_delete.DeletedAt `gorm:"softDelete:flag,DeletedAtField:DeletedAt"` // 删除标记 | ||
25 | +} | ||
26 | + | ||
27 | +func (m *MessageSubscribe) TableName() string { | ||
28 | + return "message_subscribe" | ||
29 | +} | ||
30 | + | ||
31 | +func (m *MessageSubscribe) BeforeCreate(tx *gorm.DB) (err error) { | ||
32 | + // m.CreatedAt = time.Now().Unix() | ||
33 | + // m.UpdatedAt = time.Now().Unix() | ||
34 | + return | ||
35 | +} | ||
36 | + | ||
37 | +func (m *MessageSubscribe) BeforeUpdate(tx *gorm.DB) (err error) { | ||
38 | + // m.UpdatedAt = time.Now().Unix() | ||
39 | + return | ||
40 | +} | ||
41 | + | ||
42 | +func (m *MessageSubscribe) CacheKeyFunc() string { | ||
43 | + if m.Id == 0 { | ||
44 | + return "" | ||
45 | + } | ||
46 | + return fmt.Sprintf("%v:cache:%v:id:%v", domain.ProjectName, m.TableName(), m.Id) | ||
47 | +} | ||
48 | + | ||
49 | +func (m *MessageSubscribe) CacheKeyFuncByObject(obj interface{}) string { | ||
50 | + if v, ok := obj.(*MessageSubscribe); ok { | ||
51 | + return v.CacheKeyFunc() | ||
52 | + } | ||
53 | + return "" | ||
54 | +} | ||
55 | + | ||
56 | +func (m *MessageSubscribe) CachePrimaryKeyFunc() string { | ||
57 | + if len("") == 0 { | ||
58 | + return "" | ||
59 | + } | ||
60 | + return fmt.Sprintf("%v:cache:%v:primarykey:%v", domain.ProjectName, m.TableName(), "key") | ||
61 | +} |
1 | +package models | ||
2 | + | ||
3 | +import ( | ||
4 | + "fmt" | ||
5 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain" | ||
6 | + "gorm.io/gorm" | ||
7 | + "gorm.io/plugin/soft_delete" | ||
8 | +) | ||
9 | + | ||
10 | +type UserSubscribe struct { | ||
11 | + Id int64 `json:"id"` // 唯一标识 | ||
12 | + Type int `json:"type" gorm:"type:int;"` // 分类(1评论回复 2获赞 3关注人更新) | ||
13 | + CompanyId int64 `json:"companyId"` // 公司ID | ||
14 | + UserId int64 `json:"userId"` // 用户ID | ||
15 | + Count int `json:"count" gorm:"type:int;"` // 订阅次数 | ||
16 | + CreatedAt int64 `json:",omitempty"` // 创建时间 | ||
17 | + UpdatedAt int64 `json:",omitempty"` // 更新时间 | ||
18 | + DeletedAt int64 `json:",omitempty"` // 删除时间 | ||
19 | + Version int `json:",omitempty"` // 版本 | ||
20 | + IsDel soft_delete.DeletedAt `gorm:"softDelete:flag,DeletedAtField:DeletedAt"` // 删除标记 | ||
21 | +} | ||
22 | + | ||
23 | +func (m *UserSubscribe) TableName() string { | ||
24 | + return "user_subscribe" | ||
25 | +} | ||
26 | + | ||
27 | +func (m *UserSubscribe) BeforeCreate(tx *gorm.DB) (err error) { | ||
28 | + // m.CreatedAt = time.Now().Unix() | ||
29 | + // m.UpdatedAt = time.Now().Unix() | ||
30 | + return | ||
31 | +} | ||
32 | + | ||
33 | +func (m *UserSubscribe) BeforeUpdate(tx *gorm.DB) (err error) { | ||
34 | + // m.UpdatedAt = time.Now().Unix() | ||
35 | + return | ||
36 | +} | ||
37 | + | ||
38 | +func (m *UserSubscribe) CacheKeyFunc() string { | ||
39 | + if m.Id == 0 { | ||
40 | + return "" | ||
41 | + } | ||
42 | + return fmt.Sprintf("%v:cache:%v:id:%v", domain.ProjectName, m.TableName(), m.Id) | ||
43 | +} | ||
44 | + | ||
45 | +func (m *UserSubscribe) CacheKeyFuncByObject(obj interface{}) string { | ||
46 | + if v, ok := obj.(*UserSubscribe); ok { | ||
47 | + return v.CacheKeyFunc() | ||
48 | + } | ||
49 | + return "" | ||
50 | +} | ||
51 | + | ||
52 | +func (m *UserSubscribe) CachePrimaryKeyFunc() string { | ||
53 | + if len("") == 0 { | ||
54 | + return "" | ||
55 | + } | ||
56 | + return fmt.Sprintf("%v:cache:%v:primarykey:%v", domain.ProjectName, m.TableName(), "key") | ||
57 | +} |
1 | +package models | ||
2 | + | ||
3 | +import ( | ||
4 | + "fmt" | ||
5 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain" | ||
6 | + "gorm.io/gorm" | ||
7 | + "gorm.io/plugin/soft_delete" | ||
8 | +) | ||
9 | + | ||
10 | +type UserWechat struct { | ||
11 | + Id int64 `json:"id"` // 唯一标识 | ||
12 | + OpenId string `json:"openId"` // 微信openId | ||
13 | + Phone string `json:"phone" gorm:"unique"` // 微信手机号 | ||
14 | + CreatedAt int64 `json:",omitempty"` // 创建时间 | ||
15 | + UpdatedAt int64 `json:",omitempty"` // 更新时间 | ||
16 | + DeletedAt int64 `json:",omitempty"` // 删除时间 | ||
17 | + Version int `json:",omitempty"` // 版本 | ||
18 | + IsDel soft_delete.DeletedAt `gorm:"softDelete:flag,DeletedAtField:DeletedAt"` // 删除标记 | ||
19 | +} | ||
20 | + | ||
21 | +func (m *UserWechat) TableName() string { | ||
22 | + return "user_wechat" | ||
23 | +} | ||
24 | + | ||
25 | +func (m *UserWechat) BeforeCreate(tx *gorm.DB) (err error) { | ||
26 | + // m.CreatedAt = time.Now().Unix() | ||
27 | + // m.UpdatedAt = time.Now().Unix() | ||
28 | + return | ||
29 | +} | ||
30 | + | ||
31 | +func (m *UserWechat) BeforeUpdate(tx *gorm.DB) (err error) { | ||
32 | + // m.UpdatedAt = time.Now().Unix() | ||
33 | + return | ||
34 | +} | ||
35 | + | ||
36 | +func (m *UserWechat) CacheKeyFunc() string { | ||
37 | + if m.Id == 0 { | ||
38 | + return "" | ||
39 | + } | ||
40 | + return fmt.Sprintf("%v:cache:%v:id:%v", domain.ProjectName, m.TableName(), m.Id) | ||
41 | +} | ||
42 | + | ||
43 | +func (m *UserWechat) CacheKeyFuncByObject(obj interface{}) string { | ||
44 | + if v, ok := obj.(*UserWechat); ok { | ||
45 | + return v.CacheKeyFunc() | ||
46 | + } | ||
47 | + return "" | ||
48 | +} | ||
49 | + | ||
50 | +func (m *UserWechat) CachePrimaryKeyFunc() string { | ||
51 | + if len("") == 0 { | ||
52 | + return "" | ||
53 | + } | ||
54 | + return fmt.Sprintf("%v:cache:%v:primarykey:%v", domain.ProjectName, m.TableName(), "key") | ||
55 | +} |
@@ -437,6 +437,28 @@ func (repository *ArticleCommentRepository) CustomSearchBy(ctx context.Context, | @@ -437,6 +437,28 @@ func (repository *ArticleCommentRepository) CustomSearchBy(ctx context.Context, | ||
437 | 437 | ||
438 | } | 438 | } |
439 | 439 | ||
440 | +// CommentUserCount 统计评论人数 | ||
441 | +func (repository *ArticleCommentRepository) CommentUserCount(ctx context.Context, conn transaction.Conn, companyId int64, articleId int64) (int64, error) { | ||
442 | + var ( | ||
443 | + err error | ||
444 | + tx = conn.DB() | ||
445 | + c int64 | ||
446 | + ) | ||
447 | + err = tx.Model(&models.ArticleComment{}).Where("company_id = ? and article_id = ?", companyId, articleId).Group("from_user_id").Count(&c).Error | ||
448 | + return c, err | ||
449 | +} | ||
450 | + | ||
451 | +// ReplyUserCount 统计回复人数 | ||
452 | +func (repository *ArticleCommentRepository) ReplyUserCount(ctx context.Context, conn transaction.Conn, companyId int64, commentId int64) (int64, error) { | ||
453 | + var ( | ||
454 | + err error | ||
455 | + tx = conn.DB() | ||
456 | + c int64 | ||
457 | + ) | ||
458 | + err = tx.Model(&models.ArticleComment{}).Where("company_id = ? and pid = ?", companyId, commentId).Group("from_user_id").Count(&c).Error | ||
459 | + return c, err | ||
460 | +} | ||
461 | + | ||
440 | func NewArticleCommentRepository(cache *cache.CachedRepository) domain.ArticleCommentRepository { | 462 | func NewArticleCommentRepository(cache *cache.CachedRepository) domain.ArticleCommentRepository { |
441 | return &ArticleCommentRepository{CachedRepository: cache} | 463 | return &ArticleCommentRepository{CachedRepository: cache} |
442 | } | 464 | } |
1 | +package repository | ||
2 | + | ||
3 | +import ( | ||
4 | + "context" | ||
5 | + "github.com/jinzhu/copier" | ||
6 | + "github.com/pkg/errors" | ||
7 | + "github.com/tiptok/gocomm/pkg/cache" | ||
8 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/models" | ||
9 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction" | ||
10 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain" | ||
11 | + "gorm.io/gorm" | ||
12 | +) | ||
13 | + | ||
14 | +type MessageSubscribeRepository struct { | ||
15 | + *cache.CachedRepository | ||
16 | +} | ||
17 | + | ||
18 | +func (repository *MessageSubscribeRepository) Insert(ctx context.Context, conn transaction.Conn, dm *domain.MessageSubscribe) (*domain.MessageSubscribe, error) { | ||
19 | + var ( | ||
20 | + err error | ||
21 | + m = &models.MessageSubscribe{} | ||
22 | + tx = conn.DB() | ||
23 | + ) | ||
24 | + if m, err = repository.DomainModelToModel(dm); err != nil { | ||
25 | + return nil, err | ||
26 | + } | ||
27 | + if tx = tx.Model(m).Save(m); tx.Error != nil { | ||
28 | + return nil, tx.Error | ||
29 | + } | ||
30 | + dm.Id = m.Id | ||
31 | + return repository.ModelToDomainModel(m) | ||
32 | + | ||
33 | +} | ||
34 | + | ||
35 | +func (repository *MessageSubscribeRepository) Update(ctx context.Context, conn transaction.Conn, dm *domain.MessageSubscribe) (*domain.MessageSubscribe, error) { | ||
36 | + var ( | ||
37 | + err error | ||
38 | + m *models.MessageSubscribe | ||
39 | + tx = conn.DB() | ||
40 | + ) | ||
41 | + if m, err = repository.DomainModelToModel(dm); err != nil { | ||
42 | + return nil, err | ||
43 | + } | ||
44 | + queryFunc := func() (interface{}, error) { | ||
45 | + tx = tx.Model(m).Select("*").Updates(m) | ||
46 | + return nil, tx.Error | ||
47 | + } | ||
48 | + if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil { | ||
49 | + return nil, err | ||
50 | + } | ||
51 | + return repository.ModelToDomainModel(m) | ||
52 | +} | ||
53 | + | ||
54 | +func (repository *MessageSubscribeRepository) UpdateWithVersion(ctx context.Context, transaction transaction.Conn, dm *domain.MessageSubscribe) (*domain.MessageSubscribe, error) { | ||
55 | + var ( | ||
56 | + err error | ||
57 | + m *models.MessageSubscribe | ||
58 | + tx = transaction.DB() | ||
59 | + ) | ||
60 | + if m, err = repository.DomainModelToModel(dm); err != nil { | ||
61 | + return nil, err | ||
62 | + } | ||
63 | + oldVersion := dm.Version | ||
64 | + m.Version += 1 | ||
65 | + queryFunc := func() (interface{}, error) { | ||
66 | + tx = tx.Model(m).Select("*").Where("id = ?", m.Id).Where("version = ?", oldVersion).Updates(m) | ||
67 | + if tx.RowsAffected == 0 { | ||
68 | + return nil, domain.ErrUpdateFail | ||
69 | + } | ||
70 | + return nil, tx.Error | ||
71 | + } | ||
72 | + if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil { | ||
73 | + return nil, err | ||
74 | + } | ||
75 | + return repository.ModelToDomainModel(m) | ||
76 | +} | ||
77 | + | ||
78 | +func (repository *MessageSubscribeRepository) Delete(ctx context.Context, conn transaction.Conn, dm *domain.MessageSubscribe) (*domain.MessageSubscribe, error) { | ||
79 | + var ( | ||
80 | + tx = conn.DB() | ||
81 | + m = &models.MessageSubscribe{Id: dm.Identify().(int64)} | ||
82 | + ) | ||
83 | + queryFunc := func() (interface{}, error) { | ||
84 | + tx = tx.Where("id = ?", m.Id).Delete(m) | ||
85 | + return m, tx.Error | ||
86 | + } | ||
87 | + if _, err := repository.Query(queryFunc, m.CacheKeyFunc()); err != nil { | ||
88 | + return dm, err | ||
89 | + } | ||
90 | + return repository.ModelToDomainModel(m) | ||
91 | +} | ||
92 | + | ||
93 | +func (repository *MessageSubscribeRepository) FindOne(ctx context.Context, conn transaction.Conn, id int64) (*domain.MessageSubscribe, error) { | ||
94 | + var ( | ||
95 | + err error | ||
96 | + tx = conn.DB() | ||
97 | + m = new(models.MessageSubscribe) | ||
98 | + ) | ||
99 | + queryFunc := func() (interface{}, error) { | ||
100 | + tx = tx.Model(m).Where("id = ?", id).First(m) | ||
101 | + if errors.Is(tx.Error, gorm.ErrRecordNotFound) { | ||
102 | + return nil, domain.ErrNotFound | ||
103 | + } | ||
104 | + return m, tx.Error | ||
105 | + } | ||
106 | + cacheModel := new(models.MessageSubscribe) | ||
107 | + cacheModel.Id = id | ||
108 | + if err = repository.QueryCache(cacheModel.CacheKeyFunc, m, queryFunc); err != nil { | ||
109 | + return nil, err | ||
110 | + } | ||
111 | + return repository.ModelToDomainModel(m) | ||
112 | +} | ||
113 | + | ||
114 | +func (repository *MessageSubscribeRepository) Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*domain.MessageSubscribe, error) { | ||
115 | + var ( | ||
116 | + tx = conn.DB() | ||
117 | + ms []*models.MessageSubscribe | ||
118 | + dms = make([]*domain.MessageSubscribe, 0) | ||
119 | + total int64 | ||
120 | + ) | ||
121 | + queryFunc := func() (interface{}, error) { | ||
122 | + tx = tx.Model(&ms).Order("id desc") | ||
123 | + if total, tx = transaction.PaginationAndCount(ctx, tx, queryOptions, &ms); tx.Error != nil { | ||
124 | + return dms, tx.Error | ||
125 | + } | ||
126 | + return dms, nil | ||
127 | + } | ||
128 | + | ||
129 | + if _, err := repository.Query(queryFunc); err != nil { | ||
130 | + return 0, nil, err | ||
131 | + } | ||
132 | + | ||
133 | + for _, item := range ms { | ||
134 | + if dm, err := repository.ModelToDomainModel(item); err != nil { | ||
135 | + return 0, dms, err | ||
136 | + } else { | ||
137 | + dms = append(dms, dm) | ||
138 | + } | ||
139 | + } | ||
140 | + return total, dms, nil | ||
141 | +} | ||
142 | + | ||
143 | +func (repository *MessageSubscribeRepository) ModelToDomainModel(from *models.MessageSubscribe) (*domain.MessageSubscribe, error) { | ||
144 | + to := &domain.MessageSubscribe{} | ||
145 | + err := copier.Copy(to, from) | ||
146 | + return to, err | ||
147 | +} | ||
148 | + | ||
149 | +func (repository *MessageSubscribeRepository) DomainModelToModel(from *domain.MessageSubscribe) (*models.MessageSubscribe, error) { | ||
150 | + to := &models.MessageSubscribe{} | ||
151 | + err := copier.Copy(to, from) | ||
152 | + return to, err | ||
153 | +} | ||
154 | + | ||
155 | +func NewMessageSubscribeRepository(cache *cache.CachedRepository) domain.MessageSubscribeRepository { | ||
156 | + return &MessageSubscribeRepository{CachedRepository: cache} | ||
157 | +} |
@@ -174,7 +174,12 @@ func (repository *UserRepository) Find(ctx context.Context, conn transaction.Con | @@ -174,7 +174,12 @@ func (repository *UserRepository) Find(ctx context.Context, conn transaction.Con | ||
174 | tx.Where("position = ? ", v) | 174 | tx.Where("position = ? ", v) |
175 | } | 175 | } |
176 | if v, ok := queryOptions["departmentId"]; ok { | 176 | if v, ok := queryOptions["departmentId"]; ok { |
177 | - tx.Where(fmt.Sprintf("departments @>'[%v]'", v)) | 177 | + // 未分组用户部门ID=0 |
178 | + if vi, okVi := v.(int64); okVi && vi == domain.DefaultDepartmentId { | ||
179 | + tx.Where(fmt.Sprintf("departments = '[]'")) | ||
180 | + } else { | ||
181 | + tx.Where(fmt.Sprintf("departments @>'[%v]'", v)) | ||
182 | + } | ||
178 | } | 183 | } |
179 | if v, ok := queryOptions["roleId"]; ok { | 184 | if v, ok := queryOptions["roleId"]; ok { |
180 | tx.Where(fmt.Sprintf("roles @>'[%v]'", v)) | 185 | tx.Where(fmt.Sprintf("roles @>'[%v]'", v)) |
1 | +package repository | ||
2 | + | ||
3 | +import ( | ||
4 | + "context" | ||
5 | + "github.com/jinzhu/copier" | ||
6 | + "github.com/pkg/errors" | ||
7 | + "github.com/tiptok/gocomm/pkg/cache" | ||
8 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/models" | ||
9 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction" | ||
10 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain" | ||
11 | + "gorm.io/gorm" | ||
12 | +) | ||
13 | + | ||
14 | +type UserSubscribeRepository struct { | ||
15 | + *cache.CachedRepository | ||
16 | +} | ||
17 | + | ||
18 | +func (repository *UserSubscribeRepository) Insert(ctx context.Context, conn transaction.Conn, dm *domain.UserSubscribe) (*domain.UserSubscribe, error) { | ||
19 | + var ( | ||
20 | + err error | ||
21 | + m = &models.UserSubscribe{} | ||
22 | + tx = conn.DB() | ||
23 | + ) | ||
24 | + if m, err = repository.DomainModelToModel(dm); err != nil { | ||
25 | + return nil, err | ||
26 | + } | ||
27 | + if tx = tx.Model(m).Save(m); tx.Error != nil { | ||
28 | + return nil, tx.Error | ||
29 | + } | ||
30 | + dm.Id = m.Id | ||
31 | + return repository.ModelToDomainModel(m) | ||
32 | + | ||
33 | +} | ||
34 | + | ||
35 | +func (repository *UserSubscribeRepository) Update(ctx context.Context, conn transaction.Conn, dm *domain.UserSubscribe) (*domain.UserSubscribe, error) { | ||
36 | + var ( | ||
37 | + err error | ||
38 | + m *models.UserSubscribe | ||
39 | + tx = conn.DB() | ||
40 | + ) | ||
41 | + if m, err = repository.DomainModelToModel(dm); err != nil { | ||
42 | + return nil, err | ||
43 | + } | ||
44 | + queryFunc := func() (interface{}, error) { | ||
45 | + tx = tx.Model(m).Select("*").Updates(m) | ||
46 | + return nil, tx.Error | ||
47 | + } | ||
48 | + if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil { | ||
49 | + return nil, err | ||
50 | + } | ||
51 | + return repository.ModelToDomainModel(m) | ||
52 | +} | ||
53 | + | ||
54 | +func (repository *UserSubscribeRepository) UpdateWithVersion(ctx context.Context, transaction transaction.Conn, dm *domain.UserSubscribe) (*domain.UserSubscribe, error) { | ||
55 | + var ( | ||
56 | + err error | ||
57 | + m *models.UserSubscribe | ||
58 | + tx = transaction.DB() | ||
59 | + ) | ||
60 | + if m, err = repository.DomainModelToModel(dm); err != nil { | ||
61 | + return nil, err | ||
62 | + } | ||
63 | + oldVersion := dm.Version | ||
64 | + m.Version += 1 | ||
65 | + queryFunc := func() (interface{}, error) { | ||
66 | + tx = tx.Model(m).Select("*").Where("id = ?", m.Id).Where("version = ?", oldVersion).Updates(m) | ||
67 | + if tx.RowsAffected == 0 { | ||
68 | + return nil, domain.ErrUpdateFail | ||
69 | + } | ||
70 | + return nil, tx.Error | ||
71 | + } | ||
72 | + if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil { | ||
73 | + return nil, err | ||
74 | + } | ||
75 | + return repository.ModelToDomainModel(m) | ||
76 | +} | ||
77 | + | ||
78 | +func (repository *UserSubscribeRepository) Delete(ctx context.Context, conn transaction.Conn, dm *domain.UserSubscribe) (*domain.UserSubscribe, error) { | ||
79 | + var ( | ||
80 | + tx = conn.DB() | ||
81 | + m = &models.UserSubscribe{Id: dm.Identify().(int64)} | ||
82 | + ) | ||
83 | + queryFunc := func() (interface{}, error) { | ||
84 | + tx = tx.Where("id = ?", m.Id).Delete(m) | ||
85 | + return m, tx.Error | ||
86 | + } | ||
87 | + if _, err := repository.Query(queryFunc, m.CacheKeyFunc()); err != nil { | ||
88 | + return dm, err | ||
89 | + } | ||
90 | + return repository.ModelToDomainModel(m) | ||
91 | +} | ||
92 | + | ||
93 | +func (repository *UserSubscribeRepository) FindOne(ctx context.Context, conn transaction.Conn, id int64) (*domain.UserSubscribe, error) { | ||
94 | + var ( | ||
95 | + err error | ||
96 | + tx = conn.DB() | ||
97 | + m = new(models.UserSubscribe) | ||
98 | + ) | ||
99 | + queryFunc := func() (interface{}, error) { | ||
100 | + tx = tx.Model(m).Where("id = ?", id).First(m) | ||
101 | + if errors.Is(tx.Error, gorm.ErrRecordNotFound) { | ||
102 | + return nil, domain.ErrNotFound | ||
103 | + } | ||
104 | + return m, tx.Error | ||
105 | + } | ||
106 | + cacheModel := new(models.UserSubscribe) | ||
107 | + cacheModel.Id = id | ||
108 | + if err = repository.QueryCache(cacheModel.CacheKeyFunc, m, queryFunc); err != nil { | ||
109 | + return nil, err | ||
110 | + } | ||
111 | + return repository.ModelToDomainModel(m) | ||
112 | +} | ||
113 | + | ||
114 | +func (repository *UserSubscribeRepository) FindOneByType(ctx context.Context, conn transaction.Conn, companyId, userId int64, mType int) (*domain.UserSubscribe, error) { | ||
115 | + var ( | ||
116 | + err error | ||
117 | + tx = conn.DB() | ||
118 | + m = new(models.UserSubscribe) | ||
119 | + ) | ||
120 | + queryFunc := func() (interface{}, error) { | ||
121 | + tx = tx.Model(m).Where("company_id = ? and user_id = ? and type = ?", companyId, userId, mType).First(m) | ||
122 | + if errors.Is(tx.Error, gorm.ErrRecordNotFound) { | ||
123 | + return nil, domain.ErrNotFound | ||
124 | + } | ||
125 | + return m, tx.Error | ||
126 | + } | ||
127 | + cacheModel := new(models.UserSubscribe) | ||
128 | + cacheModel.Id = m.Id | ||
129 | + if err = repository.QueryCache(cacheModel.CacheKeyFunc, m, queryFunc); err != nil { | ||
130 | + return nil, err | ||
131 | + } | ||
132 | + return repository.ModelToDomainModel(m) | ||
133 | +} | ||
134 | + | ||
135 | +func (repository *UserSubscribeRepository) Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*domain.UserSubscribe, error) { | ||
136 | + var ( | ||
137 | + tx = conn.DB() | ||
138 | + ms []*models.UserSubscribe | ||
139 | + dms = make([]*domain.UserSubscribe, 0) | ||
140 | + total int64 | ||
141 | + ) | ||
142 | + queryFunc := func() (interface{}, error) { | ||
143 | + tx = tx.Model(&ms).Order("id desc") | ||
144 | + if v, ok := queryOptions["companyId"]; ok { | ||
145 | + tx = tx.Where("company_id = ?", v) | ||
146 | + } | ||
147 | + if v, ok := queryOptions["userId"]; ok { | ||
148 | + tx = tx.Where("user_id = ?", v) | ||
149 | + } | ||
150 | + if total, tx = transaction.PaginationAndCount(ctx, tx, queryOptions, &ms); tx.Error != nil { | ||
151 | + return dms, tx.Error | ||
152 | + } | ||
153 | + return dms, nil | ||
154 | + } | ||
155 | + | ||
156 | + if _, err := repository.Query(queryFunc); err != nil { | ||
157 | + return 0, nil, err | ||
158 | + } | ||
159 | + | ||
160 | + for _, item := range ms { | ||
161 | + if dm, err := repository.ModelToDomainModel(item); err != nil { | ||
162 | + return 0, dms, err | ||
163 | + } else { | ||
164 | + dms = append(dms, dm) | ||
165 | + } | ||
166 | + } | ||
167 | + return total, dms, nil | ||
168 | +} | ||
169 | + | ||
170 | +func (repository *UserSubscribeRepository) ModelToDomainModel(from *models.UserSubscribe) (*domain.UserSubscribe, error) { | ||
171 | + to := &domain.UserSubscribe{} | ||
172 | + err := copier.Copy(to, from) | ||
173 | + return to, err | ||
174 | +} | ||
175 | + | ||
176 | +func (repository *UserSubscribeRepository) DomainModelToModel(from *domain.UserSubscribe) (*models.UserSubscribe, error) { | ||
177 | + to := &models.UserSubscribe{} | ||
178 | + err := copier.Copy(to, from) | ||
179 | + return to, err | ||
180 | +} | ||
181 | + | ||
182 | +func NewUserSubscribeRepository(cache *cache.CachedRepository) domain.UserSubscribeRepository { | ||
183 | + return &UserSubscribeRepository{CachedRepository: cache} | ||
184 | +} |
1 | +package repository | ||
2 | + | ||
3 | +import ( | ||
4 | + "context" | ||
5 | + "github.com/jinzhu/copier" | ||
6 | + "github.com/pkg/errors" | ||
7 | + "github.com/tiptok/gocomm/pkg/cache" | ||
8 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/models" | ||
9 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction" | ||
10 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain" | ||
11 | + "gorm.io/gorm" | ||
12 | +) | ||
13 | + | ||
14 | +type UserWechatRepository struct { | ||
15 | + *cache.CachedRepository | ||
16 | +} | ||
17 | + | ||
18 | +func (repository *UserWechatRepository) Insert(ctx context.Context, conn transaction.Conn, dm *domain.UserWechat) (*domain.UserWechat, error) { | ||
19 | + var ( | ||
20 | + err error | ||
21 | + m = &models.UserWechat{} | ||
22 | + tx = conn.DB() | ||
23 | + ) | ||
24 | + if m, err = repository.DomainModelToModel(dm); err != nil { | ||
25 | + return nil, err | ||
26 | + } | ||
27 | + if tx = tx.Model(m).Save(m); tx.Error != nil { | ||
28 | + return nil, tx.Error | ||
29 | + } | ||
30 | + dm.Id = m.Id | ||
31 | + return repository.ModelToDomainModel(m) | ||
32 | + | ||
33 | +} | ||
34 | + | ||
35 | +func (repository *UserWechatRepository) Update(ctx context.Context, conn transaction.Conn, dm *domain.UserWechat) (*domain.UserWechat, error) { | ||
36 | + var ( | ||
37 | + err error | ||
38 | + m *models.UserWechat | ||
39 | + tx = conn.DB() | ||
40 | + ) | ||
41 | + if m, err = repository.DomainModelToModel(dm); err != nil { | ||
42 | + return nil, err | ||
43 | + } | ||
44 | + queryFunc := func() (interface{}, error) { | ||
45 | + tx = tx.Model(m).Updates(m) | ||
46 | + return nil, tx.Error | ||
47 | + } | ||
48 | + if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil { | ||
49 | + return nil, err | ||
50 | + } | ||
51 | + return repository.ModelToDomainModel(m) | ||
52 | +} | ||
53 | + | ||
54 | +func (repository *UserWechatRepository) UpdateWithVersion(ctx context.Context, transaction transaction.Conn, dm *domain.UserWechat) (*domain.UserWechat, error) { | ||
55 | + var ( | ||
56 | + err error | ||
57 | + m *models.UserWechat | ||
58 | + tx = transaction.DB() | ||
59 | + ) | ||
60 | + if m, err = repository.DomainModelToModel(dm); err != nil { | ||
61 | + return nil, err | ||
62 | + } | ||
63 | + oldVersion := dm.Version | ||
64 | + m.Version += 1 | ||
65 | + queryFunc := func() (interface{}, error) { | ||
66 | + tx = tx.Model(m).Select("*").Where("id = ?", m.Id).Where("version = ?", oldVersion).Updates(m) | ||
67 | + if tx.RowsAffected == 0 { | ||
68 | + return nil, domain.ErrUpdateFail | ||
69 | + } | ||
70 | + return nil, tx.Error | ||
71 | + } | ||
72 | + if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil { | ||
73 | + return nil, err | ||
74 | + } | ||
75 | + return repository.ModelToDomainModel(m) | ||
76 | +} | ||
77 | + | ||
78 | +func (repository *UserWechatRepository) Delete(ctx context.Context, conn transaction.Conn, dm *domain.UserWechat) (*domain.UserWechat, error) { | ||
79 | + var ( | ||
80 | + tx = conn.DB() | ||
81 | + m = &models.UserWechat{Id: dm.Identify().(int64)} | ||
82 | + ) | ||
83 | + queryFunc := func() (interface{}, error) { | ||
84 | + tx = tx.Where("id = ?", m.Id).Delete(m) | ||
85 | + return m, tx.Error | ||
86 | + } | ||
87 | + if _, err := repository.Query(queryFunc, m.CacheKeyFunc()); err != nil { | ||
88 | + return dm, err | ||
89 | + } | ||
90 | + return repository.ModelToDomainModel(m) | ||
91 | +} | ||
92 | + | ||
93 | +func (repository *UserWechatRepository) FindOne(ctx context.Context, conn transaction.Conn, id int64) (*domain.UserWechat, error) { | ||
94 | + var ( | ||
95 | + err error | ||
96 | + tx = conn.DB() | ||
97 | + m = new(models.UserWechat) | ||
98 | + ) | ||
99 | + queryFunc := func() (interface{}, error) { | ||
100 | + tx = tx.Model(m).Where("id = ?", id).First(m) | ||
101 | + if errors.Is(tx.Error, gorm.ErrRecordNotFound) { | ||
102 | + return nil, domain.ErrNotFound | ||
103 | + } | ||
104 | + return m, tx.Error | ||
105 | + } | ||
106 | + cacheModel := new(models.UserWechat) | ||
107 | + cacheModel.Id = id | ||
108 | + if err = repository.QueryCache(cacheModel.CacheKeyFunc, m, queryFunc); err != nil { | ||
109 | + return nil, err | ||
110 | + } | ||
111 | + return repository.ModelToDomainModel(m) | ||
112 | +} | ||
113 | + | ||
114 | +func (repository *UserWechatRepository) FindOneByPhone(ctx context.Context, conn transaction.Conn, phone string) (*domain.UserWechat, error) { | ||
115 | + var ( | ||
116 | + err error | ||
117 | + tx = conn.DB() | ||
118 | + m = new(models.UserWechat) | ||
119 | + ) | ||
120 | + queryFunc := func() (interface{}, error) { | ||
121 | + tx = tx.Model(m).Where("phone = ?", phone).First(m) | ||
122 | + if errors.Is(tx.Error, gorm.ErrRecordNotFound) { | ||
123 | + return nil, domain.ErrNotFound | ||
124 | + } | ||
125 | + return m, tx.Error | ||
126 | + } | ||
127 | + cacheModel := new(models.UserWechat) | ||
128 | + cacheModel.Id = m.Id | ||
129 | + if err = repository.QueryCache(cacheModel.CacheKeyFunc, m, queryFunc); err != nil { | ||
130 | + return nil, err | ||
131 | + } | ||
132 | + return repository.ModelToDomainModel(m) | ||
133 | +} | ||
134 | + | ||
135 | +func (repository *UserWechatRepository) Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*domain.UserWechat, error) { | ||
136 | + var ( | ||
137 | + tx = conn.DB() | ||
138 | + ms []*models.UserWechat | ||
139 | + dms = make([]*domain.UserWechat, 0) | ||
140 | + total int64 | ||
141 | + ) | ||
142 | + queryFunc := func() (interface{}, error) { | ||
143 | + tx = tx.Model(&ms).Order("id desc") | ||
144 | + if total, tx = transaction.PaginationAndCount(ctx, tx, queryOptions, &ms); tx.Error != nil { | ||
145 | + return dms, tx.Error | ||
146 | + } | ||
147 | + return dms, nil | ||
148 | + } | ||
149 | + | ||
150 | + if _, err := repository.Query(queryFunc); err != nil { | ||
151 | + return 0, nil, err | ||
152 | + } | ||
153 | + | ||
154 | + for _, item := range ms { | ||
155 | + if dm, err := repository.ModelToDomainModel(item); err != nil { | ||
156 | + return 0, dms, err | ||
157 | + } else { | ||
158 | + dms = append(dms, dm) | ||
159 | + } | ||
160 | + } | ||
161 | + return total, dms, nil | ||
162 | +} | ||
163 | + | ||
164 | +func (repository *UserWechatRepository) ModelToDomainModel(from *models.UserWechat) (*domain.UserWechat, error) { | ||
165 | + to := &domain.UserWechat{} | ||
166 | + err := copier.Copy(to, from) | ||
167 | + return to, err | ||
168 | +} | ||
169 | + | ||
170 | +func (repository *UserWechatRepository) DomainModelToModel(from *domain.UserWechat) (*models.UserWechat, error) { | ||
171 | + to := &models.UserWechat{} | ||
172 | + err := copier.Copy(to, from) | ||
173 | + return to, err | ||
174 | +} | ||
175 | + | ||
176 | +func NewUserWechatRepository(cache *cache.CachedRepository) domain.UserWechatRepository { | ||
177 | + return &UserWechatRepository{CachedRepository: cache} | ||
178 | +} |
@@ -131,6 +131,15 @@ func (m *Article) SetSummary(sectionList []*ArticleSection) { | @@ -131,6 +131,15 @@ func (m *Article) SetSummary(sectionList []*ArticleSection) { | ||
131 | m.Summary = string(runeContent[0:length]) | 131 | m.Summary = string(runeContent[0:length]) |
132 | } | 132 | } |
133 | 133 | ||
134 | +// GetSubscribeMessageTitle 获取订阅消息标题 超过20个字用... | ||
135 | +func (m *Article) GetSubscribeMessageTitle() string { | ||
136 | + runeContent := []rune(m.Title) | ||
137 | + if len(runeContent) > 20 { | ||
138 | + return string(runeContent[0:20]) + "..." | ||
139 | + } | ||
140 | + return m.Title | ||
141 | +} | ||
142 | + | ||
134 | func (m *Article) WhoCanRead(userId int64) bool { | 143 | func (m *Article) WhoCanRead(userId int64) bool { |
135 | if m.AuthorId == userId { | 144 | if m.AuthorId == userId { |
136 | return true | 145 | return true |
@@ -3,11 +3,8 @@ package domain | @@ -3,11 +3,8 @@ package domain | ||
3 | import ( | 3 | import ( |
4 | "bytes" | 4 | "bytes" |
5 | "context" | 5 | "context" |
6 | - "encoding/json" | ||
7 | - "fmt" | ||
8 | - "sort" | ||
9 | - | ||
10 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction" | 6 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction" |
7 | + "reflect" | ||
11 | ) | 8 | ) |
12 | 9 | ||
13 | // 编辑文章后保存的历史记录 | 10 | // 编辑文章后保存的历史记录 |
@@ -51,95 +48,119 @@ func (bk *ArticleBackup) CheckChangeField(oldBackup *ArticleBackup) bool { | @@ -51,95 +48,119 @@ func (bk *ArticleBackup) CheckChangeField(oldBackup *ArticleBackup) bool { | ||
51 | bk.ChangeField = make([]string, 0) | 48 | bk.ChangeField = make([]string, 0) |
52 | //比较 WhoRead | 49 | //比较 WhoRead |
53 | { | 50 | { |
54 | - whoReadChanged := false | ||
55 | - sort.Slice(bk.WhoRead, func(i, j int) bool { | ||
56 | - return bk.WhoRead[i] < bk.WhoRead[j] | ||
57 | - }) | ||
58 | - sort.Slice(oldBackup.WhoRead, func(i, j int) bool { | ||
59 | - return oldBackup.WhoRead[i] < oldBackup.WhoRead[j] | ||
60 | - }) | ||
61 | - | ||
62 | - if len(bk.WhoRead) != len(oldBackup.WhoRead) { | ||
63 | - whoReadChanged = true | ||
64 | - } else { | ||
65 | - for i := range bk.WhoRead { | ||
66 | - if bk.WhoRead[i] != oldBackup.WhoRead[i] { | ||
67 | - whoReadChanged = true | ||
68 | - } | ||
69 | - } | ||
70 | - } | ||
71 | - if whoReadChanged { | 51 | + //whoReadChanged := false |
52 | + //sort.Slice(bk.WhoRead, func(i, j int) bool { | ||
53 | + // return bk.WhoRead[i] < bk.WhoRead[j] | ||
54 | + //}) | ||
55 | + //sort.Slice(oldBackup.WhoRead, func(i, j int) bool { | ||
56 | + // return oldBackup.WhoRead[i] < oldBackup.WhoRead[j] | ||
57 | + //}) | ||
58 | + // | ||
59 | + //if len(bk.WhoRead) != len(oldBackup.WhoRead) { | ||
60 | + // whoReadChanged = true | ||
61 | + //} else { | ||
62 | + // for i := range bk.WhoRead { | ||
63 | + // if bk.WhoRead[i] != oldBackup.WhoRead[i] { | ||
64 | + // whoReadChanged = true | ||
65 | + // } | ||
66 | + // } | ||
67 | + //} | ||
68 | + //if whoReadChanged { | ||
69 | + // bk.ChangeField = append(bk.ChangeField, "WhoRead") | ||
70 | + //} | ||
71 | + if !reflect.DeepEqual(oldBackup.WhoRead, bk.WhoRead) { | ||
72 | bk.ChangeField = append(bk.ChangeField, "WhoRead") | 72 | bk.ChangeField = append(bk.ChangeField, "WhoRead") |
73 | } | 73 | } |
74 | } | 74 | } |
75 | 75 | ||
76 | //比较 whoReview | 76 | //比较 whoReview |
77 | { | 77 | { |
78 | - whoReviewChanged := false | ||
79 | - sort.Slice(bk.WhoReview, func(i, j int) bool { | ||
80 | - return bk.WhoReview[i] < bk.WhoReview[j] | ||
81 | - }) | ||
82 | - sort.Slice(oldBackup.WhoReview, func(i, j int) bool { | ||
83 | - return oldBackup.WhoReview[i] < oldBackup.WhoReview[j] | ||
84 | - }) | ||
85 | - | ||
86 | - if len(bk.WhoReview) != len(oldBackup.WhoReview) { | ||
87 | - whoReviewChanged = true | ||
88 | - } else { | ||
89 | - for i := range bk.WhoReview { | ||
90 | - if bk.WhoReview[i] != oldBackup.WhoReview[i] { | ||
91 | - whoReviewChanged = true | ||
92 | - } | ||
93 | - } | ||
94 | - } | ||
95 | - if whoReviewChanged { | 78 | + //whoReviewChanged := false |
79 | + //sort.Slice(bk.WhoReview, func(i, j int) bool { | ||
80 | + // return bk.WhoReview[i] < bk.WhoReview[j] | ||
81 | + //}) | ||
82 | + //sort.Slice(oldBackup.WhoReview, func(i, j int) bool { | ||
83 | + // return oldBackup.WhoReview[i] < oldBackup.WhoReview[j] | ||
84 | + //}) | ||
85 | + // | ||
86 | + //if len(bk.WhoReview) != len(oldBackup.WhoReview) { | ||
87 | + // whoReviewChanged = true | ||
88 | + //} else { | ||
89 | + // for i := range bk.WhoReview { | ||
90 | + // if bk.WhoReview[i] != oldBackup.WhoReview[i] { | ||
91 | + // whoReviewChanged = true | ||
92 | + // } | ||
93 | + // } | ||
94 | + //} | ||
95 | + //if whoReviewChanged { | ||
96 | + // bk.ChangeField = append(bk.ChangeField, "WhoReview") | ||
97 | + //} | ||
98 | + if !reflect.DeepEqual(oldBackup.WhoReview, bk.WhoReview) { | ||
96 | bk.ChangeField = append(bk.ChangeField, "WhoReview") | 99 | bk.ChangeField = append(bk.ChangeField, "WhoReview") |
97 | } | 100 | } |
98 | } | 101 | } |
99 | //比较段落内容+图片+视频 是否发生变更 | 102 | //比较段落内容+图片+视频 是否发生变更 |
100 | { | 103 | { |
101 | - sectionChanged := false | ||
102 | - newSectionData := map[string]string{ | ||
103 | - "title": bk.Title, | ||
104 | - } | ||
105 | - | ||
106 | - oldSectionData := map[string]string{ | ||
107 | - "title": oldBackup.Title, | ||
108 | - } | ||
109 | - | ||
110 | - for _, val := range bk.Section { | ||
111 | - mkey := fmt.Sprintf("section-%d", val.SortBy) | ||
112 | - newSectionData[mkey] = val.Content | ||
113 | - } | ||
114 | - for _, val := range bk.Images { | ||
115 | - newSectionData[val.Url] = "" | ||
116 | - } | ||
117 | - for _, val := range bk.Videos { | ||
118 | - newSectionData[val.Url] = "" | ||
119 | - } | ||
120 | - | ||
121 | - for _, val := range oldBackup.Section { | ||
122 | - mKey := fmt.Sprintf("section-%d", val.SortBy) | ||
123 | - oldSectionData[mKey] = val.Content | ||
124 | - } | ||
125 | - for _, val := range oldBackup.Images { | ||
126 | - oldSectionData[val.Url] = "" | ||
127 | - } | ||
128 | - for _, val := range oldBackup.Videos { | ||
129 | - oldSectionData[val.Url] = "" | ||
130 | - } | ||
131 | - newSectionJson, _ := json.Marshal(newSectionData) | ||
132 | - oldSectionJson, _ := json.Marshal(oldSectionData) | ||
133 | - if ok := bytes.Equal(newSectionJson, oldSectionJson); !ok { | ||
134 | - sectionChanged = true | ||
135 | - } | ||
136 | - if sectionChanged { | 104 | + //sectionChanged := false |
105 | + //newSectionData := map[string]string{ | ||
106 | + // "title": bk.Title, | ||
107 | + //} | ||
108 | + // | ||
109 | + //oldSectionData := map[string]string{ | ||
110 | + // "title": oldBackup.Title, | ||
111 | + //} | ||
112 | + // | ||
113 | + //for _, val := range bk.Section { | ||
114 | + // mkey := fmt.Sprintf("section-%d", val.SortBy) | ||
115 | + // newSectionData[mkey] = val.Content | ||
116 | + //} | ||
117 | + //for _, val := range bk.Images { | ||
118 | + // newSectionData[val.Url] = "" | ||
119 | + //} | ||
120 | + //for _, val := range bk.Videos { | ||
121 | + // newSectionData[val.Url] = "" | ||
122 | + //} | ||
123 | + // | ||
124 | + //for _, val := range oldBackup.Section { | ||
125 | + // mKey := fmt.Sprintf("section-%d", val.SortBy) | ||
126 | + // oldSectionData[mKey] = val.Content | ||
127 | + //} | ||
128 | + //for _, val := range oldBackup.Images { | ||
129 | + // oldSectionData[val.Url] = "" | ||
130 | + //} | ||
131 | + //for _, val := range oldBackup.Videos { | ||
132 | + // oldSectionData[val.Url] = "" | ||
133 | + //} | ||
134 | + //newSectionJson, _ := json.Marshal(newSectionData) | ||
135 | + //oldSectionJson, _ := json.Marshal(oldSectionData) | ||
136 | + //if ok := bytes.Equal(newSectionJson, oldSectionJson); !ok { | ||
137 | + // sectionChanged = true | ||
138 | + //} | ||
139 | + //if sectionChanged { | ||
140 | + // bk.ChangeField = append(bk.ChangeField, "Section") | ||
141 | + //} | ||
142 | + if !reflect.DeepEqual(backUpContent(bk), backUpContent(oldBackup)) { | ||
137 | bk.ChangeField = append(bk.ChangeField, "Section") | 143 | bk.ChangeField = append(bk.ChangeField, "Section") |
138 | } | 144 | } |
139 | } | 145 | } |
140 | return len(bk.ChangeField) > 0 | 146 | return len(bk.ChangeField) > 0 |
141 | } | 147 | } |
142 | 148 | ||
149 | +func backUpContent(bk *ArticleBackup) string { | ||
150 | + buf := bytes.NewBuffer(nil) | ||
151 | + buf.WriteString(bk.Title) | ||
152 | + for _, val := range bk.Images { | ||
153 | + buf.WriteString(val.Url) | ||
154 | + } | ||
155 | + for _, val := range bk.Videos { | ||
156 | + buf.WriteString(val.Url) | ||
157 | + } | ||
158 | + for _, val := range bk.Section { | ||
159 | + buf.WriteString(val.Content) | ||
160 | + } | ||
161 | + return buf.String() | ||
162 | +} | ||
163 | + | ||
143 | // 创建备份信息 | 164 | // 创建备份信息 |
144 | func (bk *ArticleBackup) MakeBackup(operator UserSimple, article *Article, section []*ArticleSection, action string) { | 165 | func (bk *ArticleBackup) MakeBackup(operator UserSimple, article *Article, section []*ArticleSection, action string) { |
145 | sectionBackup := make([]ArticleSection, len(section)) | 166 | sectionBackup := make([]ArticleSection, len(section)) |
@@ -80,6 +80,10 @@ type ArticleCommentRepository interface { | @@ -80,6 +80,10 @@ type ArticleCommentRepository interface { | ||
80 | // 特定的查询 | 80 | // 特定的查询 |
81 | CustomSearchBy(ctx context.Context, conn transaction.Conn, companyId int64, page int, size int, | 81 | CustomSearchBy(ctx context.Context, conn transaction.Conn, companyId int64, page int, size int, |
82 | topId int64, articleTitle string, contentLike string, fromUserId int64, show int, createdAtRange [2]int64) (int, []*ArticleCommentShow, error) | 82 | topId int64, articleTitle string, contentLike string, fromUserId int64, show int, createdAtRange [2]int64) (int, []*ArticleCommentShow, error) |
83 | + // CommentUserCount 统计帖子评论人数 | ||
84 | + CommentUserCount(ctx context.Context, conn transaction.Conn, companyId int64, articleId int64) (int64, error) | ||
85 | + // ReplyUserCount 统计评论回复人数 | ||
86 | + ReplyUserCount(ctx context.Context, conn transaction.Conn, companyId int64, commentId int64) (int64, error) | ||
83 | } | 87 | } |
84 | 88 | ||
85 | // 运营点数 填写的最大值 | 89 | // 运营点数 填写的最大值 |
@@ -92,3 +96,12 @@ func (m *ArticleComment) MaxCountAdminLove(articleWhoRead int) int { | @@ -92,3 +96,12 @@ func (m *ArticleComment) MaxCountAdminLove(articleWhoRead int) int { | ||
92 | } | 96 | } |
93 | return x | 97 | return x |
94 | } | 98 | } |
99 | + | ||
100 | +// GetSubscribeMessageContent 获取订阅消息评论内容 最多显示20个字,超出用... | ||
101 | +func (m *ArticleComment) GetSubscribeMessageContent() string { | ||
102 | + runeContent := []rune(m.Content) | ||
103 | + if len(runeContent) > 20 { | ||
104 | + return string(runeContent[0:20]) + "..." | ||
105 | + } | ||
106 | + return m.Content | ||
107 | +} |
1 | +package domain | ||
2 | + | ||
3 | +import ( | ||
4 | + "context" | ||
5 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction" | ||
6 | + "gorm.io/plugin/soft_delete" | ||
7 | +) | ||
8 | + | ||
9 | +type MessageSubscribe struct { | ||
10 | + Id int64 `json:"id"` // 唯一标识 | ||
11 | + Type int `json:"type"` // 分类(1评论回复 2获赞 3关注人更新) | ||
12 | + CompanyId int64 `json:"companyId"` // 公司ID | ||
13 | + UserId int64 `json:"userId"` // 用户ID | ||
14 | + OpenId string `json:"openId"` // 微信openID | ||
15 | + TemplateId string `json:"templateId"` // 模板ID | ||
16 | + TemplateData map[string]interface{} `json:"templateData"` // 模板参数 | ||
17 | + Result string `json:"result"` // 发送结果 | ||
18 | + Error string `json:"error"` // 调用接口错误信息 | ||
19 | + CreatedAt int64 `json:",omitempty"` // 创建时间 | ||
20 | + UpdatedAt int64 `json:",omitempty"` // 更新时间 | ||
21 | + DeletedAt int64 `json:",omitempty"` // 删除时间 | ||
22 | + Version int `json:",omitempty"` // 版本 | ||
23 | + IsDel soft_delete.DeletedAt `gorm:"softDelete:flag,DeletedAtField:DeletedAt"` // 删除标记 | ||
24 | +} | ||
25 | + | ||
26 | +var ( | ||
27 | + SubscribeTypeReplyComment = 1 // 评论回复 | ||
28 | + SubscribeTypeLike = 2 // 点赞 | ||
29 | + SubscribeTypeFollow = 3 // 关注人更新 | ||
30 | + | ||
31 | + SubscribeTemplateComment = "DxnQTZVHKrH7TOJiV-tK9w72hbkfLM87eXzhVy4cyhE" // 订阅消息 评论提醒 | ||
32 | + SubscribeTemplateLike = "oRdUINwfMK5_4ok_3lNgpkKT_SJqyGOvP4ZDgdsea9E" // 订阅消息 动态点赞通知 | ||
33 | + SubscribeTemplateFollow = "XdS11h2ZGGByzu-wMd16KxJ-LPjZy0yxZDmgQaVfDHE" // 订阅消息 关注更新提醒 | ||
34 | +) | ||
35 | + | ||
36 | +type MessageSubscribeRepository interface { | ||
37 | + Insert(ctx context.Context, conn transaction.Conn, dm *MessageSubscribe) (*MessageSubscribe, error) | ||
38 | + Update(ctx context.Context, conn transaction.Conn, dm *MessageSubscribe) (*MessageSubscribe, error) | ||
39 | + UpdateWithVersion(ctx context.Context, conn transaction.Conn, dm *MessageSubscribe) (*MessageSubscribe, error) | ||
40 | + Delete(ctx context.Context, conn transaction.Conn, dm *MessageSubscribe) (*MessageSubscribe, error) | ||
41 | + FindOne(ctx context.Context, conn transaction.Conn, id int64) (*MessageSubscribe, error) | ||
42 | + Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*MessageSubscribe, error) | ||
43 | +} | ||
44 | + | ||
45 | +func (m *MessageSubscribe) Identify() interface{} { | ||
46 | + if m.Id == 0 { | ||
47 | + return nil | ||
48 | + } | ||
49 | + return m.Id | ||
50 | +} |
@@ -151,6 +151,7 @@ type ( | @@ -151,6 +151,7 @@ type ( | ||
151 | PhonePasswordLogin(phone string, password string) (*LoginInfo, error) | 151 | PhonePasswordLogin(phone string, password string) (*LoginInfo, error) |
152 | PhoneSmsCodeLogin(phone string, code string) (*LoginInfo, error) | 152 | PhoneSmsCodeLogin(phone string, code string) (*LoginInfo, error) |
153 | WechatPhoneLogin(r WechatLoginRequest) (*LoginInfo, error) | 153 | WechatPhoneLogin(r WechatLoginRequest) (*LoginInfo, error) |
154 | + GetOpenId(r WechatLoginRequest) (string, error) | ||
154 | } | 155 | } |
155 | WechatLoginRequest struct { | 156 | WechatLoginRequest struct { |
156 | Code string // 授权码 | 157 | Code string // 授权码 |
1 | +package domain | ||
2 | + | ||
3 | +import ( | ||
4 | + "context" | ||
5 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction" | ||
6 | + "gorm.io/plugin/soft_delete" | ||
7 | +) | ||
8 | + | ||
9 | +type UserSubscribe struct { | ||
10 | + Id int64 `json:"id"` // 唯一标识 | ||
11 | + Type int `json:"type"` // 分类(1评论回复 2获赞 3关注人更新) | ||
12 | + CompanyId int64 `json:"companyId"` // 公司ID | ||
13 | + UserId int64 `json:"userId"` // 用户ID | ||
14 | + Count int `json:"count"` // 订阅次数 | ||
15 | + CreatedAt int64 `json:",omitempty"` // 创建时间 | ||
16 | + UpdatedAt int64 `json:",omitempty"` // 更新时间 | ||
17 | + DeletedAt int64 `json:",omitempty"` // 删除时间 | ||
18 | + Version int `json:",omitempty"` // 版本 | ||
19 | + IsDel soft_delete.DeletedAt `gorm:"softDelete:flag,DeletedAtField:DeletedAt"` // 删除标记 | ||
20 | +} | ||
21 | + | ||
22 | +type UserSubscribeRepository interface { | ||
23 | + Insert(ctx context.Context, conn transaction.Conn, dm *UserSubscribe) (*UserSubscribe, error) | ||
24 | + Update(ctx context.Context, conn transaction.Conn, dm *UserSubscribe) (*UserSubscribe, error) | ||
25 | + UpdateWithVersion(ctx context.Context, conn transaction.Conn, dm *UserSubscribe) (*UserSubscribe, error) | ||
26 | + Delete(ctx context.Context, conn transaction.Conn, dm *UserSubscribe) (*UserSubscribe, error) | ||
27 | + FindOne(ctx context.Context, conn transaction.Conn, id int64) (*UserSubscribe, error) | ||
28 | + FindOneByType(ctx context.Context, conn transaction.Conn, companyId, userId int64, mType int) (*UserSubscribe, error) | ||
29 | + Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*UserSubscribe, error) | ||
30 | +} | ||
31 | + | ||
32 | +func (m *UserSubscribe) Identify() interface{} { | ||
33 | + if m.Id == 0 { | ||
34 | + return nil | ||
35 | + } | ||
36 | + return m.Id | ||
37 | +} |
1 | +package domain | ||
2 | + | ||
3 | +import ( | ||
4 | + "context" | ||
5 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction" | ||
6 | + "gorm.io/plugin/soft_delete" | ||
7 | +) | ||
8 | + | ||
9 | +type UserWechat struct { | ||
10 | + Id int64 `json:"id"` // 唯一标识 | ||
11 | + OpenId string `json:"openId"` // 微信openId | ||
12 | + Phone string `json:"phone"` // 微信手机号 | ||
13 | + CreatedAt int64 `json:",omitempty"` // 创建时间 | ||
14 | + UpdatedAt int64 `json:",omitempty"` // 更新时间 | ||
15 | + DeletedAt int64 `json:",omitempty"` // 删除时间 | ||
16 | + Version int `json:",omitempty"` // 版本 | ||
17 | + IsDel soft_delete.DeletedAt `gorm:"softDelete:flag,DeletedAtField:DeletedAt"` // 删除标记 | ||
18 | +} | ||
19 | + | ||
20 | +type UserWechatRepository interface { | ||
21 | + Insert(ctx context.Context, conn transaction.Conn, dm *UserWechat) (*UserWechat, error) | ||
22 | + Update(ctx context.Context, conn transaction.Conn, dm *UserWechat) (*UserWechat, error) | ||
23 | + UpdateWithVersion(ctx context.Context, conn transaction.Conn, dm *UserWechat) (*UserWechat, error) | ||
24 | + Delete(ctx context.Context, conn transaction.Conn, dm *UserWechat) (*UserWechat, error) | ||
25 | + FindOne(ctx context.Context, conn transaction.Conn, id int64) (*UserWechat, error) | ||
26 | + FindOneByPhone(ctx context.Context, conn transaction.Conn, phone string) (*UserWechat, error) | ||
27 | + Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*UserWechat, error) | ||
28 | +} | ||
29 | + | ||
30 | +func (m *UserWechat) Identify() interface{} { | ||
31 | + if m.Id == 0 { | ||
32 | + return nil | ||
33 | + } | ||
34 | + return m.Id | ||
35 | +} |
1 | -CREATE TABLE `department` ( | ||
2 | - `id` int(0) NOT NULL COMMENT '唯一标识', | ||
3 | - PRIMARY KEY (`id`) USING BTREE | 1 | +CREATE TABLE `department` |
2 | +( | ||
3 | + `id` int(0) NOT NULL COMMENT '唯一标识', | ||
4 | + PRIMARY KEY (`id`) USING BTREE | ||
4 | ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; | 5 | ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; |
5 | 6 | ||
6 | -CREATE TABLE `role` ( | ||
7 | - `id` int(0) NOT NULL COMMENT '唯一标识', | ||
8 | - PRIMARY KEY (`id`) USING BTREE | 7 | +CREATE TABLE `role` |
8 | +( | ||
9 | + `id` int(0) NOT NULL COMMENT '唯一标识', | ||
10 | + PRIMARY KEY (`id`) USING BTREE | ||
9 | ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; | 11 | ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; |
10 | 12 | ||
11 | -CREATE TABLE `user` ( | ||
12 | - `id` int(0) NOT NULL COMMENT '唯一标识', | ||
13 | - PRIMARY KEY (`id`) USING BTREE | 13 | +CREATE TABLE `user` |
14 | +( | ||
15 | + `id` int(0) NOT NULL COMMENT '唯一标识', | ||
16 | + PRIMARY KEY (`id`) USING BTREE | ||
14 | ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; | 17 | ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; |
15 | 18 | ||
16 | -CREATE TABLE `user_role` ( | ||
17 | - `id` int(0) NOT NULL COMMENT '唯一标识', | ||
18 | - PRIMARY KEY (`id`) USING BTREE | 19 | +CREATE TABLE `user_role` |
20 | +( | ||
21 | + `id` int(0) NOT NULL COMMENT '唯一标识', | ||
22 | + PRIMARY KEY (`id`) USING BTREE | ||
19 | ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; | 23 | ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; |
20 | 24 | ||
21 | -CREATE TABLE `company` ( | ||
22 | - `id` int(0) NOT NULL COMMENT '唯一标识', | ||
23 | - PRIMARY KEY (`id`) USING BTREE | 25 | +CREATE TABLE `company` |
26 | +( | ||
27 | + `id` int(0) NOT NULL COMMENT '唯一标识', | ||
28 | + PRIMARY KEY (`id`) USING BTREE | ||
24 | ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; | 29 | ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; |
25 | 30 | ||
26 | -CREATE TABLE `user_follow` ( | ||
27 | - `id` int(0) NOT NULL COMMENT '唯一标识', | ||
28 | - PRIMARY KEY (`id`) USING BTREE | 31 | +CREATE TABLE `user_follow` |
32 | +( | ||
33 | + `id` int(0) NOT NULL COMMENT '唯一标识', | ||
34 | + PRIMARY KEY (`id`) USING BTREE | ||
29 | ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; | 35 | ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; |
30 | 36 | ||
31 | -CREATE TABLE `article_draft_operation` ( | ||
32 | - `id` int(0) NOT NULL COMMENT '唯一标识', | ||
33 | - PRIMARY KEY (`id`) USING BTREE | 37 | +CREATE TABLE `article_draft_operation` |
38 | +( | ||
39 | + `id` int(0) NOT NULL COMMENT '唯一标识', | ||
40 | + PRIMARY KEY (`id`) USING BTREE | ||
34 | ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; | 41 | ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; |
35 | 42 | ||
36 | -CREATE TABLE `article_category` ( | ||
37 | - `id` int(0) NOT NULL COMMENT '唯一标识', | ||
38 | - PRIMARY KEY (`id`) USING BTREE | 43 | +CREATE TABLE `article_category` |
44 | +( | ||
45 | + `id` int(0) NOT NULL COMMENT '唯一标识', | ||
46 | + PRIMARY KEY (`id`) USING BTREE | ||
47 | +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; | ||
48 | + | ||
49 | +CREATE TABLE `message_subscribe` | ||
50 | +( | ||
51 | + `id` int(0) NOT NULL COMMENT '唯一标识', | ||
52 | + PRIMARY KEY (`id`) USING BTREE | ||
53 | +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; | ||
54 | + | ||
55 | +CREATE TABLE `user_subscribe` | ||
56 | +( | ||
57 | + `id` int(0) NOT NULL COMMENT '唯一标识', | ||
58 | + PRIMARY KEY (`id`) USING BTREE | ||
59 | +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; | ||
60 | + | ||
61 | +CREATE TABLE `user_wechat` | ||
62 | +( | ||
63 | + `id` int(0) NOT NULL COMMENT '唯一标识', | ||
64 | + PRIMARY KEY (`id`) USING BTREE | ||
39 | ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; | 65 | ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; |
-
请 注册 或 登录 后发表评论