作者 yangfu

Merge branch 'dev' into test

@@ -33,12 +33,17 @@ func main() { @@ -33,12 +33,17 @@ func main() {
33 33
34 // 服务初始化 34 // 服务初始化
35 opts := make([]rest.RunOption, 0) 35 opts := make([]rest.RunOption, 0)
36 - opt := rest.WithCustomCors(func(header http.Header) { 36 + opts = append(opts, rest.WithCustomCors(func(header http.Header) {
37 header.Set("Access-Control-Allow-Headers", "*") 37 header.Set("Access-Control-Allow-Headers", "*")
38 }, func(writer http.ResponseWriter) { 38 }, func(writer http.ResponseWriter) {
39 39
40 - })  
41 - opts = append(opts, opt) 40 + }))
  41 + opts = append(opts, rest.WithUnauthorizedCallback(func(w http.ResponseWriter, r *http.Request, err error) {
  42 + if err != nil {
  43 + logx.Debugf("unauthorized: %s \n", err.Error())
  44 + }
  45 + }))
  46 +
42 server := rest.MustNewServer(c.RestConf, opts...) 47 server := rest.MustNewServer(c.RestConf, opts...)
43 defer server.Stop() 48 defer server.Stop()
44 ctx := svc.NewServiceContext(c) 49 ctx := svc.NewServiceContext(c)
@@ -73,6 +78,7 @@ func systemSetup(c config.Config) { @@ -73,6 +78,7 @@ func systemSetup(c config.Config) {
73 httpx.SetErrorHandlerCtx(func(ctx context.Context, err error) (int, any) { 78 httpx.SetErrorHandlerCtx(func(ctx context.Context, err error) (int, any) {
74 return http.StatusOK, result.Error(xerr.ServerCommonError, err.Error()) 79 return http.StatusOK, result.Error(xerr.ServerCommonError, err.Error())
75 }) 80 })
  81 +
76 // 系统成功应答包装 82 // 系统成功应答包装
77 httpx.SetOkHandler(func(ctx context.Context, a any) any { 83 httpx.SetOkHandler(func(ctx context.Context, a any) any {
78 return result.Success(a) 84 return result.Success(a)
@@ -10,13 +10,17 @@ info( @@ -10,13 +10,17 @@ info(
10 10
11 // 通用接口 11 // 通用接口
12 @server( 12 @server(
13 - prefix: v1/common 13 + prefix: v1
14 group: common 14 group: common
15 ) 15 )
16 service Core { 16 service Core {
17 @doc "短信验证码" 17 @doc "短信验证码"
18 @handler commonSmsCode 18 @handler commonSmsCode
19 - post /sms/code (CommonSmsCodeRequest) returns (CommonSmsCodeResposne) 19 + post /common/sms/code (CommonSmsCodeRequest) returns (CommonSmsCodeResposne)
  20 +
  21 + @doc "日志查询"
  22 + @handler commonGetLog
  23 + get /log/:module
20 } 24 }
21 25
22 // 短信验证码 26 // 短信验证码
@@ -108,7 +108,7 @@ type( @@ -108,7 +108,7 @@ type(
108 IsFromQr bool `json:"isFromQr,optional"` // true:扫码添加 false:手动查找添加 108 IsFromQr bool `json:"isFromQr,optional"` // true:扫码添加 false:手动查找添加
109 } 109 }
110 MiniUserApplyJoinCompanyResponse{ 110 MiniUserApplyJoinCompanyResponse{
111 - 111 + Token string `json:"token"` // x-token
112 } 112 }
113 MiniUserAuditRequest{ 113 MiniUserAuditRequest{
114 UserId int64 `json:"userId"` // 用户ID 114 UserId int64 `json:"userId"` // 用户ID
@@ -160,6 +160,7 @@ type( @@ -160,6 +160,7 @@ type(
160 CompanyId int64 `json:"companyId,omitempty"` // 公司ID 160 CompanyId int64 `json:"companyId,omitempty"` // 公司ID
161 CompanyName string `json:"companyName,omitempty"` // 公司名称 161 CompanyName string `json:"companyName,omitempty"` // 公司名称
162 CompanyCode string `json:"companyCode,omitempty"` // 公司编码(邀请码) 162 CompanyCode string `json:"companyCode,omitempty"` // 公司编码(邀请码)
  163 + CompanyLogo *string `json:"companyLogo,omitempty"` // 公司LOGO
163 //DepartmentId int64 `json:"departmentId,omitempty"` // 部门ID 164 //DepartmentId int64 `json:"departmentId,omitempty"` // 部门ID
164 //Roles []int64 `json:"roleId,omitempty"` // 角色 165 //Roles []int64 `json:"roleId,omitempty"` // 角色
165 Flag int `json:"flag,omitempty"` // 标识 1:管理员 2:普通用户 (有绑定角色是管理员) 166 Flag int `json:"flag,omitempty"` // 标识 1:管理员 2:普通用户 (有绑定角色是管理员)
@@ -7,7 +7,7 @@ Timeout: 30000 @@ -7,7 +7,7 @@ Timeout: 30000
7 # CertFile: ./key/fjmaimaimai.com_bundle.crt 7 # CertFile: ./key/fjmaimaimai.com_bundle.crt
8 # KeyFile: ./key/fjmaimaimai.com.key 8 # KeyFile: ./key/fjmaimaimai.com.key
9 Log: 9 Log:
10 - #Mode: file 10 + Mode: file
11 Encoding: plain 11 Encoding: plain
12 Level: debug # info 12 Level: debug # info
13 MaxSize: 1 # 2MB 13 MaxSize: 1 # 2MB
@@ -15,6 +15,7 @@ type Config struct { @@ -15,6 +15,7 @@ type Config struct {
15 MiniAuth config.Auth 15 MiniAuth config.Auth
16 Migrate bool `json:",optional,default=true"` 16 Migrate bool `json:",optional,default=true"`
17 ApiAuth ApiService 17 ApiAuth ApiService
  18 + DebugSmsCode string `json:",optional,default=999512"`
18 } 19 }
19 20
20 type ApiService struct { 21 type ApiService struct {
  1 +package common
  2 +
  3 +import (
  4 + "net/http"
  5 + "path/filepath"
  6 + "strings"
  7 +
  8 + "github.com/zeromicro/go-zero/rest/httpx"
  9 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
  10 +)
  11 +
  12 +func CommonGetLogHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
  13 + return func(w http.ResponseWriter, r *http.Request) {
  14 + var req struct {
  15 + Module string `path:"module"`
  16 + }
  17 + if err := httpx.Parse(r, &req); err != nil {
  18 + httpx.ErrorCtx(r.Context(), w, err)
  19 + return
  20 + }
  21 + path := svcCtx.Config.Log.Path
  22 + if svcCtx.Config.Log.Mode != "file" {
  23 + return
  24 + }
  25 + if path == "" {
  26 + path = "logs"
  27 + }
  28 + if !strings.HasSuffix(req.Module, ".log") {
  29 + req.Module += ".log"
  30 + }
  31 + handler := http.FileServer(http.Dir(path))
  32 + r.URL.Path = filepath.Join(req.Module)
  33 + handler.ServeHTTP(w, r)
  34 + }
  35 +}
@@ -23,11 +23,16 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { @@ -23,11 +23,16 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
23 []rest.Route{ 23 []rest.Route{
24 { 24 {
25 Method: http.MethodPost, 25 Method: http.MethodPost,
26 - Path: "/sms/code", 26 + Path: "/common/sms/code",
27 Handler: common.CommonSmsCodeHandler(serverCtx), 27 Handler: common.CommonSmsCodeHandler(serverCtx),
28 }, 28 },
  29 + {
  30 + Method: http.MethodGet,
  31 + Path: "/log/:module",
  32 + Handler: common.CommonGetLogHandler(serverCtx),
29 }, 33 },
30 - rest.WithPrefix("/v1/common"), 34 + },
  35 + rest.WithPrefix("/v1"),
31 ) 36 )
32 37
33 server.AddRoutes( 38 server.AddRoutes(
  1 +package common
  2 +
  3 +import (
  4 + "context"
  5 +
  6 + "github.com/zeromicro/go-zero/core/logx"
  7 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
  8 +)
  9 +
  10 +type CommonGetLogLogic struct {
  11 + logx.Logger
  12 + ctx context.Context
  13 + svcCtx *svc.ServiceContext
  14 +}
  15 +
  16 +func NewCommonGetLogLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CommonGetLogLogic {
  17 + return &CommonGetLogLogic{
  18 + Logger: logx.WithContext(ctx),
  19 + ctx: ctx,
  20 + svcCtx: svcCtx,
  21 + }
  22 +}
  23 +
  24 +func (l *CommonGetLogLogic) CommonGetLog() error {
  25 + // todo: add your logic here and delete this line
  26 +
  27 + return nil
  28 +}
@@ -32,7 +32,9 @@ func (l *MiniBusinessLogic) MiniBusiness(req *types.MessageRequest, msgType doma @@ -32,7 +32,9 @@ func (l *MiniBusinessLogic) MiniBusiness(req *types.MessageRequest, msgType doma
32 32
33 total, list, err := l.svcCtx.MessageBusinessRepository.Find(l.ctx, conn, domain.NewQueryOptions(). 33 total, list, err := l.svcCtx.MessageBusinessRepository.Find(l.ctx, conn, domain.NewQueryOptions().
34 WithOffsetLimit(req.Page, req.Size). 34 WithOffsetLimit(req.Page, req.Size).
35 - WithKV("type", msgType)) 35 + WithKV("type", msgType).
  36 + WithKV("companyId", userToken.CompanyId).
  37 + WithKV("recipientId", userToken.UserId))
36 if err != nil { 38 if err != nil {
37 return nil, err 39 return nil, err
38 } 40 }
  1 +package message
  2 +
  3 +import (
  4 + "context"
  5 +
  6 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
  7 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types"
  8 +
  9 + "github.com/zeromicro/go-zero/core/logx"
  10 +)
  11 +
  12 +type MiniCommentLogic struct {
  13 + logx.Logger
  14 + ctx context.Context
  15 + svcCtx *svc.ServiceContext
  16 +}
  17 +
  18 +func NewMiniCommentLogic(ctx context.Context, svcCtx *svc.ServiceContext) *MiniCommentLogic {
  19 + return &MiniCommentLogic{
  20 + Logger: logx.WithContext(ctx),
  21 + ctx: ctx,
  22 + svcCtx: svcCtx,
  23 + }
  24 +}
  25 +
  26 +func (l *MiniCommentLogic) MiniComment(req *types.MessageRequest) (resp *types.MessageBusinessResponse, err error) {
  27 + // todo: add your logic here and delete this line
  28 +
  29 + return
  30 +}
  1 +package message
  2 +
  3 +import (
  4 + "context"
  5 +
  6 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
  7 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types"
  8 +
  9 + "github.com/zeromicro/go-zero/core/logx"
  10 +)
  11 +
  12 +type MiniLikeLogic struct {
  13 + logx.Logger
  14 + ctx context.Context
  15 + svcCtx *svc.ServiceContext
  16 +}
  17 +
  18 +func NewMiniLikeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *MiniLikeLogic {
  19 + return &MiniLikeLogic{
  20 + Logger: logx.WithContext(ctx),
  21 + ctx: ctx,
  22 + svcCtx: svcCtx,
  23 + }
  24 +}
  25 +
  26 +func (l *MiniLikeLogic) MiniLike(req *types.MessageRequest) (resp *types.MessageBusinessResponse, err error) {
  27 + // todo: add your logic here and delete this line
  28 +
  29 + return
  30 +}
@@ -35,6 +35,7 @@ func (l *MiniUserApplyJoinCompanyLogic) MiniUserApplyJoinCompany(req *types.Mini @@ -35,6 +35,7 @@ func (l *MiniUserApplyJoinCompanyLogic) MiniUserApplyJoinCompany(req *types.Mini
35 company *domain.Company 35 company *domain.Company
36 user *domain.User 36 user *domain.User
37 name = fmt.Sprintf("用户%s", tool.Krand(6, tool.KC_RAND_KIND_NUM)) 37 name = fmt.Sprintf("用户%s", tool.Krand(6, tool.KC_RAND_KIND_NUM))
  38 + token string
38 ) 39 )
39 if company, err = l.svcCtx.CompanyRepository.FindOneByCode(l.ctx, conn, req.Code); err != nil { 40 if company, err = l.svcCtx.CompanyRepository.FindOneByCode(l.ctx, conn, req.Code); err != nil {
40 return nil, xerr.NewErrMsgErr("公司不存在", err) 41 return nil, xerr.NewErrMsgErr("公司不存在", err)
@@ -48,12 +49,14 @@ func (l *MiniUserApplyJoinCompanyLogic) MiniUserApplyJoinCompany(req *types.Mini @@ -48,12 +49,14 @@ func (l *MiniUserApplyJoinCompanyLogic) MiniUserApplyJoinCompany(req *types.Mini
48 return nil, xerr.NewErrMsgErr("申请失败", err) 49 return nil, xerr.NewErrMsgErr("申请失败", err)
49 } 50 }
50 if user != nil { 51 if user != nil {
51 - if user.AuditStatus == domain.UserAuditStatusWait {  
52 - return nil, xerr.NewErrMsgErr("已申请,待审核中", err) 52 + token, err = generateToken(l.svcCtx, user)
  53 + if err != nil {
  54 + return nil, xerr.NewErrMsgErr("登录失败", err)
53 } 55 }
54 - if user.AuditStatus == domain.UserAuditStatusPassed {  
55 - return nil, xerr.NewErrMsgErr("公司已申请", err) 56 + resp = &types.MiniUserApplyJoinCompanyResponse{
  57 + Token: token,
56 } 58 }
  59 + return
57 } 60 }
58 queryOptions := domain.NewQueryOptions(). 61 queryOptions := domain.NewQueryOptions().
59 WithOffsetLimit(1, 1). 62 WithOffsetLimit(1, 1).
@@ -87,6 +90,12 @@ func (l *MiniUserApplyJoinCompanyLogic) MiniUserApplyJoinCompany(req *types.Mini @@ -87,6 +90,12 @@ func (l *MiniUserApplyJoinCompanyLogic) MiniUserApplyJoinCompany(req *types.Mini
87 }, true); err != nil { 90 }, true); err != nil {
88 return nil, xerr.NewErrMsgErr("申请失败", err) 91 return nil, xerr.NewErrMsgErr("申请失败", err)
89 } 92 }
90 - resp = &types.MiniUserApplyJoinCompanyResponse{} 93 + token, err = generateToken(l.svcCtx, user)
  94 + if err != nil {
  95 + return nil, xerr.NewErrMsgErr("登录失败", err)
  96 + }
  97 + resp = &types.MiniUserApplyJoinCompanyResponse{
  98 + Token: token,
  99 + }
91 return 100 return
92 } 101 }
@@ -2,6 +2,7 @@ package user @@ -2,6 +2,7 @@ package user
2 2
3 import ( 3 import (
4 "context" 4 "context"
  5 + "github.com/samber/lo"
5 "github.com/zeromicro/go-zero/core/collection" 6 "github.com/zeromicro/go-zero/core/collection"
6 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain" 7 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
7 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/contextdata" 8 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/contextdata"
@@ -49,6 +50,8 @@ func (l *MiniUserInfoLogic) MiniUserInfo(req *types.MiniUserInfoRequest) (resp * @@ -49,6 +50,8 @@ func (l *MiniUserInfoLogic) MiniUserInfo(req *types.MiniUserInfoRequest) (resp *
49 Name: user.Name, 50 Name: user.Name,
50 Avatar: user.Avatar, 51 Avatar: user.Avatar,
51 Position: user.Position, 52 Position: user.Position,
  53 + AuditStatus: lo.ToPtr(user.AuditStatus),
  54 + Enable: user.Enable,
52 }, 55 },
53 Accounts: make([]types.Account, 0), 56 Accounts: make([]types.Account, 0),
54 Auths: make([]types.Auth, 0), 57 Auths: make([]types.Auth, 0),
@@ -56,6 +59,7 @@ func (l *MiniUserInfoLogic) MiniUserInfo(req *types.MiniUserInfoRequest) (resp * @@ -56,6 +59,7 @@ func (l *MiniUserInfoLogic) MiniUserInfo(req *types.MiniUserInfoRequest) (resp *
56 if company, _ := domain.LazyLoad(companyMap, l.ctx, conn, user.CompanyId, l.svcCtx.CompanyRepository.FindOne); company != nil { 59 if company, _ := domain.LazyLoad(companyMap, l.ctx, conn, user.CompanyId, l.svcCtx.CompanyRepository.FindOne); company != nil {
57 resp.User.CompanyName = company.Name 60 resp.User.CompanyName = company.Name
58 resp.User.CompanyCode = company.Code 61 resp.User.CompanyCode = company.Code
  62 + resp.User.CompanyLogo = lo.ToPtr(company.Logo)
59 } 63 }
60 _, accounts, err = l.svcCtx.UserRepository.Find(l.ctx, conn, domain.NewQueryOptions().MustWithKV("phone", user.Phone).MustWithKV("auditStatus", []int{domain.UserAuditStatusPassed})) 64 _, accounts, err = l.svcCtx.UserRepository.Find(l.ctx, conn, domain.NewQueryOptions().MustWithKV("phone", user.Phone).MustWithKV("auditStatus", []int{domain.UserAuditStatusPassed}))
61 if err != nil { 65 if err != nil {
@@ -53,13 +53,7 @@ func (l *MiniUserLoginLogic) MiniUserLogin(req *types.MiniUserLoginRequest) (res @@ -53,13 +53,7 @@ func (l *MiniUserLoginLogic) MiniUserLogin(req *types.MiniUserLoginRequest) (res
53 if loginInfo.User == nil { 53 if loginInfo.User == nil {
54 return nil, xerr.NewErrMsgErr("用户不存在", err) 54 return nil, xerr.NewErrMsgErr("用户不存在", err)
55 } 55 }
56 - var userJwtToken = tool.UserToken{}  
57 - if loginInfo.User != nil {  
58 - userJwtToken.UserId = loginInfo.User.Id  
59 - userJwtToken.CompanyId = loginInfo.User.CompanyId  
60 - userJwtToken.ClientType = "mini"  
61 - }  
62 - token, err = userJwtToken.GenerateToken(l.svcCtx.Config.MiniAuth.AccessSecret, l.svcCtx.Config.MiniAuth.AccessExpire) 56 + token, err = generateToken(l.svcCtx, loginInfo.User)
63 if err != nil { 57 if err != nil {
64 return nil, xerr.NewErrMsgErr("登录失败", err) 58 return nil, xerr.NewErrMsgErr("登录失败", err)
65 } 59 }
@@ -74,6 +68,20 @@ func (l *MiniUserLoginLogic) MiniUserLogin(req *types.MiniUserLoginRequest) (res @@ -74,6 +68,20 @@ func (l *MiniUserLoginLogic) MiniUserLogin(req *types.MiniUserLoginRequest) (res
74 return 68 return
75 } 69 }
76 70
  71 +func generateToken(svcCtx *svc.ServiceContext, user *domain.User) (token string, err error) {
  72 + var userJwtToken = tool.UserToken{}
  73 + if user != nil {
  74 + userJwtToken.UserId = user.Id
  75 + userJwtToken.CompanyId = user.CompanyId
  76 + userJwtToken.ClientType = "mini"
  77 + }
  78 + token, err = userJwtToken.GenerateToken(svcCtx.Config.MiniAuth.AccessSecret, svcCtx.Config.MiniAuth.AccessExpire)
  79 + if err != nil {
  80 + return "", xerr.NewErrMsgErr("登录失败", err)
  81 + }
  82 + return
  83 +}
  84 +
77 type WxClientLogin struct { 85 type WxClientLogin struct {
78 l *MiniUserLoginLogic 86 l *MiniUserLoginLogic
79 } 87 }
@@ -121,8 +129,12 @@ func (c WxClientLogin) PhoneSmsCodeLogin(phone string, code string) (*domain.Log @@ -121,8 +129,12 @@ func (c WxClientLogin) PhoneSmsCodeLogin(phone string, code string) (*domain.Log
121 var ( 129 var (
122 users []*domain.User 130 users []*domain.User
123 err error 131 err error
  132 + skipCheckSmsCode bool = false
124 ) 133 )
125 - if _, err = c.l.svcCtx.SmsService.CheckSmsCode(c.l.ctx, smslib.RequestCheckSmsCode{Phone: phone, Code: code}); err != nil { 134 + if c.l.svcCtx.Config.DebugSmsCode != "" && c.l.svcCtx.Config.DebugSmsCode == code {
  135 + skipCheckSmsCode = true
  136 + }
  137 + if _, err = c.l.svcCtx.SmsService.CheckSmsCode(c.l.ctx, smslib.RequestCheckSmsCode{Phone: phone, Code: code}); err != nil && !skipCheckSmsCode {
126 return nil, xerr.NewErrMsgErr(err.Error(), err) 138 return nil, xerr.NewErrMsgErr(err.Error(), err)
127 } 139 }
128 conn := c.l.svcCtx.DefaultDBConn() 140 conn := c.l.svcCtx.DefaultDBConn()
@@ -439,6 +439,7 @@ type MiniUserApplyJoinCompanyRequest struct { @@ -439,6 +439,7 @@ type MiniUserApplyJoinCompanyRequest struct {
439 } 439 }
440 440
441 type MiniUserApplyJoinCompanyResponse struct { 441 type MiniUserApplyJoinCompanyResponse struct {
  442 + Token string `json:"token"` // x-token
442 } 443 }
443 444
444 type MiniUserAuditRequest struct { 445 type MiniUserAuditRequest struct {
@@ -498,6 +499,7 @@ type UserItem struct { @@ -498,6 +499,7 @@ type UserItem struct {
498 CompanyId int64 `json:"companyId,omitempty"` // 公司ID 499 CompanyId int64 `json:"companyId,omitempty"` // 公司ID
499 CompanyName string `json:"companyName,omitempty"` // 公司名称 500 CompanyName string `json:"companyName,omitempty"` // 公司名称
500 CompanyCode string `json:"companyCode,omitempty"` // 公司编码(邀请码) 501 CompanyCode string `json:"companyCode,omitempty"` // 公司编码(邀请码)
  502 + CompanyLogo *string `json:"companyLogo,omitempty"` // 公司LOGO
501 Flag int `json:"flag,omitempty"` // 标识 1:管理员 2:普通用户 (有绑定角色是管理员) 503 Flag int `json:"flag,omitempty"` // 标识 1:管理员 2:普通用户 (有绑定角色是管理员)
502 Name string `json:"name,omitempty"` // 名称 504 Name string `json:"name,omitempty"` // 名称
503 Avatar string `json:"avatar,omitempty"` // 头像 505 Avatar string `json:"avatar,omitempty"` // 头像
  1 +-- 用户表
  2 +-- (公司ID)索引
  3 +CREATE INDEX IF NOT EXISTS idx_user_company_id ON "public"."user" USING btree(company_id);
  4 +
  5 +-- (手机号)索引
  6 +CREATE INDEX IF NOT EXISTS idx_user_phone ON "public"."user" USING btree(phone);
  7 +
  8 +-- 用户关注表
  9 +-- (发起人)索引
  10 +CREATE INDEX IF NOT EXISTS idx_user_follow_from_user_id ON "public".user_follow USING btree(from_user_id);
  11 +
  12 +-- 角色表
  13 +-- (公司ID)索引
  14 +CREATE INDEX IF NOT EXISTS idx_role_company_id ON "public"."role" USING btree(company_id);
  15 +
  16 +-- 文章表
  17 +-- (公司ID)索引
  18 +CREATE INDEX article_company_id_idx ON public.article USING btree(company_id);
  19 +
  20 +-- 文章与标签关系表
  21 +-- (公司ID)索引
  22 +CREATE INDEX article_and_tag_company_id_idx ON public.article_and_tag USING btree(company_id);
  23 +
  24 +-- 文章历史记录
  25 +-- (公司ID)索引
  26 +CREATE INDEX article_backup_company_id_idx ON public.article_backup USING btree(company_id);
  27 +
  28 +-- 文章的评论记录
  29 +-- (公司ID)索引
  30 +CREATE INDEX article_comment_company_id_idx ON public.article_comment USING btree(company_id);
  31 +
  32 +-- 文章的草稿箱记录
  33 +-- (公司ID)索引
  34 +CREATE INDEX article_draft_company_id_idx ON public.article_draft USING btree(company_id);
  35 +
  36 +-- 文章的段落内容
  37 +-- (公司ID)索引
  38 +CREATE INDEX article_section_company_id_idx ON public.article_section USING btree(company_id);
  39 +
  40 +-- 文章的段落内容
  41 +-- (文章ID)索引
  42 +CREATE INDEX article_section_article_id_idx ON public.article_section USING btree(article_id);
  43 +
  44 +-- 标签
  45 +-- (公司ID)索引
  46 +CREATE INDEX article_tag_company_id_idx ON public.article_tag USING btree(company_id);
  47 +
  48 +-- 人员点赞标识
  49 +-- (评论id)索引
  50 +CREATE INDEX user_love_flag_comment_id_idx ON public.user_love_flag USING btree(comment_id);
  51 +
  52 +-- 人员点赞标识
  53 +-- (用户id)索引
  54 +CREATE INDEX user_love_flag_user_id_idx ON public.user_love_flag USING btree(user_id);
  55 +
  56 +-- 标记人员已浏览的文章
  57 +-- (公司ID)索引
  58 +CREATE INDEX user_read_article_company_id_idx ON public.user_read_article USING btree(company_id);
  59 +
  60 +-- 标记人员已浏览的文章
  61 +-- (用户id)索引
  62 +CREATE INDEX user_read_article_user_id_idx ON public.user_read_article USING btree(user_id);
  63 +
  64 +
  65 +
  66 +-- 部门表
  67 +-- (公司ID)索引
  68 +CREATE INDEX IF NOT EXISTS idx_department_company_id ON "public"."department" USING btree(company_id);
  69 +
  70 +-- 系统消息表
  71 +-- (公司ID)索引
  72 +CREATE INDEX IF NOT EXISTS idx_message_system_company_id ON "public"."message_system" USING btree(company_id);
  73 +
  74 +-- 业务消息表
  75 +-- (公司ID)索引
  76 +CREATE INDEX IF NOT EXISTS idx_message_business_company_id ON "public"."message_business" USING btree(company_id);