作者 Administrator

合并分支 'test' 到 'master'

Test



查看合并请求 !13
正在显示 48 个修改的文件 包含 2250 行增加95 行删除
... ... @@ -60,6 +60,7 @@ type (
Page int `json:"page"`
Size int `json:"size"`
IncludeRootCompany bool `json:"includeRootCompany,optional"` // 包含公司(把公司当作部门作为顶级节点 部门ID:0)
IncludeDefaultDepartment bool `json:"includeDefaultDepartment,optional"` // 包含默认分组
}
DepartmentListResponse {
... ...
... ... @@ -26,6 +26,14 @@ service Core {
@doc "点赞消息"
@handler miniLike
post /mini/message/like (MessageRequest) returns (MessageBusinessResponse)
@doc "增加订阅消息次数"
@handler miniMessageSubscribeAdd
post /mini/message/subscribe/add (MessageSubscribeAddRequest) returns (MessageSubscribeAddResponse)
@doc "获取订阅消息次数"
@handler miniMessageSubscribeList
post /mini/message/subscribe/list (MessageSubscribeListRequest) returns (MessageSubscribeListResponse)
}
type (
... ... @@ -86,4 +94,25 @@ type (
CountComment int `json:"countComment"` // 评论数量
Show int `json:"show"` // 文章的展示状态(0显示、1不显示)
}
// 增加消息订阅次数
MessageSubscribeAddRequest {
Types []int `json:"types"` // 订阅消息类型
}
MessageSubscribeAddResponse {
Items []MessageSubscribeItem `json:"items"`
}
MessageSubscribeItem {
Type int `json:"type"` // 订阅消息类型
Count int `json:"count"` // 订阅次数
UserId int64 `json:"userId"` // 用户ID
CompanyId int64 `json:"companyId"` // 公司ID
}
//订阅消息次数详情
MessageSubscribeListRequest {
}
MessageSubscribeListResponse {
Items []MessageSubscribeItem `json:"items"`
}
)
... ...
... ... @@ -95,6 +95,13 @@ service Core {
@doc "个人主页-用户发布的信息"
@handler miniHomepageUserNews
post /mini/homepage/user_news (MiniHomepageUserNewsRequest)returns(MiniHomepageUserNewsResposne)
@doc "检测是否绑定微信"
@handler miniWechatInfo
get /mini/wechat/info (MiniWechatInfoRequest) returns (MiniWechatInfoResponse)
@doc "绑定微信"
@handler miniWechatBind
post /mini/wechat/bind (MiniWechatBindRequest) returns (MiniWechatBindResponse)
}
type(
... ... @@ -279,6 +286,7 @@ type(
ParentId int64 `json:"parentId"` // 父级ID
Name string `json:"name"` // 部门名称
UserIds []int64 `json:"userIds"` // 部门下的用户
TotalUser int `json:"totalUser"` // 累计用户
}
UserSearchRequest{
Page int `json:"page,optional"`
... ... @@ -471,7 +479,7 @@ type(
Phone string `json:"phone,optional"` // 手机号 唯一
Position string `json:"position,optional"` // 职位
Enable int `json:"enable,optional"` // 启用状态 1:启用 2:禁用
DepartmentId int64 `json:"departmentId,optional"` // 所属部门
DepartmentId *int64 `json:"departmentId,optional"` // 所属部门
}
SystemUserSearchResponse{
List []SystemUser `json:"list"`
... ... @@ -524,3 +532,29 @@ type(
Total int64 `json:"total"`
}
)
// 检测微信绑定信息
type (
MiniWechatInfoRequest {
}
MiniWechatInfoResponse {
Bind bool `json:"bind"` // 绑定结果 true-已绑定 false-未绑定
OpenId string `json:"openId"` // 绑定的微信openId
Phone string `json:"phone"` // 绑定手机号
}
)
// 绑定微信账号
type (
MiniWechatBindRequest {
WechatAuthCode string `json:"wechatAuthcode"` // 微信登录 授权码
WechatEncryptedData string `json:"wechatEncryptedData"` // 微信登录 加密数据
WechatIV string `json:"wechatIV"` // 微信登录 加密算法初始向量
}
MiniWechatBindResponse {
Bind bool `json:"bind"` // 绑定结果 true-已绑定 false-未绑定
OpenId string `json:"openId"` // 绑定的微信openId
Phone string `json:"phone"` // 绑定手机号
}
)
\ No newline at end of file
... ...
package message
import (
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/result"
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/logic/message"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types"
)
func MiniMessageSubscribeAddHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.MessageSubscribeAddRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := message.NewMiniMessageSubscribeAddLogic(r.Context(), svcCtx)
resp, err := l.MiniMessageSubscribeAdd(&req)
result.HttpResult(r, w, resp, err)
}
}
... ...
package message
import (
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/result"
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/logic/message"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types"
)
func MiniMessageSubscribeListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.MessageSubscribeListRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := message.NewMiniMessageSubscribeListLogic(r.Context(), svcCtx)
resp, err := l.MiniMessageSubscribeList(&req)
result.HttpResult(r, w, resp, err)
}
}
... ...
... ... @@ -163,6 +163,16 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
Path: "/mini/message/like",
Handler: message.MiniLikeHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/mini/message/subscribe/add",
Handler: message.MiniMessageSubscribeAddHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/mini/message/subscribe/list",
Handler: message.MiniMessageSubscribeListHandler(serverCtx),
},
}...,
),
rest.WithJwt(serverCtx.Config.MiniAuth.AccessSecret),
... ... @@ -339,6 +349,16 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
Path: "/mini/homepage/user_news",
Handler: user.MiniHomepageUserNewsHandler(serverCtx),
},
{
Method: http.MethodGet,
Path: "/mini/wechat/info",
Handler: user.MiniWechatInfoHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/mini/wechat/bind",
Handler: user.MiniWechatBindHandler(serverCtx),
},
}...,
),
rest.WithJwt(serverCtx.Config.MiniAuth.AccessSecret),
... ...
package user
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/logic/user"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types"
)
func MiniWechatBindHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.MiniWechatBindRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := user.NewMiniWechatBindLogic(r.Context(), svcCtx)
resp, err := l.MiniWechatBind(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
... ...
package user
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/logic/user"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types"
)
func MiniWechatInfoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.MiniWechatInfoRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := user.NewMiniWechatInfoLogic(r.Context(), svcCtx)
resp, err := l.MiniWechatInfo(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
... ...
... ... @@ -87,6 +87,7 @@ func (l *MiniArticleBackupSearchLogic) MiniArticleBackupSearch(req *types.MiniAr
changeFiled = append(changeFiled, "修改了评论范围")
case "Section":
{
changeFiled = append(changeFiled, "修改了文章内容")
item.Title = backupList[i].Title
item.Content = content.String()
item.Images = images
... ...
... ... @@ -2,6 +2,7 @@ package article
import (
"context"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/logic/message"
"strconv"
"strings"
"text/template"
... ... @@ -198,6 +199,12 @@ func (l *MiniCreateArticleLogic) MiniCreateArticle(req *types.MiniArticleCreateR
if err != nil {
return xerr.NewErrMsgErr("创建文章失败", err)
}
//发送订阅消息
err = message.NewMiniSubscribeLogic(l.ctx, l.svcCtx).FollowArticle(conn, newArticle)
if err != nil {
return xerr.NewErrMsgErr("创建文章失败", err)
}
return nil
}, true)
if err != nil {
... ...
... ... @@ -271,6 +271,11 @@ func (l *MiniSetUserLikeLogic) setUserLikeArticle(req *types.MiniSetUserLikeRequ
return err
}
//发送订阅消息
err = message.NewMiniSubscribeLogic(l.ctx, l.svcCtx).LikeArticle(c, articleInfo, userInfo)
if err != nil {
return err
}
return nil
}, true)
if err != nil {
... ... @@ -362,6 +367,11 @@ func (l *MiniSetUserLikeLogic) setUserLikeComment(req *types.MiniSetUserLikeRequ
return err
}
// 订阅消息
err = message.NewMiniSubscribeLogic(l.ctx, l.svcCtx).LikeComment(c, commentInfo, userInfo)
if err != nil {
return err
}
return nil
}, true)
if err != nil {
... ...
... ... @@ -4,6 +4,7 @@ import (
"context"
"github.com/pkg/errors"
"github.com/samber/lo"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/logic/message"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/gateway/authlib"
... ... @@ -154,6 +155,11 @@ func (l *SystemCreateArticleLogic) SystemCreateArticle(req *types.SystemArticleC
return xerr.NewErrMsg("删除草稿失败")
}
}
//发送订阅消息
err = message.NewMiniSubscribeLogic(l.ctx, l.svcCtx).FollowArticle(conn, article)
if err != nil {
return xerr.NewErrMsgErr("创建文章失败", err)
}
return nil
}, true)
if err != nil {
... ...
... ... @@ -206,7 +206,11 @@ func (l *MiniCreateArticleCommentLogic) MiniCreateArticleComment(req *types.Mini
if err != nil {
return err
}
// 发送订阅消息
err = message.NewMiniSubscribeLogic(l.ctx, l.svcCtx).ReplyComment(c, articleInfo, &newComment)
if err != nil {
return err
}
return nil
}, true)
... ...
... ... @@ -2,6 +2,7 @@ package department
import (
"context"
"github.com/samber/lo"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
... ... @@ -39,6 +40,30 @@ func (l *SystemListLogic) SystemList(req *types.DepartmentListRequest) (resp *ty
Total: total,
List: make([]types.Department, 0),
}
_, users, _ := l.svcCtx.UserRepository.Find(l.ctx, conn, domain.NewQueryOptions().
MustWithKV("companyId", userToken.CompanyId).
WithKV("auditStatus", []int{domain.UserAuditStatusPassed}))
// 统计部门用户数量
var counterByDepartment = make(map[int64]int)
lo.ForEach(users, func(item *domain.User, index int) {
if len(item.Departments) == 0 {
if _, ok := counterByDepartment[domain.DefaultDepartmentId]; ok {
counterByDepartment[domain.DefaultDepartmentId]++
} else {
counterByDepartment[domain.DefaultDepartmentId] = 1
}
return
}
for _, dep := range item.Departments {
if _, ok := counterByDepartment[dep]; ok {
counterByDepartment[dep]++
} else {
counterByDepartment[dep] = 1
}
}
})
if req.IncludeRootCompany {
company, _ := l.svcCtx.CompanyRepository.FindOne(l.ctx, conn, userToken.CompanyId)
if company != nil {
... ... @@ -47,9 +72,24 @@ func (l *SystemListLogic) SystemList(req *types.DepartmentListRequest) (resp *ty
CompanyId: company.Id,
ParentId: -1,
Name: company.Name,
TotalUser: len(users),
})
}
}
if req.IncludeDefaultDepartment {
to := types.Department{
Id: domain.DefaultDepartmentId,
CompanyId: userToken.CompanyId,
ParentId: 0,
Name: "未分组",
}
if v, ok := counterByDepartment[domain.DefaultDepartmentId]; ok {
to.TotalUser = v
}
resp.List = append(resp.List, to)
}
for _, item := range list {
to := types.Department{
Id: item.Id,
... ... @@ -57,6 +97,9 @@ func (l *SystemListLogic) SystemList(req *types.DepartmentListRequest) (resp *ty
ParentId: item.ParentId,
Name: item.Name,
}
if v, ok := counterByDepartment[item.Id]; ok {
to.TotalUser = v
}
resp.List = append(resp.List, to)
}
return resp, nil
... ...
package message
import (
"context"
"github.com/samber/lo"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/contextdata"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type MiniMessageSubscribeAddLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewMiniMessageSubscribeAddLogic(ctx context.Context, svcCtx *svc.ServiceContext) *MiniMessageSubscribeAddLogic {
return &MiniMessageSubscribeAddLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *MiniMessageSubscribeAddLogic) MiniMessageSubscribeAdd(req *types.MessageSubscribeAddRequest) (resp *types.MessageSubscribeAddResponse, err error) {
var userToken = contextdata.GetUserTokenFromCtx(l.ctx)
userId := userToken.UserId
companyId := userToken.CompanyId
var conn = l.svcCtx.DefaultDBConn()
//验证类型
for _, item := range req.Types {
if !lo.Contains([]int{domain.SubscribeTypeReplyComment, domain.SubscribeTypeLike, domain.SubscribeTypeFollow}, item) {
return nil, xerr.NewErrMsg("请订阅正确的消息类型")
}
}
resp = &types.MessageSubscribeAddResponse{Items: make([]types.MessageSubscribeItem, 0)}
err = transaction.UseTrans(l.ctx, conn.DB(), func(ctx context.Context, conn transaction.Conn) error {
for _, item := range req.Types {
userSubscribe, err := l.svcCtx.UserSubscribeRepository.FindOneByType(l.ctx, conn, companyId, userId, item)
if err == nil { //已有数据增加次数
userSubscribe.Count += 1
_, err = l.svcCtx.UserSubscribeRepository.Update(l.ctx, conn, userSubscribe)
if err != nil {
return err
}
} else { //新增
userSubscribe, err = l.svcCtx.UserSubscribeRepository.Insert(l.ctx, conn, &domain.UserSubscribe{
Type: item,
UserId: userId,
CompanyId: companyId,
Count: 1,
})
if err != nil {
return err
}
}
resp.Items = append(resp.Items, types.MessageSubscribeItem{
Type: userSubscribe.Type,
Count: userSubscribe.Count,
UserId: userSubscribe.UserId,
CompanyId: userSubscribe.CompanyId,
})
}
return nil
}, true)
if err != nil {
return nil, xerr.NewErrMsgErr("增加订阅消息次数失败", err)
}
return
}
... ...
package message
import (
"context"
"github.com/samber/lo"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/contextdata"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type MiniMessageSubscribeListLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewMiniMessageSubscribeListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *MiniMessageSubscribeListLogic {
return &MiniMessageSubscribeListLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *MiniMessageSubscribeListLogic) MiniMessageSubscribeList(req *types.MessageSubscribeListRequest) (resp *types.MessageSubscribeListResponse, err error) {
var userToken = contextdata.GetUserTokenFromCtx(l.ctx)
userId := userToken.UserId
companyId := userToken.CompanyId
var conn = l.svcCtx.DefaultDBConn()
resp = &types.MessageSubscribeListResponse{Items: make([]types.MessageSubscribeItem, 0)}
_, list, err := l.svcCtx.UserSubscribeRepository.Find(l.ctx, conn, domain.NewQueryOptions().WithKV("companyId", companyId).WithKV("userId", userId))
lo.ForEach(list, func(item *domain.UserSubscribe, index int) {
resp.Items = append(resp.Items, types.MessageSubscribeItem{
Type: item.Type,
Count: item.Count,
UserId: item.UserId,
CompanyId: item.CompanyId,
})
})
return
}
... ...
package message
import (
"context"
"fmt"
"github.com/jinzhu/copier"
"github.com/silenceper/wechat/v2"
"github.com/silenceper/wechat/v2/cache"
miniConfig "github.com/silenceper/wechat/v2/miniprogram/config"
"github.com/silenceper/wechat/v2/miniprogram/subscribe"
"github.com/zeromicro/go-zero/core/logx"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr"
"strings"
"time"
)
type MiniSubscribeLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewMiniSubscribeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *MiniSubscribeLogic {
return &MiniSubscribeLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *MiniSubscribeLogic) getSubScribe() *subscribe.Subscribe {
miniprogram := wechat.NewWechat().GetMiniProgram(&miniConfig.Config{
AppID: l.svcCtx.Config.Wechat.AppID,
AppSecret: l.svcCtx.Config.Wechat.AppSecret,
Cache: cache.NewMemory(),
})
return miniprogram.GetSubscribe()
}
// getOpenId 获取绑定用户openID
func (l *MiniSubscribeLogic) getOpenId(conn transaction.Conn, userId int64) (string, error) {
userInfo, err := l.svcCtx.UserRepository.FindOne(l.ctx, conn, userId)
if err != nil {
return "", err
}
//获取微信绑定
userWechat, err := l.svcCtx.UserWechatRepository.FindOneByPhone(l.ctx, conn, userInfo.Phone)
if err != nil {
return "", err
}
return userWechat.OpenId, nil
}
// sendAndDecrease 保存并扣减订阅消息
func (l *MiniSubscribeLogic) sendAndDecrease(conn transaction.Conn, companyId, userId int64, mType int, msg *subscribe.Message) error {
templateData := make(map[string]interface{})
_ = copier.Copy(&templateData, msg.Data)
subscribeMessage := &domain.MessageSubscribe{
Type: mType,
CompanyId: companyId,
UserId: userId,
OpenId: msg.ToUser,
TemplateId: msg.TemplateID,
TemplateData: templateData,
}
//获取订阅次数
userSubscribe, err := l.svcCtx.UserSubscribeRepository.FindOneByType(l.ctx, conn, companyId, userId, mType)
if err != nil || userSubscribe.Count <= 0 {
subscribeMessage.Result = "fail"
subscribeMessage.Error = "订阅次数已用完"
} else {
//扣减订阅次数
userSubscribe.Count = userSubscribe.Count - 1
_, err = l.svcCtx.UserSubscribeRepository.Update(l.ctx, conn, userSubscribe)
if err != nil {
return err
}
//发送订阅消息
subCtx := l.getSubScribe()
sendErr := subCtx.Send(msg)
if sendErr != nil {
subscribeMessage.Result = "fail"
subscribeMessage.Error = sendErr.Error()
} else {
subscribeMessage.Result = "ok"
}
}
//保存订阅结果
_, err = l.svcCtx.MessageSubscribeRepository.Insert(l.ctx, conn, subscribeMessage)
if err != nil {
return err
}
return nil
}
func (l *MiniSubscribeLogic) messageSubscribe(companyId, userId int64, mType int) *domain.MessageSubscribe {
return &domain.MessageSubscribe{
Type: mType,
CompanyId: companyId,
UserId: userId,
}
}
// getReplyCommentUserInfo 获取评论消息用户信息 用户名称+职位 例:张三-董事办
func (l *MiniSubscribeLogic) getReplyCommentUserInfo(conn transaction.Conn, companyId, userId int64) (string, error) {
userInfo, err := l.svcCtx.UserRepository.FindOne(l.ctx, conn, userId)
if err != nil {
return "", xerr.NewErrMsgErr("获取评论用户信息失败", err)
}
users := []string{userInfo.Name}
if len(userInfo.Roles) > 0 {
_, roles, err := l.svcCtx.RoleRepository.Find(l.ctx, conn, domain.IndexCompanyId(companyId)().MustWithKV("ids", userInfo.Roles))
if err == nil && len(roles) > 0 {
roleNames := make([]string, 0)
for _, item := range roles {
roleNames = append(roleNames, item.Name)
}
users = append(users, strings.Join(roleNames, "、"))
}
}
return strings.Join(users, "-"), nil
}
// ReplyComment 发送评论订阅消息
// @param conn 数据库连接
// @param article 文章
// @param comment 评论
func (l *MiniSubscribeLogic) ReplyComment(conn transaction.Conn, article *domain.Article, comment *domain.ArticleComment) error {
//评论用户+职位 例: 张三-董事办
fromUserName, err := l.getReplyCommentUserInfo(conn, comment.CompanyId, comment.FromUserId)
if err != nil {
return xerr.NewErrMsgErr("发送消息失败", err)
}
//评论消息
msg := &subscribe.Message{
TemplateID: domain.SubscribeTemplateComment,
Data: map[string]*subscribe.DataItem{
//文章标题
"thing1": &subscribe.DataItem{Value: article.GetSubscribeMessageTitle()},
//评论内容
"thing2": &subscribe.DataItem{Value: comment.GetSubscribeMessageContent()},
//评论时间
"time3": &subscribe.DataItem{Value: time.Now().Format("2006-01-02 15:04:05")},
//评论用户
"thing5": &subscribe.DataItem{Value: fromUserName},
//备注
"thing9": &subscribe.DataItem{Value: ""},
},
MiniprogramState: l.svcCtx.Config.Wechat.QrcodeEnv,
}
//发帖人接收消息
openId, err := l.getOpenId(conn, article.AuthorId)
//未绑定微信号,直接返回
if err == nil && openId != "" {
msg.ToUser = openId
msg.Page = fmt.Sprintf("/pages/detail/more-comment?id=%v", article.Id) //跳转页面 帖子评论聚合页
//备注
userCount, err := l.svcCtx.ArticleCommentRepository.CommentUserCount(l.ctx, conn, comment.CompanyId, comment.ArticleId)
msg.Data["thing9"] = &subscribe.DataItem{Value: fmt.Sprintf("您的帖子最近已有%v人评论,点击查看详情", userCount)}
//发送微信订阅消息
err = l.sendAndDecrease(conn, comment.CompanyId, article.AuthorId, domain.SubscribeTypeReplyComment, msg)
if err != nil {
return xerr.NewErrMsgErr("评论失败", err)
}
}
//评论回复
if comment.Pid > 0 {
toOpenId, err := l.getOpenId(conn, comment.ToUserId)
if err == nil && toOpenId != "" {
msg.ToUser = toOpenId
msg.Page = fmt.Sprintf("/pages/detail/reply-comment?id=%v&commentId=%v", article.Id, comment.Pid) //跳转页面评论聚合页
//备注
replyCount, err := l.svcCtx.ArticleCommentRepository.ReplyUserCount(l.ctx, conn, comment.CompanyId, comment.Pid)
if err == nil {
msg.Data["thing9"] = &subscribe.DataItem{Value: fmt.Sprintf("您的评论最近已有%v人回复,点击查看详情", replyCount)}
//发送微信订阅消息
err = l.sendAndDecrease(conn, comment.CompanyId, comment.ToUserId, domain.SubscribeTypeReplyComment, msg)
if err != nil {
return xerr.NewErrMsgErr("评论失败", err)
}
}
}
}
//@消息
if len(comment.AtWho) > 0 {
for _, at := range comment.AtWho {
atOpenId, err := l.getOpenId(conn, at.Id)
//未绑定微信跳过
if err != nil || atOpenId == "" {
continue
}
msg.ToUser = atOpenId
msg.Page = fmt.Sprintf("/pages/detail/reply-comment?id=%v&commentId=%v", article.Id, comment.Pid) //跳转页面 评论详情页
//备注
msg.Data["thing9"] = &subscribe.DataItem{Value: fmt.Sprintf("%v在评论中提到了你", comment.FromUser.Name)}
//发送微信订阅消息
err = l.sendAndDecrease(conn, comment.CompanyId, at.Id, domain.SubscribeTypeReplyComment, msg)
if err != nil {
return xerr.NewErrMsgErr("评论失败", err)
}
}
}
return nil
}
// LikeArticle 帖子点赞订阅消息
func (l *MiniSubscribeLogic) LikeArticle(conn transaction.Conn, article *domain.Article, userInfo *domain.User) error {
openId, err := l.getOpenId(conn, article.AuthorId)
if err != nil || openId == "" {
return nil
}
newArticle, err := l.svcCtx.ArticleRepository.FindOne(l.ctx, conn, article.Id)
if err != nil {
return xerr.NewErrMsgErr("未获取到帖子信息", err)
}
msg := &subscribe.Message{
ToUser: openId,
TemplateID: domain.SubscribeTemplateLike,
Page: fmt.Sprintf("/pages/detail/detail?id=%v", article.Id),
Data: map[string]*subscribe.DataItem{
//点赞用户
"name1": &subscribe.DataItem{Value: userInfo.Name},
//点赞时间
"date2": &subscribe.DataItem{Value: time.Now().Format("2006-01-02 15:04:05")},
//动态内容
"thing8": &subscribe.DataItem{Value: article.GetSubscribeMessageTitle()},
//被赞次数
"number4": &subscribe.DataItem{Value: newArticle.CountLove},
//温馨提示
"thing5": &subscribe.DataItem{Value: "这条内容很受欢迎哦,快来看看吧"},
},
MiniprogramState: l.svcCtx.Config.Wechat.QrcodeEnv,
}
err = l.sendAndDecrease(conn, article.CompanyId, article.AuthorId, domain.SubscribeTypeLike, msg)
if err != nil {
return xerr.NewErrMsgErr("点赞失败", err)
}
return nil
}
// LikeComment 点赞评论订阅消息
func (l *MiniSubscribeLogic) LikeComment(conn transaction.Conn, comment *domain.ArticleComment, userInfo *domain.User) error {
openId, err := l.getOpenId(conn, comment.FromUserId)
if err != nil || openId == "" {
return nil
}
//获取被赞次数
newComment, err := l.svcCtx.ArticleCommentRepository.FindOne(l.ctx, conn, comment.Id)
if err != nil {
return xerr.NewErrMsgErr("未获取到评论信息", err)
}
msg := &subscribe.Message{
ToUser: openId,
TemplateID: domain.SubscribeTemplateLike,
Page: fmt.Sprintf("/pages/detail/reply-comment?id=%v&commentId=%v", comment.ArticleId, comment.Id),
Data: map[string]*subscribe.DataItem{
//点赞用户
"name1": &subscribe.DataItem{Value: userInfo.Name},
//点赞时间
"date2": &subscribe.DataItem{Value: time.Now().Format("2006-01-02 15:04:05")},
//动态内容
"thing8": &subscribe.DataItem{Value: comment.GetSubscribeMessageContent()},
//被赞次数
"number4": &subscribe.DataItem{Value: newComment.CountUserLove},
//温馨提示
"thing5": &subscribe.DataItem{Value: "这条内容很受欢迎哦,快来看看吧"},
},
MiniprogramState: l.svcCtx.Config.Wechat.QrcodeEnv,
}
err = l.sendAndDecrease(conn, comment.CompanyId, comment.FromUserId, domain.SubscribeTypeLike, msg)
if err != nil {
return xerr.NewErrMsgErr("点赞失败", err)
}
return nil
}
// FollowArticle 发帖关注更新提醒
func (l *MiniSubscribeLogic) FollowArticle(conn transaction.Conn, article *domain.Article) error {
//获取关注帖子作者的人员
_, userInfo, err := l.svcCtx.UserFollowRepository.Find(l.ctx, conn, domain.NewQueryOptions().WithKV("toUserIds", []int64{article.AuthorId}))
if err == nil && len(userInfo) > 0 {
for _, item := range userInfo {
openId, err := l.getOpenId(conn, item.FromUserId)
if err != nil || openId == "" {
continue
}
msg := &subscribe.Message{
ToUser: openId,
TemplateID: domain.SubscribeTemplateFollow,
Page: fmt.Sprintf("/pages/detail/detail?id=%v", article.Id),
Data: map[string]*subscribe.DataItem{
//创作者
"thing1": &subscribe.DataItem{Value: article.Author.Name},
//作品名称
"thing2": &subscribe.DataItem{Value: article.Title},
//内容摘要
"thing5": &subscribe.DataItem{Value: ""},
//发布时间
"time6": &subscribe.DataItem{Value: time.Now().Format("2006-01-02 15:04:05")},
//温馨提示
"thing3": &subscribe.DataItem{Value: "你关注的人发布了新的帖子"},
},
MiniprogramState: l.svcCtx.Config.Wechat.QrcodeEnv,
}
err = l.sendAndDecrease(conn, article.CompanyId, item.FromUserId, domain.SubscribeTypeFollow, msg)
if err != nil {
return xerr.NewErrMsgErr("保存订阅消息失败", err)
}
}
}
return nil
}
... ...
... ... @@ -40,7 +40,7 @@ func (l *MiniUserDepartmentUsersLogic) MiniUserDepartmentUsers(req *types.MiniUs
"list": groups,
}
company, err = l.svcCtx.CompanyRepository.FindOne(l.ctx, conn, userToken.CompanyId)
if err != nil {
if err != nil || company == nil {
return nil, xerr.NewErrMsgErr("查找部门用户失败", err)
}
_, departments, err = l.svcCtx.DepartmentRepository.Find(l.ctx, conn, domain.IndexCompanyId(userToken.CompanyId)().WithFindOnly())
... ... @@ -51,7 +51,7 @@ func (l *MiniUserDepartmentUsersLogic) MiniUserDepartmentUsers(req *types.MiniUs
if err != nil {
return nil, xerr.NewErrMsgErr("查找部门用户失败", err)
}
departments = append([]*domain.Department{&domain.Department{Id: 0, Name: company.Name}}, departments...)
departments = append([]*domain.Department{&domain.Department{Id: 0, Name: "未分组"}}, departments...)
lo.ForEach(departments, func(item *domain.Department, index int) {
group := DepartmentUser{
Id: item.Id,
... ... @@ -61,7 +61,7 @@ func (l *MiniUserDepartmentUsersLogic) MiniUserDepartmentUsers(req *types.MiniUs
groupUserSet := collection.NewSet()
for _, user := range users {
// 未分配部门的归类到公司底下
if len(user.Departments) == 0 {
if item.Id == 0 && len(user.Departments) == 0 {
if !groupUserSet.Contains(user.Id) {
group.Users = append(group.Users, &domain.User{
Id: user.Id,
... ...
... ... @@ -35,7 +35,7 @@ func (l *MiniUserLoginLogic) MiniUserLogin(req *types.MiniUserLoginRequest) (res
var (
loginInfo *domain.LoginInfo
token string
loginCreator domain.LoginCreator = WxClientLogin{l: l}
loginCreator domain.LoginCreator = WxClientLogin{svcCtx: l.svcCtx, ctx: l.ctx}
)
switch req.LoginType {
case domain.LoginTypeWechatLogin:
... ... @@ -102,7 +102,8 @@ func generateToken(svcCtx *svc.ServiceContext, user *domain.User) (token string,
}
type WxClientLogin struct {
l *MiniUserLoginLogic
svcCtx *svc.ServiceContext
ctx context.Context
}
func (c WxClientLogin) WechatPhoneLogin(r domain.WechatLoginRequest) (*domain.LoginInfo, error) {
... ... @@ -111,8 +112,8 @@ func (c WxClientLogin) WechatPhoneLogin(r domain.WechatLoginRequest) (*domain.Lo
Phone: "",
}
miniprogram := wechat.NewWechat().GetMiniProgram(&miniConfig.Config{
AppID: c.l.svcCtx.Config.Wechat.AppID,
AppSecret: c.l.svcCtx.Config.Wechat.AppSecret,
AppID: c.svcCtx.Config.Wechat.AppID,
AppSecret: c.svcCtx.Config.Wechat.AppSecret,
Cache: cache.NewMemory(),
})
authResult, err := miniprogram.GetAuth().GetPhoneNumber(code)
... ... @@ -130,6 +131,23 @@ func (c WxClientLogin) WechatLogin(r domain.WechatLoginRequest) (*domain.LoginIn
return nil, nil
}
func (c WxClientLogin) GetOpenId(r domain.WechatLoginRequest) (string, error) {
miniprogram := wechat.NewWechat().GetMiniProgram(&miniConfig.Config{
AppID: c.svcCtx.Config.Wechat.AppID,
AppSecret: c.svcCtx.Config.Wechat.AppSecret,
Cache: cache.NewMemory(),
})
result, err := miniprogram.GetAuth().Code2Session(r.Code)
if err != nil {
return "", xerr.NewErrMsgErr("发起授权请求失败", err)
}
plainData, err := miniprogram.GetEncryptor().Decrypt(result.SessionKey, r.EncryptedData, r.IV)
if err != nil {
return "", xerr.NewErrMsgErr("获取授权用户失败", err)
}
return plainData.OpenID, nil
}
func (c WxClientLogin) PhonePasswordLogin(phone string, password string) (*domain.LoginInfo, error) {
panic("implement me")
}
... ... @@ -139,10 +157,10 @@ func (c WxClientLogin) PhoneSmsCodeLogin(phone string, code string) (*domain.Log
err error
skipCheckSmsCode bool = false
)
if c.l.svcCtx.Config.DebugSmsCode != "" && c.l.svcCtx.Config.DebugSmsCode == code {
if c.svcCtx.Config.DebugSmsCode != "" && c.svcCtx.Config.DebugSmsCode == code {
skipCheckSmsCode = true
}
if _, err = c.l.svcCtx.SmsService.CheckSmsCode(c.l.ctx, smslib.RequestCheckSmsCode{Phone: phone, Code: code}); err != nil && !skipCheckSmsCode {
if _, err = c.svcCtx.SmsService.CheckSmsCode(c.ctx, smslib.RequestCheckSmsCode{Phone: phone, Code: code}); err != nil && !skipCheckSmsCode {
return nil, xerr.NewErrMsgErr(err.Error(), err)
}
response := &domain.LoginInfo{
... ...
package user
import (
"context"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/contextdata"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type MiniWechatBindLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewMiniWechatBindLogic(ctx context.Context, svcCtx *svc.ServiceContext) *MiniWechatBindLogic {
return &MiniWechatBindLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *MiniWechatBindLogic) MiniWechatBind(req *types.MiniWechatBindRequest) (resp *types.MiniWechatBindResponse, err error) {
var loginCreator domain.LoginCreator = WxClientLogin{svcCtx: l.svcCtx, ctx: l.ctx}
openId, err := loginCreator.GetOpenId(domain.WechatLoginRequest{
Code: req.WechatAuthCode,
EncryptedData: req.WechatEncryptedData,
IV: req.WechatIV,
})
if err != nil {
return nil, xerr.NewErrMsgErr("授权失败", err)
}
var userToken = contextdata.GetUserTokenFromCtx(l.ctx)
userId := userToken.UserId
var conn = l.svcCtx.DefaultDBConn()
//获取用户信息
userInfo, err := l.svcCtx.UserRepository.FindOne(l.ctx, conn, userId)
if err != nil {
return nil, xerr.NewErrMsgErr("获取用户信息失败", err)
}
_, err = l.svcCtx.UserWechatRepository.FindOneByPhone(l.ctx, conn, userInfo.Phone)
if err != nil { // 未存储
_, err = l.svcCtx.UserWechatRepository.Insert(l.ctx, conn, &domain.UserWechat{
Phone: userInfo.Phone,
OpenId: openId,
})
if err != nil {
return nil, xerr.NewErrMsgErr("授权失败", err)
}
}
if err != nil {
return nil, xerr.NewErrMsg("保存用户信息失败")
}
return &types.MiniWechatBindResponse{
Bind: true,
Phone: userInfo.Phone,
OpenId: openId,
}, nil
}
... ...
package user
import (
"context"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/contextdata"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type MiniWechatInfoLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewMiniWechatInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *MiniWechatInfoLogic {
return &MiniWechatInfoLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *MiniWechatInfoLogic) MiniWechatInfo(req *types.MiniWechatInfoRequest) (resp *types.MiniWechatInfoResponse, err error) {
var userToken = contextdata.GetUserTokenFromCtx(l.ctx)
userId := userToken.UserId
var conn = l.svcCtx.DefaultDBConn()
user, err := l.svcCtx.UserRepository.FindOne(l.ctx, conn, userId)
if err != nil {
return nil, xerr.NewErrMsg("未获取到用户信息")
}
userWechat, err := l.svcCtx.UserWechatRepository.FindOneByPhone(l.ctx, conn, user.Phone)
if err != nil {
return &types.MiniWechatInfoResponse{
Bind: false,
}, nil
} else {
return &types.MiniWechatInfoResponse{
Bind: true,
OpenId: userWechat.OpenId,
Phone: userWechat.Phone,
}, nil
}
}
... ...
... ... @@ -41,8 +41,11 @@ func (l *SystemUserSearchLogic) SystemUserSearch(req *types.SystemUserSearchRequ
WithKV("likePhone", req.Phone).
WithKV("position", req.Position).
WithKV("enable", req.Enable).
WithKV("departmentId", req.DepartmentId).
WithKV("auditStatus", []int{domain.UserAuditStatusPassed})
if req.DepartmentId != nil {
queryOptions.MustWithKV("departmentId", *req.DepartmentId)
}
if total, users, err = l.svcCtx.UserRepository.Find(l.ctx, conn, queryOptions); err != nil {
return nil, xerr.NewErr(err)
}
... ...
... ... @@ -41,12 +41,15 @@ type ServiceContext struct {
DepartmentRepository domain.DepartmentRepository
MessageBusinessRepository domain.MessageBusinessRepository
MessageSystemRepository domain.MessageSystemRepository
MessageSubscribeRepository domain.MessageSubscribeRepository
RoleRepository domain.RoleRepository
UserFollowRepository domain.UserFollowRepository
UserLoveFlagRepository domain.UserLoveFlagRepository
UserReadArticleRepository domain.UserReadArticleRepository
UserRepository domain.UserRepository
UserRoleRepository domain.UserRoleRepository
UserSubscribeRepository domain.UserSubscribeRepository
UserWechatRepository domain.UserWechatRepository
ApiAuthService authlib.ApiAuthService
SmsService smslib.SMSService
... ... @@ -96,6 +99,7 @@ func NewServiceContext(c config.Config) *ServiceContext {
DepartmentRepository: repository.NewDepartmentRepository(cache.NewCachedRepository(mlCache)),
MessageBusinessRepository: repository.NewMessageBusinessRepository(cache.NewCachedRepository(mlCache)),
MessageSystemRepository: repository.NewMessageSystemRepository(cache.NewCachedRepository(mlCache)),
MessageSubscribeRepository: repository.NewMessageSubscribeRepository(cache.NewCachedRepository(mlCache)),
RoleRepository: repository.NewRoleRepository(cache.NewCachedRepository(mlCache)),
UserFollowRepository: repository.NewUserFollowRepository(cache.NewCachedRepository(mlCache)),
UserLoveFlagRepository: repository.NewUserLoveFlagRepository(cache.NewCachedRepository(mlCache)),
... ... @@ -103,6 +107,8 @@ func NewServiceContext(c config.Config) *ServiceContext {
UserReadArticleRepository: repository.NewUserReadArticleRepository(cache.NewCachedRepository(mlCache)),
ArticleTagRepository: repository.NewArticleTagRepository(cache.NewCachedRepository(mlCache)),
UserRoleRepository: repository.NewUserRoleRepository(cache.NewCachedRepository(mlCache)),
UserSubscribeRepository: repository.NewUserSubscribeRepository(cache.NewCachedRepository(mlCache)),
UserWechatRepository: repository.NewUserWechatRepository(cache.NewCachedRepository(mlCache)),
}
}
... ...
... ... @@ -347,6 +347,28 @@ type SimpleArticle struct {
Show int `json:"show"` // 文章的展示状态(0显示、1不显示)
}
type MessageSubscribeAddRequest struct {
Types []int `json:"types"` // 订阅消息类型
}
type MessageSubscribeAddResponse struct {
Items []MessageSubscribeItem `json:"items"`
}
type MessageSubscribeItem struct {
Type int `json:"type"` // 订阅消息类型
Count int `json:"count"` // 订阅次数
UserId int64 `json:"userId"` // 用户ID
CompanyId int64 `json:"companyId"` // 公司ID
}
type MessageSubscribeListRequest struct {
}
type MessageSubscribeListResponse struct {
Items []MessageSubscribeItem `json:"items"`
}
type TagCreateRequest struct {
CompanyId int64 `json:",optional"`
Image string `json:"image"`
... ... @@ -637,6 +659,7 @@ type Department struct {
ParentId int64 `json:"parentId"` // 父级ID
Name string `json:"name"` // 部门名称
UserIds []int64 `json:"userIds"` // 部门下的用户
TotalUser int `json:"totalUser"` // 累计用户
}
type UserSearchRequest struct {
... ... @@ -786,7 +809,7 @@ type SystemUserSearchRequest struct {
Phone string `json:"phone,optional"` // 手机号 唯一
Position string `json:"position,optional"` // 职位
Enable int `json:"enable,optional"` // 启用状态 1:启用 2:禁用
DepartmentId int64 `json:"departmentId,optional"` // 所属部门
DepartmentId *int64 `json:"departmentId,optional"` // 所属部门
}
type SystemUserSearchResponse struct {
... ... @@ -846,6 +869,27 @@ type SystemUserAccountSearchResponse struct {
Total int64 `json:"total"`
}
type MiniWechatInfoRequest struct {
}
type MiniWechatInfoResponse struct {
Bind bool `json:"bind"` // 绑定结果 true-已绑定 false-未绑定
OpenId string `json:"openId"` // 绑定的微信openId
Phone string `json:"phone"` // 绑定手机号
}
type MiniWechatBindRequest struct {
WechatAuthCode string `json:"wechatAuthcode"` // 微信登录 授权码
WechatEncryptedData string `json:"wechatEncryptedData"` // 微信登录 加密数据
WechatIV string `json:"wechatIV"` // 微信登录 加密算法初始向量
}
type MiniWechatBindResponse struct {
Bind bool `json:"bind"` // 绑定结果 true-已绑定 false-未绑定
OpenId string `json:"openId"` // 绑定的微信openId
Phone string `json:"phone"` // 绑定手机号
}
type CompanySearchRequest struct {
Page int `json:"page,optional"`
Size int `json:"size,optional"`
... ... @@ -1730,6 +1774,7 @@ type DepartmentListRequest struct {
Page int `json:"page"`
Size int `json:"size"`
IncludeRootCompany bool `json:"includeRootCompany,optional"` // 包含公司(把公司当作部门作为顶级节点 部门ID:0)
IncludeDefaultDepartment bool `json:"includeDefaultDepartment,optional"` // 包含默认分组
}
type DepartmentListResponse struct {
... ...
syntax = "v1"
info(
title: "xx实例"
desc: "xx实例"
author: "author"
email: "email"
version: "v1"
)
@server(
prefix: message_subscribe/v1
group: message_subscribe
jwt: JwtAuth
)
service Core {
@handler getMessageSubscribe
post /message_subscribe/:id (MessageSubscribeGetRequest) returns (MessageSubscribeGetResponse)
@handler saveMessageSubscribe
post /message_subscribe (MessageSubscribeSaveRequest) returns (MessageSubscribeSaveResponse)
@handler deleteMessageSubscribe
delete /message_subscribe/:id (MessageSubscribeDeleteRequest) returns (MessageSubscribeDeleteResponse)
@handler updateMessageSubscribe
put /message_subscribe/:id (MessageSubscribeUpdateRequest) returns (MessageSubscribeUpdateResponse)
@handler searchMessageSubscribe
post /message_subscribe/search (MessageSubscribeSearchRequest) returns (MessageSubscribeSearchResponse)
}
type (
MessageSubscribeGetRequest {
Id int64 `path:"id"`
}
MessageSubscribeGetResponse struct{
MessageSubscribe MessageSubscribeItem `json:"message_subscribe"`
}
MessageSubscribeSaveRequest struct{
MessageSubscribe MessageSubscribeItem `json:"message_subscribe"`
}
MessageSubscribeSaveResponse struct{}
MessageSubscribeDeleteRequest struct{
Id int64 `path:"id"`
}
MessageSubscribeDeleteResponse struct{}
MessageSubscribeUpdateRequest struct{
Id int64 `path:"id"`
MessageSubscribe MessageSubscribeItem `json:"message_subscribe"`
}
MessageSubscribeUpdateResponse struct{}
MessageSubscribeSearchRequest struct{
Page int `json:"page"`
Size int `json:"size"`
}
MessageSubscribeSearchResponse{
List []MessageSubscribeItem `json:"list"`
Total int64 `json:"total"`
}
MessageSubscribeItem struct{
}
)
... ...
syntax = "v1"
info(
title: "xx实例"
desc: "xx实例"
author: "author"
email: "email"
version: "v1"
)
@server(
prefix: user_subscribe/v1
group: user_subscribe
jwt: JwtAuth
)
service Core {
@handler getUserSubscribe
post /user_subscribe/:id (UserSubscribeGetRequest) returns (UserSubscribeGetResponse)
@handler saveUserSubscribe
post /user_subscribe (UserSubscribeSaveRequest) returns (UserSubscribeSaveResponse)
@handler deleteUserSubscribe
delete /user_subscribe/:id (UserSubscribeDeleteRequest) returns (UserSubscribeDeleteResponse)
@handler updateUserSubscribe
put /user_subscribe/:id (UserSubscribeUpdateRequest) returns (UserSubscribeUpdateResponse)
@handler searchUserSubscribe
post /user_subscribe/search (UserSubscribeSearchRequest) returns (UserSubscribeSearchResponse)
}
type (
UserSubscribeGetRequest {
Id int64 `path:"id"`
}
UserSubscribeGetResponse struct{
UserSubscribe UserSubscribeItem `json:"user_subscribe"`
}
UserSubscribeSaveRequest struct{
UserSubscribe UserSubscribeItem `json:"user_subscribe"`
}
UserSubscribeSaveResponse struct{}
UserSubscribeDeleteRequest struct{
Id int64 `path:"id"`
}
UserSubscribeDeleteResponse struct{}
UserSubscribeUpdateRequest struct{
Id int64 `path:"id"`
UserSubscribe UserSubscribeItem `json:"user_subscribe"`
}
UserSubscribeUpdateResponse struct{}
UserSubscribeSearchRequest struct{
Page int `json:"page"`
Size int `json:"size"`
}
UserSubscribeSearchResponse{
List []UserSubscribeItem `json:"list"`
Total int64 `json:"total"`
}
UserSubscribeItem struct{
}
)
... ...
syntax = "v1"
info(
title: "xx实例"
desc: "xx实例"
author: "author"
email: "email"
version: "v1"
)
@server(
prefix: user_wechat/v1
group: user_wechat
jwt: JwtAuth
)
service Core {
@handler getUserWechat
post /user_wechat/:id (UserWechatGetRequest) returns (UserWechatGetResponse)
@handler saveUserWechat
post /user_wechat (UserWechatSaveRequest) returns (UserWechatSaveResponse)
@handler deleteUserWechat
delete /user_wechat/:id (UserWechatDeleteRequest) returns (UserWechatDeleteResponse)
@handler updateUserWechat
put /user_wechat/:id (UserWechatUpdateRequest) returns (UserWechatUpdateResponse)
@handler searchUserWechat
post /user_wechat/search (UserWechatSearchRequest) returns (UserWechatSearchResponse)
}
type (
UserWechatGetRequest {
Id int64 `path:"id"`
}
UserWechatGetResponse struct{
UserWechat UserWechatItem `json:"user_wechat"`
}
UserWechatSaveRequest struct{
UserWechat UserWechatItem `json:"user_wechat"`
}
UserWechatSaveResponse struct{}
UserWechatDeleteRequest struct{
Id int64 `path:"id"`
}
UserWechatDeleteResponse struct{}
UserWechatUpdateRequest struct{
Id int64 `path:"id"`
UserWechat UserWechatItem `json:"user_wechat"`
}
UserWechatUpdateResponse struct{}
UserWechatSearchRequest struct{
Page int `json:"page"`
Size int `json:"size"`
}
UserWechatSearchResponse{
List []UserWechatItem `json:"list"`
Total int64 `json:"total"`
}
UserWechatItem struct{
}
)
... ...
syntax = "proto3";
option go_package ="./pb";
package pb;
message MessageSubscribeGetReq {
int64 Id = 1;
}
message MessageSubscribeGetResp{
MessageSubscribeItem User = 1;
}
message MessageSubscribeSaveReq {
}
message MessageSubscribeSaveResp{
}
message MessageSubscribeDeleteReq {
int64 Id = 1;
}
message MessageSubscribeDeleteResp{
}
message MessageSubscribeUpdateReq {
int64 Id = 1;
}
message MessageSubscribeUpdateResp{
}
message MessageSubscribeSearchReq {
int64 PageNumber = 1;
int64 PageSize = 2;
}
message MessageSubscribeSearchResp{
repeated MessageSubscribeItem List =1;
int64 Total =2;
}
message MessageSubscribeItem {
}
service MessageSubscribeService {
rpc MessageSubscribeGet(MessageSubscribeGetReq) returns(MessageSubscribeGetResp);
rpc MessageSubscribeSave(MessageSubscribeSaveReq) returns(MessageSubscribeSaveResp);
rpc MessageSubscribeDelete(MessageSubscribeDeleteReq) returns(MessageSubscribeDeleteResp);
rpc MessageSubscribeUpdate(MessageSubscribeUpdateReq) returns(MessageSubscribeUpdateResp);
rpc MessageSubscribeSearch(MessageSubscribeSearchReq) returns(MessageSubscribeSearchResp);
}
... ...
syntax = "proto3";
option go_package ="./pb";
package pb;
message UserSubscribeGetReq {
int64 Id = 1;
}
message UserSubscribeGetResp{
UserSubscribeItem User = 1;
}
message UserSubscribeSaveReq {
}
message UserSubscribeSaveResp{
}
message UserSubscribeDeleteReq {
int64 Id = 1;
}
message UserSubscribeDeleteResp{
}
message UserSubscribeUpdateReq {
int64 Id = 1;
}
message UserSubscribeUpdateResp{
}
message UserSubscribeSearchReq {
int64 PageNumber = 1;
int64 PageSize = 2;
}
message UserSubscribeSearchResp{
repeated UserSubscribeItem List =1;
int64 Total =2;
}
message UserSubscribeItem {
}
service UserSubscribeService {
rpc UserSubscribeGet(UserSubscribeGetReq) returns(UserSubscribeGetResp);
rpc UserSubscribeSave(UserSubscribeSaveReq) returns(UserSubscribeSaveResp);
rpc UserSubscribeDelete(UserSubscribeDeleteReq) returns(UserSubscribeDeleteResp);
rpc UserSubscribeUpdate(UserSubscribeUpdateReq) returns(UserSubscribeUpdateResp);
rpc UserSubscribeSearch(UserSubscribeSearchReq) returns(UserSubscribeSearchResp);
}
... ...
syntax = "proto3";
option go_package ="./pb";
package pb;
message UserWechatGetReq {
int64 Id = 1;
}
message UserWechatGetResp{
UserWechatItem User = 1;
}
message UserWechatSaveReq {
}
message UserWechatSaveResp{
}
message UserWechatDeleteReq {
int64 Id = 1;
}
message UserWechatDeleteResp{
}
message UserWechatUpdateReq {
int64 Id = 1;
}
message UserWechatUpdateResp{
}
message UserWechatSearchReq {
int64 PageNumber = 1;
int64 PageSize = 2;
}
message UserWechatSearchResp{
repeated UserWechatItem List =1;
int64 Total =2;
}
message UserWechatItem {
}
service UserWechatService {
rpc UserWechatGet(UserWechatGetReq) returns(UserWechatGetResp);
rpc UserWechatSave(UserWechatSaveReq) returns(UserWechatSaveResp);
rpc UserWechatDelete(UserWechatDeleteReq) returns(UserWechatDeleteResp);
rpc UserWechatUpdate(UserWechatUpdateReq) returns(UserWechatUpdateResp);
rpc UserWechatSearch(UserWechatSearchReq) returns(UserWechatSearchResp);
}
... ...
... ... @@ -24,8 +24,11 @@ func Migrate(db *gorm.DB) {
//&models.MessageBusiness{},
//&models.Department{},
//&models.ArticleAndTag{},
&models.ArticleDraftOperation{},
&models.ArticleCategory{},
//&models.ArticleDraftOperation{},
//&models.ArticleCategory{},
&models.UserSubscribe{},
&models.MessageSubscribe{},
&models.UserWechat{},
}
db.AutoMigrate(modelsList...)
... ...
package models
import (
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
"gorm.io/gorm"
"gorm.io/plugin/soft_delete"
)
type MessageSubscribe struct {
Id int64 `json:"id"` // 唯一标识
Type int `json:"type"` // 分类(1评论回复 2获赞 3关注人更新)
CompanyId int64 `json:"companyId"` // 公司ID
UserId int64 `json:"userId"` // 用户ID
OpenId string `json:"openId"` // 微信openID
TemplateId string `json:"templateId"` // 模板ID
TemplateData map[string]interface{} `json:"templateData" gorm:"serializer:json;type:text;"` // 模板参数
Result string `json:"result"` // 发送结果
Error string `json:"error"` // 调用接口错误信息
CreatedAt int64 `json:",omitempty"` // 创建时间
UpdatedAt int64 `json:",omitempty"` // 更新时间
DeletedAt int64 `json:",omitempty"` // 删除时间
Version int `json:",omitempty"` // 版本
IsDel soft_delete.DeletedAt `gorm:"softDelete:flag,DeletedAtField:DeletedAt"` // 删除标记
}
func (m *MessageSubscribe) TableName() string {
return "message_subscribe"
}
func (m *MessageSubscribe) BeforeCreate(tx *gorm.DB) (err error) {
// m.CreatedAt = time.Now().Unix()
// m.UpdatedAt = time.Now().Unix()
return
}
func (m *MessageSubscribe) BeforeUpdate(tx *gorm.DB) (err error) {
// m.UpdatedAt = time.Now().Unix()
return
}
func (m *MessageSubscribe) CacheKeyFunc() string {
if m.Id == 0 {
return ""
}
return fmt.Sprintf("%v:cache:%v:id:%v", domain.ProjectName, m.TableName(), m.Id)
}
func (m *MessageSubscribe) CacheKeyFuncByObject(obj interface{}) string {
if v, ok := obj.(*MessageSubscribe); ok {
return v.CacheKeyFunc()
}
return ""
}
func (m *MessageSubscribe) CachePrimaryKeyFunc() string {
if len("") == 0 {
return ""
}
return fmt.Sprintf("%v:cache:%v:primarykey:%v", domain.ProjectName, m.TableName(), "key")
}
... ...
package models
import (
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
"gorm.io/gorm"
"gorm.io/plugin/soft_delete"
)
type UserSubscribe struct {
Id int64 `json:"id"` // 唯一标识
Type int `json:"type" gorm:"type:int;"` // 分类(1评论回复 2获赞 3关注人更新)
CompanyId int64 `json:"companyId"` // 公司ID
UserId int64 `json:"userId"` // 用户ID
Count int `json:"count" gorm:"type:int;"` // 订阅次数
CreatedAt int64 `json:",omitempty"` // 创建时间
UpdatedAt int64 `json:",omitempty"` // 更新时间
DeletedAt int64 `json:",omitempty"` // 删除时间
Version int `json:",omitempty"` // 版本
IsDel soft_delete.DeletedAt `gorm:"softDelete:flag,DeletedAtField:DeletedAt"` // 删除标记
}
func (m *UserSubscribe) TableName() string {
return "user_subscribe"
}
func (m *UserSubscribe) BeforeCreate(tx *gorm.DB) (err error) {
// m.CreatedAt = time.Now().Unix()
// m.UpdatedAt = time.Now().Unix()
return
}
func (m *UserSubscribe) BeforeUpdate(tx *gorm.DB) (err error) {
// m.UpdatedAt = time.Now().Unix()
return
}
func (m *UserSubscribe) CacheKeyFunc() string {
if m.Id == 0 {
return ""
}
return fmt.Sprintf("%v:cache:%v:id:%v", domain.ProjectName, m.TableName(), m.Id)
}
func (m *UserSubscribe) CacheKeyFuncByObject(obj interface{}) string {
if v, ok := obj.(*UserSubscribe); ok {
return v.CacheKeyFunc()
}
return ""
}
func (m *UserSubscribe) CachePrimaryKeyFunc() string {
if len("") == 0 {
return ""
}
return fmt.Sprintf("%v:cache:%v:primarykey:%v", domain.ProjectName, m.TableName(), "key")
}
... ...
package models
import (
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
"gorm.io/gorm"
"gorm.io/plugin/soft_delete"
)
type UserWechat struct {
Id int64 `json:"id"` // 唯一标识
OpenId string `json:"openId"` // 微信openId
Phone string `json:"phone" gorm:"unique"` // 微信手机号
CreatedAt int64 `json:",omitempty"` // 创建时间
UpdatedAt int64 `json:",omitempty"` // 更新时间
DeletedAt int64 `json:",omitempty"` // 删除时间
Version int `json:",omitempty"` // 版本
IsDel soft_delete.DeletedAt `gorm:"softDelete:flag,DeletedAtField:DeletedAt"` // 删除标记
}
func (m *UserWechat) TableName() string {
return "user_wechat"
}
func (m *UserWechat) BeforeCreate(tx *gorm.DB) (err error) {
// m.CreatedAt = time.Now().Unix()
// m.UpdatedAt = time.Now().Unix()
return
}
func (m *UserWechat) BeforeUpdate(tx *gorm.DB) (err error) {
// m.UpdatedAt = time.Now().Unix()
return
}
func (m *UserWechat) CacheKeyFunc() string {
if m.Id == 0 {
return ""
}
return fmt.Sprintf("%v:cache:%v:id:%v", domain.ProjectName, m.TableName(), m.Id)
}
func (m *UserWechat) CacheKeyFuncByObject(obj interface{}) string {
if v, ok := obj.(*UserWechat); ok {
return v.CacheKeyFunc()
}
return ""
}
func (m *UserWechat) CachePrimaryKeyFunc() string {
if len("") == 0 {
return ""
}
return fmt.Sprintf("%v:cache:%v:primarykey:%v", domain.ProjectName, m.TableName(), "key")
}
... ...
... ... @@ -437,6 +437,28 @@ func (repository *ArticleCommentRepository) CustomSearchBy(ctx context.Context,
}
// CommentUserCount 统计评论人数
func (repository *ArticleCommentRepository) CommentUserCount(ctx context.Context, conn transaction.Conn, companyId int64, articleId int64) (int64, error) {
var (
err error
tx = conn.DB()
c int64
)
err = tx.Model(&models.ArticleComment{}).Where("company_id = ? and article_id = ?", companyId, articleId).Group("from_user_id").Count(&c).Error
return c, err
}
// ReplyUserCount 统计回复人数
func (repository *ArticleCommentRepository) ReplyUserCount(ctx context.Context, conn transaction.Conn, companyId int64, commentId int64) (int64, error) {
var (
err error
tx = conn.DB()
c int64
)
err = tx.Model(&models.ArticleComment{}).Where("company_id = ? and pid = ?", companyId, commentId).Group("from_user_id").Count(&c).Error
return c, err
}
func NewArticleCommentRepository(cache *cache.CachedRepository) domain.ArticleCommentRepository {
return &ArticleCommentRepository{CachedRepository: cache}
}
... ...
package repository
import (
"context"
"github.com/jinzhu/copier"
"github.com/pkg/errors"
"github.com/tiptok/gocomm/pkg/cache"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/models"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
"gorm.io/gorm"
)
type MessageSubscribeRepository struct {
*cache.CachedRepository
}
func (repository *MessageSubscribeRepository) Insert(ctx context.Context, conn transaction.Conn, dm *domain.MessageSubscribe) (*domain.MessageSubscribe, error) {
var (
err error
m = &models.MessageSubscribe{}
tx = conn.DB()
)
if m, err = repository.DomainModelToModel(dm); err != nil {
return nil, err
}
if tx = tx.Model(m).Save(m); tx.Error != nil {
return nil, tx.Error
}
dm.Id = m.Id
return repository.ModelToDomainModel(m)
}
func (repository *MessageSubscribeRepository) Update(ctx context.Context, conn transaction.Conn, dm *domain.MessageSubscribe) (*domain.MessageSubscribe, error) {
var (
err error
m *models.MessageSubscribe
tx = conn.DB()
)
if m, err = repository.DomainModelToModel(dm); err != nil {
return nil, err
}
queryFunc := func() (interface{}, error) {
tx = tx.Model(m).Select("*").Updates(m)
return nil, tx.Error
}
if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
return nil, err
}
return repository.ModelToDomainModel(m)
}
func (repository *MessageSubscribeRepository) UpdateWithVersion(ctx context.Context, transaction transaction.Conn, dm *domain.MessageSubscribe) (*domain.MessageSubscribe, error) {
var (
err error
m *models.MessageSubscribe
tx = transaction.DB()
)
if m, err = repository.DomainModelToModel(dm); err != nil {
return nil, err
}
oldVersion := dm.Version
m.Version += 1
queryFunc := func() (interface{}, error) {
tx = tx.Model(m).Select("*").Where("id = ?", m.Id).Where("version = ?", oldVersion).Updates(m)
if tx.RowsAffected == 0 {
return nil, domain.ErrUpdateFail
}
return nil, tx.Error
}
if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
return nil, err
}
return repository.ModelToDomainModel(m)
}
func (repository *MessageSubscribeRepository) Delete(ctx context.Context, conn transaction.Conn, dm *domain.MessageSubscribe) (*domain.MessageSubscribe, error) {
var (
tx = conn.DB()
m = &models.MessageSubscribe{Id: dm.Identify().(int64)}
)
queryFunc := func() (interface{}, error) {
tx = tx.Where("id = ?", m.Id).Delete(m)
return m, tx.Error
}
if _, err := repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
return dm, err
}
return repository.ModelToDomainModel(m)
}
func (repository *MessageSubscribeRepository) FindOne(ctx context.Context, conn transaction.Conn, id int64) (*domain.MessageSubscribe, error) {
var (
err error
tx = conn.DB()
m = new(models.MessageSubscribe)
)
queryFunc := func() (interface{}, error) {
tx = tx.Model(m).Where("id = ?", id).First(m)
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, domain.ErrNotFound
}
return m, tx.Error
}
cacheModel := new(models.MessageSubscribe)
cacheModel.Id = id
if err = repository.QueryCache(cacheModel.CacheKeyFunc, m, queryFunc); err != nil {
return nil, err
}
return repository.ModelToDomainModel(m)
}
func (repository *MessageSubscribeRepository) Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*domain.MessageSubscribe, error) {
var (
tx = conn.DB()
ms []*models.MessageSubscribe
dms = make([]*domain.MessageSubscribe, 0)
total int64
)
queryFunc := func() (interface{}, error) {
tx = tx.Model(&ms).Order("id desc")
if total, tx = transaction.PaginationAndCount(ctx, tx, queryOptions, &ms); tx.Error != nil {
return dms, tx.Error
}
return dms, nil
}
if _, err := repository.Query(queryFunc); err != nil {
return 0, nil, err
}
for _, item := range ms {
if dm, err := repository.ModelToDomainModel(item); err != nil {
return 0, dms, err
} else {
dms = append(dms, dm)
}
}
return total, dms, nil
}
func (repository *MessageSubscribeRepository) ModelToDomainModel(from *models.MessageSubscribe) (*domain.MessageSubscribe, error) {
to := &domain.MessageSubscribe{}
err := copier.Copy(to, from)
return to, err
}
func (repository *MessageSubscribeRepository) DomainModelToModel(from *domain.MessageSubscribe) (*models.MessageSubscribe, error) {
to := &models.MessageSubscribe{}
err := copier.Copy(to, from)
return to, err
}
func NewMessageSubscribeRepository(cache *cache.CachedRepository) domain.MessageSubscribeRepository {
return &MessageSubscribeRepository{CachedRepository: cache}
}
... ...
... ... @@ -174,8 +174,13 @@ func (repository *UserRepository) Find(ctx context.Context, conn transaction.Con
tx.Where("position = ? ", v)
}
if v, ok := queryOptions["departmentId"]; ok {
// 未分组用户部门ID=0
if vi, okVi := v.(int64); okVi && vi == domain.DefaultDepartmentId {
tx.Where(fmt.Sprintf("departments = '[]'"))
} else {
tx.Where(fmt.Sprintf("departments @>'[%v]'", v))
}
}
if v, ok := queryOptions["roleId"]; ok {
tx.Where(fmt.Sprintf("roles @>'[%v]'", v))
}
... ...
package repository
import (
"context"
"github.com/jinzhu/copier"
"github.com/pkg/errors"
"github.com/tiptok/gocomm/pkg/cache"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/models"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
"gorm.io/gorm"
)
type UserSubscribeRepository struct {
*cache.CachedRepository
}
func (repository *UserSubscribeRepository) Insert(ctx context.Context, conn transaction.Conn, dm *domain.UserSubscribe) (*domain.UserSubscribe, error) {
var (
err error
m = &models.UserSubscribe{}
tx = conn.DB()
)
if m, err = repository.DomainModelToModel(dm); err != nil {
return nil, err
}
if tx = tx.Model(m).Save(m); tx.Error != nil {
return nil, tx.Error
}
dm.Id = m.Id
return repository.ModelToDomainModel(m)
}
func (repository *UserSubscribeRepository) Update(ctx context.Context, conn transaction.Conn, dm *domain.UserSubscribe) (*domain.UserSubscribe, error) {
var (
err error
m *models.UserSubscribe
tx = conn.DB()
)
if m, err = repository.DomainModelToModel(dm); err != nil {
return nil, err
}
queryFunc := func() (interface{}, error) {
tx = tx.Model(m).Select("*").Updates(m)
return nil, tx.Error
}
if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
return nil, err
}
return repository.ModelToDomainModel(m)
}
func (repository *UserSubscribeRepository) UpdateWithVersion(ctx context.Context, transaction transaction.Conn, dm *domain.UserSubscribe) (*domain.UserSubscribe, error) {
var (
err error
m *models.UserSubscribe
tx = transaction.DB()
)
if m, err = repository.DomainModelToModel(dm); err != nil {
return nil, err
}
oldVersion := dm.Version
m.Version += 1
queryFunc := func() (interface{}, error) {
tx = tx.Model(m).Select("*").Where("id = ?", m.Id).Where("version = ?", oldVersion).Updates(m)
if tx.RowsAffected == 0 {
return nil, domain.ErrUpdateFail
}
return nil, tx.Error
}
if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
return nil, err
}
return repository.ModelToDomainModel(m)
}
func (repository *UserSubscribeRepository) Delete(ctx context.Context, conn transaction.Conn, dm *domain.UserSubscribe) (*domain.UserSubscribe, error) {
var (
tx = conn.DB()
m = &models.UserSubscribe{Id: dm.Identify().(int64)}
)
queryFunc := func() (interface{}, error) {
tx = tx.Where("id = ?", m.Id).Delete(m)
return m, tx.Error
}
if _, err := repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
return dm, err
}
return repository.ModelToDomainModel(m)
}
func (repository *UserSubscribeRepository) FindOne(ctx context.Context, conn transaction.Conn, id int64) (*domain.UserSubscribe, error) {
var (
err error
tx = conn.DB()
m = new(models.UserSubscribe)
)
queryFunc := func() (interface{}, error) {
tx = tx.Model(m).Where("id = ?", id).First(m)
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, domain.ErrNotFound
}
return m, tx.Error
}
cacheModel := new(models.UserSubscribe)
cacheModel.Id = id
if err = repository.QueryCache(cacheModel.CacheKeyFunc, m, queryFunc); err != nil {
return nil, err
}
return repository.ModelToDomainModel(m)
}
func (repository *UserSubscribeRepository) FindOneByType(ctx context.Context, conn transaction.Conn, companyId, userId int64, mType int) (*domain.UserSubscribe, error) {
var (
err error
tx = conn.DB()
m = new(models.UserSubscribe)
)
queryFunc := func() (interface{}, error) {
tx = tx.Model(m).Where("company_id = ? and user_id = ? and type = ?", companyId, userId, mType).First(m)
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, domain.ErrNotFound
}
return m, tx.Error
}
cacheModel := new(models.UserSubscribe)
cacheModel.Id = m.Id
if err = repository.QueryCache(cacheModel.CacheKeyFunc, m, queryFunc); err != nil {
return nil, err
}
return repository.ModelToDomainModel(m)
}
func (repository *UserSubscribeRepository) Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*domain.UserSubscribe, error) {
var (
tx = conn.DB()
ms []*models.UserSubscribe
dms = make([]*domain.UserSubscribe, 0)
total int64
)
queryFunc := func() (interface{}, error) {
tx = tx.Model(&ms).Order("id desc")
if v, ok := queryOptions["companyId"]; ok {
tx = tx.Where("company_id = ?", v)
}
if v, ok := queryOptions["userId"]; ok {
tx = tx.Where("user_id = ?", v)
}
if total, tx = transaction.PaginationAndCount(ctx, tx, queryOptions, &ms); tx.Error != nil {
return dms, tx.Error
}
return dms, nil
}
if _, err := repository.Query(queryFunc); err != nil {
return 0, nil, err
}
for _, item := range ms {
if dm, err := repository.ModelToDomainModel(item); err != nil {
return 0, dms, err
} else {
dms = append(dms, dm)
}
}
return total, dms, nil
}
func (repository *UserSubscribeRepository) ModelToDomainModel(from *models.UserSubscribe) (*domain.UserSubscribe, error) {
to := &domain.UserSubscribe{}
err := copier.Copy(to, from)
return to, err
}
func (repository *UserSubscribeRepository) DomainModelToModel(from *domain.UserSubscribe) (*models.UserSubscribe, error) {
to := &models.UserSubscribe{}
err := copier.Copy(to, from)
return to, err
}
func NewUserSubscribeRepository(cache *cache.CachedRepository) domain.UserSubscribeRepository {
return &UserSubscribeRepository{CachedRepository: cache}
}
... ...
package repository
import (
"context"
"github.com/jinzhu/copier"
"github.com/pkg/errors"
"github.com/tiptok/gocomm/pkg/cache"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/models"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
"gorm.io/gorm"
)
type UserWechatRepository struct {
*cache.CachedRepository
}
func (repository *UserWechatRepository) Insert(ctx context.Context, conn transaction.Conn, dm *domain.UserWechat) (*domain.UserWechat, error) {
var (
err error
m = &models.UserWechat{}
tx = conn.DB()
)
if m, err = repository.DomainModelToModel(dm); err != nil {
return nil, err
}
if tx = tx.Model(m).Save(m); tx.Error != nil {
return nil, tx.Error
}
dm.Id = m.Id
return repository.ModelToDomainModel(m)
}
func (repository *UserWechatRepository) Update(ctx context.Context, conn transaction.Conn, dm *domain.UserWechat) (*domain.UserWechat, error) {
var (
err error
m *models.UserWechat
tx = conn.DB()
)
if m, err = repository.DomainModelToModel(dm); err != nil {
return nil, err
}
queryFunc := func() (interface{}, error) {
tx = tx.Model(m).Updates(m)
return nil, tx.Error
}
if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
return nil, err
}
return repository.ModelToDomainModel(m)
}
func (repository *UserWechatRepository) UpdateWithVersion(ctx context.Context, transaction transaction.Conn, dm *domain.UserWechat) (*domain.UserWechat, error) {
var (
err error
m *models.UserWechat
tx = transaction.DB()
)
if m, err = repository.DomainModelToModel(dm); err != nil {
return nil, err
}
oldVersion := dm.Version
m.Version += 1
queryFunc := func() (interface{}, error) {
tx = tx.Model(m).Select("*").Where("id = ?", m.Id).Where("version = ?", oldVersion).Updates(m)
if tx.RowsAffected == 0 {
return nil, domain.ErrUpdateFail
}
return nil, tx.Error
}
if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
return nil, err
}
return repository.ModelToDomainModel(m)
}
func (repository *UserWechatRepository) Delete(ctx context.Context, conn transaction.Conn, dm *domain.UserWechat) (*domain.UserWechat, error) {
var (
tx = conn.DB()
m = &models.UserWechat{Id: dm.Identify().(int64)}
)
queryFunc := func() (interface{}, error) {
tx = tx.Where("id = ?", m.Id).Delete(m)
return m, tx.Error
}
if _, err := repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
return dm, err
}
return repository.ModelToDomainModel(m)
}
func (repository *UserWechatRepository) FindOne(ctx context.Context, conn transaction.Conn, id int64) (*domain.UserWechat, error) {
var (
err error
tx = conn.DB()
m = new(models.UserWechat)
)
queryFunc := func() (interface{}, error) {
tx = tx.Model(m).Where("id = ?", id).First(m)
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, domain.ErrNotFound
}
return m, tx.Error
}
cacheModel := new(models.UserWechat)
cacheModel.Id = id
if err = repository.QueryCache(cacheModel.CacheKeyFunc, m, queryFunc); err != nil {
return nil, err
}
return repository.ModelToDomainModel(m)
}
func (repository *UserWechatRepository) FindOneByPhone(ctx context.Context, conn transaction.Conn, phone string) (*domain.UserWechat, error) {
var (
err error
tx = conn.DB()
m = new(models.UserWechat)
)
queryFunc := func() (interface{}, error) {
tx = tx.Model(m).Where("phone = ?", phone).First(m)
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, domain.ErrNotFound
}
return m, tx.Error
}
cacheModel := new(models.UserWechat)
cacheModel.Id = m.Id
if err = repository.QueryCache(cacheModel.CacheKeyFunc, m, queryFunc); err != nil {
return nil, err
}
return repository.ModelToDomainModel(m)
}
func (repository *UserWechatRepository) Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*domain.UserWechat, error) {
var (
tx = conn.DB()
ms []*models.UserWechat
dms = make([]*domain.UserWechat, 0)
total int64
)
queryFunc := func() (interface{}, error) {
tx = tx.Model(&ms).Order("id desc")
if total, tx = transaction.PaginationAndCount(ctx, tx, queryOptions, &ms); tx.Error != nil {
return dms, tx.Error
}
return dms, nil
}
if _, err := repository.Query(queryFunc); err != nil {
return 0, nil, err
}
for _, item := range ms {
if dm, err := repository.ModelToDomainModel(item); err != nil {
return 0, dms, err
} else {
dms = append(dms, dm)
}
}
return total, dms, nil
}
func (repository *UserWechatRepository) ModelToDomainModel(from *models.UserWechat) (*domain.UserWechat, error) {
to := &domain.UserWechat{}
err := copier.Copy(to, from)
return to, err
}
func (repository *UserWechatRepository) DomainModelToModel(from *domain.UserWechat) (*models.UserWechat, error) {
to := &models.UserWechat{}
err := copier.Copy(to, from)
return to, err
}
func NewUserWechatRepository(cache *cache.CachedRepository) domain.UserWechatRepository {
return &UserWechatRepository{CachedRepository: cache}
}
... ...
... ... @@ -131,6 +131,15 @@ func (m *Article) SetSummary(sectionList []*ArticleSection) {
m.Summary = string(runeContent[0:length])
}
// GetSubscribeMessageTitle 获取订阅消息标题 超过20个字用...
func (m *Article) GetSubscribeMessageTitle() string {
runeContent := []rune(m.Title)
if len(runeContent) > 20 {
return string(runeContent[0:20]) + "..."
}
return m.Title
}
func (m *Article) WhoCanRead(userId int64) bool {
if m.AuthorId == userId {
return true
... ...
... ... @@ -3,11 +3,8 @@ package domain
import (
"bytes"
"context"
"encoding/json"
"fmt"
"sort"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction"
"reflect"
)
// 编辑文章后保存的历史记录
... ... @@ -51,93 +48,117 @@ func (bk *ArticleBackup) CheckChangeField(oldBackup *ArticleBackup) bool {
bk.ChangeField = make([]string, 0)
//比较 WhoRead
{
whoReadChanged := false
sort.Slice(bk.WhoRead, func(i, j int) bool {
return bk.WhoRead[i] < bk.WhoRead[j]
})
sort.Slice(oldBackup.WhoRead, func(i, j int) bool {
return oldBackup.WhoRead[i] < oldBackup.WhoRead[j]
})
if len(bk.WhoRead) != len(oldBackup.WhoRead) {
whoReadChanged = true
} else {
for i := range bk.WhoRead {
if bk.WhoRead[i] != oldBackup.WhoRead[i] {
whoReadChanged = true
}
}
}
if whoReadChanged {
//whoReadChanged := false
//sort.Slice(bk.WhoRead, func(i, j int) bool {
// return bk.WhoRead[i] < bk.WhoRead[j]
//})
//sort.Slice(oldBackup.WhoRead, func(i, j int) bool {
// return oldBackup.WhoRead[i] < oldBackup.WhoRead[j]
//})
//
//if len(bk.WhoRead) != len(oldBackup.WhoRead) {
// whoReadChanged = true
//} else {
// for i := range bk.WhoRead {
// if bk.WhoRead[i] != oldBackup.WhoRead[i] {
// whoReadChanged = true
// }
// }
//}
//if whoReadChanged {
// bk.ChangeField = append(bk.ChangeField, "WhoRead")
//}
if !reflect.DeepEqual(oldBackup.WhoRead, bk.WhoRead) {
bk.ChangeField = append(bk.ChangeField, "WhoRead")
}
}
//比较 whoReview
{
whoReviewChanged := false
sort.Slice(bk.WhoReview, func(i, j int) bool {
return bk.WhoReview[i] < bk.WhoReview[j]
})
sort.Slice(oldBackup.WhoReview, func(i, j int) bool {
return oldBackup.WhoReview[i] < oldBackup.WhoReview[j]
})
if len(bk.WhoReview) != len(oldBackup.WhoReview) {
whoReviewChanged = true
} else {
for i := range bk.WhoReview {
if bk.WhoReview[i] != oldBackup.WhoReview[i] {
whoReviewChanged = true
}
}
}
if whoReviewChanged {
//whoReviewChanged := false
//sort.Slice(bk.WhoReview, func(i, j int) bool {
// return bk.WhoReview[i] < bk.WhoReview[j]
//})
//sort.Slice(oldBackup.WhoReview, func(i, j int) bool {
// return oldBackup.WhoReview[i] < oldBackup.WhoReview[j]
//})
//
//if len(bk.WhoReview) != len(oldBackup.WhoReview) {
// whoReviewChanged = true
//} else {
// for i := range bk.WhoReview {
// if bk.WhoReview[i] != oldBackup.WhoReview[i] {
// whoReviewChanged = true
// }
// }
//}
//if whoReviewChanged {
// bk.ChangeField = append(bk.ChangeField, "WhoReview")
//}
if !reflect.DeepEqual(oldBackup.WhoReview, bk.WhoReview) {
bk.ChangeField = append(bk.ChangeField, "WhoReview")
}
}
//比较段落内容+图片+视频 是否发生变更
{
sectionChanged := false
newSectionData := map[string]string{
"title": bk.Title,
//sectionChanged := false
//newSectionData := map[string]string{
// "title": bk.Title,
//}
//
//oldSectionData := map[string]string{
// "title": oldBackup.Title,
//}
//
//for _, val := range bk.Section {
// mkey := fmt.Sprintf("section-%d", val.SortBy)
// newSectionData[mkey] = val.Content
//}
//for _, val := range bk.Images {
// newSectionData[val.Url] = ""
//}
//for _, val := range bk.Videos {
// newSectionData[val.Url] = ""
//}
//
//for _, val := range oldBackup.Section {
// mKey := fmt.Sprintf("section-%d", val.SortBy)
// oldSectionData[mKey] = val.Content
//}
//for _, val := range oldBackup.Images {
// oldSectionData[val.Url] = ""
//}
//for _, val := range oldBackup.Videos {
// oldSectionData[val.Url] = ""
//}
//newSectionJson, _ := json.Marshal(newSectionData)
//oldSectionJson, _ := json.Marshal(oldSectionData)
//if ok := bytes.Equal(newSectionJson, oldSectionJson); !ok {
// sectionChanged = true
//}
//if sectionChanged {
// bk.ChangeField = append(bk.ChangeField, "Section")
//}
if !reflect.DeepEqual(backUpContent(bk), backUpContent(oldBackup)) {
bk.ChangeField = append(bk.ChangeField, "Section")
}
oldSectionData := map[string]string{
"title": oldBackup.Title,
}
return len(bk.ChangeField) > 0
}
for _, val := range bk.Section {
mkey := fmt.Sprintf("section-%d", val.SortBy)
newSectionData[mkey] = val.Content
}
func backUpContent(bk *ArticleBackup) string {
buf := bytes.NewBuffer(nil)
buf.WriteString(bk.Title)
for _, val := range bk.Images {
newSectionData[val.Url] = ""
buf.WriteString(val.Url)
}
for _, val := range bk.Videos {
newSectionData[val.Url] = ""
}
for _, val := range oldBackup.Section {
mKey := fmt.Sprintf("section-%d", val.SortBy)
oldSectionData[mKey] = val.Content
}
for _, val := range oldBackup.Images {
oldSectionData[val.Url] = ""
}
for _, val := range oldBackup.Videos {
oldSectionData[val.Url] = ""
}
newSectionJson, _ := json.Marshal(newSectionData)
oldSectionJson, _ := json.Marshal(oldSectionData)
if ok := bytes.Equal(newSectionJson, oldSectionJson); !ok {
sectionChanged = true
}
if sectionChanged {
bk.ChangeField = append(bk.ChangeField, "Section")
buf.WriteString(val.Url)
}
for _, val := range bk.Section {
buf.WriteString(val.Content)
}
return len(bk.ChangeField) > 0
return buf.String()
}
// 创建备份信息
... ...
... ... @@ -80,6 +80,10 @@ type ArticleCommentRepository interface {
// 特定的查询
CustomSearchBy(ctx context.Context, conn transaction.Conn, companyId int64, page int, size int,
topId int64, articleTitle string, contentLike string, fromUserId int64, show int, createdAtRange [2]int64) (int, []*ArticleCommentShow, error)
// CommentUserCount 统计帖子评论人数
CommentUserCount(ctx context.Context, conn transaction.Conn, companyId int64, articleId int64) (int64, error)
// ReplyUserCount 统计评论回复人数
ReplyUserCount(ctx context.Context, conn transaction.Conn, companyId int64, commentId int64) (int64, error)
}
// 运营点数 填写的最大值
... ... @@ -92,3 +96,12 @@ func (m *ArticleComment) MaxCountAdminLove(articleWhoRead int) int {
}
return x
}
// GetSubscribeMessageContent 获取订阅消息评论内容 最多显示20个字,超出用...
func (m *ArticleComment) GetSubscribeMessageContent() string {
runeContent := []rune(m.Content)
if len(runeContent) > 20 {
return string(runeContent[0:20]) + "..."
}
return m.Content
}
... ...
... ... @@ -31,3 +31,5 @@ func (m *Department) Identify() interface{} {
}
return m.Id
}
const DefaultDepartmentId = -1
... ...
package domain
import (
"context"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction"
"gorm.io/plugin/soft_delete"
)
type MessageSubscribe struct {
Id int64 `json:"id"` // 唯一标识
Type int `json:"type"` // 分类(1评论回复 2获赞 3关注人更新)
CompanyId int64 `json:"companyId"` // 公司ID
UserId int64 `json:"userId"` // 用户ID
OpenId string `json:"openId"` // 微信openID
TemplateId string `json:"templateId"` // 模板ID
TemplateData map[string]interface{} `json:"templateData"` // 模板参数
Result string `json:"result"` // 发送结果
Error string `json:"error"` // 调用接口错误信息
CreatedAt int64 `json:",omitempty"` // 创建时间
UpdatedAt int64 `json:",omitempty"` // 更新时间
DeletedAt int64 `json:",omitempty"` // 删除时间
Version int `json:",omitempty"` // 版本
IsDel soft_delete.DeletedAt `gorm:"softDelete:flag,DeletedAtField:DeletedAt"` // 删除标记
}
var (
SubscribeTypeReplyComment = 1 // 评论回复
SubscribeTypeLike = 2 // 点赞
SubscribeTypeFollow = 3 // 关注人更新
SubscribeTemplateComment = "DxnQTZVHKrH7TOJiV-tK9w72hbkfLM87eXzhVy4cyhE" // 订阅消息 评论提醒
SubscribeTemplateLike = "oRdUINwfMK5_4ok_3lNgpkKT_SJqyGOvP4ZDgdsea9E" // 订阅消息 动态点赞通知
SubscribeTemplateFollow = "XdS11h2ZGGByzu-wMd16KxJ-LPjZy0yxZDmgQaVfDHE" // 订阅消息 关注更新提醒
)
type MessageSubscribeRepository interface {
Insert(ctx context.Context, conn transaction.Conn, dm *MessageSubscribe) (*MessageSubscribe, error)
Update(ctx context.Context, conn transaction.Conn, dm *MessageSubscribe) (*MessageSubscribe, error)
UpdateWithVersion(ctx context.Context, conn transaction.Conn, dm *MessageSubscribe) (*MessageSubscribe, error)
Delete(ctx context.Context, conn transaction.Conn, dm *MessageSubscribe) (*MessageSubscribe, error)
FindOne(ctx context.Context, conn transaction.Conn, id int64) (*MessageSubscribe, error)
Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*MessageSubscribe, error)
}
func (m *MessageSubscribe) Identify() interface{} {
if m.Id == 0 {
return nil
}
return m.Id
}
... ...
... ... @@ -151,6 +151,7 @@ type (
PhonePasswordLogin(phone string, password string) (*LoginInfo, error)
PhoneSmsCodeLogin(phone string, code string) (*LoginInfo, error)
WechatPhoneLogin(r WechatLoginRequest) (*LoginInfo, error)
GetOpenId(r WechatLoginRequest) (string, error)
}
WechatLoginRequest struct {
Code string // 授权码
... ...
package domain
import (
"context"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction"
"gorm.io/plugin/soft_delete"
)
type UserSubscribe struct {
Id int64 `json:"id"` // 唯一标识
Type int `json:"type"` // 分类(1评论回复 2获赞 3关注人更新)
CompanyId int64 `json:"companyId"` // 公司ID
UserId int64 `json:"userId"` // 用户ID
Count int `json:"count"` // 订阅次数
CreatedAt int64 `json:",omitempty"` // 创建时间
UpdatedAt int64 `json:",omitempty"` // 更新时间
DeletedAt int64 `json:",omitempty"` // 删除时间
Version int `json:",omitempty"` // 版本
IsDel soft_delete.DeletedAt `gorm:"softDelete:flag,DeletedAtField:DeletedAt"` // 删除标记
}
type UserSubscribeRepository interface {
Insert(ctx context.Context, conn transaction.Conn, dm *UserSubscribe) (*UserSubscribe, error)
Update(ctx context.Context, conn transaction.Conn, dm *UserSubscribe) (*UserSubscribe, error)
UpdateWithVersion(ctx context.Context, conn transaction.Conn, dm *UserSubscribe) (*UserSubscribe, error)
Delete(ctx context.Context, conn transaction.Conn, dm *UserSubscribe) (*UserSubscribe, error)
FindOne(ctx context.Context, conn transaction.Conn, id int64) (*UserSubscribe, error)
FindOneByType(ctx context.Context, conn transaction.Conn, companyId, userId int64, mType int) (*UserSubscribe, error)
Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*UserSubscribe, error)
}
func (m *UserSubscribe) Identify() interface{} {
if m.Id == 0 {
return nil
}
return m.Id
}
... ...
package domain
import (
"context"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction"
"gorm.io/plugin/soft_delete"
)
type UserWechat struct {
Id int64 `json:"id"` // 唯一标识
OpenId string `json:"openId"` // 微信openId
Phone string `json:"phone"` // 微信手机号
CreatedAt int64 `json:",omitempty"` // 创建时间
UpdatedAt int64 `json:",omitempty"` // 更新时间
DeletedAt int64 `json:",omitempty"` // 删除时间
Version int `json:",omitempty"` // 版本
IsDel soft_delete.DeletedAt `gorm:"softDelete:flag,DeletedAtField:DeletedAt"` // 删除标记
}
type UserWechatRepository interface {
Insert(ctx context.Context, conn transaction.Conn, dm *UserWechat) (*UserWechat, error)
Update(ctx context.Context, conn transaction.Conn, dm *UserWechat) (*UserWechat, error)
UpdateWithVersion(ctx context.Context, conn transaction.Conn, dm *UserWechat) (*UserWechat, error)
Delete(ctx context.Context, conn transaction.Conn, dm *UserWechat) (*UserWechat, error)
FindOne(ctx context.Context, conn transaction.Conn, id int64) (*UserWechat, error)
FindOneByPhone(ctx context.Context, conn transaction.Conn, phone string) (*UserWechat, error)
Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*UserWechat, error)
}
func (m *UserWechat) Identify() interface{} {
if m.Id == 0 {
return nil
}
return m.Id
}
... ...
CREATE TABLE `department` (
CREATE TABLE `department`
(
`id` int(0) NOT NULL COMMENT '唯一标识',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
CREATE TABLE `role` (
CREATE TABLE `role`
(
`id` int(0) NOT NULL COMMENT '唯一标识',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
CREATE TABLE `user` (
CREATE TABLE `user`
(
`id` int(0) NOT NULL COMMENT '唯一标识',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
CREATE TABLE `user_role` (
CREATE TABLE `user_role`
(
`id` int(0) NOT NULL COMMENT '唯一标识',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
CREATE TABLE `company` (
CREATE TABLE `company`
(
`id` int(0) NOT NULL COMMENT '唯一标识',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
CREATE TABLE `user_follow` (
CREATE TABLE `user_follow`
(
`id` int(0) NOT NULL COMMENT '唯一标识',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
CREATE TABLE `article_draft_operation` (
CREATE TABLE `article_draft_operation`
(
`id` int(0) NOT NULL COMMENT '唯一标识',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
CREATE TABLE `article_category` (
CREATE TABLE `article_category`
(
`id` int(0) NOT NULL COMMENT '唯一标识',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
CREATE TABLE `message_subscribe`
(
`id` int(0) NOT NULL COMMENT '唯一标识',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
CREATE TABLE `user_subscribe`
(
`id` int(0) NOT NULL COMMENT '唯一标识',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
CREATE TABLE `user_wechat`
(
`id` int(0) NOT NULL COMMENT '唯一标识',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
\ No newline at end of file
... ...