作者 zhuangmx

Merge branch 'dev' into test

正在显示 39 个修改的文件 包含 2086 行增加57 行删除
@@ -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(
@@ -524,4 +531,30 @@ type( @@ -524,4 +531,30 @@ type(
524 List []SystemUser `json:"list"` 531 List []SystemUser `json:"list"`
525 Total int64 `json:"total"` 532 Total int64 `json:"total"`
526 } 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 + }
527 ) 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 +}
@@ -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
  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 +// saveMessage 保存订阅消息
  58 +func (l *MiniSubscribeLogic) saveMessage(conn transaction.Conn, companyId, userId int64, mType int, msg *subscribe.Message, sendErr error) 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 + if sendErr != nil {
  70 + subscribeMessage.Result = "fail"
  71 + subscribeMessage.Error = sendErr.Error()
  72 + } else {
  73 + subscribeMessage.Result = "ok"
  74 + }
  75 + _, err := l.svcCtx.MessageSubscribeRepository.Insert(l.ctx, conn, subscribeMessage)
  76 + return err
  77 +}
  78 +
  79 +func (l *MiniSubscribeLogic) messageSubscribe(companyId, userId int64, mType int) *domain.MessageSubscribe {
  80 + return &domain.MessageSubscribe{
  81 + Type: mType,
  82 + CompanyId: companyId,
  83 + UserId: userId,
  84 + }
  85 +}
  86 +
  87 +// getReplyCommentUserInfo 获取评论消息用户信息 用户名称+职位 例:张三-董事办
  88 +func (l *MiniSubscribeLogic) getReplyCommentUserInfo(conn transaction.Conn, companyId, userId int64) (string, error) {
  89 + userInfo, err := l.svcCtx.UserRepository.FindOne(l.ctx, conn, userId)
  90 + if err != nil {
  91 + return "", xerr.NewErrMsgErr("获取评论用户信息失败", err)
  92 + }
  93 + users := []string{userInfo.Name}
  94 + if len(userInfo.Roles) > 0 {
  95 + _, roles, err := l.svcCtx.RoleRepository.Find(l.ctx, conn, domain.IndexCompanyId(companyId)().MustWithKV("ids", userInfo.Roles))
  96 + if err == nil && len(roles) > 0 {
  97 + roleNames := make([]string, 0)
  98 + for _, item := range roles {
  99 + roleNames = append(roleNames, item.Name)
  100 + }
  101 + users = append(users, strings.Join(roleNames, "、"))
  102 + }
  103 + }
  104 + return strings.Join(users, "-"), nil
  105 +}
  106 +
  107 +// ReplyComment 发送评论订阅消息
  108 +// @param conn 数据库连接
  109 +// @param article 文章
  110 +// @param comment 评论
  111 +func (l *MiniSubscribeLogic) ReplyComment(conn transaction.Conn, article *domain.Article, comment *domain.ArticleComment) error {
  112 + subCtx := l.getSubScribe()
  113 + //评论用户+职位 例: 张三-董事办
  114 + fromUserName, err := l.getReplyCommentUserInfo(conn, comment.CompanyId, comment.FromUserId)
  115 + if err != nil {
  116 + return xerr.NewErrMsgErr("发送消息失败", err)
  117 + }
  118 + //评论消息
  119 + msg := &subscribe.Message{
  120 + TemplateID: domain.SubscribeTemplateComment,
  121 + Data: map[string]*subscribe.DataItem{
  122 + //文章标题
  123 + "thing1": &subscribe.DataItem{Value: article.GetSubscribeMessageTitle()},
  124 + //评论内容
  125 + "thing2": &subscribe.DataItem{Value: comment.GetSubscribeMessageContent()},
  126 + //评论时间
  127 + "thing3": &subscribe.DataItem{Value: time.Now().Format("2006-01-02 15:04:05")},
  128 + //评论用户
  129 + "thing5": &subscribe.DataItem{Value: fromUserName},
  130 + //备注
  131 + "thing9": &subscribe.DataItem{Value: ""},
  132 + },
  133 + MiniprogramState: l.svcCtx.Config.Wechat.QrcodeEnv,
  134 + }
  135 + //发帖人接收消息
  136 + openId, err := l.getOpenId(conn, article.AuthorId)
  137 + //未绑定微信号,直接返回
  138 + if err == nil && openId != "" {
  139 + msg.ToUser = openId
  140 + msg.Page = fmt.Sprintf("/pages/detail/more-comment?id=%v", article.Id) //跳转页面 帖子评论聚合页
  141 + //备注
  142 + msg.Data["thing9"] = &subscribe.DataItem{Value: fmt.Sprintf("您的帖子最近已有%v人评论,点击查看详情", article.CountComment)}
  143 + //发送微信订阅消息
  144 + err = subCtx.Send(msg)
  145 + err = l.saveMessage(conn, comment.CompanyId, article.AuthorId, domain.SubscribeTypeReplyComment, msg, err)
  146 + if err != nil {
  147 + return xerr.NewErrMsgErr("评论失败", err)
  148 + }
  149 + }
  150 + //评论回复
  151 + if comment.Pid > 0 {
  152 + toOpenId, err := l.getOpenId(conn, comment.ToUserId)
  153 + if err == nil && toOpenId != "" {
  154 + msg.ToUser = toOpenId
  155 + msg.Page = fmt.Sprintf("/pages/detail/reply-comment?id=%v&commentId=%v", article.Id, comment.Pid) //跳转页面评论聚合页
  156 + //备注
  157 + parent, err := l.svcCtx.ArticleCommentRepository.FindOne(l.ctx, conn, comment.Pid)
  158 + if err == nil && parent.Id > 0 {
  159 + msg.Data["thing9"] = &subscribe.DataItem{Value: fmt.Sprintf("您的评论最近已有%v人回复,点击查看详情", parent.CountReply)}
  160 + //发送微信订阅消息
  161 + err = subCtx.Send(msg)
  162 + err = l.saveMessage(conn, comment.CompanyId, comment.ToUserId, domain.SubscribeTypeReplyComment, msg, err)
  163 + if err != nil {
  164 + return xerr.NewErrMsgErr("评论失败", err)
  165 + }
  166 + }
  167 + }
  168 + }
  169 + //@消息
  170 + if len(comment.AtWho) > 0 {
  171 + for _, at := range comment.AtWho {
  172 + atOpenId, err := l.getOpenId(conn, at.Id)
  173 + //未绑定微信跳过
  174 + if err != nil || atOpenId == "" {
  175 + continue
  176 + }
  177 + msg.ToUser = atOpenId
  178 + msg.Page = fmt.Sprintf("/pages/detail/reply-comment?id=%v&commentId=%v", article.Id, comment.Pid) //跳转页面 评论详情页
  179 + //备注
  180 + msg.Data["thing9"] = &subscribe.DataItem{Value: fmt.Sprintf("%v在评论中提到了你", comment.FromUser.Name)}
  181 + //发送微信订阅消息
  182 + err = subCtx.Send(msg)
  183 + err = l.saveMessage(conn, comment.CompanyId, at.Id, domain.SubscribeTypeReplyComment, msg, err)
  184 + if err != nil {
  185 + return xerr.NewErrMsgErr("评论失败", err)
  186 + }
  187 + }
  188 + }
  189 + return nil
  190 +}
  191 +
  192 +// LikeArticle 帖子点赞订阅消息
  193 +func (l *MiniSubscribeLogic) LikeArticle(conn transaction.Conn, article *domain.Article, userInfo *domain.User) error {
  194 + subCtx := l.getSubScribe()
  195 + openId, err := l.getOpenId(conn, article.AuthorId)
  196 + if err != nil || openId == "" {
  197 + return nil
  198 + }
  199 + msg := &subscribe.Message{
  200 + ToUser: openId,
  201 + TemplateID: domain.SubscribeTemplateLike,
  202 + Page: fmt.Sprintf("/pages/detail/detail?id=%v", article.Id),
  203 + Data: map[string]*subscribe.DataItem{
  204 + //点赞用户
  205 + "name1": &subscribe.DataItem{Value: userInfo.Name},
  206 + //点赞时间
  207 + "data2": &subscribe.DataItem{Value: time.Now().Format("2006-01-02 15:04:05")},
  208 + //动态内容
  209 + "thing8": &subscribe.DataItem{Value: article.GetSubscribeMessageTitle()},
  210 + //被赞次数
  211 + "number4": &subscribe.DataItem{Value: article.CountLove},
  212 + //温馨提示
  213 + "thing5": &subscribe.DataItem{Value: "这条内容很受欢迎哦,快来看看吧"},
  214 + },
  215 + MiniprogramState: l.svcCtx.Config.Wechat.QrcodeEnv,
  216 + }
  217 + err = subCtx.Send(msg)
  218 + err = l.saveMessage(conn, article.CompanyId, article.AuthorId, domain.SubscribeTypeLike, msg, err)
  219 + if err != nil {
  220 + return xerr.NewErrMsgErr("点赞失败", err)
  221 + }
  222 + return nil
  223 +}
  224 +
  225 +// LikeComment 点赞评论订阅消息
  226 +func (l *MiniSubscribeLogic) LikeComment(conn transaction.Conn, comment *domain.ArticleComment, userInfo *domain.User) error {
  227 + subCtx := l.getSubScribe()
  228 + openId, err := l.getOpenId(conn, comment.FromUserId)
  229 + if err != nil || openId == "" {
  230 + return nil
  231 + }
  232 + msg := &subscribe.Message{
  233 + ToUser: openId,
  234 + TemplateID: domain.SubscribeTemplateLike,
  235 + Page: fmt.Sprintf("/pages/detail/reply-comment?id=%v&commentId=%v", comment.ArticleId, comment.Id),
  236 + Data: map[string]*subscribe.DataItem{
  237 + //点赞用户
  238 + "name1": &subscribe.DataItem{Value: userInfo.Name},
  239 + //点赞时间
  240 + "data2": &subscribe.DataItem{Value: time.Now().Format("2006-01-02 15:04:05")},
  241 + //动态内容
  242 + "thing8": &subscribe.DataItem{Value: comment.GetSubscribeMessageContent()},
  243 + //被赞次数
  244 + "number4": &subscribe.DataItem{Value: comment.CountUserLove},
  245 + //温馨提示
  246 + "thing5": &subscribe.DataItem{Value: "这条内容很受欢迎哦,快来看看吧"},
  247 + },
  248 + MiniprogramState: l.svcCtx.Config.Wechat.QrcodeEnv,
  249 + }
  250 + err = subCtx.Send(msg)
  251 + err = l.saveMessage(conn, comment.CompanyId, comment.FromUserId, domain.SubscribeTypeLike, msg, err)
  252 + if err != nil {
  253 + return xerr.NewErrMsgErr("点赞失败", err)
  254 + }
  255 + return nil
  256 +}
  257 +
  258 +// FollowArticle 发帖关注更新提醒
  259 +func (l *MiniSubscribeLogic) FollowArticle(conn transaction.Conn, article *domain.Article) error {
  260 + subCtx := l.getSubScribe()
  261 + //获取关注帖子作者的人员
  262 + _, userInfo, err := l.svcCtx.UserFollowRepository.Find(l.ctx, conn, domain.NewQueryOptions().WithKV("toUserIds", []int64{article.AuthorId}))
  263 + if err == nil && len(userInfo) > 0 {
  264 + for _, item := range userInfo {
  265 + openId, err := l.getOpenId(conn, item.FromUserId)
  266 + if err != nil || openId == "" {
  267 + continue
  268 + }
  269 + msg := &subscribe.Message{
  270 + ToUser: openId,
  271 + TemplateID: domain.SubscribeTemplateFollow,
  272 + Page: fmt.Sprintf("/pages/detail/detail?id=%v", article.Id),
  273 + Data: map[string]*subscribe.DataItem{
  274 + //创作者
  275 + "thing1": &subscribe.DataItem{Value: article.Author.Name},
  276 + //作品名称
  277 + "thing2": &subscribe.DataItem{Value: article.Title},
  278 + //内容摘要
  279 + "thing5": &subscribe.DataItem{Value: ""},
  280 + //发布时间
  281 + "thing6": &subscribe.DataItem{Value: time.Now().Format("2006-01-02 15:04:05")},
  282 + //温馨提示
  283 + "thing3": &subscribe.DataItem{Value: "你关注的人发布了新的帖子"},
  284 + },
  285 + MiniprogramState: l.svcCtx.Config.Wechat.QrcodeEnv,
  286 + }
  287 + err = subCtx.Send(msg)
  288 + err = l.saveMessage(conn, article.CompanyId, item.FromUserId, domain.SubscribeTypeFollow, msg, err)
  289 + if err != nil {
  290 + return xerr.NewErrMsgErr("保存订阅消息失败", err)
  291 + }
  292 + }
  293 + }
  294 + return nil
  295 +}
@@ -2,10 +2,10 @@ package user @@ -2,10 +2,10 @@ package user
2 2
3 import ( 3 import (
4 "context" 4 "context"
5 - "fmt"  
6 "github.com/silenceper/wechat/v2" 5 "github.com/silenceper/wechat/v2"
7 "github.com/silenceper/wechat/v2/cache" 6 "github.com/silenceper/wechat/v2/cache"
8 miniConfig "github.com/silenceper/wechat/v2/miniprogram/config" 7 miniConfig "github.com/silenceper/wechat/v2/miniprogram/config"
  8 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction"
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/domain"
10 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/gateway/smslib" 10 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/gateway/smslib"
11 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/tool" 11 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/tool"
@@ -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:
@@ -53,6 +53,11 @@ func (l *MiniUserLoginLogic) MiniUserLogin(req *types.MiniUserLoginRequest) (res @@ -53,6 +53,11 @@ func (l *MiniUserLoginLogic) MiniUserLogin(req *types.MiniUserLoginRequest) (res
53 53
54 var users []*domain.User 54 var users []*domain.User
55 conn := l.svcCtx.DefaultDBConn() 55 conn := l.svcCtx.DefaultDBConn()
  56 + //保存微信用户信息
  57 + err = saveUserWechat(l.svcCtx, l.ctx, conn, loginInfo)
  58 + if err != nil {
  59 + return nil, err
  60 + }
56 _, users, err = l.svcCtx.UserRepository.Find(l.ctx, conn, domain.NewQueryOptions(). 61 _, users, err = l.svcCtx.UserRepository.Find(l.ctx, conn, domain.NewQueryOptions().
57 MustWithKV("phone", loginInfo.Phone). 62 MustWithKV("phone", loginInfo.Phone).
58 MustWithKV("auditStatus", []int{domain.UserAuditStatusWait, domain.UserAuditStatusPassed}). 63 MustWithKV("auditStatus", []int{domain.UserAuditStatusWait, domain.UserAuditStatusPassed}).
@@ -87,6 +92,23 @@ func (l *MiniUserLoginLogic) MiniUserLogin(req *types.MiniUserLoginRequest) (res @@ -87,6 +92,23 @@ func (l *MiniUserLoginLogic) MiniUserLogin(req *types.MiniUserLoginRequest) (res
87 return 92 return
88 } 93 }
89 94
  95 +// saveUserWechat 保存微信授权信息
  96 +func saveUserWechat(svcCtx *svc.ServiceContext, ctx context.Context, conn transaction.Conn, loginInfo *domain.LoginInfo) error {
  97 + if loginInfo.Phone != "" && loginInfo.OpenId != "" {
  98 + _, err := svcCtx.UserWechatRepository.FindOneByPhone(ctx, conn, loginInfo.Phone)
  99 + if err != nil { // 未存储
  100 + _, err = svcCtx.UserWechatRepository.Insert(ctx, conn, &domain.UserWechat{
  101 + OpenId: loginInfo.OpenId,
  102 + Phone: loginInfo.Phone,
  103 + })
  104 + if err != nil {
  105 + return err
  106 + }
  107 + }
  108 + }
  109 + return nil
  110 +}
  111 +
90 func generateToken(svcCtx *svc.ServiceContext, user *domain.User) (token string, err error) { 112 func generateToken(svcCtx *svc.ServiceContext, user *domain.User) (token string, err error) {
91 var userJwtToken = tool.UserToken{} 113 var userJwtToken = tool.UserToken{}
92 if user != nil { 114 if user != nil {
@@ -102,7 +124,8 @@ func generateToken(svcCtx *svc.ServiceContext, user *domain.User) (token string, @@ -102,7 +124,8 @@ func generateToken(svcCtx *svc.ServiceContext, user *domain.User) (token string,
102 } 124 }
103 125
104 type WxClientLogin struct { 126 type WxClientLogin struct {
105 - l *MiniUserLoginLogic 127 + svcCtx *svc.ServiceContext
  128 + ctx context.Context
106 } 129 }
107 130
108 func (c WxClientLogin) WechatPhoneLogin(r domain.WechatLoginRequest) (*domain.LoginInfo, error) { 131 func (c WxClientLogin) WechatPhoneLogin(r domain.WechatLoginRequest) (*domain.LoginInfo, error) {
@@ -111,18 +134,29 @@ func (c WxClientLogin) WechatPhoneLogin(r domain.WechatLoginRequest) (*domain.Lo @@ -111,18 +134,29 @@ func (c WxClientLogin) WechatPhoneLogin(r domain.WechatLoginRequest) (*domain.Lo
111 Phone: "", 134 Phone: "",
112 } 135 }
113 miniprogram := wechat.NewWechat().GetMiniProgram(&miniConfig.Config{ 136 miniprogram := wechat.NewWechat().GetMiniProgram(&miniConfig.Config{
114 - AppID: c.l.svcCtx.Config.Wechat.AppID,  
115 - AppSecret: c.l.svcCtx.Config.Wechat.AppSecret, 137 + AppID: c.svcCtx.Config.Wechat.AppID,
  138 + AppSecret: c.svcCtx.Config.Wechat.AppSecret,
116 Cache: cache.NewMemory(), 139 Cache: cache.NewMemory(),
117 }) 140 })
118 - authResult, err := miniprogram.GetAuth().GetPhoneNumber(code) 141 + result, err := miniprogram.GetAuth().Code2Session(code)
  142 + if err != nil {
  143 + return nil, xerr.NewErrMsgErr("发起授权请求失败", err)
  144 + }
  145 + plainData, err := miniprogram.GetEncryptor().Decrypt(result.SessionKey, r.EncryptedData, r.IV)
  146 + if err != nil {
  147 + return nil, xerr.NewErrMsgErr("获取授权用户失败", err)
  148 + }
  149 + //增加微信用户openId
  150 + response.OpenId = plainData.OpenID
  151 + response.Phone = plainData.PhoneNumber
  152 + /*authResult, err := miniprogram.GetAuth().GetPhoneNumber(code)
119 if err != nil || authResult.ErrCode != 0 || authResult.PhoneInfo.PhoneNumber == "" { 153 if err != nil || authResult.ErrCode != 0 || authResult.PhoneInfo.PhoneNumber == "" {
120 return response, xerr.NewCodeErrMsg(xerr.ErrWxMiniAuthFailError, nil, fmt.Sprintf("发起授权请求失败1 err : %v , code : %s , authResult : %+v", err, code, authResult)) 154 return response, xerr.NewCodeErrMsg(xerr.ErrWxMiniAuthFailError, nil, fmt.Sprintf("发起授权请求失败1 err : %v , code : %s , authResult : %+v", err, code, authResult))
121 } 155 }
122 var ( 156 var (
123 phone = authResult.PhoneInfo.PhoneNumber 157 phone = authResult.PhoneInfo.PhoneNumber
124 ) 158 )
125 - response.Phone = phone 159 + response.Phone = phone*/
126 return response, nil 160 return response, nil
127 } 161 }
128 162
@@ -139,10 +173,10 @@ func (c WxClientLogin) PhoneSmsCodeLogin(phone string, code string) (*domain.Log @@ -139,10 +173,10 @@ func (c WxClientLogin) PhoneSmsCodeLogin(phone string, code string) (*domain.Log
139 err error 173 err error
140 skipCheckSmsCode bool = false 174 skipCheckSmsCode bool = false
141 ) 175 )
142 - if c.l.svcCtx.Config.DebugSmsCode != "" && c.l.svcCtx.Config.DebugSmsCode == code { 176 + if c.svcCtx.Config.DebugSmsCode != "" && c.svcCtx.Config.DebugSmsCode == code {
143 skipCheckSmsCode = true 177 skipCheckSmsCode = true
144 } 178 }
145 - if _, err = c.l.svcCtx.SmsService.CheckSmsCode(c.l.ctx, smslib.RequestCheckSmsCode{Phone: phone, Code: code}); err != nil && !skipCheckSmsCode { 179 + 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) 180 return nil, xerr.NewErrMsgErr(err.Error(), err)
147 } 181 }
148 response := &domain.LoginInfo{ 182 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/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 MiniWechatBindLogic struct {
  15 + logx.Logger
  16 + ctx context.Context
  17 + svcCtx *svc.ServiceContext
  18 +}
  19 +
  20 +func NewMiniWechatBindLogic(ctx context.Context, svcCtx *svc.ServiceContext) *MiniWechatBindLogic {
  21 + return &MiniWechatBindLogic{
  22 + Logger: logx.WithContext(ctx),
  23 + ctx: ctx,
  24 + svcCtx: svcCtx,
  25 + }
  26 +}
  27 +
  28 +func (l *MiniWechatBindLogic) MiniWechatBind(req *types.MiniWechatBindRequest) (resp *types.MiniWechatBindResponse, err error) {
  29 + var loginCreator domain.LoginCreator = WxClientLogin{svcCtx: l.svcCtx, ctx: l.ctx}
  30 + loginInfo, err := loginCreator.WechatPhoneLogin(domain.WechatLoginRequest{
  31 + Code: req.WechatAuthCode,
  32 + EncryptedData: req.WechatEncryptedData,
  33 + IV: req.WechatIV,
  34 + })
  35 + if err != nil {
  36 + return nil, xerr.NewErrMsgErr("授权失败", err)
  37 + }
  38 + var conn = l.svcCtx.DefaultDBConn()
  39 + err = saveUserWechat(l.svcCtx, l.ctx, conn, loginInfo)
  40 + if err != nil {
  41 + return nil, xerr.NewErrMsg("保存用户信息失败")
  42 + }
  43 + return &types.MiniWechatBindResponse{
  44 + Bind: true,
  45 + Phone: loginInfo.Phone,
  46 + OpenId: loginInfo.OpenId,
  47 + }, nil
  48 +}
  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 +}
@@ -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"`
@@ -847,6 +869,27 @@ type SystemUserAccountSearchResponse struct { @@ -847,6 +869,27 @@ type SystemUserAccountSearchResponse struct {
847 Total int64 `json:"total"` 869 Total int64 `json:"total"`
848 } 870 }
849 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 +
850 type CompanySearchRequest struct { 893 type CompanySearchRequest struct {
851 Page int `json:"page,optional"` 894 Page int `json:"page,optional"`
852 Size int `json:"size,optional"` 895 Size int `json:"size,optional"`
  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 +)
  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 +)
  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 +}
  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 +}
  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" gorm:"unique"` // 微信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 +}
  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 +}
  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
@@ -92,3 +92,12 @@ func (m *ArticleComment) MaxCountAdminLove(articleWhoRead int) int { @@ -92,3 +92,12 @@ func (m *ArticleComment) MaxCountAdminLove(articleWhoRead int) int {
92 } 92 }
93 return x 93 return x
94 } 94 }
  95 +
  96 +// GetSubscribeMessageContent 获取订阅消息评论内容 最多显示20个字,超出用...
  97 +func (m *ArticleComment) GetSubscribeMessageContent() string {
  98 + runeContent := []rune(m.Content)
  99 + if len(runeContent) > 20 {
  100 + return string(runeContent[0:20]) + "..."
  101 + }
  102 + return m.Content
  103 +}
  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 +}
@@ -161,5 +161,6 @@ type ( @@ -161,5 +161,6 @@ type (
161 User *User 161 User *User
162 Phone string 162 Phone string
163 Message string 163 Message string
  164 + OpenId string
164 } 165 }
165 ) 166 )
  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;