作者 yangfu

Merge branch 'dev'

# Conflicts:
#	cmd/chart-server/api/etc/core.yaml
正在显示 66 个修改的文件 包含 3186 行增加122 行删除
@@ -24,6 +24,7 @@ _testmain.go @@ -24,6 +24,7 @@ _testmain.go
24 .log 24 .log
25 .idea 25 .idea
26 .vscode 26 .vscode
  27 +cmd/chart-server/api/go_build_bchart
27 28
28 app.log 29 app.log
29 #go.sum 30 #go.sum
@@ -6,6 +6,8 @@ ARG PROJECT=core @@ -6,6 +6,8 @@ ARG PROJECT=core
6 WORKDIR /build 6 WORKDIR /build
7 COPY . . 7 COPY . .
8 8
  9 +RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
  10 +RUN apk update --no-cache && apk add --no-cache tzdata
9 RUN go env -w GO111MODULE=on \ 11 RUN go env -w GO111MODULE=on \
10 && go env -w GOPROXY=https://goproxy.cn,direct \ 12 && go env -w GOPROXY=https://goproxy.cn,direct \
11 && go env -w CGO_ENABLED=0 \ 13 && go env -w CGO_ENABLED=0 \
@@ -28,7 +30,9 @@ LABEL org.opencontainers.image.authors=${AUTHOR} @@ -28,7 +30,9 @@ LABEL org.opencontainers.image.authors=${AUTHOR}
28 WORKDIR /app 30 WORKDIR /app
29 ENV PROJECT=${PROJECT} 31 ENV PROJECT=${PROJECT}
30 ENV CONFIG_FILE=${CONFIG_FILE} 32 ENV CONFIG_FILE=${CONFIG_FILE}
  33 +ENV TZ Asia/Shanghai
31 34
  35 +COPY --from=builder /usr/share/zoneinfo/Asia/Shanghai /usr/share/zoneinfo/Asia/Shanghai
32 COPY --from=builder /build/api/${PROJECT} ./ 36 COPY --from=builder /build/api/${PROJECT} ./
33 COPY --from=builder /build/cmd/chart-server/api/etc/${CONFIG_FILE} ./etc/ 37 COPY --from=builder /build/cmd/chart-server/api/etc/${CONFIG_FILE} ./etc/
34 COPY --from=builder /build/cmd/chart-server/api/public ./public/ 38 COPY --from=builder /build/cmd/chart-server/api/public ./public/
@@ -5,7 +5,8 @@ ARG PROJECT=core @@ -5,7 +5,8 @@ ARG PROJECT=core
5 5
6 WORKDIR /build 6 WORKDIR /build
7 COPY . . 7 COPY . .
8 - 8 +RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
  9 +RUN apk update --no-cache && apk add --no-cache tzdata
9 RUN go env -w GO111MODULE=on \ 10 RUN go env -w GO111MODULE=on \
10 && go env -w GOPROXY=https://goproxy.cn,direct \ 11 && go env -w GOPROXY=https://goproxy.cn,direct \
11 && go env -w CGO_ENABLED=0 \ 12 && go env -w CGO_ENABLED=0 \
@@ -28,7 +29,9 @@ LABEL org.opencontainers.image.authors=${AUTHOR} @@ -28,7 +29,9 @@ LABEL org.opencontainers.image.authors=${AUTHOR}
28 WORKDIR /app 29 WORKDIR /app
29 ENV PROJECT=${PROJECT} 30 ENV PROJECT=${PROJECT}
30 ENV CONFIG_FILE=${CONFIG_FILE} 31 ENV CONFIG_FILE=${CONFIG_FILE}
  32 +ENV TZ Asia/Shanghai
31 33
  34 +COPY --from=builder /usr/share/zoneinfo/Asia/Shanghai /usr/share/zoneinfo/Asia/Shanghai
32 COPY --from=builder /build/api/${PROJECT} ./ 35 COPY --from=builder /build/api/${PROJECT} ./
33 COPY --from=builder /build/cmd/chart-server/api/etc/${CONFIG_FILE} ./etc/ 36 COPY --from=builder /build/cmd/chart-server/api/etc/${CONFIG_FILE} ./etc/
34 COPY --from=builder /build/cmd/chart-server/api/public ./public/ 37 COPY --from=builder /build/cmd/chart-server/api/public ./public/
@@ -2,17 +2,18 @@ package main @@ -2,17 +2,18 @@ package main
2 2
3 import ( 3 import (
4 "flag" 4 "flag"
  5 + "github.com/golang-jwt/jwt/v4/request"
  6 + "github.com/zeromicro/go-queue/kq"
5 "github.com/zeromicro/go-zero/core/logx" 7 "github.com/zeromicro/go-zero/core/logx"
  8 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/api/internal/config"
  9 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/api/internal/handler"
  10 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/api/internal/logic/consumer"
  11 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/api/internal/svc"
6 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/db" 12 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/db"
7 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/domain" 13 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/domain"
8 "net/http" 14 "net/http"
9 "strings" 15 "strings"
10 -  
11 - "github.com/golang-jwt/jwt/v4/request"  
12 -  
13 - "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/api/internal/config"  
14 - "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/api/internal/handler"  
15 - "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/api/internal/svc" 16 + "time"
16 17
17 "github.com/zeromicro/go-zero/core/conf" 18 "github.com/zeromicro/go-zero/core/conf"
18 "github.com/zeromicro/go-zero/rest" 19 "github.com/zeromicro/go-zero/rest"
@@ -54,9 +55,33 @@ func main() { @@ -54,9 +55,33 @@ func main() {
54 55
55 ctx := svc.NewServiceContext(c) 56 ctx := svc.NewServiceContext(c)
56 handler.RegisterHandlers(server, ctx) 57 handler.RegisterHandlers(server, ctx)
57 - 58 + handler.RegisterExternalHandlers(server, ctx)
58 db.Migrate(ctx.DB) 59 db.Migrate(ctx.DB)
  60 + //启动消费队列
  61 + startConsume(ctx)
59 62
60 logx.Infof("Starting server at %s:%d... \n", c.Host, c.Port) 63 logx.Infof("Starting server at %s:%d... \n", c.Host, c.Port)
61 server.Start() 64 server.Start()
62 } 65 }
  66 +
  67 +func startConsume(svcCtx *svc.ServiceContext) {
  68 + //kafka消费队列 处理字库推送事件
  69 + go func() {
  70 + queue, err := kq.NewQueue(svcCtx.Config.KqConsumerConf, consumer.NewByteNoticeLogic(svcCtx))
  71 + if err != nil {
  72 + panic(err)
  73 + } else {
  74 + queue.Start()
  75 + }
  76 + }()
  77 + //redis消费队列 处理表数据存储到本地
  78 + go func() {
  79 + for {
  80 + str, err := svcCtx.Redis.Rpop(svcCtx.Config.Name + ":table_data")
  81 + if err == nil {
  82 + _ = consumer.NewByteTableDataLogic(svcCtx).Sync(str)
  83 + }
  84 + time.Sleep(3 * time.Second)
  85 + }
  86 + }()
  87 +}
1 Name: chart 1 Name: chart
2 Host: 0.0.0.0 2 Host: 0.0.0.0
3 Port: 8080 3 Port: 8080
4 -Verbose: true 4 +Verbose: false
5 HostName: http://sumifcc-bchart-dev.sumifcc.com 5 HostName: http://sumifcc-bchart-dev.sumifcc.com
  6 +Timeout: 30000
  7 +LogRequest: true # 记录详细请求日志
6 8
7 Log: 9 Log:
8 Mode: file 10 Mode: file
9 Encoding: plain 11 Encoding: plain
10 Level: debug # info 12 Level: debug # info
  13 + MaxSize: 1 # 2MB
  14 + TimeFormat: 2006-01-02 15:04:05.000
  15 + MaxContentLength: 5120 # 5KB
11 16
12 JwtAuth: 17 JwtAuth:
13 AccessSecret: digital-platform 18 AccessSecret: digital-platform
14 Expire: 360000 19 Expire: 360000
15 20
  21 +ApiAuth:
  22 + Name: ApiAuth
  23 + Host: http://digital-platform-dev.fjmaimaimai.com
  24 + Timeout: 0s
  25 +
16 Redis: 26 Redis:
17 Host: 192.168.0.243:6379 27 Host: 192.168.0.243:6379
18 Type: node 28 Type: node
@@ -24,3 +34,10 @@ ByteMetadata: @@ -24,3 +34,10 @@ ByteMetadata:
24 Name: ApiByteMetadata 34 Name: ApiByteMetadata
25 Host: http://character-library-metadata-bastion-test.fjmaimaimai.com 35 Host: http://character-library-metadata-bastion-test.fjmaimaimai.com
26 Timeout: 0s 36 Timeout: 0s
  37 +KqConsumerConf:
  38 + Name: KqConsumer
  39 + Brokers:
  40 + - 47.97.5.102:9092
  41 + Group: bchart_dev
  42 + Topic: allied_creation_metadata_table_sync_notice
  43 + Processors: 1
@@ -3,6 +3,7 @@ Host: 0.0.0.0 @@ -3,6 +3,7 @@ Host: 0.0.0.0
3 Port: 8080 3 Port: 8080
4 Verbose: false 4 Verbose: false
5 HostName: http://sumifcc-bchart.sumifcc.com 5 HostName: http://sumifcc-bchart.sumifcc.com
  6 +LogRequest: true # 记录详细请求日志
6 7
7 Log: 8 Log:
8 Mode: file 9 Mode: file
@@ -13,6 +14,11 @@ JwtAuth: @@ -13,6 +14,11 @@ JwtAuth:
13 AccessSecret: digital-platform 14 AccessSecret: digital-platform
14 Expire: 360000 15 Expire: 360000
15 16
  17 +ApiAuth:
  18 + Name: ApiAuth
  19 + Host: https://digital-platform.sumifcc.com
  20 + Timeout: 0s
  21 +
16 Redis: 22 Redis:
17 Host: 192.168.0.243:30379 23 Host: 192.168.0.243:30379
18 Type: node 24 Type: node
1 Name: chart 1 Name: chart
2 Host: 0.0.0.0 2 Host: 0.0.0.0
3 Port: 8081 3 Port: 8081
4 -Verbose: true 4 +Verbose: false
5 HostName: http://sumifcc-bchart-dev.sumifcc.com 5 HostName: http://sumifcc-bchart-dev.sumifcc.com
  6 +Timeout: 30000
  7 +LogRequest: true # 记录详细请求日志
6 8
7 Log: 9 Log:
8 - #Mode: file 10 + Mode: file
9 Encoding: plain 11 Encoding: plain
10 Level: debug # info 12 Level: debug # info
11 MaxSize: 1 # 2MB 13 MaxSize: 1 # 2MB
12 TimeFormat: 2006-01-02 15:04:05.000 14 TimeFormat: 2006-01-02 15:04:05.000
  15 + MaxContentLength: 5120 # 5KB
13 16
14 JwtAuth: 17 JwtAuth:
15 AccessSecret: digital-platform 18 AccessSecret: digital-platform
16 Expire: 360000 19 Expire: 360000
17 20
  21 +ApiAuth:
  22 + Name: ApiAuth
  23 + Host: http://digital-platform-dev.fjmaimaimai.com
  24 + Timeout: 0s
  25 +
18 Redis: 26 Redis:
19 Host: 192.168.0.245:6379 27 Host: 192.168.0.245:6379
20 Type: node 28 Type: node
@@ -27,3 +35,11 @@ ByteMetadata: @@ -27,3 +35,11 @@ ByteMetadata:
27 Host1: http://127.0.0.1:8080 35 Host1: http://127.0.0.1:8080
28 Host: https://character-library-metadata-bastion-prd.fjmaimaimai.com 36 Host: https://character-library-metadata-bastion-prd.fjmaimaimai.com
29 Timeout: 0s 37 Timeout: 0s
  38 +
  39 +KqConsumerConf:
  40 + Name: KqConsumer
  41 + Brokers:
  42 + - 47.97.5.102:9092
  43 + Group: bchart_local
  44 + Topic: allied_creation_metadata_table_sync_notice
  45 + Processors: 1
1 package config 1 package config
2 2
3 import ( 3 import (
  4 + "github.com/zeromicro/go-queue/kq"
4 "github.com/zeromicro/go-zero/core/stores/redis" 5 "github.com/zeromicro/go-zero/core/stores/redis"
5 "github.com/zeromicro/go-zero/rest" 6 "github.com/zeromicro/go-zero/rest"
6 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/pkg/config" 7 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/pkg/config"
@@ -12,7 +13,10 @@ type Config struct { @@ -12,7 +13,10 @@ type Config struct {
12 config.Config 13 config.Config
13 Redis redis.RedisConf `json:",optional"` 14 Redis redis.RedisConf `json:",optional"`
14 ByteMetadata ApiService 15 ByteMetadata ApiService
  16 + ApiAuth ApiService
  17 + LogRequest bool `json:",optional,default=true"`
15 HostName string // 服务域名 18 HostName string // 服务域名
  19 + KqConsumerConf kq.KqConf
16 } 20 }
17 21
18 type ApiService struct { 22 type ApiService struct {
  1 +package handler
  2 +
  3 +import (
  4 + "github.com/zeromicro/go-zero/rest"
  5 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/api/internal/svc"
  6 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/pkg/openapi/rd"
  7 +)
  8 +
  9 +func RegisterExternalHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
  10 + server.AddRoutes(rd.Routers(serverCtx.Redis, serverCtx.Config.Name))
  11 +}
@@ -16,6 +16,8 @@ import ( @@ -16,6 +16,8 @@ import (
16 16
17 func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { 17 func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
18 server.AddRoutes( 18 server.AddRoutes(
  19 + rest.WithMiddlewares(
  20 + []rest.Middleware{serverCtx.LoginStatusCheck, serverCtx.LogRequest},
19 []rest.Route{ 21 []rest.Route{
20 { 22 {
21 Method: http.MethodPost, 23 Method: http.MethodPost,
@@ -57,12 +59,15 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { @@ -57,12 +59,15 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
57 Path: "/chart/components/search", 59 Path: "/chart/components/search",
58 Handler: chart.SearchChartComponentsHandler(serverCtx), 60 Handler: chart.SearchChartComponentsHandler(serverCtx),
59 }, 61 },
60 - }, 62 + }...,
  63 + ),
61 rest.WithJwt(serverCtx.Config.JwtAuth.AccessSecret), 64 rest.WithJwt(serverCtx.Config.JwtAuth.AccessSecret),
62 rest.WithPrefix("/v1"), 65 rest.WithPrefix("/v1"),
63 ) 66 )
64 67
65 server.AddRoutes( 68 server.AddRoutes(
  69 + rest.WithMiddlewares(
  70 + []rest.Middleware{serverCtx.LogRequest},
66 []rest.Route{ 71 []rest.Route{
67 { 72 {
68 Method: http.MethodPost, 73 Method: http.MethodPost,
@@ -74,7 +79,8 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { @@ -74,7 +79,8 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
74 Path: "/chart/:id", 79 Path: "/chart/:id",
75 Handler: chart.GetChartHandler(serverCtx), 80 Handler: chart.GetChartHandler(serverCtx),
76 }, 81 },
77 - }, 82 + }...,
  83 + ),
78 rest.WithPrefix("/v1"), 84 rest.WithPrefix("/v1"),
79 ) 85 )
80 86
@@ -95,23 +101,33 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { @@ -95,23 +101,33 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
95 Path: "/table/data", 101 Path: "/table/data",
96 Handler: table.SearchTableDataHandler(serverCtx), 102 Handler: table.SearchTableDataHandler(serverCtx),
97 }, 103 },
  104 + {
  105 + Method: http.MethodGet,
  106 + Path: "/table/sync",
  107 + Handler: table.SyncTableHandler(serverCtx),
  108 + },
98 }, 109 },
99 rest.WithPrefix("/v1"), 110 rest.WithPrefix("/v1"),
100 ) 111 )
101 112
102 server.AddRoutes( 113 server.AddRoutes(
  114 + rest.WithMiddlewares(
  115 + []rest.Middleware{serverCtx.LoginStatusCheck, serverCtx.LogRequest},
103 []rest.Route{ 116 []rest.Route{
104 { 117 {
105 Method: http.MethodPost, 118 Method: http.MethodPost,
106 Path: "/table/search-by-module", 119 Path: "/table/search-by-module",
107 Handler: table.SearchTableByModuleHandler(serverCtx), 120 Handler: table.SearchTableByModuleHandler(serverCtx),
108 }, 121 },
109 - }, 122 + }...,
  123 + ),
110 rest.WithJwt(serverCtx.Config.JwtAuth.AccessSecret), 124 rest.WithJwt(serverCtx.Config.JwtAuth.AccessSecret),
111 rest.WithPrefix("/v1"), 125 rest.WithPrefix("/v1"),
112 ) 126 )
113 127
114 server.AddRoutes( 128 server.AddRoutes(
  129 + rest.WithMiddlewares(
  130 + []rest.Middleware{serverCtx.LoginStatusCheck, serverCtx.LogRequest},
115 []rest.Route{ 131 []rest.Route{
116 { 132 {
117 Method: http.MethodPost, 133 Method: http.MethodPost,
@@ -143,12 +159,15 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { @@ -143,12 +159,15 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
143 Path: "/app-page/create-share", 159 Path: "/app-page/create-share",
144 Handler: page.CreateAppPageShareUrlHandler(serverCtx), 160 Handler: page.CreateAppPageShareUrlHandler(serverCtx),
145 }, 161 },
146 - }, 162 + }...,
  163 + ),
147 rest.WithJwt(serverCtx.Config.JwtAuth.AccessSecret), 164 rest.WithJwt(serverCtx.Config.JwtAuth.AccessSecret),
148 rest.WithPrefix("/v1"), 165 rest.WithPrefix("/v1"),
149 ) 166 )
150 167
151 server.AddRoutes( 168 server.AddRoutes(
  169 + rest.WithMiddlewares(
  170 + []rest.Middleware{serverCtx.LogRequest},
152 []rest.Route{ 171 []rest.Route{
153 { 172 {
154 Method: http.MethodGet, 173 Method: http.MethodGet,
@@ -160,7 +179,8 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { @@ -160,7 +179,8 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
160 Path: "/api/app-page/get-share-detail/:key", 179 Path: "/api/app-page/get-share-detail/:key",
161 Handler: page.GetAppPageShareDetailHandler(serverCtx), 180 Handler: page.GetAppPageShareDetailHandler(serverCtx),
162 }, 181 },
163 - }, 182 + }...,
  183 + ),
164 rest.WithPrefix("/v1"), 184 rest.WithPrefix("/v1"),
165 ) 185 )
166 186
  1 +package table
  2 +
  3 +import (
  4 + "net/http"
  5 +
  6 + "github.com/zeromicro/go-zero/rest/httpx"
  7 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/api/internal/logic/table"
  8 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/api/internal/svc"
  9 +)
  10 +
  11 +func SyncTableHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
  12 + return func(w http.ResponseWriter, r *http.Request) {
  13 + l := table.NewSyncTableLogic(r.Context(), svcCtx)
  14 + resp, err := l.SyncTable()
  15 + if err != nil {
  16 + httpx.ErrorCtx(r.Context(), w, err)
  17 + } else {
  18 + httpx.OkJsonCtx(r.Context(), w, resp)
  19 + }
  20 + }
  21 +}
@@ -3,6 +3,7 @@ package chart @@ -3,6 +3,7 @@ package chart
3 import ( 3 import (
4 "context" 4 "context"
5 "fmt" 5 "fmt"
  6 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/db/transaction"
6 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/domain" 7 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/domain"
7 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/pkg/contextdata" 8 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/pkg/contextdata"
8 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/pkg/xerr" 9 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/pkg/xerr"
@@ -35,6 +36,7 @@ func (l *DeleteChartLogic) DeleteChart(req *types.ChartDeleteRequest) (resp *typ @@ -35,6 +36,7 @@ func (l *DeleteChartLogic) DeleteChart(req *types.ChartDeleteRequest) (resp *typ
35 appPage *domain.AppPage 36 appPage *domain.AppPage
36 ) 37 )
37 resp = &types.ChartDeleteResponse{} 38 resp = &types.ChartDeleteResponse{}
  39 +
38 if chart, err = l.svcCtx.ChartRepository.FindOne(l.ctx, conn, req.Id); err != nil { 40 if chart, err = l.svcCtx.ChartRepository.FindOne(l.ctx, conn, req.Id); err != nil {
39 return nil, xerr.NewErrMsgErr("不存在", err) 41 return nil, xerr.NewErrMsgErr("不存在", err)
40 } 42 }
@@ -48,9 +50,29 @@ func (l *DeleteChartLogic) DeleteChart(req *types.ChartDeleteRequest) (resp *typ @@ -48,9 +50,29 @@ func (l *DeleteChartLogic) DeleteChart(req *types.ChartDeleteRequest) (resp *typ
48 if appPage.Identify() != nil { 50 if appPage.Identify() != nil {
49 return nil, xerr.NewErrMsgErr(fmt.Sprintf("该图表已被页面\"%v\"引用", appPage.Name), err) 51 return nil, xerr.NewErrMsgErr(fmt.Sprintf("该图表已被页面\"%v\"引用", appPage.Name), err)
50 } 52 }
  53 +
  54 + err = transaction.UseTrans(l.ctx, conn.DB(), func(ctx context.Context, conn transaction.Conn) error {
51 if chart, err = l.svcCtx.ChartRepository.Delete(l.ctx, conn, chart); err != nil { 55 if chart, err = l.svcCtx.ChartRepository.Delete(l.ctx, conn, chart); err != nil {
52 - return nil, xerr.NewErrMsgErr("删除失败", err) 56 + return xerr.NewErrMsgErr("删除失败", err)
  57 + }
  58 + //删除数据源
  59 + chartSetting, err := l.svcCtx.ChartSettingRepository.FindOne(l.ctx, conn, chart.Id)
  60 + if err == nil && len(chartSetting.DataSourceIds) > 0 {
  61 + for _, sourceId := range chartSetting.DataSourceIds {
  62 + //删除数据源
  63 + err = DeleteObjectTable(l.ctx, l.svcCtx, conn, int(sourceId))
  64 + if err != nil {
  65 + return xerr.NewErrMsg("删除失败")
  66 + }
  67 + //删除分组
  68 + err = l.svcCtx.ObjectTableRepository.DeleteGroup(ctx, conn, tenantId, int(sourceId))
  69 + if err != nil {
  70 + return xerr.NewErrMsg("删除失败")
  71 + }
  72 + }
53 } 73 }
  74 + return nil
  75 + }, true)
54 76
55 resp = &types.ChartDeleteResponse{} 77 resp = &types.ChartDeleteResponse{}
56 return 78 return
@@ -2,6 +2,7 @@ package chart @@ -2,6 +2,7 @@ package chart
2 2
3 import ( 3 import (
4 "context" 4 "context"
  5 + "encoding/json"
5 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/db/transaction" 6 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/db/transaction"
6 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/domain" 7 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/domain"
7 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/pkg/contextdata" 8 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/pkg/contextdata"
@@ -89,6 +90,16 @@ func (l *SaveChartLogic) SaveChart(req *types.ChartSaveRequest) (resp *types.Cha @@ -89,6 +90,16 @@ func (l *SaveChartLogic) SaveChart(req *types.ChartSaveRequest) (resp *types.Cha
89 }, true); err != nil { 90 }, true); err != nil {
90 return nil, xerr.NewErrMsgErr("创建失败", err) 91 return nil, xerr.NewErrMsgErr("创建失败", err)
91 } 92 }
  93 + if len(chartSetting.DataSourceIds) > 0 {
  94 + for _, sourceId := range chartSetting.DataSourceIds {
  95 + pusher := &types.SyncTableDataPusher{
  96 + CompanyId: tenantId,
  97 + ObjectId: int(sourceId),
  98 + }
  99 + mBytes, _ := json.Marshal(pusher)
  100 + _, _ = l.svcCtx.Redis.Lpush(l.svcCtx.Config.Name+":table_data", string(mBytes))
  101 + }
  102 + }
92 resp = &types.ChartSaveResponse{ 103 resp = &types.ChartSaveResponse{
93 Chart: types.NewChartItemWithSetting(chart, chartSetting), 104 Chart: types.NewChartItemWithSetting(chart, chartSetting),
94 } 105 }
@@ -2,6 +2,8 @@ package chart @@ -2,6 +2,8 @@ package chart
2 2
3 import ( 3 import (
4 "context" 4 "context"
  5 + "encoding/json"
  6 + "github.com/samber/lo"
5 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/db/transaction" 7 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/db/transaction"
6 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/domain" 8 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/domain"
7 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/pkg/contextdata" 9 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/pkg/contextdata"
@@ -41,6 +43,7 @@ func (l *UpdateChartLogic) UpdateChart(req *types.ChartUpdateRequest) (resp *typ @@ -41,6 +43,7 @@ func (l *UpdateChartLogic) UpdateChart(req *types.ChartUpdateRequest) (resp *typ
41 if chartSetting, err = l.svcCtx.ChartSettingRepository.FindOne(l.ctx, conn, req.Id); err != nil { 43 if chartSetting, err = l.svcCtx.ChartSettingRepository.FindOne(l.ctx, conn, req.Id); err != nil {
42 return nil, xerr.NewErrMsgErr("图表配置不存在", err) 44 return nil, xerr.NewErrMsgErr("图表配置不存在", err)
43 } 45 }
  46 + oldDataSource := chartSetting.DataSourceIds
44 47
45 if err = transaction.UseTrans(l.ctx, l.svcCtx.DB, func(ctx context.Context, conn transaction.Conn) error { 48 if err = transaction.UseTrans(l.ctx, l.svcCtx.DB, func(ctx context.Context, conn transaction.Conn) error {
46 if len(req.Cover) > 0 && chart.Cover != req.Cover { 49 if len(req.Cover) > 0 && chart.Cover != req.Cover {
@@ -54,12 +57,81 @@ func (l *UpdateChartLogic) UpdateChart(req *types.ChartUpdateRequest) (resp *typ @@ -54,12 +57,81 @@ func (l *UpdateChartLogic) UpdateChart(req *types.ChartUpdateRequest) (resp *typ
54 chartSetting.TableAbility = chartProperty.TableAbility 57 chartSetting.TableAbility = chartProperty.TableAbility
55 chartSetting.Series = chartProperty.Series 58 chartSetting.Series = chartProperty.Series
56 chartSetting.Other = chartProperty.Other 59 chartSetting.Other = chartProperty.Other
  60 + chartSetting.DataSourceIds = chartProperty.GetAllDataSourceId()
57 if chartSetting, err = l.svcCtx.ChartSettingRepository.UpdateWithVersion(l.ctx, conn, chartSetting); err != nil { 61 if chartSetting, err = l.svcCtx.ChartSettingRepository.UpdateWithVersion(l.ctx, conn, chartSetting); err != nil {
58 return err 62 return err
59 } 63 }
60 - return nil 64 + err = l.SyncTableData(tenantId, conn, chartSetting.DataSourceIds, oldDataSource)
  65 + return err
61 }, true); err != nil { 66 }, true); err != nil {
62 return nil, xerr.NewErrMsgErr("创建失败", err) 67 return nil, xerr.NewErrMsgErr("创建失败", err)
63 } 68 }
64 return 69 return
65 } 70 }
  71 +
  72 +func (l *UpdateChartLogic) SyncTableData(tenantId int64, conn transaction.Conn, newDataSourceIds, oldDataSourceIds []int64) error {
  73 + if len(newDataSourceIds) > 0 {
  74 + for _, sourceId := range newDataSourceIds {
  75 + pusher := &types.SyncTableDataPusher{
  76 + CompanyId: tenantId,
  77 + ObjectId: int(sourceId),
  78 + }
  79 + mBytes, _ := json.Marshal(pusher)
  80 + _, _ = l.svcCtx.Redis.Lpush(l.svcCtx.Config.Name+":table_data", string(mBytes))
  81 + }
  82 + }
  83 + //对比更新前后数据源
  84 + left, right := lo.Difference(newDataSourceIds, oldDataSourceIds)
  85 + //同步
  86 + if len(left) > 0 {
  87 + for _, sourceId := range left {
  88 + pusher := &types.SyncTableDataPusher{
  89 + CompanyId: tenantId,
  90 + ObjectId: int(sourceId),
  91 + }
  92 + mBytes, _ := json.Marshal(pusher)
  93 + _, _ = l.svcCtx.Redis.Lpush(l.svcCtx.Config.Name+":table_data", string(mBytes))
  94 + }
  95 + }
  96 + //删除
  97 + if len(right) > 0 {
  98 + for _, sourceId := range right {
  99 + err := DeleteObjectTable(l.ctx, l.svcCtx, conn, int(sourceId))
  100 + if err != nil {
  101 + return err
  102 + }
  103 + }
  104 + }
  105 + return nil
  106 +}
  107 +
  108 +func DeleteObjectTable(ctx context.Context, svcCtx *svc.ServiceContext, conn transaction.Conn, sourceId int) error {
  109 + //验证其他图表是否使用
  110 + used, err := svcCtx.ChartSettingRepository.CheckUseDataSource(ctx, conn, sourceId)
  111 + if err == nil && !used { //未使用,删除
  112 + err = svcCtx.ObjectTableDataRepository.DropTable(ctx, conn, sourceId)
  113 + if err != nil {
  114 + return err
  115 + }
  116 + //是否远程已删除
  117 + objectTable, err := svcCtx.ObjectTableRepository.FindOneByTableId(ctx, conn, sourceId)
  118 + if err == nil && objectTable.Id > 0 && objectTable.RemoteDeleted == 1 {
  119 + //删除表
  120 + _, err = svcCtx.ObjectTableRepository.Delete(ctx, conn, &domain.ObjectTable{Id: objectTable.Id, TableType: objectTable.TableType})
  121 + if err != nil {
  122 + return err
  123 + }
  124 + //删除字段
  125 + _, err = svcCtx.ObjectFieldRepository.Delete(ctx, conn, &domain.ObjectField{Id: int64(sourceId)})
  126 + if err != nil {
  127 + return err
  128 + }
  129 + //删除分组
  130 + err = svcCtx.ObjectTableRepository.DeleteGroup(ctx, conn, objectTable.CompanyId, objectTable.ParentId)
  131 + if err != nil {
  132 + return err
  133 + }
  134 + }
  135 + }
  136 + return nil
  137 +}
  1 +package consumer
  2 +
  3 +import (
  4 + "context"
  5 + "encoding/json"
  6 + "fmt"
  7 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/api/internal/svc"
  8 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/api/internal/types"
  9 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/db/transaction"
  10 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/domain"
  11 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/gateway/bytelib"
  12 +)
  13 +
  14 +type ByteNoticeLogic struct {
  15 + ctx context.Context
  16 + svcCtx *svc.ServiceContext
  17 + conn transaction.Conn
  18 +}
  19 +
  20 +func NewByteNoticeLogic(svcCtx *svc.ServiceContext) *ByteNoticeLogic {
  21 + return &ByteNoticeLogic{
  22 + ctx: context.Background(),
  23 + svcCtx: svcCtx,
  24 + conn: svcCtx.DefaultDBConn(),
  25 + }
  26 +}
  27 +
  28 +func (logic *ByteNoticeLogic) Consume(key, value string) error {
  29 + fmt.Println(key, value)
  30 + notice := &domain.ObjectNotice{}
  31 + err := json.Unmarshal([]byte(value), notice)
  32 + if err != nil {
  33 + return err
  34 + }
  35 + //保存推送消息
  36 + _, err = logic.svcCtx.ObjectNoticeRepository.Insert(logic.ctx, logic.conn, notice)
  37 + if err != nil {
  38 + return err
  39 + }
  40 + //处理消息
  41 + err = transaction.UseTrans(logic.ctx, logic.conn.DB(), func(ctx context.Context, conn transaction.Conn) error {
  42 + return logic.handleNotice(conn, notice)
  43 + }, true)
  44 + //更新处理结果
  45 + if err != nil {
  46 + notice.Status = domain.ObjectNoticeStatusError
  47 + notice.Message = err.Error()
  48 + } else {
  49 + notice.Status = domain.ObjectNoticeStatusDone
  50 + notice.Message = "OK"
  51 + }
  52 + _, _ = logic.svcCtx.ObjectNoticeRepository.Update(logic.ctx, logic.conn, notice)
  53 + return err
  54 +}
  55 +
  56 +// handleNotice 处理消息
  57 +func (logic *ByteNoticeLogic) handleNotice(conn transaction.Conn, notice *domain.ObjectNotice) error {
  58 + //是否删除消息
  59 + if notice.IsDeletedEvent() {
  60 + return logic.handleDelete(conn, notice)
  61 + }
  62 + accessToken, _ := types.TableAccessToken{CompanyId: notice.CompanyId}.GenerateToken()
  63 + //结构变更
  64 + if notice.StructChanged {
  65 + request := bytelib.ObjectTableSearchRequest{
  66 + Token: accessToken,
  67 + Module: bytelib.ModuleChartTemplate,
  68 + }
  69 + if notice.ObjectType == "导入模块" {
  70 + request.TableTypes = []string{bytelib.MainTable, bytelib.SubTable, bytelib.SideTable}
  71 + }
  72 + if notice.ObjectType == "拆解模块" {
  73 + request.TableTypes = []string{bytelib.SchemaTable}
  74 + request.ReturnGroupItem = true
  75 + }
  76 + if notice.ObjectType == "计算模块" {
  77 + request.TableTypes = []string{bytelib.CalculateItem, bytelib.CalculateSet}
  78 + request.ReturnGroupItem = true
  79 + request.ExcludeTables = []int{0}
  80 + }
  81 + list, err := logic.svcCtx.ByteMetadataService.ObjectTableSearch(logic.ctx, request)
  82 + if err != nil {
  83 + return err
  84 + }
  85 + tablePreview, err := logic.svcCtx.ByteMetadataService.TableDataPreview(logic.ctx, &bytelib.TableDataPreviewRequest{
  86 + Token: accessToken,
  87 + ObjectId: int64(notice.TableId),
  88 + ObjectType: bytelib.ObjectMetaTable,
  89 + Where: &bytelib.TableQueryWhere{
  90 + PageNumber: 1,
  91 + PageSize: 1,
  92 + },
  93 + UseCache: false,
  94 + HiddenData: false,
  95 + })
  96 + if err != nil || tablePreview.ObjectId <= 0 {
  97 + return nil
  98 + }
  99 + if len(list.List) > 0 {
  100 + objectTables := make([]*domain.ObjectTable, 0)
  101 + for _, item := range list.List {
  102 + if item.TableId == notice.TableId {
  103 + objectTables = append(objectTables, &domain.ObjectTable{
  104 + Id: item.Id,
  105 + TableId: item.TableId,
  106 + Name: item.Name,
  107 + TableType: item.TableType,
  108 + CompanyId: notice.CompanyId,
  109 + ParentId: item.ParentId,
  110 + Flag: item.Flag,
  111 + })
  112 + //父级节点
  113 + objectTables = append(objectTables, logic.getParents(notice.CompanyId, item.ParentId, list.List)...)
  114 + }
  115 + }
  116 + err = logic.saveTables(conn, objectTables)
  117 + if err != nil {
  118 + return err
  119 + }
  120 + }
  121 + //保存字段
  122 + _, err = logic.saveFields(conn, &domain.ObjectField{
  123 + Id: tablePreview.ObjectId,
  124 + Name: tablePreview.Name,
  125 + Fields: tablePreview.Fields,
  126 + })
  127 + if err != nil {
  128 + return err
  129 + }
  130 + }
  131 + //数据变更
  132 + if notice.DataChanged {
  133 + data := &types.SyncTableDataPusher{
  134 + CompanyId: notice.CompanyId,
  135 + ObjectId: notice.TableId,
  136 + }
  137 + mBytes, _ := json.Marshal(data)
  138 + _, err := logic.svcCtx.Redis.LpushCtx(logic.ctx, logic.svcCtx.Config.Name+":table_data", string(mBytes))
  139 + return err
  140 + }
  141 + return nil
  142 +}
  143 +
  144 +func (logic *ByteNoticeLogic) getParents(companyId int64, parentId int, list []*bytelib.Table) []*domain.ObjectTable {
  145 + result := make([]*domain.ObjectTable, 0)
  146 + for _, item := range list {
  147 + if item.Id == parentId {
  148 + result = append(result, &domain.ObjectTable{
  149 + Id: item.Id,
  150 + TableId: item.TableId,
  151 + Name: item.Name,
  152 + TableType: item.TableType,
  153 + CompanyId: companyId,
  154 + ParentId: item.ParentId,
  155 + Flag: item.Flag,
  156 + })
  157 + if item.ParentId > 0 {
  158 + result = append(result, logic.getParents(companyId, item.ParentId, list)...)
  159 + }
  160 + }
  161 + }
  162 + return result
  163 +}
  164 +
  165 +// handleDelete 删除
  166 +func (logic *ByteNoticeLogic) handleDelete(conn transaction.Conn, notice *domain.ObjectNotice) error {
  167 + objectTable, err := logic.svcCtx.ObjectTableRepository.FindOneByTableId(logic.ctx, conn, notice.TableId)
  168 + if err == nil && objectTable.Id > 0 {
  169 + objectTable.RemoteDeleted = 1
  170 + _, err := logic.svcCtx.ObjectTableRepository.Update(logic.ctx, conn, objectTable)
  171 + if err != nil {
  172 + return err
  173 + }
  174 + //是否有使用数据源
  175 + used, err := logic.svcCtx.ChartSettingRepository.CheckUseDataSource(logic.ctx, conn, notice.TableId)
  176 + if err == nil && !used {
  177 + err = logic.svcCtx.ObjectTableDataRepository.DropTable(logic.ctx, conn, notice.TableId)
  178 + if err != nil {
  179 + return err
  180 + }
  181 + //删除表
  182 + _, err = logic.svcCtx.ObjectTableRepository.Delete(logic.ctx, conn, objectTable)
  183 + if err != nil {
  184 + return err
  185 + }
  186 + //删除字段
  187 + _, err = logic.svcCtx.ObjectFieldRepository.Delete(logic.ctx, conn, &domain.ObjectField{Id: int64(objectTable.Id)})
  188 + if err != nil {
  189 + return err
  190 + }
  191 + //删除分组
  192 + err = logic.svcCtx.ObjectTableRepository.DeleteGroup(logic.ctx, conn, objectTable.CompanyId, objectTable.ParentId)
  193 + if err != nil {
  194 + return err
  195 + }
  196 + }
  197 + }
  198 + return nil
  199 +}
  200 +
  201 +// saveTables 保存表结构
  202 +func (logic *ByteNoticeLogic) saveTables(conn transaction.Conn, tables []*domain.ObjectTable) error {
  203 + if len(tables) > 0 {
  204 + for _, item := range tables {
  205 + objectTable, err := logic.svcCtx.ObjectTableRepository.FindOne(logic.ctx, conn, item.Id, item.TableType)
  206 + if err == nil && objectTable.Id > 0 {
  207 + item.Id = objectTable.Id
  208 + item.Version = objectTable.Version + 1
  209 + _, err := logic.svcCtx.ObjectTableRepository.Update(logic.ctx, conn, item)
  210 + if err != nil {
  211 + return err
  212 + }
  213 + } else {
  214 + _, err := logic.svcCtx.ObjectTableRepository.Insert(logic.ctx, conn, item)
  215 + if err != nil {
  216 + return err
  217 + }
  218 + }
  219 + }
  220 + }
  221 + return nil
  222 +}
  223 +
  224 +// saveFields 保存表字段
  225 +func (logic *ByteNoticeLogic) saveFields(conn transaction.Conn, objectField *domain.ObjectField) (*domain.ObjectField, error) {
  226 + mField, err := logic.svcCtx.ObjectFieldRepository.FindOne(logic.ctx, conn, objectField.Id)
  227 + if err == nil && mField.Id > 0 { //已存在 - 更新
  228 + objectField.Version = mField.Version + 1
  229 + return logic.svcCtx.ObjectFieldRepository.Update(logic.ctx, conn, objectField)
  230 + } else {
  231 + return logic.svcCtx.ObjectFieldRepository.Insert(logic.ctx, conn, objectField)
  232 + }
  233 +}
  1 +package consumer
  2 +
  3 +import (
  4 + "context"
  5 + "encoding/json"
  6 + "github.com/pkg/errors"
  7 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/api/internal/svc"
  8 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/api/internal/types"
  9 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/db/transaction"
  10 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/gateway/bytelib"
  11 +)
  12 +
  13 +type ByteTableDataLogic struct {
  14 + ctx context.Context
  15 + svcCtx *svc.ServiceContext
  16 +}
  17 +
  18 +func NewByteTableDataLogic(svcCtx *svc.ServiceContext) *ByteTableDataLogic {
  19 + return &ByteTableDataLogic{
  20 + svcCtx: svcCtx,
  21 + ctx: context.Background(),
  22 + }
  23 +}
  24 +
  25 +func (logic *ByteTableDataLogic) Sync(pusherStr string) error {
  26 + pusher := &types.SyncTableDataPusher{}
  27 + err := json.Unmarshal([]byte(pusherStr), pusher)
  28 + if err != nil {
  29 + return err
  30 + }
  31 + conn := logic.svcCtx.DefaultDBConn()
  32 + //验证是否有使用数据源
  33 + used, err := logic.svcCtx.ChartSettingRepository.CheckUseDataSource(logic.ctx, conn, pusher.ObjectId)
  34 + if err != nil || !used {
  35 + return err
  36 + }
  37 + accessToken, _ := types.TableAccessToken{CompanyId: pusher.CompanyId}.GenerateToken()
  38 + tableDataPreview, err := logic.svcCtx.ByteMetadataService.TableDataPreview(logic.ctx, &bytelib.TableDataPreviewRequest{
  39 + Token: accessToken,
  40 + ObjectId: int64(pusher.ObjectId),
  41 + ObjectType: bytelib.ObjectMetaTable,
  42 + Where: &bytelib.TableQueryWhere{
  43 + PageNumber: 1,
  44 + PageSize: bytelib.MaxPageSize,
  45 + },
  46 + UseCache: true,
  47 + HiddenData: false,
  48 + })
  49 + if err != nil {
  50 + return err
  51 + }
  52 + err = transaction.UseTrans(logic.ctx, conn.DB(), func(ctx context.Context, conn transaction.Conn) error {
  53 + err = logic.svcCtx.ObjectTableDataRepository.InsertWithTableData(logic.ctx, conn, bytelib.TableData(tableDataPreview))
  54 + if err != nil {
  55 + return err
  56 + }
  57 + //更新标记本地存储
  58 + err = logic.updateTableWithLocal(conn, int(tableDataPreview.ObjectId))
  59 + if err != nil {
  60 + return err
  61 + }
  62 + return nil
  63 + }, true)
  64 + return err
  65 +}
  66 +
  67 +// updateTableWithLocal 更新表标记本地存储
  68 +func (logic *ByteTableDataLogic) updateTableWithLocal(conn transaction.Conn, tableId int) error {
  69 + objectTable, err := logic.svcCtx.ObjectTableRepository.FindOneByTableId(logic.ctx, conn, tableId)
  70 + if err == nil && objectTable.Id > 0 {
  71 + objectTable.IsLocal = true
  72 + _, err = logic.svcCtx.ObjectTableRepository.Update(logic.ctx, conn, objectTable)
  73 + return err
  74 + }
  75 + return errors.New("表不存在")
  76 +}
@@ -26,6 +26,11 @@ func NewGetTableDetailLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Ge @@ -26,6 +26,11 @@ func NewGetTableDetailLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Ge
26 } 26 }
27 27
28 func (l *GetTableDetailLogic) GetTableDetail(req *types.GetTableDetailRequest) (resp interface{}, err error) { 28 func (l *GetTableDetailLogic) GetTableDetail(req *types.GetTableDetailRequest) (resp interface{}, err error) {
  29 + //获取本地数据
  30 + local, err := l.GetLocal(req.TableId)
  31 + if err == nil {
  32 + return local, nil
  33 + }
29 response, err := l.svcCtx.ByteMetadataService.TableInfo(l.ctx, &bytelib.TableInfoRequest{TableId: req.TableId, Token: req.Token}) 34 response, err := l.svcCtx.ByteMetadataService.TableInfo(l.ctx, &bytelib.TableInfoRequest{TableId: req.TableId, Token: req.Token})
30 if err != nil { 35 if err != nil {
31 logx.Error(err) 36 logx.Error(err)
@@ -35,3 +40,25 @@ func (l *GetTableDetailLogic) GetTableDetail(req *types.GetTableDetailRequest) ( @@ -35,3 +40,25 @@ func (l *GetTableDetailLogic) GetTableDetail(req *types.GetTableDetailRequest) (
35 resp = response 40 resp = response
36 return 41 return
37 } 42 }
  43 +
  44 +func (l *GetTableDetailLogic) GetLocal(tableId int) (interface{}, error) {
  45 + conn := l.svcCtx.DefaultDBConn()
  46 + //查询表数据
  47 + objectTable, err := l.svcCtx.ObjectTableRepository.FindOneByTableId(l.ctx, conn, tableId)
  48 + if err != nil || objectTable.Id <= 0 {
  49 + return nil, xerr.NewErrMsg("表不存在")
  50 + }
  51 + //查询表字段
  52 + objectField, err := l.svcCtx.ObjectFieldRepository.FindOne(l.ctx, conn, int64(tableId))
  53 + if err != nil || objectField.Id <= 0 {
  54 + return nil, xerr.NewErrMsg("表字段不存在")
  55 + }
  56 + resp := bytelib.TableInfoResponse{
  57 + TableId: objectTable.TableId,
  58 + TableType: objectTable.TableType,
  59 + Name: objectTable.Name,
  60 + ParentId: objectTable.ParentId,
  61 + Fields: removeIdField(objectField.Fields),
  62 + }
  63 + return resp, nil
  64 +}
@@ -8,6 +8,7 @@ import ( @@ -8,6 +8,7 @@ import (
8 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/api/internal/svc" 8 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/api/internal/svc"
9 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/api/internal/types" 9 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/api/internal/types"
10 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/gateway/bytelib" 10 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/gateway/bytelib"
  11 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/pkg/contextdata"
11 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/pkg/xerr" 12 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/pkg/xerr"
12 ) 13 )
13 14
@@ -29,38 +30,86 @@ func (l *SearchTableByModuleLogic) SearchTableByModule(req *types.SearchTableByM @@ -29,38 +30,86 @@ func (l *SearchTableByModuleLogic) SearchTableByModule(req *types.SearchTableByM
29 var result = make(map[string]interface{}) 30 var result = make(map[string]interface{})
30 var batchError errorx.BatchError 31 var batchError errorx.BatchError
31 fx.Parallel(func() { 32 fx.Parallel(func() {
32 - list, err := l.svcCtx.ByteMetadataService.ObjectTableSearch(l.ctx, bytelib.ObjectTableSearchRequest{  
33 - Token: req.Token,  
34 - TableTypes: []string{bytelib.MainTable, bytelib.SubTable, bytelib.SideTable},  
35 - Module: bytelib.ModuleDigitalCenter,  
36 - }) 33 + mResp, err := l.getTableByLocal([]string{bytelib.MainTable, bytelib.SubTable, bytelib.SideTable})
37 if err != nil { 34 if err != nil {
38 batchError.Add(err) 35 batchError.Add(err)
39 } 36 }
40 - result["导入模块"] = newList(list) 37 + result["导入模块"] = mResp
  38 + //if err == nil {
  39 + // result["导入模块"] = mResp
  40 + //} else {
  41 + // list, err := l.svcCtx.ByteMetadataService.ObjectTableSearch(l.ctx, bytelib.ObjectTableSearchRequest{
  42 + // Token: req.Token,
  43 + // TableTypes: []string{bytelib.MainTable, bytelib.SubTable, bytelib.SideTable},
  44 + // Module: bytelib.ModuleChartTemplate, // TODO:字库更新完改为只查 bytelib.ModuleChartTemplate
  45 + // })
  46 + // if err != nil {
  47 + // batchError.Add(err)
  48 + // }
  49 + // result["导入模块"] = newList(list)
  50 + //}
41 }, func() { 51 }, func() {
42 - list, err := l.svcCtx.ByteMetadataService.ObjectTableSearch(l.ctx, bytelib.ObjectTableSearchRequest{  
43 - Token: req.Token,  
44 - TableTypes: []string{bytelib.SchemaTable},  
45 - Module: bytelib.ModuleQuerySetCenter,  
46 - ReturnGroupItem: true,  
47 - }) 52 + mResp, err := l.getTableByLocal([]string{bytelib.SchemaTable})
48 if err != nil { 53 if err != nil {
49 batchError.Add(err) 54 batchError.Add(err)
50 } 55 }
51 - result["拆解模块"] = newList(list) 56 + result["拆解模块"] = mResp
  57 + //if err == nil {
  58 + // result["拆解模块"] = mResp
  59 + //} else {
  60 + // list, err := l.svcCtx.ByteMetadataService.ObjectTableSearch(l.ctx, bytelib.ObjectTableSearchRequest{
  61 + // Token: req.Token,
  62 + // TableTypes: []string{bytelib.SchemaTable},
  63 + // Module: bytelib.ModuleQuerySetCenter,
  64 + // ReturnGroupItem: true,
  65 + // })
  66 + // if err != nil {
  67 + // batchError.Add(err)
  68 + // }
  69 + // result["拆解模块"] = newList(list)
  70 + //}
52 }, func() { 71 }, func() {
53 - list, err := l.svcCtx.ByteMetadataService.ObjectTableSearch(l.ctx, bytelib.ObjectTableSearchRequest{  
54 - Token: req.Token,  
55 - TableTypes: []string{bytelib.CalculateItem, bytelib.CalculateSet},  
56 - Module: bytelib.ModuleCalculateCenter,  
57 - ReturnGroupItem: true,  
58 - ExcludeTables: []int{0},  
59 - }) 72 + mResp, err := l.getTableByLocal([]string{bytelib.CalculateItem})
  73 + if err != nil {
  74 + batchError.Add(err)
  75 + }
  76 + result["计算项"] = mResp
  77 + //if err == nil {
  78 + // result["计算项"] = mResp
  79 + //} else {
  80 + // list, err := l.svcCtx.ByteMetadataService.ObjectTableSearch(l.ctx, bytelib.ObjectTableSearchRequest{
  81 + // Token: req.Token,
  82 + // TableTypes: []string{bytelib.CalculateItem},
  83 + // Module: bytelib.ModuleCalculateCenter,
  84 + // ReturnGroupItem: true,
  85 + // ExcludeTables: []int{0},
  86 + // })
  87 + // if err != nil {
  88 + // batchError.Add(err)
  89 + // }
  90 + // result["计算项"] = newList(list)
  91 + //}
  92 + }, func() {
  93 + mResp, err := l.getTableByLocal([]string{bytelib.CalculateSet})
60 if err != nil { 94 if err != nil {
61 batchError.Add(err) 95 batchError.Add(err)
62 } 96 }
63 - result["计算模块"] = newList(list) 97 + result["计算集"] = mResp
  98 + //if err == nil {
  99 + // result["计算集"] = mResp
  100 + //} else {
  101 + // list, err := l.svcCtx.ByteMetadataService.ObjectTableSearch(l.ctx, bytelib.ObjectTableSearchRequest{
  102 + // Token: req.Token,
  103 + // TableTypes: []string{bytelib.CalculateSet},
  104 + // Module: bytelib.ModuleCalculateCenter,
  105 + // ReturnGroupItem: true,
  106 + // ExcludeTables: []int{0},
  107 + // })
  108 + // if err != nil {
  109 + // batchError.Add(err)
  110 + // }
  111 + // result["计算集"] = newList(list)
  112 + //}
64 }) 113 })
65 if err = batchError.Err(); err != nil { 114 if err = batchError.Err(); err != nil {
66 logx.Error(err) 115 logx.Error(err)
@@ -76,3 +125,31 @@ func newList(r bytelib.ObjectTableSearchResponse) interface{} { @@ -76,3 +125,31 @@ func newList(r bytelib.ObjectTableSearchResponse) interface{} {
76 "list": r.List, 125 "list": r.List,
77 } 126 }
78 } 127 }
  128 +
  129 +func (l *SearchTableByModuleLogic) getTableByLocal(modules []string) (types.SearchTableByModuleResponse, error) {
  130 + tenantId := contextdata.GetTenantFromCtx(l.ctx)
  131 + response := types.SearchTableByModuleResponse{
  132 + Count: 0,
  133 + List: make([]types.SearchTableByModuleItem, 0),
  134 + }
  135 + total, list, err := l.svcCtx.ObjectTableRepository.Find(l.ctx, l.svcCtx.DefaultDBConn(), map[string]interface{}{
  136 + "companyId": tenantId,
  137 + "tableTypeIn": modules,
  138 + })
  139 + if err != nil {
  140 + return response, err
  141 + }
  142 + response.Count = int(total)
  143 + for _, item := range list {
  144 + response.List = append(response.List, types.SearchTableByModuleItem{
  145 + Id: item.Id,
  146 + TableId: item.TableId,
  147 + TableType: item.TableType,
  148 + Name: item.Name,
  149 + ParentId: item.ParentId,
  150 + Flag: item.Flag,
  151 + IsLocal: item.IsLocal,
  152 + })
  153 + }
  154 + return response, nil
  155 +}
@@ -2,13 +2,16 @@ package table @@ -2,13 +2,16 @@ package table
2 2
3 import ( 3 import (
4 "context" 4 "context"
5 - "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/gateway/bytelib"  
6 - "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/pkg/xerr"  
7 - 5 + "github.com/jinzhu/copier"
  6 + "github.com/zeromicro/go-zero/core/logx"
8 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/api/internal/svc" 7 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/api/internal/svc"
9 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/api/internal/types" 8 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/api/internal/types"
10 -  
11 - "github.com/zeromicro/go-zero/core/logx" 9 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/domain"
  10 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/gateway/bytelib"
  11 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/pkg/xerr"
  12 + "sort"
  13 + "strconv"
  14 + "strings"
12 ) 15 )
13 16
14 type SearchTableDataLogic struct { 17 type SearchTableDataLogic struct {
@@ -32,9 +35,68 @@ func (l *SearchTableDataLogic) SearchTableData(req *types.SearchTableDataRequest @@ -32,9 +35,68 @@ func (l *SearchTableDataLogic) SearchTableData(req *types.SearchTableDataRequest
32 "fields": nil, 35 "fields": nil,
33 "total": 0, 36 "total": 0,
34 "data": make([]string, 0), 37 "data": make([]string, 0),
  38 + "local": false,
35 } 39 }
36 return 40 return
37 } 41 }
  42 + resp, err = l.getLocal(req)
  43 + if err == nil {
  44 + return resp, nil
  45 + }
  46 + return l.getRemote(req)
  47 +}
  48 +
  49 +// getLocal 获取本地数据
  50 +func (l *SearchTableDataLogic) getLocal(req *types.SearchTableDataRequest) (interface{}, error) {
  51 + conn := l.svcCtx.DefaultDBConn()
  52 + conditions := make([]*domain.TableDataCondition, 0)
  53 + _ = copier.Copy(&conditions, req.Condition)
  54 + //查询表数据
  55 + objectTable, err := l.svcCtx.ObjectTableRepository.FindOneByTableId(l.ctx, conn, req.ObjectId)
  56 + if err != nil || objectTable.Id <= 0 {
  57 + return nil, xerr.NewErrMsg("表不存在")
  58 + }
  59 + if !objectTable.IsLocal {
  60 + return nil, xerr.NewErrMsg("未保存到本地存储")
  61 + }
  62 + //查询表字段
  63 + objectField, err := l.svcCtx.ObjectFieldRepository.FindOne(l.ctx, conn, int64(req.ObjectId))
  64 + if err != nil || objectField.Id <= 0 {
  65 + return nil, xerr.NewErrMsg("表字段不存在")
  66 + }
  67 + //替换中文字段
  68 + for _, item := range conditions {
  69 + replace := false
  70 + for _, field := range objectField.Fields {
  71 + if field.Name == item.FieldName {
  72 + item.FieldName = field.SQLName
  73 + replace = true
  74 + }
  75 + }
  76 + if !replace {
  77 + return nil, xerr.NewErrMsg("字段" + item.FieldName + "不存在")
  78 + }
  79 + }
  80 + //表数据
  81 + total, list, err := l.svcCtx.ObjectTableDataRepository.Find(l.ctx, conn, req.ObjectId, &domain.ObjectTableDataQuery{
  82 + Page: req.PageNumber,
  83 + Size: req.PageSize,
  84 + Conditions: conditions,
  85 + })
  86 + if err != nil {
  87 + return nil, xerr.NewErrMsg("查询表数据失败")
  88 + }
  89 + return map[string]interface{}{
  90 + "objectId": req.ObjectId,
  91 + "fields": removeIdField(objectField.Fields),
  92 + "total": total,
  93 + "data": list,
  94 + "local": true,
  95 + }, nil
  96 +}
  97 +
  98 +// getRemote 获取远程字库数据
  99 +func (l *SearchTableDataLogic) getRemote(req *types.SearchTableDataRequest) (resp interface{}, err error) {
38 tableDataPreviewRequest := &bytelib.TableDataPreviewRequest{ 100 tableDataPreviewRequest := &bytelib.TableDataPreviewRequest{
39 Token: req.Token, 101 Token: req.Token,
40 ObjectType: bytelib.ObjectMetaTable, 102 ObjectType: bytelib.ObjectMetaTable,
@@ -48,11 +110,53 @@ func (l *SearchTableDataLogic) SearchTableData(req *types.SearchTableDataRequest @@ -48,11 +110,53 @@ func (l *SearchTableDataLogic) SearchTableData(req *types.SearchTableDataRequest
48 if err != nil { 110 if err != nil {
49 return resp, xerr.NewErr(err) 111 return resp, xerr.NewErr(err)
50 } 112 }
  113 + //排序
  114 + orderField := ""
  115 + orderBy := ""
  116 + fieldType := "string"
  117 + for _, item := range req.Condition {
  118 + if item.Order != "" {
  119 + orderField = item.FieldName
  120 + orderBy = item.Order
  121 + break
  122 + }
  123 + }
  124 + for _, item := range response.Fields {
  125 + if orderField == item.SQLName {
  126 + fieldType = item.SQLType
  127 + }
  128 + }
  129 + fieldType = strings.ToLower(fieldType)
  130 + if orderField != "" && orderBy != "" {
  131 + sort.Slice(response.Grid.List, func(i, j int) bool {
  132 + if _, ok := response.Grid.List[i][orderField]; ok {
  133 + if _, ok := response.Grid.List[j][orderField]; ok {
  134 + if fieldType == "bigint" || fieldType == "int" || fieldType == "float" {
  135 + idata, _ := strconv.ParseFloat(response.Grid.List[i][orderField], 64)
  136 + jdata, _ := strconv.ParseFloat(response.Grid.List[j][orderField], 64)
  137 + if strings.ToLower(orderBy) == "asc" {
  138 + return idata < jdata
  139 + } else {
  140 + return idata > jdata
  141 + }
  142 + } else {
  143 + if strings.ToLower(orderBy) == "asc" {
  144 + return response.Grid.List[i][orderField] < response.Grid.List[j][orderField]
  145 + } else {
  146 + return response.Grid.List[i][orderField] > response.Grid.List[j][orderField]
  147 + }
  148 + }
  149 + }
  150 + }
  151 + return true
  152 + })
  153 + }
51 resp = map[string]interface{}{ 154 resp = map[string]interface{}{
52 "objectId": response.ObjectId, 155 "objectId": response.ObjectId,
53 "fields": removeIdField(response.Fields), 156 "fields": removeIdField(response.Fields),
54 "total": response.Grid.Total, 157 "total": response.Grid.Total,
55 "data": response.Grid.List, 158 "data": response.Grid.List,
  159 + "local": false,
56 } 160 }
57 return 161 return
58 } 162 }
@@ -2,13 +2,15 @@ package table @@ -2,13 +2,15 @@ package table
2 2
3 import ( 3 import (
4 "context" 4 "context"
5 - "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/gateway/bytelib"  
6 - "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/pkg/xerr"  
7 - 5 + "fmt"
  6 + "github.com/jinzhu/copier"
  7 + "github.com/samber/lo"
  8 + "github.com/zeromicro/go-zero/core/logx"
8 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/api/internal/svc" 9 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/api/internal/svc"
9 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/api/internal/types" 10 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/api/internal/types"
10 -  
11 - "github.com/zeromicro/go-zero/core/logx" 11 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/domain"
  12 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/gateway/bytelib"
  13 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/pkg/xerr"
12 ) 14 )
13 15
14 type SearchTableFieldOptionalValuesLogic struct { 16 type SearchTableFieldOptionalValuesLogic struct {
@@ -26,6 +28,12 @@ func NewSearchTableFieldOptionalValuesLogic(ctx context.Context, svcCtx *svc.Ser @@ -26,6 +28,12 @@ func NewSearchTableFieldOptionalValuesLogic(ctx context.Context, svcCtx *svc.Ser
26 } 28 }
27 29
28 func (l *SearchTableFieldOptionalValuesLogic) SearchTableFieldOptionalValues(req *types.SearchTableFieldOptionalValuesRequest) (resp *types.SearchTableFieldOptionalValuesResponse, err error) { 30 func (l *SearchTableFieldOptionalValuesLogic) SearchTableFieldOptionalValues(req *types.SearchTableFieldOptionalValuesRequest) (resp *types.SearchTableFieldOptionalValuesResponse, err error) {
  31 + //取本地数据
  32 + resp, err = l.getLocal(req)
  33 + if err == nil {
  34 + return resp, err
  35 + }
  36 + //获取远程数据
29 fieldOptionalValuesRequest := &bytelib.TableFieldOptionalValuesRequest{ 37 fieldOptionalValuesRequest := &bytelib.TableFieldOptionalValuesRequest{
30 Token: req.Token, 38 Token: req.Token,
31 ObjectType: bytelib.ObjectMetaTable, 39 ObjectType: bytelib.ObjectMetaTable,
@@ -58,6 +66,7 @@ func newWhere(conditions []*types.Condition) *bytelib.TableQueryWhere { @@ -58,6 +66,7 @@ func newWhere(conditions []*types.Condition) *bytelib.TableQueryWhere {
58 //if order == "" { 66 //if order == "" {
59 // order = "ASC" 67 // order = "ASC"
60 //} 68 //}
  69 + if c.Like != "" || len(c.In) > 0 {
61 where.Conditions = append(where.Conditions, &bytelib.TableQueryCondition{ 70 where.Conditions = append(where.Conditions, &bytelib.TableQueryCondition{
62 Field: &bytelib.Field{ 71 Field: &bytelib.Field{
63 Name: c.FieldName, 72 Name: c.FieldName,
@@ -67,5 +76,67 @@ func newWhere(conditions []*types.Condition) *bytelib.TableQueryWhere { @@ -67,5 +76,67 @@ func newWhere(conditions []*types.Condition) *bytelib.TableQueryWhere {
67 //Order: order, 76 //Order: order,
68 }) 77 })
69 } 78 }
  79 + }
70 return where 80 return where
71 } 81 }
  82 +
  83 +func (l *SearchTableFieldOptionalValuesLogic) getLocal(req *types.SearchTableFieldOptionalValuesRequest) (resp *types.SearchTableFieldOptionalValuesResponse, err error) {
  84 + conn := l.svcCtx.DefaultDBConn()
  85 + //查询表数据
  86 + objectTable, err := l.svcCtx.ObjectTableRepository.FindOneByTableId(l.ctx, conn, req.ObjectId)
  87 + if err != nil || objectTable.Id <= 0 {
  88 + return nil, xerr.NewErrMsg("表不存在")
  89 + }
  90 + if !objectTable.IsLocal {
  91 + return nil, xerr.NewErrMsg("未保存到本地存储")
  92 + }
  93 + //查询表字段
  94 + objectField, err := l.svcCtx.ObjectFieldRepository.FindOne(l.ctx, conn, int64(req.ObjectId))
  95 + if err != nil || objectField.Id <= 0 {
  96 + return nil, xerr.NewErrMsg("表字段不存在")
  97 + }
  98 + conditions := make([]*domain.TableDataCondition, 0)
  99 + _ = copier.Copy(&conditions, req.Condition)
  100 + //替换中文字段
  101 + for _, item := range conditions {
  102 + replace := false
  103 + for _, field := range objectField.Fields {
  104 + if field.Name == item.FieldName {
  105 + item.FieldName = field.SQLName
  106 + replace = true
  107 + }
  108 + }
  109 + if !replace {
  110 + return nil, xerr.NewErrMsg("字段" + item.FieldName + "不存在")
  111 + }
  112 + }
  113 + field := req.Field
  114 + for _, item := range objectField.Fields {
  115 + if req.Field == item.Name {
  116 + field = item.SQLName
  117 + }
  118 + }
  119 + //表数据
  120 + _, list, err := l.svcCtx.ObjectTableDataRepository.Find(l.ctx, conn, req.ObjectId, &domain.ObjectTableDataQuery{
  121 + Conditions: conditions,
  122 + Group: field,
  123 + Select: field,
  124 + })
  125 + if err != nil {
  126 + return nil, xerr.NewErrMsg("查询表数据失败")
  127 + }
  128 + resp = &types.SearchTableFieldOptionalValuesResponse{
  129 + Values: make([]string, 0),
  130 + Total: 0,
  131 + }
  132 + if len(list) > 0 {
  133 + lo.ForEach(list, func(item map[string]interface{}, index int) {
  134 + if _, ok := item[field]; ok {
  135 + resp.Values = append(resp.Values, fmt.Sprintf("%v", item[field]))
  136 + }
  137 + })
  138 + resp.Values = lo.Uniq(resp.Values)
  139 + resp.Total = int64(len(resp.Values))
  140 + }
  141 + return resp, nil
  142 +}
  1 +package table
  2 +
  3 +import (
  4 + "context"
  5 + "encoding/json"
  6 + "fmt"
  7 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/api/internal/types"
  8 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/db/transaction"
  9 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/domain"
  10 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/gateway/bytelib"
  11 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/pkg/xerr"
  12 +
  13 + "github.com/zeromicro/go-zero/core/logx"
  14 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/api/internal/svc"
  15 +)
  16 +
  17 +type SyncTableLogic struct {
  18 + logx.Logger
  19 + ctx context.Context
  20 + svcCtx *svc.ServiceContext
  21 + conn transaction.Conn
  22 +}
  23 +
  24 +func NewSyncTableLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SyncTableLogic {
  25 + return &SyncTableLogic{
  26 + Logger: logx.WithContext(ctx),
  27 + ctx: ctx,
  28 + svcCtx: svcCtx,
  29 + conn: svcCtx.DefaultDBConn(),
  30 + }
  31 +}
  32 +
  33 +func (l *SyncTableLogic) SyncTable() (resp interface{}, err error) {
  34 + companyIds, err := l.svcCtx.ChartRepository.FindCompanyIds(l.ctx, l.conn)
  35 + if err != nil {
  36 + return nil, xerr.NewErrMsg("查询公司ID失败:" + err.Error())
  37 + }
  38 + tables := make([]*domain.ObjectTable, 0)
  39 + for _, companyId := range companyIds {
  40 + accessToken, _ := types.TableAccessToken{CompanyId: companyId}.GenerateToken()
  41 + //获取导入模块
  42 + response, err := l.svcCtx.ByteMetadataService.ObjectTableSearch(l.ctx, bytelib.ObjectTableSearchRequest{
  43 + Token: accessToken,
  44 + TableTypes: []string{bytelib.MainTable, bytelib.SubTable, bytelib.SideTable},
  45 + Module: bytelib.ModuleChartTemplate,
  46 + })
  47 + if err == nil {
  48 + tables = append(tables, l.getTables(companyId, response)...)
  49 + }
  50 + //拆解模块
  51 + response, err = l.svcCtx.ByteMetadataService.ObjectTableSearch(l.ctx, bytelib.ObjectTableSearchRequest{
  52 + Token: accessToken,
  53 + TableTypes: []string{bytelib.SchemaTable},
  54 + Module: bytelib.ModuleQuerySetCenter,
  55 + ReturnGroupItem: true,
  56 + })
  57 + if err == nil {
  58 + tables = append(tables, l.getTables(companyId, response)...)
  59 + }
  60 + //计算项 计算集
  61 + response, err = l.svcCtx.ByteMetadataService.ObjectTableSearch(l.ctx, bytelib.ObjectTableSearchRequest{
  62 + Token: accessToken,
  63 + TableTypes: []string{bytelib.CalculateItem, bytelib.CalculateSet},
  64 + Module: bytelib.ModuleCalculateCenter,
  65 + ReturnGroupItem: true,
  66 + ExcludeTables: []int{0},
  67 + })
  68 + if err == nil {
  69 + tables = append(tables, l.getTables(companyId, response)...)
  70 + }
  71 + }
  72 + //获取字段信息
  73 + fields := l.getFields(tables)
  74 + //保存数据
  75 + err = transaction.UseTrans(l.ctx, l.conn.DB(), func(ctx context.Context, conn transaction.Conn) error {
  76 + err = l.SaveTables(conn, tables)
  77 + if err != nil {
  78 + return err
  79 + }
  80 + err = l.SaveFields(conn, fields)
  81 + if err != nil {
  82 + return err
  83 + }
  84 + return nil
  85 + }, true)
  86 + if err != nil {
  87 + return nil, xerr.NewErrMsg("保存表失败:" + err.Error())
  88 + }
  89 + //同步表数据
  90 + for _, item := range tables {
  91 + if item.TableId <= 0 {
  92 + continue
  93 + }
  94 + used, err := l.svcCtx.ChartSettingRepository.CheckUseDataSource(l.ctx, l.conn, item.TableId)
  95 + if err == nil && used {
  96 + pusher := &types.SyncTableDataPusher{
  97 + CompanyId: item.CompanyId,
  98 + ObjectId: int(item.TableId),
  99 + }
  100 + mBytes, _ := json.Marshal(pusher)
  101 + _, _ = l.svcCtx.Redis.Lpush(l.svcCtx.Config.Name+":table_data", string(mBytes))
  102 + fmt.Println(" ===========================> 加入数据下载队列 " + string(mBytes))
  103 + }
  104 + }
  105 + fmt.Println("========>数据同步完成")
  106 + return companyIds, err
  107 +}
  108 +
  109 +func (l *SyncTableLogic) getTables(companyId int64, response bytelib.ObjectTableSearchResponse) []*domain.ObjectTable {
  110 + tables := make([]*domain.ObjectTable, 0)
  111 + if len(response.List) > 0 {
  112 + for _, item := range response.List {
  113 + tables = append(tables, &domain.ObjectTable{
  114 + Id: item.Id,
  115 + TableId: item.TableId,
  116 + Name: item.Name,
  117 + TableType: item.TableType,
  118 + CompanyId: companyId,
  119 + ParentId: item.ParentId,
  120 + Flag: item.Flag,
  121 + Version: 1,
  122 + IsLocal: false,
  123 + RemoteDeleted: 0,
  124 + })
  125 + }
  126 + }
  127 + return tables
  128 +}
  129 +
  130 +func (l *SyncTableLogic) getFields(list []*domain.ObjectTable) []*domain.ObjectField {
  131 + fields := make([]*domain.ObjectField, 0)
  132 + for _, item := range list {
  133 + accessToken, _ := types.TableAccessToken{CompanyId: item.CompanyId}.GenerateToken()
  134 + if item.TableId > 0 {
  135 + //response, err := l.svcCtx.ByteMetadataService.TableInfo(l.ctx, &bytelib.TableInfoRequest{
  136 + // Token: accessToken,
  137 + // TableId: item.TableId,
  138 + //})
  139 + response, err := l.svcCtx.ByteMetadataService.TableDataPreview(l.ctx, &bytelib.TableDataPreviewRequest{
  140 + Token: accessToken,
  141 + ObjectId: int64(item.TableId),
  142 + ObjectType: bytelib.ObjectMetaTable,
  143 + Where: &bytelib.TableQueryWhere{
  144 + PageNumber: 1,
  145 + PageSize: 1,
  146 + },
  147 + UseCache: false,
  148 + HiddenData: false,
  149 + })
  150 + if err == nil {
  151 + fields = append(fields, &domain.ObjectField{
  152 + Id: int64(item.TableId),
  153 + Name: response.Name,
  154 + Fields: response.Fields,
  155 + Version: 1,
  156 + })
  157 + }
  158 + }
  159 + }
  160 + return fields
  161 +}
  162 +
  163 +// SaveTables 保存数据
  164 +func (l *SyncTableLogic) SaveTables(conn transaction.Conn, list []*domain.ObjectTable) error {
  165 + for _, item := range list {
  166 + objectTable, err := l.svcCtx.ObjectTableRepository.FindOne(l.ctx, conn, item.Id, item.TableType)
  167 + if err == nil && objectTable.Id > 0 {
  168 + item.IsLocal = objectTable.IsLocal
  169 + item.Version = objectTable.Version + 1
  170 + }
  171 + _, err = l.svcCtx.ObjectTableRepository.Insert(l.ctx, conn, item)
  172 + if err != nil {
  173 + return err
  174 + }
  175 + }
  176 + return nil
  177 +}
  178 +
  179 +func (l *SyncTableLogic) SaveFields(conn transaction.Conn, list []*domain.ObjectField) error {
  180 + for _, item := range list {
  181 + objectTable, err := l.svcCtx.ObjectFieldRepository.FindOne(l.ctx, conn, item.Id)
  182 + if err == nil && objectTable.Id > 0 {
  183 + item.Version = objectTable.Version + 1
  184 + }
  185 + _, err = l.svcCtx.ObjectFieldRepository.Insert(l.ctx, conn, item)
  186 + if err != nil {
  187 + return err
  188 + }
  189 + }
  190 + return nil
  191 +}
  1 +package middleware
  2 +
  3 +import (
  4 + "github.com/zeromicro/go-zero/rest/httpx"
  5 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/gateway"
  6 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/gateway/authlib"
  7 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/pkg/result"
  8 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/pkg/xerr"
  9 + "net/http"
  10 +)
  11 +
  12 +type LoginStatusCheckMiddleware struct {
  13 + apiAuth authlib.ApiAuthService
  14 +}
  15 +
  16 +func NewLoginStatusCheckMiddleware(apiAuth authlib.ApiAuthService) *LoginStatusCheckMiddleware {
  17 + return &LoginStatusCheckMiddleware{
  18 + apiAuth: apiAuth,
  19 + }
  20 +}
  21 +
  22 +func (m *LoginStatusCheckMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
  23 + return func(w http.ResponseWriter, r *http.Request) {
  24 + token := r.Header.Get("x-mmm-accesstoken")
  25 + if len(token) > 0 {
  26 + _, err := m.apiAuth.LoginCheck(r.Context(), authlib.RequestLoginCheck{
  27 + Token: token,
  28 + })
  29 + if err != nil {
  30 + gatewayError, ok := err.(gateway.HttpError)
  31 + if ok {
  32 + unAuthResponse(w, gatewayError.Base.Code, gatewayError.Base.Msg)
  33 + return
  34 + }
  35 + result.HttpResult(r, w, struct{}{}, xerr.NewErr(err))
  36 + return
  37 + }
  38 + }
  39 + next(w, r)
  40 + }
  41 +}
  42 +
  43 +func unAuthResponse(w http.ResponseWriter, code int, msg string) {
  44 + data := map[string]interface{}{
  45 + "msg": msg,
  46 + "code": code,
  47 + "data": struct{}{},
  48 + }
  49 + httpx.WriteJson(w, http.StatusUnauthorized, data)
  50 +}
  1 +package middleware
  2 +
  3 +import (
  4 + "github.com/zeromicro/go-zero/rest/handler"
  5 + "net/http"
  6 +)
  7 +
  8 +type LogRequestMiddleware struct {
  9 + logRequest bool
  10 +}
  11 +
  12 +// NewLogRequestMiddleware 记录请求
  13 +// logRequest true开启记录,false关闭记录
  14 +func NewLogRequestMiddleware(logRequest bool) *LogRequestMiddleware {
  15 + return &LogRequestMiddleware{
  16 + logRequest: logRequest,
  17 + }
  18 +}
  19 +
  20 +func (m *LogRequestMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
  21 + if !m.logRequest {
  22 + return func(writer http.ResponseWriter, request *http.Request) {
  23 + next(writer, request)
  24 + }
  25 + }
  26 + return handler.DetailedLogHandler(next).(http.HandlerFunc)
  27 +}
@@ -3,11 +3,14 @@ package svc @@ -3,11 +3,14 @@ package svc
3 import ( 3 import (
4 "github.com/tiptok/gocomm/pkg/cache/gzcache" 4 "github.com/tiptok/gocomm/pkg/cache/gzcache"
5 "github.com/zeromicro/go-zero/core/stores/redis" 5 "github.com/zeromicro/go-zero/core/stores/redis"
  6 + "github.com/zeromicro/go-zero/rest"
6 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/api/internal/config" 7 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/api/internal/config"
  8 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/api/internal/middleware"
7 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/db/repository" 9 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/db/repository"
8 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/db/transaction" 10 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/db/transaction"
9 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/domain" 11 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/domain"
10 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/gateway" 12 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/gateway"
  13 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/gateway/authlib"
11 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/gateway/bytelib" 14 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/gateway/bytelib"
12 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/pkg/cache" 15 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/pkg/cache"
13 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/pkg/database" 16 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/pkg/database"
@@ -22,6 +25,14 @@ type ServiceContext struct { @@ -22,6 +25,14 @@ type ServiceContext struct {
22 ChartRepository domain.ChartRepository 25 ChartRepository domain.ChartRepository
23 ChartSettingRepository domain.ChartSettingRepository 26 ChartSettingRepository domain.ChartSettingRepository
24 AppPageRepository domain.AppPageRepository 27 AppPageRepository domain.AppPageRepository
  28 + ObjectNoticeRepository domain.ObjectNoticeRepository
  29 + ObjectTableRepository domain.ObjectTableRepository
  30 + ObjectFieldRepository domain.ObjectFieldRepository
  31 + ObjectTableDataRepository domain.ObjectTableDataRepository
  32 +
  33 + ApiAuthService authlib.ApiAuthService
  34 + LoginStatusCheck rest.Middleware
  35 + LogRequest rest.Middleware
25 36
26 ByteMetadataService bytelib.ByteMetadataService 37 ByteMetadataService bytelib.ByteMetadataService
27 } 38 }
@@ -31,15 +42,24 @@ func NewServiceContext(c config.Config) *ServiceContext { @@ -31,15 +42,24 @@ func NewServiceContext(c config.Config) *ServiceContext {
31 mlCache := cache.NewMultiLevelCache([]string{c.Redis.Host}, c.Redis.Pass) 42 mlCache := cache.NewMultiLevelCache([]string{c.Redis.Host}, c.Redis.Pass)
32 redisCache := gzcache.NewClusterCache([]string{c.Redis.Host}, c.Redis.Pass) 43 redisCache := gzcache.NewClusterCache([]string{c.Redis.Host}, c.Redis.Pass)
33 redis, _ := redis.NewRedis(redis.RedisConf{Host: c.Redis.Host, Pass: c.Redis.Pass, Type: "node"}) 44 redis, _ := redis.NewRedis(redis.RedisConf{Host: c.Redis.Host, Pass: c.Redis.Pass, Type: "node"})
34 - 45 + apiAuth := authlib.ApiAuthService{
  46 + Service: gateway.NewService(c.ApiAuth.Name, c.ApiAuth.Host, c.ApiAuth.Timeout),
  47 + }
35 return &ServiceContext{ 48 return &ServiceContext{
36 Config: c, 49 Config: c,
37 DB: db, 50 DB: db,
38 RedisCache: redisCache, 51 RedisCache: redisCache,
39 Redis: redis, 52 Redis: redis,
  53 + ApiAuthService: apiAuth,
  54 + LoginStatusCheck: middleware.NewLoginStatusCheckMiddleware(apiAuth).Handle,
  55 + LogRequest: middleware.NewLogRequestMiddleware(c.LogRequest).Handle,
40 ChartRepository: repository.NewChartRepository(cache.NewCachedRepository(mlCache)), 56 ChartRepository: repository.NewChartRepository(cache.NewCachedRepository(mlCache)),
41 ChartSettingRepository: repository.NewChartSettingRepository(cache.NewCachedRepository(mlCache)), 57 ChartSettingRepository: repository.NewChartSettingRepository(cache.NewCachedRepository(mlCache)),
42 AppPageRepository: repository.NewAppPageRepository(cache.NewCachedRepository(mlCache)), 58 AppPageRepository: repository.NewAppPageRepository(cache.NewCachedRepository(mlCache)),
  59 + ObjectNoticeRepository: repository.NewObjectNoticeRepository(cache.NewCachedRepository(mlCache)),
  60 + ObjectTableRepository: repository.NewObjectTableRepository(cache.NewCachedRepository(mlCache)),
  61 + ObjectFieldRepository: repository.NewObjectFieldRepository(cache.NewCachedRepository(mlCache)),
  62 + ObjectTableDataRepository: repository.NewObjectTableDataRepository(),
43 63
44 ByteMetadataService: bytelib.ByteMetadataService{ 64 ByteMetadataService: bytelib.ByteMetadataService{
45 Service: gateway.NewService(c.ByteMetadata.Name, c.ByteMetadata.Host, c.ByteMetadata.Timeout), 65 Service: gateway.NewService(c.ByteMetadata.Name, c.ByteMetadata.Host, c.ByteMetadata.Timeout),
@@ -42,6 +42,7 @@ func NewAppPageItem(appPage *domain.AppPage, charts []*domain.Chart) AppPageItem @@ -42,6 +42,7 @@ func NewAppPageItem(appPage *domain.AppPage, charts []*domain.Chart) AppPageItem
42 Id: appPage.Id, 42 Id: appPage.Id,
43 Name: appPage.Name, 43 Name: appPage.Name,
44 Cover: appPage.Cover, 44 Cover: appPage.Cover,
  45 + UpdatedAt: appPage.UpdatedAt,
45 } 46 }
46 for _, id := range appPage.Charts { 47 for _, id := range appPage.Charts {
47 if v, ok := chartsMap[id]; ok { 48 if v, ok := chartsMap[id]; ok {
1 package types 1 package types
  2 +
  3 +import (
  4 + "github.com/golang-jwt/jwt/v4"
  5 + "time"
  6 +)
  7 +
  8 +type TableAccessToken struct {
  9 + UserId int64 `json:"userId"`
  10 + CompanyId int64 `json:"companyId"`
  11 + UserName string `json:"userName"`
  12 + Phone string `json:"phone"`
  13 +}
  14 +
  15 +func (tk TableAccessToken) GenerateToken() (string, error) {
  16 + claims := make(jwt.MapClaims)
  17 + claims["exp"] = time.Now().Unix() + 3600
  18 + claims["iat"] = time.Now().Unix()
  19 + claims["UserId"] = tk.UserId
  20 + claims["CompanyId"] = tk.CompanyId
  21 + claims["UserName"] = tk.UserName
  22 + claims["Phone"] = tk.Phone
  23 + token := jwt.New(jwt.SigningMethodHS256)
  24 + token.Claims = claims
  25 + return token.SignedString([]byte("digital-platform"))
  26 +}
@@ -82,6 +82,7 @@ type ChartItem struct { @@ -82,6 +82,7 @@ type ChartItem struct {
82 Name string `json:"name,optional"` // 名称 82 Name string `json:"name,optional"` // 名称
83 Cover string `json:"cover,optional"` // 封面 83 Cover string `json:"cover,optional"` // 封面
84 ChartType string `json:"chartType,optional"` // 图表类型 84 ChartType string `json:"chartType,optional"` // 图表类型
  85 + UpdatedAt int `json:"updatedAt,optional"` // 更新时间
85 ChartProperty *ChartProperty `json:"property,optional,omitempty"` //属性 86 ChartProperty *ChartProperty `json:"property,optional,omitempty"` //属性
86 } 87 }
87 88
@@ -117,24 +118,55 @@ type ChartProperty struct { @@ -117,24 +118,55 @@ type ChartProperty struct {
117 118
118 type Other struct { 119 type Other struct {
119 Quarter *Quarter `json:"quarter,optional,omitempty"` // 四分图 120 Quarter *Quarter `json:"quarter,optional,omitempty"` // 四分图
  121 + Divider *Divider `json:"divider,optional,omitempty"` // 分割线
  122 + Rank *Rank `json:"rank,optional,omitempty"` // 排名图
  123 + Deviation *Deviation `json:"deviation,optional,omitempty"` // 偏差图
  124 + Notepaper *Notepaper `json:"notepaper,optional,omitempty"` // 便签(富文本)
120 } 125 }
121 126
122 type Quarter struct { 127 type Quarter struct {
123 XAxisLabel string `json:"xAxisLabel"` // x轴标签名 128 XAxisLabel string `json:"xAxisLabel"` // x轴标签名
124 XAxisFirstLabel string `json:"xAxisFirstLabel"` // 签名1 129 XAxisFirstLabel string `json:"xAxisFirstLabel"` // 签名1
125 XAxisSecondLabel string `json:"xAxisSecondLabel"` // 签名2 130 XAxisSecondLabel string `json:"xAxisSecondLabel"` // 签名2
  131 + XAxisFirstColor string `json:"xAxisFirstColor,optional,omitempty"` // x轴标签1默认颜色
  132 + XAxisSecondColor string `json:"xAxisSecondColor,optional,omitempty"` // x轴标签2默认颜色
126 YAxisLabel string `json:"yAxisLabel"` // y轴标签名 133 YAxisLabel string `json:"yAxisLabel"` // y轴标签名
127 YAxisFirstLabel string `json:"yAxisFirstLabel"` // y标签1 134 YAxisFirstLabel string `json:"yAxisFirstLabel"` // y标签1
128 YAxisSecondLabel string `json:"yAxisSecondLabel"` // y标签2 135 YAxisSecondLabel string `json:"yAxisSecondLabel"` // y标签2
  136 + YAxisFirstColor string `json:"yAxisFirstColor,optional,omitempty"` // y轴标签1默认颜色
  137 + YAxisSecondColor string `json:"yAxisSecondColor,optional,omitempty"` // y轴标签2默认颜色
129 Area string `json:"area"` // 图形面积 138 Area string `json:"area"` // 图形面积
130 AreaColor bool `json:"areaColor"` // 颜色 139 AreaColor bool `json:"areaColor"` // 颜色
131 SeriesList []QuarterSeries `json:"seriesList"` // 图形系列 140 SeriesList []QuarterSeries `json:"seriesList"` // 图形系列
  141 + TableSwitch bool `json:"tableSwitch"` // 是否展示记录型表格
132 } 142 }
133 143
134 type QuarterSeries struct { 144 type QuarterSeries struct {
135 SeriesValue string `json:"seriesValue"` 145 SeriesValue string `json:"seriesValue"`
136 } 146 }
137 147
  148 +type Divider struct {
  149 + SelectedIdx string `json:"selectedIdx,optional,omitempty"` // 选择的分割线样式
  150 + TextSwitch bool `json:"textSwitch,optional,omitempty"` // 是否展示组件文本
  151 + Text string `json:"text"` // 组件文本内容
  152 +}
  153 +
  154 +type Rank struct {
  155 + FirstLine []RankLine `json:"firstLine,optional,omitempty"` // 第一名设置
  156 + SecondLine []RankLine `json:"secondLine,optional,omitempty"` // 第二名设置
  157 + SortBySwitch bool `json:"sortBySwitch,optional,omitempty"` // 排序开关
  158 + SortBySeries string `json:"sortBySeries,optional,omitempty"` // 排序依据
  159 + SortByArrow string `json:"sortByArrow,optional,omitempty"` // 排序方向 1-降序 2-升序
  160 +}
  161 +
  162 +type RankLine struct {
  163 + SeriesValue string `json:"seriesValue"` // 排名图序列值
  164 + LabelSwitch bool `json:"labelSwitch"` // 标签开关
  165 + Label string `json:"label"` // 标签
  166 + ArrowSwitch bool `json:"arrowSwitch"` // 箭头开关
  167 + Unit string `json:"unit"` // 单位
  168 +}
  169 +
138 type Title struct { 170 type Title struct {
139 TitleSwitch bool `json:"titleSwitch,optional"` // 组件标题开关 171 TitleSwitch bool `json:"titleSwitch,optional"` // 组件标题开关
140 IntroduceSwitch bool `json:"introduceSwitch,optional"` // 组件说明开关 172 IntroduceSwitch bool `json:"introduceSwitch,optional"` // 组件说明开关
@@ -153,6 +185,13 @@ type Title struct { @@ -153,6 +185,13 @@ type Title struct {
153 type TableAbility struct { 185 type TableAbility struct {
154 FilterSwitch bool `json:"filterSwitch,optional"` // 表筛选功能开关 186 FilterSwitch bool `json:"filterSwitch,optional"` // 表筛选功能开关
155 DimensionList []Dimension `json:"dimensionList,optional"` // 维度列表 187 DimensionList []Dimension `json:"dimensionList,optional"` // 维度列表
  188 + CardSwitch bool `json:"cardSwitch,optional"` // 顺序标识开关
  189 + CardIdent string `json:"cardIdent,optional"` // 顺序标识
  190 + CardOrderList []CardOrderItem `json:"cardOrderList,optional"` // 卡片列表顺序
  191 +}
  192 +
  193 +type CardOrderItem struct {
  194 + CardId string `json:"cardId,optional"`
156 } 195 }
157 196
158 type Series struct { 197 type Series struct {
@@ -177,11 +216,58 @@ type Dimension struct { @@ -177,11 +216,58 @@ type Dimension struct {
177 Value string `json:"dimensionVal,optional"` 216 Value string `json:"dimensionVal,optional"`
178 } 217 }
179 218
  219 +type Deviation struct {
  220 + XAxisLabel string `json:"xAxisLabel,optional,omitempty"` // 分类标签
  221 + TopChart TopChart `json:"topChart,optional,omitempty"`
  222 + MidChart MidChart `json:"midChart,optional,omitempty"`
  223 + BotChart []BotChart `json:"botChart,optional,omitempty"`
  224 +}
  225 +
  226 +type Notepaper struct {
  227 + Text string `json:"text,optional,omitempty"` // 富文本内容
  228 + Theme string `json:"theme,optional,omitempty"` // 主题风格
  229 +}
  230 +
  231 +type TopChart struct {
  232 + SeriesValue string `json:"seriesValue,optional,omitempty"` // 系列
  233 + Legend string `json:"legend,optional,omitempty"` // 图例
  234 + FormatType string `json:"formatType,optional,omitempty"` //
  235 + FormatPoint string `json:"formatPoint,optional,omitempty"` //
  236 +}
  237 +
  238 +type MidChart struct {
  239 + SeriesValue string `json:"seriesValue,optional,omitempty"` // 系列
  240 + Legend string `json:"legend,optional,omitempty"` // 图例
  241 + FormatType string `json:"formatType,optional,omitempty"` //
  242 + FormatPoint string `json:"formatPoint,optional,omitempty"` //
  243 +}
  244 +
  245 +type BotChart struct {
  246 + SeriesSwitch bool `json:"seriesSwitch,optional,omitempty"` // 是否显示
  247 + Type string `json:"type,optional,omitempty"` // 图表类型
  248 + SeriesValue string `json:"seriesValue,optional,omitempty"` // 系列
  249 + Legend string `json:"legend,optional,omitempty"` // 图例
  250 + FormatType string `json:"formatType,optional,omitempty"` //
  251 + FormatPoint string `json:"formatPoint,optional,omitempty"` //
  252 +}
  253 +
180 type SearchTableByModuleRequest struct { 254 type SearchTableByModuleRequest struct {
181 Token string `header:"x-mmm-accesstoken,optional"` 255 Token string `header:"x-mmm-accesstoken,optional"`
182 } 256 }
183 257
184 type SearchTableByModuleResponse struct { 258 type SearchTableByModuleResponse struct {
  259 + Count int `json:"count"`
  260 + List []SearchTableByModuleItem `json:"list"`
  261 +}
  262 +
  263 +type SearchTableByModuleItem struct {
  264 + Id int `json:"id"` //ID
  265 + TableId int `json:"tableId"` //表ID
  266 + Name string `json:"name"` //表名
  267 + TableType string `json:"tableType"` //表类型
  268 + ParentId int `json:"parentId"` //父级ID
  269 + Flag string `json:"flag"` //分组:Group 集合:Set
  270 + IsLocal bool `json:"isLocal"` //是否本地存储
185 } 271 }
186 272
187 type SearchTableFieldOptionalValuesRequest struct { 273 type SearchTableFieldOptionalValuesRequest struct {
@@ -222,6 +308,14 @@ type SearchTableDataRequest struct { @@ -222,6 +308,14 @@ type SearchTableDataRequest struct {
222 type SearchTableDataResponse struct { 308 type SearchTableDataResponse struct {
223 } 309 }
224 310
  311 +type SyncTableDataPusher struct {
  312 + CompanyId int64 `json:"companyId,string"` //公司ID
  313 + ObjectId int `json:"objectId"`
  314 +}
  315 +
  316 +type SyncTableResponse struct {
  317 +}
  318 +
225 type AppPageGetRequest struct { 319 type AppPageGetRequest struct {
226 Id int64 `path:"id"` 320 Id int64 `path:"id"`
227 } 321 }
@@ -291,6 +385,7 @@ type AppPageItem struct { @@ -291,6 +385,7 @@ type AppPageItem struct {
291 Name string `json:"name,optional"` // 名称 385 Name string `json:"name,optional"` // 名称
292 Cover string `json:"cover,optional"` // 封面 386 Cover string `json:"cover,optional"` // 封面
293 Charts []AppPageChartItem `json:"charts,optional"` // 图表 387 Charts []AppPageChartItem `json:"charts,optional"` // 图表
  388 + UpdatedAt int64 `json:"updatedAt,optional"` //更新时间
294 } 389 }
295 390
296 type AppPageChartItem struct { 391 type AppPageChartItem struct {
  1 +
  2 +syntax = "v1"
  3 +
  4 +info(
  5 + title: "xx实例"
  6 + desc: "xx实例"
  7 + author: "author"
  8 + email: "email"
  9 + version: "v1"
  10 +)
  11 +
  12 +@server(
  13 + prefix: object_field/v1
  14 + group: object_field
  15 + jwt: JwtAuth
  16 +)
  17 +service Core {
  18 + @handler getObjectField
  19 + post /object_field/:id (ObjectFieldGetRequest) returns (ObjectFieldGetResponse)
  20 + @handler saveObjectField
  21 + post /object_field (ObjectFieldSaveRequest) returns (ObjectFieldSaveResponse)
  22 + @handler deleteObjectField
  23 + delete /object_field/:id (ObjectFieldDeleteRequest) returns (ObjectFieldDeleteResponse)
  24 + @handler updateObjectField
  25 + put /object_field/:id (ObjectFieldUpdateRequest) returns (ObjectFieldUpdateResponse)
  26 + @handler searchObjectField
  27 + post /object_field/search (ObjectFieldSearchRequest) returns (ObjectFieldSearchResponse)
  28 +}
  29 +
  30 +type (
  31 + ObjectFieldGetRequest {
  32 + Id int64 `path:"id"`
  33 + }
  34 + ObjectFieldGetResponse struct{
  35 + ObjectField ObjectFieldItem `json:"object_field"`
  36 + }
  37 +
  38 + ObjectFieldSaveRequest struct{
  39 + ObjectField ObjectFieldItem `json:"object_field"`
  40 + }
  41 + ObjectFieldSaveResponse struct{}
  42 +
  43 + ObjectFieldDeleteRequest struct{
  44 + Id int64 `path:"id"`
  45 + }
  46 + ObjectFieldDeleteResponse struct{}
  47 +
  48 + ObjectFieldUpdateRequest struct{
  49 + Id int64 `path:"id"`
  50 + ObjectField ObjectFieldItem `json:"object_field"`
  51 + }
  52 + ObjectFieldUpdateResponse struct{}
  53 +
  54 + ObjectFieldSearchRequest struct{
  55 + Page int `json:"page"`
  56 + Size int `json:"size"`
  57 + }
  58 + ObjectFieldSearchResponse{
  59 + List []ObjectFieldItem `json:"list"`
  60 + Total int64 `json:"total"`
  61 + }
  62 + ObjectFieldItem struct{
  63 +
  64 + }
  65 +)
  1 +
  2 +syntax = "v1"
  3 +
  4 +info(
  5 + title: "xx实例"
  6 + desc: "xx实例"
  7 + author: "author"
  8 + email: "email"
  9 + version: "v1"
  10 +)
  11 +
  12 +@server(
  13 + prefix: object_notice/v1
  14 + group: object_notice
  15 + jwt: JwtAuth
  16 +)
  17 +service Core {
  18 + @handler getObjectNotice
  19 + post /object_notice/:id (ObjectNoticeGetRequest) returns (ObjectNoticeGetResponse)
  20 + @handler saveObjectNotice
  21 + post /object_notice (ObjectNoticeSaveRequest) returns (ObjectNoticeSaveResponse)
  22 + @handler deleteObjectNotice
  23 + delete /object_notice/:id (ObjectNoticeDeleteRequest) returns (ObjectNoticeDeleteResponse)
  24 + @handler updateObjectNotice
  25 + put /object_notice/:id (ObjectNoticeUpdateRequest) returns (ObjectNoticeUpdateResponse)
  26 + @handler searchObjectNotice
  27 + post /object_notice/search (ObjectNoticeSearchRequest) returns (ObjectNoticeSearchResponse)
  28 +}
  29 +
  30 +type (
  31 + ObjectNoticeGetRequest {
  32 + Id int64 `path:"id"`
  33 + }
  34 + ObjectNoticeGetResponse struct{
  35 + ObjectNotice ObjectNoticeItem `json:"object_notice"`
  36 + }
  37 +
  38 + ObjectNoticeSaveRequest struct{
  39 + ObjectNotice ObjectNoticeItem `json:"object_notice"`
  40 + }
  41 + ObjectNoticeSaveResponse struct{}
  42 +
  43 + ObjectNoticeDeleteRequest struct{
  44 + Id int64 `path:"id"`
  45 + }
  46 + ObjectNoticeDeleteResponse struct{}
  47 +
  48 + ObjectNoticeUpdateRequest struct{
  49 + Id int64 `path:"id"`
  50 + ObjectNotice ObjectNoticeItem `json:"object_notice"`
  51 + }
  52 + ObjectNoticeUpdateResponse struct{}
  53 +
  54 + ObjectNoticeSearchRequest struct{
  55 + Page int `json:"page"`
  56 + Size int `json:"size"`
  57 + }
  58 + ObjectNoticeSearchResponse{
  59 + List []ObjectNoticeItem `json:"list"`
  60 + Total int64 `json:"total"`
  61 + }
  62 + ObjectNoticeItem struct{
  63 +
  64 + }
  65 +)
  1 +
  2 +syntax = "v1"
  3 +
  4 +info(
  5 + title: "xx实例"
  6 + desc: "xx实例"
  7 + author: "author"
  8 + email: "email"
  9 + version: "v1"
  10 +)
  11 +
  12 +@server(
  13 + prefix: object_table/v1
  14 + group: object_table
  15 + jwt: JwtAuth
  16 +)
  17 +service Core {
  18 + @handler getObjectTable
  19 + post /object_table/:id (ObjectTableGetRequest) returns (ObjectTableGetResponse)
  20 + @handler saveObjectTable
  21 + post /object_table (ObjectTableSaveRequest) returns (ObjectTableSaveResponse)
  22 + @handler deleteObjectTable
  23 + delete /object_table/:id (ObjectTableDeleteRequest) returns (ObjectTableDeleteResponse)
  24 + @handler updateObjectTable
  25 + put /object_table/:id (ObjectTableUpdateRequest) returns (ObjectTableUpdateResponse)
  26 + @handler searchObjectTable
  27 + post /object_table/search (ObjectTableSearchRequest) returns (ObjectTableSearchResponse)
  28 +}
  29 +
  30 +type (
  31 + ObjectTableGetRequest {
  32 + Id int64 `path:"id"`
  33 + }
  34 + ObjectTableGetResponse struct{
  35 + ObjectTable ObjectTableItem `json:"object_table"`
  36 + }
  37 +
  38 + ObjectTableSaveRequest struct{
  39 + ObjectTable ObjectTableItem `json:"object_table"`
  40 + }
  41 + ObjectTableSaveResponse struct{}
  42 +
  43 + ObjectTableDeleteRequest struct{
  44 + Id int64 `path:"id"`
  45 + }
  46 + ObjectTableDeleteResponse struct{}
  47 +
  48 + ObjectTableUpdateRequest struct{
  49 + Id int64 `path:"id"`
  50 + ObjectTable ObjectTableItem `json:"object_table"`
  51 + }
  52 + ObjectTableUpdateResponse struct{}
  53 +
  54 + ObjectTableSearchRequest struct{
  55 + Page int `json:"page"`
  56 + Size int `json:"size"`
  57 + }
  58 + ObjectTableSearchResponse{
  59 + List []ObjectTableItem `json:"list"`
  60 + Total int64 `json:"total"`
  61 + }
  62 + ObjectTableItem struct{
  63 +
  64 + }
  65 +)
  1 +
  2 +syntax = "proto3";
  3 +
  4 +option go_package ="./pb";
  5 +
  6 +package pb;
  7 +
  8 +message ObjectFieldGetReq {
  9 + int64 Id = 1;
  10 +}
  11 +message ObjectFieldGetResp{
  12 + ObjectFieldItem User = 1;
  13 +}
  14 +
  15 +message ObjectFieldSaveReq {
  16 +
  17 +}
  18 +message ObjectFieldSaveResp{
  19 +
  20 +}
  21 +
  22 +message ObjectFieldDeleteReq {
  23 + int64 Id = 1;
  24 +}
  25 +message ObjectFieldDeleteResp{
  26 +
  27 +}
  28 +
  29 +message ObjectFieldUpdateReq {
  30 + int64 Id = 1;
  31 +}
  32 +message ObjectFieldUpdateResp{
  33 +
  34 +}
  35 +
  36 +message ObjectFieldSearchReq {
  37 + int64 PageNumber = 1;
  38 + int64 PageSize = 2;
  39 +}
  40 +message ObjectFieldSearchResp{
  41 + repeated ObjectFieldItem List =1;
  42 + int64 Total =2;
  43 +}
  44 +message ObjectFieldItem {
  45 +
  46 +}
  47 +
  48 +service ObjectFieldService {
  49 + rpc ObjectFieldGet(ObjectFieldGetReq) returns(ObjectFieldGetResp);
  50 + rpc ObjectFieldSave(ObjectFieldSaveReq) returns(ObjectFieldSaveResp);
  51 + rpc ObjectFieldDelete(ObjectFieldDeleteReq) returns(ObjectFieldDeleteResp);
  52 + rpc ObjectFieldUpdate(ObjectFieldUpdateReq) returns(ObjectFieldUpdateResp);
  53 + rpc ObjectFieldSearch(ObjectFieldSearchReq) returns(ObjectFieldSearchResp);
  54 +}
  1 +
  2 +syntax = "proto3";
  3 +
  4 +option go_package ="./pb";
  5 +
  6 +package pb;
  7 +
  8 +message ObjectNoticeGetReq {
  9 + int64 Id = 1;
  10 +}
  11 +message ObjectNoticeGetResp{
  12 + ObjectNoticeItem User = 1;
  13 +}
  14 +
  15 +message ObjectNoticeSaveReq {
  16 +
  17 +}
  18 +message ObjectNoticeSaveResp{
  19 +
  20 +}
  21 +
  22 +message ObjectNoticeDeleteReq {
  23 + int64 Id = 1;
  24 +}
  25 +message ObjectNoticeDeleteResp{
  26 +
  27 +}
  28 +
  29 +message ObjectNoticeUpdateReq {
  30 + int64 Id = 1;
  31 +}
  32 +message ObjectNoticeUpdateResp{
  33 +
  34 +}
  35 +
  36 +message ObjectNoticeSearchReq {
  37 + int64 PageNumber = 1;
  38 + int64 PageSize = 2;
  39 +}
  40 +message ObjectNoticeSearchResp{
  41 + repeated ObjectNoticeItem List =1;
  42 + int64 Total =2;
  43 +}
  44 +message ObjectNoticeItem {
  45 +
  46 +}
  47 +
  48 +service ObjectNoticeService {
  49 + rpc ObjectNoticeGet(ObjectNoticeGetReq) returns(ObjectNoticeGetResp);
  50 + rpc ObjectNoticeSave(ObjectNoticeSaveReq) returns(ObjectNoticeSaveResp);
  51 + rpc ObjectNoticeDelete(ObjectNoticeDeleteReq) returns(ObjectNoticeDeleteResp);
  52 + rpc ObjectNoticeUpdate(ObjectNoticeUpdateReq) returns(ObjectNoticeUpdateResp);
  53 + rpc ObjectNoticeSearch(ObjectNoticeSearchReq) returns(ObjectNoticeSearchResp);
  54 +}
  1 +
  2 +syntax = "proto3";
  3 +
  4 +option go_package ="./pb";
  5 +
  6 +package pb;
  7 +
  8 +message ObjectTableGetReq {
  9 + int64 Id = 1;
  10 +}
  11 +message ObjectTableGetResp{
  12 + ObjectTableItem User = 1;
  13 +}
  14 +
  15 +message ObjectTableSaveReq {
  16 +
  17 +}
  18 +message ObjectTableSaveResp{
  19 +
  20 +}
  21 +
  22 +message ObjectTableDeleteReq {
  23 + int64 Id = 1;
  24 +}
  25 +message ObjectTableDeleteResp{
  26 +
  27 +}
  28 +
  29 +message ObjectTableUpdateReq {
  30 + int64 Id = 1;
  31 +}
  32 +message ObjectTableUpdateResp{
  33 +
  34 +}
  35 +
  36 +message ObjectTableSearchReq {
  37 + int64 PageNumber = 1;
  38 + int64 PageSize = 2;
  39 +}
  40 +message ObjectTableSearchResp{
  41 + repeated ObjectTableItem List =1;
  42 + int64 Total =2;
  43 +}
  44 +message ObjectTableItem {
  45 +
  46 +}
  47 +
  48 +service ObjectTableService {
  49 + rpc ObjectTableGet(ObjectTableGetReq) returns(ObjectTableGetResp);
  50 + rpc ObjectTableSave(ObjectTableSaveReq) returns(ObjectTableSaveResp);
  51 + rpc ObjectTableDelete(ObjectTableDeleteReq) returns(ObjectTableDeleteResp);
  52 + rpc ObjectTableUpdate(ObjectTableUpdateReq) returns(ObjectTableUpdateResp);
  53 + rpc ObjectTableSearch(ObjectTableSearchReq) returns(ObjectTableSearchResp);
  54 +}
@@ -10,5 +10,8 @@ func Migrate(db *gorm.DB) { @@ -10,5 +10,8 @@ func Migrate(db *gorm.DB) {
10 &models.Chart{}, 10 &models.Chart{},
11 &models.ChartSetting{}, 11 &models.ChartSetting{},
12 &models.AppPage{}, 12 &models.AppPage{},
  13 + &models.ObjectNotice{},
  14 + &models.ObjectTable{},
  15 + &models.ObjectField{},
13 ) 16 )
14 } 17 }
  1 +package models
  2 +
  3 +import (
  4 + "fmt"
  5 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/domain"
  6 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/gateway/bytelib"
  7 + "gorm.io/gorm"
  8 + "gorm.io/plugin/soft_delete"
  9 + "time"
  10 +)
  11 +
  12 +type ObjectField struct {
  13 + Id int64 `json:"id" gorm:"primaryKey"` // ID
  14 + Name string `json:"name"` //表名
  15 + Fields []*bytelib.Field `json:"fields" gorm:"serializer:json"` //表字段
  16 + Version int `json:",omitempty"` //版本
  17 + IsDel soft_delete.DeletedAt `gorm:"softDelete:flag,DeletedAtField:DeletedAt"` //删除标记
  18 + CreatedAt int64 `json:",omitempty"` //创建时间
  19 + UpdatedAt int64 `json:",omitempty"` //更新时间
  20 + DeletedAt int64 `json:",omitempty"` //删除时间
  21 +}
  22 +
  23 +func (m *ObjectField) TableName() string {
  24 + return "object_field"
  25 +}
  26 +
  27 +func (m *ObjectField) BeforeCreate(tx *gorm.DB) (err error) {
  28 + m.CreatedAt = time.Now().Unix()
  29 + m.UpdatedAt = time.Now().Unix()
  30 + return
  31 +}
  32 +
  33 +func (m *ObjectField) BeforeUpdate(tx *gorm.DB) (err error) {
  34 + m.UpdatedAt = time.Now().Unix()
  35 + return
  36 +}
  37 +
  38 +func (m *ObjectField) CacheKeyFunc() string {
  39 + if m.Id == 0 {
  40 + return ""
  41 + }
  42 + return fmt.Sprintf("%v:cache:%v:id:%v", domain.ProjectName, m.TableName(), m.Id)
  43 +}
  44 +
  45 +func (m *ObjectField) CacheKeyFuncByObject(obj interface{}) string {
  46 + if v, ok := obj.(*ObjectField); ok {
  47 + return v.CacheKeyFunc()
  48 + }
  49 + return ""
  50 +}
  51 +
  52 +func (m *ObjectField) CachePrimaryKeyFunc() string {
  53 + if len("") == 0 {
  54 + return ""
  55 + }
  56 + return fmt.Sprintf("%v:cache:%v:primarykey:%v", domain.ProjectName, m.TableName(), "key")
  57 +}
  1 +package models
  2 +
  3 +import (
  4 + "fmt"
  5 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/domain"
  6 + "gorm.io/gorm"
  7 + "gorm.io/plugin/soft_delete"
  8 + "time"
  9 +)
  10 +
  11 +type ObjectNotice struct {
  12 + Id int64 `json:"id" gorm:"primaryKey"` // ID
  13 + CompanyId int64 `json:"companyId"` //公司ID
  14 + TableId int64 `json:"tableId"` //表ID
  15 + TableType string `json:"tableType"` //表类型 导入模块(主表、附表、分表) 拆解(方案、子过程、计算表) 计算(计算项、计算集)
  16 + ObjectType string `json:"objectType"` //模块 导入模块、拆解模块、计算模块
  17 + Event string `json:"event"` //事件
  18 + TableAffectedList []int `json:"TableAffectedList" gorm:"serializer:json"` //级联影响到的表
  19 + DataChanged bool `json:"dataChanged"` //数据有更新
  20 + StructChanged bool `json:"structChanged"` //结构有更新
  21 + Status int `json:"status" gorm:"index:idx_object_notice_status"` //状态 1-等待处理 2-处理完成 3-处理失败
  22 + Message string `json:"message"` //错误信息
  23 + Retry int `json:"retry" gorm:"default:0"` //重试次数
  24 + MetaData domain.ObjectNoticeMetaData `json:"metaData" gorm:"serializer:json"` //模块信息
  25 + Version int `json:",omitempty"` //版本
  26 + IsDel soft_delete.DeletedAt `gorm:"softDelete:flag,DeletedAtField:DeletedAt"` //删除标记
  27 + CreatedAt int64 `json:",omitempty"` //创建时间
  28 + UpdatedAt int64 `json:",omitempty"` //更新时间
  29 + DeletedAt int64 `json:",omitempty"` //删除时间
  30 +}
  31 +
  32 +func (m *ObjectNotice) TableName() string {
  33 + return "object_notice"
  34 +}
  35 +
  36 +func (m *ObjectNotice) BeforeCreate(tx *gorm.DB) (err error) {
  37 + m.CreatedAt = time.Now().Unix()
  38 + m.UpdatedAt = time.Now().Unix()
  39 + return
  40 +}
  41 +
  42 +func (m *ObjectNotice) BeforeUpdate(tx *gorm.DB) (err error) {
  43 + m.UpdatedAt = time.Now().Unix()
  44 + return
  45 +}
  46 +
  47 +func (m *ObjectNotice) CacheKeyFunc() string {
  48 + if m.Id == 0 {
  49 + return ""
  50 + }
  51 + return fmt.Sprintf("%v:cache:%v:id:%v", domain.ProjectName, m.TableName(), m.Id)
  52 +}
  53 +
  54 +func (m *ObjectNotice) CacheKeyFuncByObject(obj interface{}) string {
  55 + if v, ok := obj.(*ObjectNotice); ok {
  56 + return v.CacheKeyFunc()
  57 + }
  58 + return ""
  59 +}
  60 +
  61 +func (m *ObjectNotice) CachePrimaryKeyFunc() string {
  62 + if len("") == 0 {
  63 + return ""
  64 + }
  65 + return fmt.Sprintf("%v:cache:%v:primarykey:%v", domain.ProjectName, m.TableName(), "key")
  66 +}
  1 +package models
  2 +
  3 +import (
  4 + "fmt"
  5 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/domain"
  6 + "gorm.io/gorm"
  7 + "gorm.io/plugin/soft_delete"
  8 + "time"
  9 +)
  10 +
  11 +type ObjectTable struct {
  12 + Id int `json:"id" gorm:"primaryKey;autoIncrement:false"` // ID
  13 + TableId int `json:"tableId" gorm:"index:idx_object_table_id"` //表ID
  14 + Name string `json:"name"` //表名
  15 + TableType string `json:"tableType" gorm:"primaryKey;autoIncrement:false;index:idx_object_table_type"` //模块
  16 + CompanyId int64 `json:"companyId" gorm:"index:idx_object_table_company"` //公司id
  17 + ParentId int `json:"parentId" gorm:"default:0"` //父id
  18 + Flag string `json:"flag"` //分组:Group 集合:Set
  19 + Version int `json:",omitempty"` //版本
  20 + IsLocal bool `json:"isLocal" gorm:"default:false"` //是否有本地存储
  21 + RemoteDeleted int `json:"remoteDeleted"` //远端删除
  22 + IsDel soft_delete.DeletedAt `gorm:"softDelete:flag,DeletedAtField:DeletedAt"` //删除标记
  23 + CreatedAt int64 `json:",omitempty"` //创建时间
  24 + UpdatedAt int64 `json:",omitempty"` //更新时间
  25 + DeletedAt int64 `json:",omitempty"` //删除时间
  26 +}
  27 +
  28 +func (m *ObjectTable) TableName() string {
  29 + return "object_table"
  30 +}
  31 +
  32 +func (m *ObjectTable) BeforeCreate(tx *gorm.DB) (err error) {
  33 + m.CreatedAt = time.Now().Unix()
  34 + m.UpdatedAt = time.Now().Unix()
  35 + return
  36 +}
  37 +
  38 +func (m *ObjectTable) BeforeUpdate(tx *gorm.DB) (err error) {
  39 + m.UpdatedAt = time.Now().Unix()
  40 + return
  41 +}
  42 +
  43 +func (m *ObjectTable) CacheKeyFunc() string {
  44 + if m.Id == 0 {
  45 + return ""
  46 + }
  47 + return fmt.Sprintf("%v:cache:%v:id:%v", domain.ProjectName, m.TableName(), m.Id)
  48 +}
  49 +
  50 +func (m *ObjectTable) CacheKeyFuncByObject(obj interface{}) string {
  51 + if v, ok := obj.(*ObjectTable); ok {
  52 + return v.CacheKeyFunc()
  53 + }
  54 + return ""
  55 +}
  56 +
  57 +func (m *ObjectTable) CachePrimaryKeyFunc() string {
  58 + if len("") == 0 {
  59 + return ""
  60 + }
  61 + return fmt.Sprintf("%v:cache:%v:primarykey:%v", domain.ProjectName, m.TableName(), "key")
  62 +}
@@ -162,7 +162,7 @@ func (repository *AppPageRepository) Find(ctx context.Context, conn transaction. @@ -162,7 +162,7 @@ func (repository *AppPageRepository) Find(ctx context.Context, conn transaction.
162 total int64 162 total int64
163 ) 163 )
164 queryFunc := func() (interface{}, error) { 164 queryFunc := func() (interface{}, error) {
165 - tx = tx.Model(&ms).Order("id desc") 165 + tx = tx.Model(&ms).Order("updated_at desc")
166 if v, ok := queryOptions["tenantId"]; ok { 166 if v, ok := queryOptions["tenantId"]; ok {
167 tx.Where("tenant_id = ?", v) 167 tx.Where("tenant_id = ?", v)
168 } 168 }
@@ -119,7 +119,7 @@ func (repository *ChartRepository) Find(ctx context.Context, conn transaction.Co @@ -119,7 +119,7 @@ func (repository *ChartRepository) Find(ctx context.Context, conn transaction.Co
119 total int64 119 total int64
120 ) 120 )
121 queryFunc := func() (interface{}, error) { 121 queryFunc := func() (interface{}, error) {
122 - tx = tx.Model(&ms).Order("id desc") //.Order("pid asc").Order("sort asc") 122 + tx = tx.Model(&ms).Order("updated_at desc") //.Order("pid asc").Order("sort asc")
123 if v, ok := queryOptions["ids"]; ok { 123 if v, ok := queryOptions["ids"]; ok {
124 tx.Where("id in (?)", v) 124 tx.Where("id in (?)", v)
125 } 125 }
@@ -201,6 +201,18 @@ func (repository *ChartRepository) FindOneByGroup(ctx context.Context, conn tran @@ -201,6 +201,18 @@ func (repository *ChartRepository) FindOneByGroup(ctx context.Context, conn tran
201 return repository.ModelToDomainModel(m) 201 return repository.ModelToDomainModel(m)
202 } 202 }
203 203
  204 +// FindCompanyIds 获取所有的公司ID
  205 +func (repository *ChartRepository) FindCompanyIds(ctx context.Context, conn transaction.Conn) ([]int64, error) {
  206 + var (
  207 + err error
  208 + tx = conn.DB()
  209 + m = new(models.Chart)
  210 + )
  211 + list := make([]int64, 0)
  212 + err = tx.Model(&m).Group("tenant_id").Pluck("tenant_id", &list).Error
  213 + return list, err
  214 +}
  215 +
204 func (repository *ChartRepository) ModelToDomainModel(from *models.Chart) (*domain.Chart, error) { 216 func (repository *ChartRepository) ModelToDomainModel(from *models.Chart) (*domain.Chart, error) {
205 to := &domain.Chart{} 217 to := &domain.Chart{}
206 err := copier.Copy(to, from) 218 err := copier.Copy(to, from)
@@ -2,6 +2,7 @@ package repository @@ -2,6 +2,7 @@ package repository
2 2
3 import ( 3 import (
4 "context" 4 "context"
  5 + "fmt"
5 "github.com/jinzhu/copier" 6 "github.com/jinzhu/copier"
6 "github.com/pkg/errors" 7 "github.com/pkg/errors"
7 "github.com/tiptok/gocomm/pkg/cache" 8 "github.com/tiptok/gocomm/pkg/cache"
@@ -140,6 +141,19 @@ func (repository *ChartSettingRepository) Find(ctx context.Context, conn transac @@ -140,6 +141,19 @@ func (repository *ChartSettingRepository) Find(ctx context.Context, conn transac
140 return total, dms, nil 141 return total, dms, nil
141 } 142 }
142 143
  144 +// CheckUseDataSource 检验是否使用数据源
  145 +func (repository *ChartSettingRepository) CheckUseDataSource(ctx context.Context, conn transaction.Conn, objectId int) (bool, error) {
  146 + var count int64
  147 + err := conn.DB().Model(&models.ChartSetting{}).
  148 + Joins("left join chart on chart.id=chart_setting.chart_id").
  149 + Where("chart.is_del = 0").
  150 + Where(fmt.Sprintf("data_source_ids::jsonb @>'[%v]'", objectId)).Count(&count).Error
  151 + if err != nil {
  152 + return false, err
  153 + }
  154 + return count > 0, nil
  155 +}
  156 +
143 func (repository *ChartSettingRepository) ModelToDomainModel(from *models.ChartSetting) (*domain.ChartSetting, error) { 157 func (repository *ChartSettingRepository) ModelToDomainModel(from *models.ChartSetting) (*domain.ChartSetting, error) {
144 to := &domain.ChartSetting{} 158 to := &domain.ChartSetting{}
145 err := copier.Copy(to, from) 159 err := copier.Copy(to, from)
  1 +package repository
  2 +
  3 +import (
  4 + "context"
  5 + "github.com/jinzhu/copier"
  6 + "github.com/pkg/errors"
  7 + "github.com/tiptok/gocomm/pkg/cache"
  8 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/db/models"
  9 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/db/transaction"
  10 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/domain"
  11 + "gorm.io/gorm"
  12 +)
  13 +
  14 +type ObjectFieldRepository struct {
  15 + *cache.CachedRepository
  16 +}
  17 +
  18 +func (repository *ObjectFieldRepository) Insert(ctx context.Context, conn transaction.Conn, dm *domain.ObjectField) (*domain.ObjectField, error) {
  19 + var (
  20 + err error
  21 + m = &models.ObjectField{}
  22 + tx = conn.DB()
  23 + )
  24 + if m, err = repository.DomainModelToModel(dm); err != nil {
  25 + return nil, err
  26 + }
  27 + if tx = tx.Model(m).Save(m); tx.Error != nil {
  28 + return nil, tx.Error
  29 + }
  30 + dm.Id = m.Id
  31 + return repository.ModelToDomainModel(m)
  32 +}
  33 +
  34 +func (repository *ObjectFieldRepository) Update(ctx context.Context, conn transaction.Conn, dm *domain.ObjectField) (*domain.ObjectField, error) {
  35 + var (
  36 + err error
  37 + m *models.ObjectField
  38 + tx = conn.DB()
  39 + )
  40 + if m, err = repository.DomainModelToModel(dm); err != nil {
  41 + return nil, err
  42 + }
  43 + queryFunc := func() (interface{}, error) {
  44 + tx = tx.Model(m).Updates(m)
  45 + return nil, tx.Error
  46 + }
  47 + if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
  48 + return nil, err
  49 + }
  50 + return repository.ModelToDomainModel(m)
  51 +}
  52 +
  53 +func (repository *ObjectFieldRepository) UpdateWithVersion(ctx context.Context, transaction transaction.Conn, dm *domain.ObjectField) (*domain.ObjectField, error) {
  54 + var (
  55 + err error
  56 + m *models.ObjectField
  57 + tx = transaction.DB()
  58 + )
  59 + if m, err = repository.DomainModelToModel(dm); err != nil {
  60 + return nil, err
  61 + }
  62 + oldVersion := dm.Version
  63 + m.Version += 1
  64 + queryFunc := func() (interface{}, error) {
  65 + tx = tx.Model(m).Select("*").Where("id = ?", m.Id).Where("version = ?", oldVersion).Updates(m)
  66 + if tx.RowsAffected == 0 {
  67 + return nil, domain.ErrUpdateFail
  68 + }
  69 + return nil, tx.Error
  70 + }
  71 + if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
  72 + return nil, err
  73 + }
  74 + return repository.ModelToDomainModel(m)
  75 +}
  76 +
  77 +func (repository *ObjectFieldRepository) Delete(ctx context.Context, conn transaction.Conn, dm *domain.ObjectField) (*domain.ObjectField, error) {
  78 + var (
  79 + tx = conn.DB()
  80 + m = &models.ObjectField{Id: dm.Identify().(int64)}
  81 + )
  82 + queryFunc := func() (interface{}, error) {
  83 + tx = tx.Where("id = ?", m.Id).Unscoped().Delete(m)
  84 + return m, tx.Error
  85 + }
  86 + if _, err := repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
  87 + return dm, err
  88 + }
  89 + return repository.ModelToDomainModel(m)
  90 +}
  91 +
  92 +func (repository *ObjectFieldRepository) FindOne(ctx context.Context, conn transaction.Conn, id int64) (*domain.ObjectField, error) {
  93 + var (
  94 + err error
  95 + tx = conn.DB()
  96 + m = new(models.ObjectField)
  97 + )
  98 + queryFunc := func() (interface{}, error) {
  99 + tx = tx.Model(m).Where("id = ?", id).First(m)
  100 + if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
  101 + return nil, domain.ErrNotFound
  102 + }
  103 + return m, tx.Error
  104 + }
  105 + cacheModel := new(models.ObjectField)
  106 + cacheModel.Id = id
  107 + if err = repository.QueryCache(cacheModel.CacheKeyFunc, m, queryFunc); err != nil {
  108 + return nil, err
  109 + }
  110 + return repository.ModelToDomainModel(m)
  111 +}
  112 +
  113 +func (repository *ObjectFieldRepository) Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*domain.ObjectField, error) {
  114 + var (
  115 + tx = conn.DB()
  116 + ms []*models.ObjectField
  117 + dms = make([]*domain.ObjectField, 0)
  118 + total int64
  119 + )
  120 + queryFunc := func() (interface{}, error) {
  121 + tx = tx.Model(&ms).Order("id desc")
  122 + if total, tx = transaction.PaginationAndCount(ctx, tx, queryOptions, &ms); tx.Error != nil {
  123 + return dms, tx.Error
  124 + }
  125 + return dms, nil
  126 + }
  127 +
  128 + if _, err := repository.Query(queryFunc); err != nil {
  129 + return 0, nil, err
  130 + }
  131 +
  132 + for _, item := range ms {
  133 + if dm, err := repository.ModelToDomainModel(item); err != nil {
  134 + return 0, dms, err
  135 + } else {
  136 + dms = append(dms, dm)
  137 + }
  138 + }
  139 + return total, dms, nil
  140 +}
  141 +
  142 +func (repository *ObjectFieldRepository) ModelToDomainModel(from *models.ObjectField) (*domain.ObjectField, error) {
  143 + to := &domain.ObjectField{}
  144 + err := copier.Copy(to, from)
  145 + return to, err
  146 +}
  147 +
  148 +func (repository *ObjectFieldRepository) DomainModelToModel(from *domain.ObjectField) (*models.ObjectField, error) {
  149 + to := &models.ObjectField{}
  150 + err := copier.Copy(to, from)
  151 + return to, err
  152 +}
  153 +
  154 +func NewObjectFieldRepository(cache *cache.CachedRepository) domain.ObjectFieldRepository {
  155 + return &ObjectFieldRepository{CachedRepository: cache}
  156 +}
  1 +package repository
  2 +
  3 +import (
  4 + "context"
  5 + "github.com/jinzhu/copier"
  6 + "github.com/pkg/errors"
  7 + "github.com/tiptok/gocomm/pkg/cache"
  8 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/db/models"
  9 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/db/transaction"
  10 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/domain"
  11 + "gorm.io/gorm"
  12 +)
  13 +
  14 +type ObjectNoticeRepository struct {
  15 + *cache.CachedRepository
  16 +}
  17 +
  18 +func (repository *ObjectNoticeRepository) Insert(ctx context.Context, conn transaction.Conn, dm *domain.ObjectNotice) (*domain.ObjectNotice, error) {
  19 + var (
  20 + err error
  21 + m = &models.ObjectNotice{}
  22 + tx = conn.DB()
  23 + )
  24 + if m, err = repository.DomainModelToModel(dm); err != nil {
  25 + return nil, err
  26 + }
  27 + if tx = tx.Model(m).Save(m); tx.Error != nil {
  28 + return nil, tx.Error
  29 + }
  30 + dm.Id = m.Id
  31 + return repository.ModelToDomainModel(m)
  32 +
  33 +}
  34 +
  35 +func (repository *ObjectNoticeRepository) Update(ctx context.Context, conn transaction.Conn, dm *domain.ObjectNotice) (*domain.ObjectNotice, error) {
  36 + var (
  37 + err error
  38 + m *models.ObjectNotice
  39 + tx = conn.DB()
  40 + )
  41 + if m, err = repository.DomainModelToModel(dm); err != nil {
  42 + return nil, err
  43 + }
  44 + queryFunc := func() (interface{}, error) {
  45 + tx = tx.Model(m).Updates(m)
  46 + return nil, tx.Error
  47 + }
  48 + if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
  49 + return nil, err
  50 + }
  51 + return repository.ModelToDomainModel(m)
  52 +}
  53 +
  54 +func (repository *ObjectNoticeRepository) UpdateWithVersion(ctx context.Context, transaction transaction.Conn, dm *domain.ObjectNotice) (*domain.ObjectNotice, error) {
  55 + var (
  56 + err error
  57 + m *models.ObjectNotice
  58 + tx = transaction.DB()
  59 + )
  60 + if m, err = repository.DomainModelToModel(dm); err != nil {
  61 + return nil, err
  62 + }
  63 + oldVersion := dm.Version
  64 + m.Version += 1
  65 + queryFunc := func() (interface{}, error) {
  66 + tx = tx.Model(m).Select("*").Where("id = ?", m.Id).Where("version = ?", oldVersion).Updates(m)
  67 + if tx.RowsAffected == 0 {
  68 + return nil, domain.ErrUpdateFail
  69 + }
  70 + return nil, tx.Error
  71 + }
  72 + if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
  73 + return nil, err
  74 + }
  75 + return repository.ModelToDomainModel(m)
  76 +}
  77 +
  78 +func (repository *ObjectNoticeRepository) Delete(ctx context.Context, conn transaction.Conn, dm *domain.ObjectNotice) (*domain.ObjectNotice, error) {
  79 + var (
  80 + tx = conn.DB()
  81 + m = &models.ObjectNotice{Id: dm.Identify().(int64)}
  82 + )
  83 + queryFunc := func() (interface{}, error) {
  84 + tx = tx.Where("id = ?", m.Id).Delete(m)
  85 + return m, tx.Error
  86 + }
  87 + if _, err := repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
  88 + return dm, err
  89 + }
  90 + return repository.ModelToDomainModel(m)
  91 +}
  92 +
  93 +func (repository *ObjectNoticeRepository) FindOne(ctx context.Context, conn transaction.Conn, id int64) (*domain.ObjectNotice, error) {
  94 + var (
  95 + err error
  96 + tx = conn.DB()
  97 + m = new(models.ObjectNotice)
  98 + )
  99 + queryFunc := func() (interface{}, error) {
  100 + tx = tx.Model(m).Where("id = ?", id).First(m)
  101 + if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
  102 + return nil, domain.ErrNotFound
  103 + }
  104 + return m, tx.Error
  105 + }
  106 + cacheModel := new(models.ObjectNotice)
  107 + cacheModel.Id = id
  108 + if err = repository.QueryCache(cacheModel.CacheKeyFunc, m, queryFunc); err != nil {
  109 + return nil, err
  110 + }
  111 + return repository.ModelToDomainModel(m)
  112 +}
  113 +
  114 +func (repository *ObjectNoticeRepository) Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*domain.ObjectNotice, error) {
  115 + var (
  116 + tx = conn.DB()
  117 + ms []*models.ObjectNotice
  118 + dms = make([]*domain.ObjectNotice, 0)
  119 + total int64
  120 + )
  121 + queryFunc := func() (interface{}, error) {
  122 + tx = tx.Model(&ms).Order("id desc")
  123 + if total, tx = transaction.PaginationAndCount(ctx, tx, queryOptions, &ms); tx.Error != nil {
  124 + return dms, tx.Error
  125 + }
  126 + return dms, nil
  127 + }
  128 +
  129 + if _, err := repository.Query(queryFunc); err != nil {
  130 + return 0, nil, err
  131 + }
  132 +
  133 + for _, item := range ms {
  134 + if dm, err := repository.ModelToDomainModel(item); err != nil {
  135 + return 0, dms, err
  136 + } else {
  137 + dms = append(dms, dm)
  138 + }
  139 + }
  140 + return total, dms, nil
  141 +}
  142 +
  143 +func (repository *ObjectNoticeRepository) ModelToDomainModel(from *models.ObjectNotice) (*domain.ObjectNotice, error) {
  144 + to := &domain.ObjectNotice{}
  145 + err := copier.Copy(to, from)
  146 + return to, err
  147 +}
  148 +
  149 +func (repository *ObjectNoticeRepository) DomainModelToModel(from *domain.ObjectNotice) (*models.ObjectNotice, error) {
  150 + to := &models.ObjectNotice{}
  151 + err := copier.Copy(to, from)
  152 + return to, err
  153 +}
  154 +
  155 +func NewObjectNoticeRepository(cache *cache.CachedRepository) domain.ObjectNoticeRepository {
  156 + return &ObjectNoticeRepository{CachedRepository: cache}
  157 +}
  1 +package repository
  2 +
  3 +import (
  4 + "context"
  5 + "fmt"
  6 + "github.com/pkg/errors"
  7 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/db/transaction"
  8 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/domain"
  9 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/gateway/bytelib"
  10 + "strconv"
  11 + "strings"
  12 +)
  13 +
  14 +type ObjectTableDataRepository struct{}
  15 +
  16 +type TableColumnSQL struct {
  17 + Sql string `json:"sql"`
  18 + Column []string `json:"column"`
  19 + Data []map[string]string `json:"data"`
  20 +}
  21 +
  22 +// makeDropTableSQL 创建删除表SQL
  23 +func (repository *ObjectTableDataRepository) makeDropTableSQL(tableId int) (string, error) {
  24 + return fmt.Sprintf(`drop table if exists data."%v"`, tableId), nil
  25 +}
  26 +
  27 +// makeCreateTableSQL 创建表SQL
  28 +func (repository *ObjectTableDataRepository) makeCreateTableSQL(tableId int, tableData bytelib.TableData) (string, error) {
  29 + fields := tableData.Fields
  30 + list := tableData.Grid.List
  31 + if len(fields) <= 0 {
  32 + return "", errors.New("缺少字段信息")
  33 + }
  34 + columns := make([]string, 0)
  35 + for _, item := range fields {
  36 + fieldType := "text"
  37 + //判断字段是否为id,并且数据值能转为整型 设置字段类型 为 int8,否则为 text
  38 + if item.SQLName == "id" && len(list) > 0 {
  39 + listItem := list[0]
  40 + if idValue, ok := listItem["id"]; ok {
  41 + _, err := strconv.Atoi(idValue)
  42 + if err == nil {
  43 + fieldType = "int8"
  44 + }
  45 + }
  46 + }
  47 + columns = append(columns, item.SQLName+" "+fieldType+" ")
  48 + }
  49 + sql := `Create TABLE data."` + fmt.Sprintf("%v", tableId) + `" (` + strings.Join(columns, ",") + `);`
  50 + return sql, nil
  51 +}
  52 +
  53 +// makeInsertTableSQL 创建表数据SQL
  54 +func (repository *ObjectTableDataRepository) makeInsertTableSQL(tableId int, fields []*bytelib.Field, list []map[string]string) (*TableColumnSQL, error) {
  55 + tableColumnSQL := &TableColumnSQL{
  56 + Column: make([]string, 0),
  57 + Data: make([]map[string]string, 0),
  58 + }
  59 + if len(list) > 0 && len(fields) > 0 {
  60 + for _, field := range fields {
  61 + tableColumnSQL.Column = append(tableColumnSQL.Column, field.SQLName)
  62 + }
  63 + for _, item := range list {
  64 + values := make(map[string]string)
  65 + for _, field := range tableColumnSQL.Column {
  66 + if _, ok := item[field]; ok {
  67 + values[field] = item[field]
  68 + } else {
  69 + return tableColumnSQL, errors.New("未获取到字段值")
  70 + }
  71 + }
  72 + tableColumnSQL.Data = append(tableColumnSQL.Data, values)
  73 + }
  74 +
  75 + tableColumnSQL.Sql = fmt.Sprintf(`INSERT INTO data."%v" (%s) values (%s)`, tableId, strings.Join(tableColumnSQL.Column, ","), repository.sqlPlaceHoldersSnippet(tableColumnSQL.Column))
  76 + }
  77 + return tableColumnSQL, nil
  78 +}
  79 +
  80 +func (repository *ObjectTableDataRepository) sqlPlaceHoldersSnippet(sqlBuildFields []string) string {
  81 + var placeHolder []string
  82 + for i := 0; i < len(sqlBuildFields); i++ {
  83 + placeHolder = append(placeHolder, "?")
  84 + }
  85 + return strings.Join(placeHolder, ",")
  86 +}
  87 +
  88 +func (repository *ObjectTableDataRepository) DropTable(ctx context.Context, conn transaction.Conn, tableId int) error {
  89 + sql, err := repository.makeDropTableSQL(tableId)
  90 + if err != nil {
  91 + return err
  92 + }
  93 + err = conn.DB().Exec(sql).Error
  94 + if err != nil {
  95 + return err
  96 + }
  97 + //设置数据表本地存储为false
  98 + return conn.DB().Exec("update object_table set is_local=false where table_id = ? and is_del=0", tableId).Error
  99 +}
  100 +
  101 +// InsertWithTableData 写入表数据
  102 +func (repository *ObjectTableDataRepository) InsertWithTableData(ctx context.Context, conn transaction.Conn, tableDataPreview bytelib.TableData) error {
  103 + //删除表
  104 + err := repository.DropTable(ctx, conn, int(tableDataPreview.ObjectId))
  105 + if err != nil {
  106 + return err
  107 + }
  108 + //创建表
  109 + createTableSql, err := repository.makeCreateTableSQL(int(tableDataPreview.ObjectId), tableDataPreview)
  110 + if err != nil {
  111 + return err
  112 + }
  113 + err = conn.DB().Exec(createTableSql).Error
  114 + if err != nil {
  115 + return err
  116 + }
  117 + tableColumnSQL, err := repository.makeInsertTableSQL(int(tableDataPreview.ObjectId), tableDataPreview.Fields, tableDataPreview.Grid.List)
  118 + if err != nil {
  119 + return err
  120 + }
  121 + if len(tableColumnSQL.Column) > 0 && len(tableColumnSQL.Data) > 0 {
  122 + for _, item := range tableColumnSQL.Data {
  123 + if len(item) > 0 {
  124 + params := make([]interface{}, 0)
  125 + for _, m := range tableColumnSQL.Column {
  126 + if _, ok := item[m]; ok {
  127 + params = append(params, item[m])
  128 + } else {
  129 + params = append(params, "")
  130 + }
  131 + }
  132 + err = conn.DB().Exec(tableColumnSQL.Sql, params...).Error
  133 + if err != nil {
  134 + return err
  135 + }
  136 + }
  137 + }
  138 + }
  139 + return nil
  140 +}
  141 +
  142 +// Find 获取表内所有数据
  143 +func (repository *ObjectTableDataRepository) Find(ctx context.Context, conn transaction.Conn, tableId int, query *domain.ObjectTableDataQuery) (int64, []map[string]interface{}, error) {
  144 + tx := conn.DB().Table(fmt.Sprintf("data.%v", tableId))
  145 + if len(query.Conditions) > 0 {
  146 + for _, item := range query.Conditions {
  147 + if item.FieldName == "" {
  148 + continue
  149 + }
  150 + if item.Like != "" {
  151 + tx = tx.Where(item.FieldName+" like ?", item.Like)
  152 + }
  153 + if len(item.In) > 0 {
  154 + tx = tx.Where(item.FieldName+" in ?", item.In)
  155 + }
  156 + if item.Order != "" {
  157 + tx = tx.Order(item.FieldName + " " + item.Order)
  158 + }
  159 + }
  160 + }
  161 + if query.Group != "" {
  162 + tx = tx.Group(query.Group)
  163 + }
  164 + if query.Select != "" {
  165 + tx = tx.Select(query.Select)
  166 + }
  167 + list := make([]map[string]interface{}, 0)
  168 + options := domain.NewQueryOptions()
  169 + if query.Size > 0 {
  170 + options = options.WithOffsetLimit(query.Page, query.Size)
  171 + }
  172 + total, tx := transaction.PaginationAndCount(ctx, tx, options, &list)
  173 + return total, list, tx.Error
  174 +}
  175 +
  176 +// SyncData 同步表数据
  177 +//func (repository *ObjectTableDataRepository) SyncData(ctx context.Context, conn transaction.Conn, companyId int64, tableId int) error {
  178 +//
  179 +//}
  180 +
  181 +func NewObjectTableDataRepository() domain.ObjectTableDataRepository {
  182 + return &ObjectTableDataRepository{}
  183 +}
  1 +package repository
  2 +
  3 +import (
  4 + "context"
  5 + "github.com/jinzhu/copier"
  6 + "github.com/pkg/errors"
  7 + "github.com/tiptok/gocomm/pkg/cache"
  8 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/db/models"
  9 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/db/transaction"
  10 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/domain"
  11 + "gorm.io/gorm"
  12 +)
  13 +
  14 +type ObjectTableRepository struct {
  15 + *cache.CachedRepository
  16 +}
  17 +
  18 +func (repository *ObjectTableRepository) Insert(ctx context.Context, conn transaction.Conn, dm *domain.ObjectTable) (*domain.ObjectTable, error) {
  19 + var (
  20 + err error
  21 + m = &models.ObjectTable{}
  22 + tx = conn.DB()
  23 + )
  24 + if m, err = repository.DomainModelToModel(dm); err != nil {
  25 + return nil, err
  26 + }
  27 + if tx = tx.Model(m).Save(m); tx.Error != nil {
  28 + return nil, tx.Error
  29 + }
  30 + dm.Id = m.Id
  31 + return repository.ModelToDomainModel(m)
  32 +
  33 +}
  34 +
  35 +func (repository *ObjectTableRepository) Update(ctx context.Context, conn transaction.Conn, dm *domain.ObjectTable) (*domain.ObjectTable, error) {
  36 + var (
  37 + err error
  38 + m *models.ObjectTable
  39 + tx = conn.DB()
  40 + )
  41 + if m, err = repository.DomainModelToModel(dm); err != nil {
  42 + return nil, err
  43 + }
  44 + queryFunc := func() (interface{}, error) {
  45 + tx = tx.Model(m).Updates(m)
  46 + return nil, tx.Error
  47 + }
  48 + if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
  49 + return nil, err
  50 + }
  51 + return repository.ModelToDomainModel(m)
  52 +}
  53 +
  54 +func (repository *ObjectTableRepository) UpdateWithVersion(ctx context.Context, transaction transaction.Conn, dm *domain.ObjectTable) (*domain.ObjectTable, error) {
  55 + var (
  56 + err error
  57 + m *models.ObjectTable
  58 + tx = transaction.DB()
  59 + )
  60 + if m, err = repository.DomainModelToModel(dm); err != nil {
  61 + return nil, err
  62 + }
  63 + oldVersion := dm.Version
  64 + m.Version += 1
  65 + queryFunc := func() (interface{}, error) {
  66 + tx = tx.Model(m).Select("*").Where("id = ?", m.Id).Where("version = ?", oldVersion).Updates(m)
  67 + if tx.RowsAffected == 0 {
  68 + return nil, domain.ErrUpdateFail
  69 + }
  70 + return nil, tx.Error
  71 + }
  72 + if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
  73 + return nil, err
  74 + }
  75 + return repository.ModelToDomainModel(m)
  76 +}
  77 +
  78 +func (repository *ObjectTableRepository) Delete(ctx context.Context, conn transaction.Conn, dm *domain.ObjectTable) (*domain.ObjectTable, error) {
  79 + var (
  80 + tx = conn.DB()
  81 + m = &models.ObjectTable{Id: dm.Identify().(int), TableType: dm.TableType}
  82 + )
  83 + queryFunc := func() (interface{}, error) {
  84 + tx = tx.Where("id = ? and table_type = ?", m.Id, dm.TableType).Unscoped().Delete(m)
  85 + return m, tx.Error
  86 + }
  87 + if _, err := repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
  88 + return dm, err
  89 + }
  90 + return repository.ModelToDomainModel(m)
  91 +}
  92 +
  93 +func (repository *ObjectTableRepository) FindOne(ctx context.Context, conn transaction.Conn, id int, tableType string) (*domain.ObjectTable, error) {
  94 + var (
  95 + err error
  96 + tx = conn.DB()
  97 + m = new(models.ObjectTable)
  98 + )
  99 + queryFunc := func() (interface{}, error) {
  100 + tx = tx.Model(m).Where("id = ?", id).First(m)
  101 + if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
  102 + return nil, domain.ErrNotFound
  103 + }
  104 + return m, tx.Error
  105 + }
  106 + cacheModel := new(models.ObjectTable)
  107 + cacheModel.Id = id
  108 + if err = repository.QueryCache(cacheModel.CacheKeyFunc, m, queryFunc); err != nil {
  109 + return nil, err
  110 + }
  111 + return repository.ModelToDomainModel(m)
  112 +}
  113 +
  114 +func (repository *ObjectTableRepository) FindOneByTableId(ctx context.Context, conn transaction.Conn, tableId int) (*domain.ObjectTable, error) {
  115 + var (
  116 + tx = conn.DB()
  117 + m = new(models.ObjectTable)
  118 + )
  119 + tx = tx.Model(m).Where("table_id = ?", tableId).First(m)
  120 + if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
  121 + return nil, domain.ErrNotFound
  122 + }
  123 + return repository.ModelToDomainModel(m)
  124 +}
  125 +
  126 +func (repository *ObjectTableRepository) Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*domain.ObjectTable, error) {
  127 + var (
  128 + tx = conn.DB()
  129 + ms []*models.ObjectTable
  130 + dms = make([]*domain.ObjectTable, 0)
  131 + total int64
  132 + )
  133 + queryFunc := func() (interface{}, error) {
  134 + tx = tx.Model(&ms).Order("id desc")
  135 + if v, ok := queryOptions["companyId"]; ok {
  136 + tx = tx.Where("company_id = ?", v)
  137 + }
  138 + if v, ok := queryOptions["id"]; ok {
  139 + tx = tx.Where("id = ?", v)
  140 + }
  141 + if v, ok := queryOptions["flag"]; ok {
  142 + tx = tx.Where("flag = ?", v)
  143 + }
  144 + if v, ok := queryOptions["parentId"]; ok {
  145 + tx = tx.Where("parent_id = ?", v)
  146 + }
  147 + if v, ok := queryOptions["tableTypeIn"]; ok {
  148 + tx = tx.Where("table_type in ?", v)
  149 + }
  150 + if total, tx = transaction.PaginationAndCount(ctx, tx, queryOptions, &ms); tx.Error != nil {
  151 + return dms, tx.Error
  152 + }
  153 + return dms, nil
  154 + }
  155 +
  156 + if _, err := repository.Query(queryFunc); err != nil {
  157 + return 0, nil, err
  158 + }
  159 +
  160 + for _, item := range ms {
  161 + if dm, err := repository.ModelToDomainModel(item); err != nil {
  162 + return 0, dms, err
  163 + } else {
  164 + dms = append(dms, dm)
  165 + }
  166 + }
  167 + return total, dms, nil
  168 +}
  169 +
  170 +// DeleteGroup 删除分组
  171 +func (repository *ObjectTableRepository) DeleteGroup(ctx context.Context, conn transaction.Conn, companyId int64, parentId int) error {
  172 + //分组下是否有数据
  173 + _, list, err := repository.Find(ctx, conn, domain.NewQueryOptions().WithKV("companyId", companyId).WithKV("parentId", parentId))
  174 + if err != nil {
  175 + return err
  176 + }
  177 + if len(list) > 0 {
  178 + return nil
  179 + }
  180 + _, items, err := repository.Find(
  181 + ctx, conn,
  182 + domain.NewQueryOptions().
  183 + WithKV("companyId", companyId).
  184 + WithKV("id", parentId).
  185 + WithKV("flag", "Group"),
  186 + )
  187 + if err != nil {
  188 + return err
  189 + }
  190 + if len(items) > 0 {
  191 + for _, item := range items {
  192 + //删除分组
  193 + _, err = repository.Delete(ctx, conn, item)
  194 + if err != nil {
  195 + return err
  196 + }
  197 + //递归删除上级分组
  198 + err = repository.DeleteGroup(ctx, conn, companyId, item.ParentId)
  199 + if err != nil {
  200 + return err
  201 + }
  202 + }
  203 + }
  204 + return nil
  205 +}
  206 +
  207 +func (repository *ObjectTableRepository) ModelToDomainModel(from *models.ObjectTable) (*domain.ObjectTable, error) {
  208 + to := &domain.ObjectTable{}
  209 + err := copier.Copy(to, from)
  210 + return to, err
  211 +}
  212 +
  213 +func (repository *ObjectTableRepository) DomainModelToModel(from *domain.ObjectTable) (*models.ObjectTable, error) {
  214 + to := &models.ObjectTable{}
  215 + err := copier.Copy(to, from)
  216 + return to, err
  217 +}
  218 +
  219 +func NewObjectTableRepository(cache *cache.CachedRepository) domain.ObjectTableRepository {
  220 + return &ObjectTableRepository{CachedRepository: cache}
  221 +}
@@ -35,6 +35,7 @@ type ChartRepository interface { @@ -35,6 +35,7 @@ type ChartRepository interface {
35 Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*Chart, error) 35 Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*Chart, error)
36 FindOneByGroup(ctx context.Context, conn transaction.Conn, tenantId, pid int64) (*Chart, error) 36 FindOneByGroup(ctx context.Context, conn transaction.Conn, tenantId, pid int64) (*Chart, error)
37 FindByTypeAndName(ctx context.Context, conn transaction.Conn, tenantId int64, t string, name string) (int64, []*Chart, error) 37 FindByTypeAndName(ctx context.Context, conn transaction.Conn, tenantId int64, t string, name string) (int64, []*Chart, error)
  38 + FindCompanyIds(ctx context.Context, conn transaction.Conn) ([]int64, error)
38 } 39 }
39 40
40 /*************** 索引函数 开始****************/ 41 /*************** 索引函数 开始****************/
@@ -28,23 +28,54 @@ type ChartProperty struct { @@ -28,23 +28,54 @@ type ChartProperty struct {
28 } 28 }
29 type Other struct { 29 type Other struct {
30 Quarter *Quarter `json:"quarter,optional,omitempty"` // 四分图 30 Quarter *Quarter `json:"quarter,optional,omitempty"` // 四分图
  31 + Divider *Divider `json:"divider,optional,omitempty"` // 分割线
  32 + Rank *Rank `json:"rank,optional,omitempty"` // 排名图
  33 + Deviation *Deviation `json:"deviation,optional,omitempty"` // 偏差图
  34 + Notepaper *Notepaper `json:"notepaper,optional,omitempty"` // 便签(富文本)
31 } 35 }
32 type Quarter struct { 36 type Quarter struct {
33 XAxisLabel string `json:"xAxisLabel"` // x轴标签名 37 XAxisLabel string `json:"xAxisLabel"` // x轴标签名
34 XAxisFirstLabel string `json:"xAxisFirstLabel"` // 签名1 38 XAxisFirstLabel string `json:"xAxisFirstLabel"` // 签名1
35 XAxisSecondLabel string `json:"xAxisSecondLabel"` // 签名2 39 XAxisSecondLabel string `json:"xAxisSecondLabel"` // 签名2
  40 + XAxisFirstColor string `json:"xAxisFirstColor,optional,omitempty"` // x轴标签1默认颜色
  41 + XAxisSecondColor string `json:"xAxisSecondColor,optional,omitempty"` // x轴标签2默认颜色
36 YAxisLabel string `json:"yAxisLabel"` // y轴标签名 42 YAxisLabel string `json:"yAxisLabel"` // y轴标签名
37 YAxisFirstLabel string `json:"yAxisFirstLabel"` // y标签1 43 YAxisFirstLabel string `json:"yAxisFirstLabel"` // y标签1
38 YAxisSecondLabel string `json:"yAxisSecondLabel"` // y标签2 44 YAxisSecondLabel string `json:"yAxisSecondLabel"` // y标签2
  45 + YAxisFirstColor string `json:"yAxisFirstColor,optional,omitempty"` // y轴标签1默认颜色
  46 + YAxisSecondColor string `json:"yAxisSecondColor,optional,omitempty"` // y轴标签2默认颜色
39 Area string `json:"area"` // 图形面积 47 Area string `json:"area"` // 图形面积
40 AreaColor bool `json:"areaColor"` // 颜色 48 AreaColor bool `json:"areaColor"` // 颜色
41 SeriesList []QuarterSeries `json:"seriesList"` // 图形系列 49 SeriesList []QuarterSeries `json:"seriesList"` // 图形系列
  50 + TableSwitch bool `json:"tableSwitch"` // 是否展示记录型表格
42 } 51 }
43 52
44 type QuarterSeries struct { 53 type QuarterSeries struct {
45 SeriesValue string `json:"seriesValue"` 54 SeriesValue string `json:"seriesValue"`
46 } 55 }
47 56
  57 +type Divider struct {
  58 + SelectedIdx string `json:"selectedIdx,optional,omitempty"` // 选择的分割线样式
  59 + TextSwitch bool `json:"textSwitch,optional,omitempty"` // 是否展示组件文本
  60 + Text string `json:"text"` // 组件文本内容
  61 +}
  62 +
  63 +type Rank struct {
  64 + FirstLine []RankLine `json:"firstLine,optional,omitempty"` // 第一名设置
  65 + SecondLine []RankLine `json:"secondLine,optional,omitempty"` // 第二名设置
  66 + SortBySwitch bool `json:"sortBySwitch,optional,omitempty"` // 排序开关
  67 + SortBySeries string `json:"sortBySeries,optional,omitempty"` // 排序依据
  68 + SortByArrow string `json:"sortByArrow,optional,omitempty"` // 排序方向 1-降序 2-升序
  69 +}
  70 +
  71 +type RankLine struct {
  72 + SeriesValue string `json:"seriesValue"` // 排名图序列值
  73 + LabelSwitch bool `json:"labelSwitch"` // 标签开关
  74 + Label string `json:"label"` // 标签
  75 + ArrowSwitch bool `json:"arrowSwitch"` // 箭头开关
  76 + Unit string `json:"unit"` // 单位
  77 +}
  78 +
48 type Title struct { 79 type Title struct {
49 TitleSwitch bool `json:"titleSwitch,optional"` // 组件标题开关 80 TitleSwitch bool `json:"titleSwitch,optional"` // 组件标题开关
50 IntroduceSwitch bool `json:"introduceSwitch,optional"` // 组件说明开关 81 IntroduceSwitch bool `json:"introduceSwitch,optional"` // 组件说明开关
@@ -63,6 +94,13 @@ type Title struct { @@ -63,6 +94,13 @@ type Title struct {
63 type TableAbility struct { 94 type TableAbility struct {
64 FilterSwitch bool `json:"filterSwitch,optional"` // 表筛选功能开关 95 FilterSwitch bool `json:"filterSwitch,optional"` // 表筛选功能开关
65 DimensionList []Dimension `json:"dimensionList,optional"` // 维度列表 96 DimensionList []Dimension `json:"dimensionList,optional"` // 维度列表
  97 + CardSwitch bool `json:"cardSwitch,optional"` // 顺序标识开关
  98 + CardIdent string `json:"cardIdent,optional"` // 顺序标识
  99 + CardOrderList []CardOrderItem `json:"cardOrderList,optional"` // 卡片列表顺序
  100 +}
  101 +
  102 +type CardOrderItem struct {
  103 + CardId string `json:"cardId,optional"`
66 } 104 }
67 105
68 type Series struct { 106 type Series struct {
@@ -83,6 +121,39 @@ type Expression struct { @@ -83,6 +121,39 @@ type Expression struct {
83 ToValue string `json:"toValue"` // 显示值(转为) 121 ToValue string `json:"toValue"` // 显示值(转为)
84 } 122 }
85 123
  124 +type (
  125 + Deviation struct {
  126 + XAxisLabel string `json:"xAxisLabel,optional,omitempty"` // 分类标签
  127 + TopChart TopChart `json:"topChart,optional,omitempty"`
  128 + MidChart MidChart `json:"midChart,optional,omitempty"`
  129 + BotChart []BotChart `json:"botChart,optional,omitempty"`
  130 + }
  131 + Notepaper struct {
  132 + Text string `json:"text,optional,omitempty"` // 富文本内容
  133 + Theme string `json:"theme,optional,omitempty"` // 主题风格
  134 + }
  135 + TopChart struct {
  136 + SeriesValue string `json:"seriesValue,optional,omitempty"` // 系列
  137 + Legend string `json:"legend,optional,omitempty"` // 图例
  138 + FormatType string `json:"formatType,optional,omitempty"` //
  139 + FormatPoint string `json:"formatPoint,optional,omitempty"` //
  140 + }
  141 + MidChart struct {
  142 + SeriesValue string `json:"seriesValue,optional,omitempty"` // 系列
  143 + Legend string `json:"legend,optional,omitempty"` // 图例
  144 + FormatType string `json:"formatType,optional,omitempty"` //
  145 + FormatPoint string `json:"formatPoint,optional,omitempty"` //
  146 + }
  147 + BotChart struct {
  148 + SeriesSwitch bool `json:"seriesSwitch,optional,omitempty"` // 是否显示
  149 + Type string `json:"type,optional,omitempty"` // 图表类型
  150 + SeriesValue string `json:"seriesValue,optional,omitempty"` // 系列
  151 + Legend string `json:"legend,optional,omitempty"` // 图例
  152 + FormatType string `json:"formatType,optional,omitempty"` //
  153 + FormatPoint string `json:"formatPoint,optional,omitempty"` //
  154 + }
  155 +)
  156 +
86 func (exp Expression) Match(value string) (result bool, toValue string) { 157 func (exp Expression) Match(value string) (result bool, toValue string) {
87 fValue, ferr := strconv.ParseFloat(value, 64) 158 fValue, ferr := strconv.ParseFloat(value, 64)
88 cValue, cerr := strconv.ParseFloat(exp.CompareValue, 64) 159 cValue, cerr := strconv.ParseFloat(exp.CompareValue, 64)
@@ -30,6 +30,7 @@ type ChartSettingRepository interface { @@ -30,6 +30,7 @@ type ChartSettingRepository interface {
30 Delete(ctx context.Context, conn transaction.Conn, dm *ChartSetting) (*ChartSetting, error) 30 Delete(ctx context.Context, conn transaction.Conn, dm *ChartSetting) (*ChartSetting, error)
31 FindOne(ctx context.Context, conn transaction.Conn, id int64) (*ChartSetting, error) 31 FindOne(ctx context.Context, conn transaction.Conn, id int64) (*ChartSetting, error)
32 Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*ChartSetting, error) 32 Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*ChartSetting, error)
  33 + CheckUseDataSource(ctx context.Context, conn transaction.Conn, objectId int) (bool, error)
33 } 34 }
34 35
35 func (m *ChartSetting) Identify() interface{} { 36 func (m *ChartSetting) Identify() interface{} {
  1 +package domain
  2 +
  3 +import (
  4 + "context"
  5 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/db/transaction"
  6 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/gateway/bytelib"
  7 + "gorm.io/plugin/soft_delete"
  8 +)
  9 +
  10 +type ObjectField struct {
  11 + Id int64 `json:"id"` // ID
  12 + Name string `json:"name"` //表名
  13 + Fields []*bytelib.Field `json:"fields"` //表字段
  14 + Version int `json:"version,omitempty"` //版本
  15 + IsDel soft_delete.DeletedAt `json:"isDel"` //删除标记
  16 + CreatedAt int64 `json:"createdAt,omitempty"` //创建时间
  17 + UpdatedAt int64 `json:"updatedAt,omitempty"` //更新时间
  18 + DeletedAt int64 `json:"deletedAt,omitempty"` //删除时间
  19 +}
  20 +
  21 +type ObjectFieldRepository interface {
  22 + Insert(ctx context.Context, conn transaction.Conn, dm *ObjectField) (*ObjectField, error)
  23 + Update(ctx context.Context, conn transaction.Conn, dm *ObjectField) (*ObjectField, error)
  24 + UpdateWithVersion(ctx context.Context, conn transaction.Conn, dm *ObjectField) (*ObjectField, error)
  25 + Delete(ctx context.Context, conn transaction.Conn, dm *ObjectField) (*ObjectField, error)
  26 + FindOne(ctx context.Context, conn transaction.Conn, id int64) (*ObjectField, error)
  27 + Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*ObjectField, error)
  28 +}
  29 +
  30 +func (m *ObjectField) Identify() interface{} {
  31 + if m.Id == 0 {
  32 + return nil
  33 + }
  34 + return m.Id
  35 +}
  1 +package domain
  2 +
  3 +import (
  4 + "context"
  5 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/db/transaction"
  6 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/gateway/bytelib"
  7 + "gorm.io/plugin/soft_delete"
  8 +)
  9 +
  10 +type ObjectNotice struct {
  11 + Id int64 `json:"id"` // ID
  12 + CompanyId int64 `json:"companyId"` //公司ID
  13 + TableId int `json:"tableId"` //表ID
  14 + TableType string `json:"tableType"` //表类型 导入模块(主表、附表、分表) 拆解(方案、子过程、计算表) 计算(计算项、计算集)
  15 + ObjectType string `json:"objectType"` //模块 导入模块、拆解模块、计算模块
  16 + Event string `json:"event"` //事件
  17 + TableAffectedList []int `json:"TableAffectedList"` //级联影响到的表
  18 + DataChanged bool `json:"dataChanged"` //数据有更新
  19 + StructChanged bool `json:"structChanged"` //结构有更新
  20 + Status int `json:"status"` //状态 1-等待处理 2-处理完成 3-处理失败
  21 + UpdateTable int `json:"updateTable"` //更新表结构
  22 + UpdateData int `json:"updateData"` //更新表数据
  23 + Message string `json:"message"` //错误信息
  24 + Retry int `json:"retry"` //重试次数
  25 + MetaData ObjectNoticeMetaData `json:"metaData"` //模块信息
  26 + Version int `json:",omitempty"` //版本
  27 + IsDel soft_delete.DeletedAt `json:"isDel"` //删除标记
  28 + CreatedAt int64 `json:"createdAt,omitempty"` //创建时间
  29 + UpdatedAt int64 `json:"updatedAt,omitempty"` //更新时间
  30 + DeletedAt int64 `json:"deletedAt,omitempty"` //删除时间
  31 +}
  32 +
  33 +type ObjectNoticeMetaData struct {
  34 + Module int `json:"module"` // 导入模块判断是否 取消应用
  35 + Status int `json:"status"` // 拆解模块判断是否 取消
  36 +}
  37 +
  38 +var (
  39 + ObjectNoticeStatusWait = 1 //等待处理
  40 + ObjectNoticeStatusDone = 2 //处理完成
  41 + ObjectNoticeStatusError = 3 //处理失败
  42 +)
  43 +
  44 +type ObjectNoticeRepository interface {
  45 + Insert(ctx context.Context, conn transaction.Conn, dm *ObjectNotice) (*ObjectNotice, error)
  46 + Update(ctx context.Context, conn transaction.Conn, dm *ObjectNotice) (*ObjectNotice, error)
  47 + UpdateWithVersion(ctx context.Context, conn transaction.Conn, dm *ObjectNotice) (*ObjectNotice, error)
  48 + Delete(ctx context.Context, conn transaction.Conn, dm *ObjectNotice) (*ObjectNotice, error)
  49 + FindOne(ctx context.Context, conn transaction.Conn, id int64) (*ObjectNotice, error)
  50 + Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*ObjectNotice, error)
  51 +}
  52 +
  53 +func (m *ObjectNotice) Identify() interface{} {
  54 + if m.Id == 0 {
  55 + return nil
  56 + }
  57 + return m.Id
  58 +}
  59 +
  60 +// IsDeletedEvent 是否删除事件
  61 +func (m *ObjectNotice) IsDeletedEvent() bool {
  62 + deletedEvents := []string{
  63 + "table.delete",
  64 + "table.query.set.delete",
  65 + }
  66 + for _, event := range deletedEvents {
  67 + if m.Event == event {
  68 + return true
  69 + }
  70 + }
  71 + //导入模块 取消应用和应用于
  72 + if m.Event == "table.apply-on" {
  73 + if m.MetaData.Module&bytelib.ModuleChartTemplate == 0 {
  74 + return true
  75 + }
  76 + }
  77 + //拆解模块 方案启用、禁用
  78 + //计算模块 计算项和计算集启用、禁用
  79 + if m.Event == "table.query.set.update.status" {
  80 + if m.MetaData.Status&bytelib.ModuleDigitalCenter == 0 {
  81 + return true
  82 + }
  83 + }
  84 + return false
  85 +}
  1 +package domain
  2 +
  3 +import (
  4 + "context"
  5 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/db/transaction"
  6 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/gateway/bytelib"
  7 + "gorm.io/plugin/soft_delete"
  8 +)
  9 +
  10 +type ObjectTable struct {
  11 + Id int `json:"id"` // ID
  12 + TableId int `json:"tableId" ` //表ID
  13 + Name string `json:"name"` //表名
  14 + TableType string `json:"tableType" ` //模块
  15 + CompanyId int64 `json:"companyId"` //公司id
  16 + ParentId int `json:"parentId"` //父id
  17 + Flag string `json:"flag"` //分组:Group 集合:Set
  18 + Version int `json:"version,omitempty"` //版本
  19 + IsLocal bool `json:"isLocal"` //是否有本地存储
  20 + RemoteDeleted int `json:"remoteDeleted"` //远端删除
  21 + IsDel soft_delete.DeletedAt `json:"isDel,omitempty"` //删除标记
  22 + CreatedAt int64 `json:"createdAt,omitempty"` //创建时间
  23 + UpdatedAt int64 `json:"updatedAt,omitempty"` //更新时间
  24 + DeletedAt int64 `json:"deletedAt,omitempty"` //删除时间
  25 +}
  26 +
  27 +type ObjectTableRepository interface {
  28 + Insert(ctx context.Context, conn transaction.Conn, dm *ObjectTable) (*ObjectTable, error)
  29 + Update(ctx context.Context, conn transaction.Conn, dm *ObjectTable) (*ObjectTable, error)
  30 + UpdateWithVersion(ctx context.Context, conn transaction.Conn, dm *ObjectTable) (*ObjectTable, error)
  31 + Delete(ctx context.Context, conn transaction.Conn, dm *ObjectTable) (*ObjectTable, error)
  32 + FindOne(ctx context.Context, conn transaction.Conn, id int, tableType string) (*ObjectTable, error)
  33 + FindOneByTableId(ctx context.Context, conn transaction.Conn, tableId int) (*ObjectTable, error)
  34 + Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*ObjectTable, error)
  35 + DeleteGroup(ctx context.Context, conn transaction.Conn, companyId int64, parentId int) error
  36 +}
  37 +
  38 +type ObjectTableDataQuery struct {
  39 + Page int
  40 + Size int
  41 + Conditions []*TableDataCondition
  42 + Group string
  43 + Select string
  44 +}
  45 +
  46 +type TableDataCondition struct {
  47 + FieldName string `json:"field"` // 条件字段
  48 + Like string `json:"like"` // 模糊匹配
  49 + In []string `json:"in"` // 匹配多个值
  50 + Order string `json:"order"` // 排序 ASC DESC 默认ASC
  51 +}
  52 +
  53 +type ObjectTableDataRepository interface {
  54 + InsertWithTableData(ctx context.Context, conn transaction.Conn, tableDataPreview bytelib.TableData) error
  55 + Find(ctx context.Context, conn transaction.Conn, tableId int, query *ObjectTableDataQuery) (int64, []map[string]interface{}, error)
  56 + DropTable(ctx context.Context, conn transaction.Conn, tableId int) error
  57 +}
  58 +
  59 +func (m *ObjectTable) Identify() interface{} {
  60 + if m.Id == 0 {
  61 + return nil
  62 + }
  63 + return m.Id
  64 +}
  1 +package authlib
  2 +
  3 +import (
  4 + "context"
  5 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-bchart/cmd/chart-server/interanl/pkg/gateway"
  6 + "net/http"
  7 +)
  8 +
  9 +type ApiAuthService struct {
  10 + gateway.Service
  11 +}
  12 +
  13 +func (svc *ApiAuthService) MeInfo(ctx context.Context, request RequestUserMeQuery) (*DataUserMe, error) {
  14 + var result DataUserMe
  15 + if err := svc.Do(ctx, "/v1/user/me", http.MethodGet, request, &result); err != nil {
  16 + return nil, err
  17 + }
  18 + return &result, nil
  19 +}
  20 +
  21 +func (svc *ApiAuthService) MeAppInfo(ctx context.Context, request RequestUserMeQuery) (*DataUserAppInfo, error) {
  22 + var result DataUserAppInfo
  23 + if err := svc.Do(ctx, "/v1/user/me-app-info", http.MethodGet, request, &result); err != nil {
  24 + return nil, err
  25 + }
  26 + return &result, nil
  27 +}
  28 +
  29 +func (svc *ApiAuthService) LoginCheck(ctx context.Context, request RequestLoginCheck) (*DataLoginCheck, error) {
  30 + var (
  31 + result DataLoginCheck
  32 + err error
  33 + )
  34 + if err = svc.Do(ctx, "/v1/login/check?token="+request.Token, http.MethodGet, request, &result); err != nil {
  35 + return nil, err
  36 + }
  37 + if errCodeMsg, ok := err.(gateway.HttpError); ok {
  38 + return &DataLoginCheck{
  39 + Code: errCodeMsg.Base.Code,
  40 + Msg: errCodeMsg.Base.Msg,
  41 + }, nil
  42 + }
  43 + return &result, nil
  44 +}
  45 +
  46 +func (svc *ApiAuthService) AppLogin(ctx context.Context, request RequestAppLogin) (*DataAppLogin, error) {
  47 + var result DataAppLogin
  48 + if err := svc.Do(ctx, "/v1/login/check?token="+request.Token, http.MethodGet, request, &result); err != nil {
  49 + return nil, err
  50 + }
  51 + return &result, nil
  52 +}
  1 +package authlib
  2 +
  3 +type RequestUserMeQuery struct {
  4 + Token string `header:"x-mmm-accesstoken"`
  5 + //UserId int
  6 + //CompanyId int
  7 +}
  8 +
  9 +type DataUserMe struct {
  10 + User *struct {
  11 + ID string `json:"id"`
  12 + Phone string `json:"phone"`
  13 + NickName string `json:"nickName"`
  14 + Avatar string `json:"avatar"`
  15 + } `json:"user,optional"`
  16 + CompanyList []*struct {
  17 + ID string `json:"id"`
  18 + Name string `json:"name"`
  19 + Logo string `json:"logo"`
  20 + DefaultLogin int `json:"defaultLogin"`
  21 + Types int `json:"types"`
  22 + } `json:"companyList,optional"`
  23 + CurrentCompany *struct {
  24 + ID string `json:"id"`
  25 + Name string `json:"name"`
  26 + Logo string `json:"logo"`
  27 + DefaultLogin int `json:"defaultLogin"`
  28 + Types int `json:"types"`
  29 + } `json:"currentCompany,optional"`
  30 + Workbench []*struct {
  31 + ID int `json:"id"`
  32 + Name string `json:"name"`
  33 + Code string `json:"code"`
  34 + CoverImage string `json:"coverImage"`
  35 + URL string `json:"url"`
  36 + } `json:"workbench,optional"`
  37 + Menus []*struct {
  38 + MenuID int `json:"menuId"`
  39 + ParentID int `json:"parentId"`
  40 + MenuName string `json:"menuName"`
  41 + Code string `json:"code"`
  42 + Types string `json:"types"`
  43 + } `json:"menus,optional"`
  44 +}
  45 +
  46 +type RequestLoginCheck struct {
  47 + Token string
  48 +}
  49 +type DataLoginCheck struct {
  50 + Code int `json:"code,optional"`
  51 + Msg string `json:"msg,optional"`
  52 +}
  53 +
  54 +type (
  55 + RequestAppLogin struct {
  56 + AppKey string `json:"appKey" valid:"Required"` // 应用键值
  57 + Token string `json:"token" valid:"Required"` // 凭证
  58 + }
  59 + DataAppLogin struct {
  60 + AppEnabled bool `json:"appEnabled"`
  61 + }
  62 +)
  63 +
  64 +type (
  65 + DataUserAppInfo struct {
  66 + Apps []AppItem `json:"apps"`
  67 + }
  68 + AppItem struct {
  69 + AppId int64
  70 + AppKey string
  71 + AppName string
  72 + }
  73 +)
@@ -7,7 +7,7 @@ import ( @@ -7,7 +7,7 @@ import (
7 7
8 func (gateway *ByteMetadataService) TableDataPreview(ctx context.Context, request *TableDataPreviewRequest) (TablePreviewResponse, error) { 8 func (gateway *ByteMetadataService) TableDataPreview(ctx context.Context, request *TableDataPreviewRequest) (TablePreviewResponse, error) {
9 var result TablePreviewResponse 9 var result TablePreviewResponse
10 - if err := gateway.Do(ctx, "/data/table-preview", http.MethodPost, request, &result); err != nil { 10 + if err := gateway.Do(ctx, "/api/tables/table-preview", http.MethodPost, request, &result); err != nil {
11 return result, err 11 return result, err
12 } 12 }
13 return result, nil 13 return result, nil
@@ -75,7 +75,7 @@ type TableData struct { @@ -75,7 +75,7 @@ type TableData struct {
75 //数据 75 //数据
76 Grid *TableDataGrid `json:"grid,optional"` 76 Grid *TableDataGrid `json:"grid,optional"`
77 //字段 77 //字段
78 - Fields []*Field `json:"fields"` 78 + Fields []*Field `json:"fields,optional"`
79 } 79 }
80 80
81 type TableDataGrid struct { 81 type TableDataGrid struct {
@@ -7,7 +7,7 @@ import ( @@ -7,7 +7,7 @@ import (
7 7
8 func (gateway *ByteMetadataService) TableFieldOptionalValues(ctx context.Context, request *TableFieldOptionalValuesRequest) (TableFieldOptionalValuesResponse, error) { 8 func (gateway *ByteMetadataService) TableFieldOptionalValues(ctx context.Context, request *TableFieldOptionalValuesRequest) (TableFieldOptionalValuesResponse, error) {
9 var result TableFieldOptionalValuesResponse 9 var result TableFieldOptionalValuesResponse
10 - if err := gateway.Do(ctx, "/data/field-optional-values", http.MethodPost, request, &result); err != nil { 10 + if err := gateway.Do(ctx, "/api/tables/field-optional-values", http.MethodPost, request, &result); err != nil {
11 return result, err 11 return result, err
12 } 12 }
13 return result, nil 13 return result, nil
@@ -7,7 +7,7 @@ import ( @@ -7,7 +7,7 @@ import (
7 7
8 func (gateway *ByteMetadataService) TableInfo(ctx context.Context, request *TableInfoRequest) (TableInfoResponse, error) { 8 func (gateway *ByteMetadataService) TableInfo(ctx context.Context, request *TableInfoRequest) (TableInfoResponse, error) {
9 var result TableInfoResponse 9 var result TableInfoResponse
10 - if err := gateway.Do(ctx, "/data/tables/:tableId", http.MethodGet, request, &result); err != nil { 10 + if err := gateway.Do(ctx, "/api/tables/tables/:tableId", http.MethodGet, request, &result); err != nil {
11 return result, err 11 return result, err
12 } 12 }
13 return result, nil 13 return result, nil
@@ -7,7 +7,7 @@ import ( @@ -7,7 +7,7 @@ import (
7 7
8 func (gateway *ByteMetadataService) ObjectTableSearch(ctx context.Context, request ObjectTableSearchRequest) (ObjectTableSearchResponse, error) { 8 func (gateway *ByteMetadataService) ObjectTableSearch(ctx context.Context, request ObjectTableSearchRequest) (ObjectTableSearchResponse, error) {
9 result := ObjectTableSearchResponse{} 9 result := ObjectTableSearchResponse{}
10 - if err := gateway.Do(ctx, "/data/table-object-search", http.MethodPost, request, &result); err != nil { 10 + if err := gateway.Do(ctx, "/api/tables/table-object-search", http.MethodPost, request, &result); err != nil {
11 return result, err 11 return result, err
12 } 12 }
13 return result, nil 13 return result, nil
@@ -12,10 +12,11 @@ var ( @@ -12,10 +12,11 @@ var (
12 ) 12 )
13 13
14 const ( 14 const (
15 - ModuleAll = ModuleDigitalCenter | ModuleQuerySetCenter | ModuleCalculateCenter 15 + ModuleAll = ModuleDigitalCenter | ModuleQuerySetCenter | ModuleCalculateCenter | ModuleChartTemplate
16 ModuleDigitalCenter = 1 16 ModuleDigitalCenter = 1
17 ModuleQuerySetCenter = 2 17 ModuleQuerySetCenter = 2
18 ModuleCalculateCenter = 4 18 ModuleCalculateCenter = 4
  19 + ModuleChartTemplate = 8
19 ) 20 )
20 21
21 const ( 22 const (
@@ -23,3 +24,7 @@ const ( @@ -23,3 +24,7 @@ const (
23 ObjectMetaTable = "MetaTable" 24 ObjectMetaTable = "MetaTable"
24 ObjectDBTable = "DBTable" 25 ObjectDBTable = "DBTable"
25 ) 26 )
  27 +
  28 +const (
  29 + MaxPageSize = 30000 //最大读取行数
  30 +)
@@ -13,6 +13,7 @@ info( @@ -13,6 +13,7 @@ info(
13 prefix: v1 13 prefix: v1
14 group: page 14 group: page
15 jwt: JwtAuth 15 jwt: JwtAuth
  16 + middleware: LoginStatusCheck,LogRequest
16 ) 17 )
17 service Core { 18 service Core {
18 @doc "保存应用页" 19 @doc "保存应用页"
@@ -94,6 +95,7 @@ type ( @@ -94,6 +95,7 @@ type (
94 Name string `json:"name,optional"` // 名称 95 Name string `json:"name,optional"` // 名称
95 Cover string `json:"cover,optional"` // 封面 96 Cover string `json:"cover,optional"` // 封面
96 Charts []AppPageChartItem `json:"charts,optional"`// 图表 97 Charts []AppPageChartItem `json:"charts,optional"`// 图表
  98 + UpdatedAt int64 `json:"updatedAt,optional"` //更新时间
97 } 99 }
98 AppPageChartItem struct{ 100 AppPageChartItem struct{
99 ChartId int64 `json:"chartId"` // 图表ID 101 ChartId int64 `json:"chartId"` // 图表ID
@@ -107,6 +109,7 @@ type ( @@ -107,6 +109,7 @@ type (
107 @server( 109 @server(
108 prefix: v1 110 prefix: v1
109 group: page 111 group: page
  112 + middleware: LogRequest
110 ) 113 )
111 service Core { 114 service Core {
112 @doc "获取应用页详情" 115 @doc "获取应用页详情"
1 -  
2 syntax = "v1" 1 syntax = "v1"
3 2
4 info( 3 info(
@@ -13,7 +12,7 @@ info( @@ -13,7 +12,7 @@ info(
13 prefix: v1 12 prefix: v1
14 group: chart 13 group: chart
15 jwt: JwtAuth 14 jwt: JwtAuth
16 - //middleware: Authority 15 + middleware: LoginStatusCheck,LogRequest
17 ) 16 )
18 service Core { 17 service Core {
19 @doc "保存图表" 18 @doc "保存图表"
@@ -46,6 +45,7 @@ service Core { @@ -46,6 +45,7 @@ service Core {
46 @server( 45 @server(
47 prefix: v1 46 prefix: v1
48 group: chart 47 group: chart
  48 + middleware: LogRequest
49 ) 49 )
50 service Core { 50 service Core {
51 @doc "加载图表数据" 51 @doc "加载图表数据"
@@ -60,120 +60,148 @@ type ( @@ -60,120 +60,148 @@ type (
60 ChartGetRequest { 60 ChartGetRequest {
61 Id int64 `path:"id"` 61 Id int64 `path:"id"`
62 } 62 }
63 - ChartGetResponse struct{ 63 + ChartGetResponse {
64 Chart ChartItem `json:"chart"` 64 Chart ChartItem `json:"chart"`
65 } 65 }
66 66
67 - ChartSaveRequest struct{  
68 - Pid int64 `json:"pid,optional"`// 父级ID  
69 - Type string `json:"type"`// 类型 report:报表 group:分组 chart:图表  
70 - Name string `json:"name,optional"`// 名称 67 + ChartSaveRequest {
  68 + Pid int64 `json:"pid,optional"` // 父级ID
  69 + Type string `json:"type"` // 类型 report:报表 group:分组 chart:图表
  70 + Name string `json:"name,optional"` // 名称
71 ChartType string `json:"chartType"` // 图表类型 71 ChartType string `json:"chartType"` // 图表类型
72 Cover string `json:"cover,optional"` // 封面 72 Cover string `json:"cover,optional"` // 封面
73 ChartProperty ChartProperty `json:"property"` // 图表属性 73 ChartProperty ChartProperty `json:"property"` // 图表属性
74 } 74 }
75 - ChartSaveResponse struct{ 75 + ChartSaveResponse {
76 Chart ChartItem `json:"chart"` 76 Chart ChartItem `json:"chart"`
77 } 77 }
78 78
79 - ChartSaveAsRequest struct{ 79 + ChartSaveAsRequest {
80 ChartId int64 `json:"chartId"` // 图表Id 80 ChartId int64 `json:"chartId"` // 图表Id
81 - Name string `json:"name"`// 名称 81 + Name string `json:"name"` // 名称
82 } 82 }
83 - ChartSaveAsResponse struct{ 83 + ChartSaveAsResponse {
84 Chart ChartItem `json:"chart"` 84 Chart ChartItem `json:"chart"`
85 } 85 }
86 86
87 - ChartDeleteRequest struct{ 87 + ChartDeleteRequest {
88 Id int64 `path:"id"` 88 Id int64 `path:"id"`
89 } 89 }
90 ChartDeleteResponse struct{} 90 ChartDeleteResponse struct{}
91 91
92 - ChartUpdateRequest struct{ 92 + ChartUpdateRequest {
93 Id int64 `path:"id"` 93 Id int64 `path:"id"`
94 Cover string `json:"cover,optional"` // 封面 94 Cover string `json:"cover,optional"` // 封面
95 ChartProperty ChartProperty `json:"property"` // 图表属性 95 ChartProperty ChartProperty `json:"property"` // 图表属性
96 } 96 }
97 ChartUpdateResponse struct{} 97 ChartUpdateResponse struct{}
98 98
99 - ChartSearchRequest struct { 99 + ChartSearchRequest {
100 IncludeTypes []string `json:"includeTypes,optional"` //包含的类型: 类型 report:报表 group:分组 chart:图表(未指定返回所有) 100 IncludeTypes []string `json:"includeTypes,optional"` //包含的类型: 类型 report:报表 group:分组 chart:图表(未指定返回所有)
101 DataStyle string `json:"dataStyle,optional"` // 数据样式 tree:树形 flat:平铺 101 DataStyle string `json:"dataStyle,optional"` // 数据样式 tree:树形 flat:平铺
102 } 102 }
103 - ChartSearchResponse{ 103 + ChartSearchResponse {
104 List []ChartItem `json:"list"` 104 List []ChartItem `json:"list"`
105 Total int64 `json:"total"` 105 Total int64 `json:"total"`
106 } 106 }
107 - ChartUpdateSortRequest struct{ 107 + ChartUpdateSortRequest {
108 Id int64 `json:"id"` 108 Id int64 `json:"id"`
109 Pid int64 `json:"pid"` 109 Pid int64 `json:"pid"`
110 Index int `json:"index"` // 元素下标 110 Index int `json:"index"` // 元素下标
111 } 111 }
112 ChartUpdateSortResponse struct{} 112 ChartUpdateSortResponse struct{}
113 - ChartRenameRequest struct{ 113 + ChartRenameRequest {
114 Id int64 `json:"id"` 114 Id int64 `json:"id"`
115 - Name string `json:"name"`// 名称 115 + Name string `json:"name"` // 名称
116 } 116 }
117 ChartRenameResponse struct{} 117 ChartRenameResponse struct{}
118 - ChartItem struct{  
119 - Id int64 `json:"id,optional"`// ID  
120 - Pid int64 `json:"pid,optional"`// 父级ID  
121 - Type string `json:"type,optional"`// 类型 report:报表 group:分组 chart:图表  
122 - Sort int64 `json:"sort,optional"`// 排序  
123 - Name string `json:"name,optional"`// 名称 118 + ChartItem {
  119 + Id int64 `json:"id,optional"` // ID
  120 + Pid int64 `json:"pid,optional"` // 父级ID
  121 + Type string `json:"type,optional"` // 类型 report:报表 group:分组 chart:图表
  122 + Sort int64 `json:"sort,optional"` // 排序
  123 + Name string `json:"name,optional"` // 名称
124 Cover string `json:"cover,optional"` // 封面 124 Cover string `json:"cover,optional"` // 封面
125 ChartType string `json:"chartType,optional"` // 图表类型 125 ChartType string `json:"chartType,optional"` // 图表类型
  126 + UpdatedAt int `json:"updatedAt,optional"` // 更新时间
126 ChartProperty *ChartProperty `json:"property,optional,omitempty"` //属性 127 ChartProperty *ChartProperty `json:"property,optional,omitempty"` //属性
127 } 128 }
128 - LoadChartDataRequest struct{ 129 + LoadChartDataRequest {
129 ChartId int64 `json:"chartId"` 130 ChartId int64 `json:"chartId"`
130 } 131 }
131 - LoadChartDataResponse struct{  
132 - 132 + LoadChartDataResponse {
133 } 133 }
134 ) 134 )
135 135
136 -type(  
137 - ChartComponentSearchRequest{ 136 +type (
  137 + ChartComponentSearchRequest {
138 Name string `json:"name,optional"` 138 Name string `json:"name,optional"`
139 } 139 }
140 - ChartComponentSearchResponse{ 140 + ChartComponentSearchResponse {
141 List []ChartComponentItem `json:"list"` 141 List []ChartComponentItem `json:"list"`
142 Total int64 `json:"total"` 142 Total int64 `json:"total"`
143 } 143 }
144 - ChartComponentItem struct{  
145 - Name string `json:"name,optional"`// 名称  
146 - Code string `json:"code,optional"`// 编码 144 + ChartComponentItem {
  145 + Name string `json:"name,optional"` // 名称
  146 + Code string `json:"code,optional"` // 编码
147 Cover string `json:"cover,optional"` // 封面 147 Cover string `json:"cover,optional"` // 封面
148 - Desc string `json:"desc,optional"`// 描述 148 + Desc string `json:"desc,optional"` // 描述
149 } 149 }
150 ) 150 )
151 151
152 -type(  
153 - ChartProperty struct { 152 +type (
  153 + ChartProperty {
154 Title Title `json:"title,optional"` // 标题 154 Title Title `json:"title,optional"` // 标题
155 TableAbility TableAbility `json:"table,optional"` // 表筛选功能 155 TableAbility TableAbility `json:"table,optional"` // 表筛选功能
156 Series []Series `json:"series,optional"` // 系列(数据源) 156 Series []Series `json:"series,optional"` // 系列(数据源)
157 Other Other `json:"other,optional"` // 其他额外配置 157 Other Other `json:"other,optional"` // 其他额外配置
158 } 158 }
159 - Other struct { 159 + Other {
160 Quarter *Quarter `json:"quarter,optional,omitempty"` // 四分图 160 Quarter *Quarter `json:"quarter,optional,omitempty"` // 四分图
  161 + Divider *Divider `json:"divider,optional,omitempty"` // 分割线
  162 + Rank *Rank `json:"rank,optional,omitempty"` // 排名图
  163 + Deviation *Deviation `json:"deviation,optional,omitempty"` // 偏差图
  164 + Notepaper *Notepaper `json:"notepaper,optional,omitempty"` // 便签(富文本)
161 } 165 }
162 - Quarter struct { 166 + Quarter {
163 XAxisLabel string `json:"xAxisLabel"` // x轴标签名 167 XAxisLabel string `json:"xAxisLabel"` // x轴标签名
164 XAxisFirstLabel string `json:"xAxisFirstLabel"` // 签名1 168 XAxisFirstLabel string `json:"xAxisFirstLabel"` // 签名1
165 XAxisSecondLabel string `json:"xAxisSecondLabel"` // 签名2 169 XAxisSecondLabel string `json:"xAxisSecondLabel"` // 签名2
  170 + XAxisFirstColor string `json:"xAxisFirstColor,optional,omitempty"` // x轴标签1默认颜色
  171 + XAxisSecondColor string `json:"xAxisSecondColor,optional,omitempty"` // x轴标签2默认颜色
166 YAxisLabel string `json:"yAxisLabel"` // y轴标签名 172 YAxisLabel string `json:"yAxisLabel"` // y轴标签名
167 YAxisFirstLabel string `json:"yAxisFirstLabel"` // y标签1 173 YAxisFirstLabel string `json:"yAxisFirstLabel"` // y标签1
168 YAxisSecondLabel string `json:"yAxisSecondLabel"` // y标签2 174 YAxisSecondLabel string `json:"yAxisSecondLabel"` // y标签2
  175 + YAxisFirstColor string `json:"yAxisFirstColor,optional,omitempty"` // y轴标签1默认颜色
  176 + YAxisSecondColor string `json:"yAxisSecondColor,optional,omitempty"` // y轴标签2默认颜色
169 Area string `json:"area"` // 图形面积 177 Area string `json:"area"` // 图形面积
170 AreaColor bool `json:"areaColor"` // 颜色 178 AreaColor bool `json:"areaColor"` // 颜色
171 SeriesList []QuarterSeries `json:"seriesList"` // 图形系列 179 SeriesList []QuarterSeries `json:"seriesList"` // 图形系列
  180 + TableSwitch bool `json:"tableSwitch"` // 是否展示记录型表格
172 } 181 }
173 - QuarterSeries struct { 182 + QuarterSeries {
174 SeriesValue string `json:"seriesValue"` 183 SeriesValue string `json:"seriesValue"`
175 } 184 }
176 - Title struct { 185 + Divider {
  186 + SelectedIdx string `json:"selectedIdx,optional,omitempty"` // 选择的分割线样式
  187 + TextSwitch bool `json:"textSwitch,optional,omitempty"` // 是否展示组件文本
  188 + Text string `json:"text"` // 组件文本内容
  189 + }
  190 + Rank {
  191 + FirstLine []RankLine `json:"firstLine,optional,omitempty"` // 第一名设置
  192 + SecondLine []RankLine `json:"secondLine,optional,omitempty"` // 第二名设置
  193 + SortBySwitch bool `json:"sortBySwitch,optional,omitempty"` // 排序开关
  194 + SortBySeries string `json:"sortBySeries,optional,omitempty"` // 排序依据
  195 + SortByArrow string `json:"sortByArrow,optional,omitempty"` // 排序方向 1-降序 2-升序
  196 + }
  197 + RankLine {
  198 + SeriesValue string `json:"seriesValue"` // 排名图序列值
  199 + LabelSwitch bool `json:"labelSwitch"` // 标签开关
  200 + Label string `json:"label"` // 标签
  201 + ArrowSwitch bool `json:"arrowSwitch"` // 箭头开关
  202 + Unit string `json:"unit"` // 单位
  203 + }
  204 + Title {
177 TitleSwitch bool `json:"titleSwitch,optional"` // 组件标题开关 205 TitleSwitch bool `json:"titleSwitch,optional"` // 组件标题开关
178 IntroduceSwitch bool `json:"introduceSwitch,optional"` // 组件说明开关 206 IntroduceSwitch bool `json:"introduceSwitch,optional"` // 组件说明开关
179 TitleType string `json:"titleType"` // 标题类型 207 TitleType string `json:"titleType"` // 标题类型
@@ -187,11 +215,17 @@ type( @@ -187,11 +215,17 @@ type(
187 HeadingAlign string `json:"headingAlign,optional"` // 主标题 文本对齐方式 left center right 215 HeadingAlign string `json:"headingAlign,optional"` // 主标题 文本对齐方式 left center right
188 SubAlign string `json:"subAlign,optional"` // 副标题 文本对齐方式 left center right 216 SubAlign string `json:"subAlign,optional"` // 副标题 文本对齐方式 left center right
189 } 217 }
190 - TableAbility struct { 218 + TableAbility {
191 FilterSwitch bool `json:"filterSwitch,optional"` // 表筛选功能开关 219 FilterSwitch bool `json:"filterSwitch,optional"` // 表筛选功能开关
192 DimensionList []Dimension `json:"dimensionList,optional"` // 维度列表 220 DimensionList []Dimension `json:"dimensionList,optional"` // 维度列表
  221 + CardSwitch bool `json:"cardSwitch,optional"` // 顺序标识开关
  222 + CardIdent string `json:"cardIdent,optional"` // 顺序标识
  223 + CardOrderList []CardOrderItem `json:"cardOrderList,optional"` // 卡片列表顺序
  224 + }
  225 + CardOrderItem {
  226 + CardId string `json:"cardId,optional"`
193 } 227 }
194 - Series struct {// 图表类型 (记录型表格:RecordTable-1 总体指标:MetricsCard-1 容器卡片:ContainerCard-1 四分图:QuarterChart-1) 228 + Series { // 图表类型 (记录型表格:RecordTable-1 总体指标:MetricsCard-1 容器卡片:ContainerCard-1 四分图:QuarterChart-1)
195 Name string `json:"name"` // 名称 (例如 指标1、指标2) 229 Name string `json:"name"` // 名称 (例如 指标1、指标2)
196 SourceFrom string `json:"from,options=[ByteBank,User]"` // 数据源类型 ByteBank:字库 User:用户自定义 230 SourceFrom string `json:"from,options=[ByteBank,User]"` // 数据源类型 ByteBank:字库 User:用户自定义
197 DataSourceId int64 `json:"dataSourceId,optional,omitempty"` // 数据源ID(from值为ByteBank时有值) 231 DataSourceId int64 `json:"dataSourceId,optional,omitempty"` // 数据源ID(from值为ByteBank时有值)
@@ -201,13 +235,46 @@ type( @@ -201,13 +235,46 @@ type(
201 TargetNum string `json:"targetNum,optional,omitempty"` // 指标数值 235 TargetNum string `json:"targetNum,optional,omitempty"` // 指标数值
202 TargetUnit string `json:"targetUnit,optional,omitempty"` // 指标单位 236 TargetUnit string `json:"targetUnit,optional,omitempty"` // 指标单位
203 } 237 }
204 - Expression struct { 238 + Expression {
205 Operator string `json:"operator"` // 操作符号 <,>,==,<>,<=,>= 239 Operator string `json:"operator"` // 操作符号 <,>,==,<>,<=,>=
206 CompareValue string `json:"compareValue"` // 比较值 240 CompareValue string `json:"compareValue"` // 比较值
207 ToValue string `json:"toValue"` // 显示值(转为) 241 ToValue string `json:"toValue"` // 显示值(转为)
208 } 242 }
209 - Dimension struct{ 243 + Dimension {
210 Name string `json:"name,optional,omitempty"` 244 Name string `json:"name,optional,omitempty"`
211 Value string `json:"dimensionVal,optional"` 245 Value string `json:"dimensionVal,optional"`
212 } 246 }
213 ) 247 )
  248 +
  249 +type (
  250 + Deviation struct {
  251 + XAxisLabel string `json:"xAxisLabel,optional,omitempty"` // 分类标签
  252 + TopChart TopChart `json:"topChart,optional,omitempty"`
  253 + MidChart MidChart `json:"midChart,optional,omitempty"`
  254 + BotChart []BotChart `json:"botChart,optional,omitempty"`
  255 + }
  256 + Notepaper struct {
  257 + Text string `json:"text,optional,omitempty"` // 富文本内容
  258 + Theme string `json:"theme,optional,omitempty"` // 主题风格
  259 + }
  260 + TopChart struct {
  261 + SeriesValue string `json:"seriesValue,optional,omitempty"` // 系列
  262 + Legend string `json:"legend,optional,omitempty"` // 图例
  263 + FormatType string `json:"formatType,optional,omitempty"` //
  264 + FormatPoint string `json:"formatPoint,optional,omitempty"` //
  265 + }
  266 + MidChart struct {
  267 + SeriesValue string `json:"seriesValue,optional,omitempty"` // 系列
  268 + Legend string `json:"legend,optional,omitempty"` // 图例
  269 + FormatType string `json:"formatType,optional,omitempty"` //
  270 + FormatPoint string `json:"formatPoint,optional,omitempty"` //
  271 + }
  272 + BotChart struct {
  273 + SeriesSwitch bool `json:"seriesSwitch,optional,omitempty"` // 是否显示
  274 + Type string `json:"type,optional,omitempty"` // 图表类型
  275 + SeriesValue string `json:"seriesValue,optional,omitempty"` // 系列
  276 + Legend string `json:"legend,optional,omitempty"` // 图例
  277 + FormatType string `json:"formatType,optional,omitempty"` //
  278 + FormatPoint string `json:"formatPoint,optional,omitempty"` //
  279 + }
  280 +)
@@ -13,6 +13,7 @@ info( @@ -13,6 +13,7 @@ info(
13 prefix: v1 13 prefix: v1
14 group: chart-setting 14 group: chart-setting
15 jwt: JwtAuth 15 jwt: JwtAuth
  16 + middleware: LoginStatusCheck,LogRequest
16 ) 17 )
17 service Core { 18 service Core {
18 @handler getChartSetting 19 @handler getChartSetting
@@ -26,12 +26,17 @@ service Core { @@ -26,12 +26,17 @@ service Core {
26 @doc "源数据表-数据" 26 @doc "源数据表-数据"
27 @handler searchTableData 27 @handler searchTableData
28 post /table/data (SearchTableDataRequest) returns (SearchTableDataResponse) 28 post /table/data (SearchTableDataRequest) returns (SearchTableDataResponse)
  29 +
  30 + @doc "源数据表-初始化同步表(首次使用本地存储执行一次)"
  31 + @handler syncTable
  32 + get /table/sync returns (SyncTableResponse)
29 } 33 }
30 34
31 @server( 35 @server(
32 prefix: v1 36 prefix: v1
33 group: table 37 group: table
34 jwt: JwtAuth 38 jwt: JwtAuth
  39 + middleware: LoginStatusCheck,LogRequest
35 //middleware: Authority 40 //middleware: Authority
36 ) 41 )
37 service Core { 42 service Core {
@@ -41,14 +46,24 @@ service Core { @@ -41,14 +46,24 @@ service Core {
41 } 46 }
42 47
43 type ( 48 type (
44 - SearchTableByModuleRequest struct{ 49 + SearchTableByModuleRequest {
45 Token string `header:"x-mmm-accesstoken,optional"` 50 Token string `header:"x-mmm-accesstoken,optional"`
46 } 51 }
47 - SearchTableByModuleResponse struct{  
48 - 52 + SearchTableByModuleResponse {
  53 + Count int `json:"count"`
  54 + List []SearchTableByModuleItem `json:"list"`
  55 + }
  56 + SearchTableByModuleItem {
  57 + Id int `json:"id"` //ID
  58 + TableId int `json:"tableId"` //表ID
  59 + Name string `json:"name"` //表名
  60 + TableType string `json:"tableType"` //表类型
  61 + ParentId int `json:"parentId"` //父级ID
  62 + Flag string `json:"flag"` //分组:Group 集合:Set
  63 + IsLocal bool `json:"isLocal"` //是否本地存储
49 } 64 }
50 65
51 - SearchTableFieldOptionalValuesRequest struct{ 66 + SearchTableFieldOptionalValuesRequest {
52 Token string `header:"x-mmm-accesstoken,optional"` 67 Token string `header:"x-mmm-accesstoken,optional"`
53 ObjectId int `json:"objectId"` // 对象ID 68 ObjectId int `json:"objectId"` // 对象ID
54 Field string `json:"field"` // 当前选择的字段 69 Field string `json:"field"` // 当前选择的字段
@@ -58,11 +73,11 @@ type ( @@ -58,11 +73,11 @@ type (
58 //PageSize int `json:"pageSize,optional"` // 页码 73 //PageSize int `json:"pageSize,optional"` // 页码
59 Condition []*Condition `json:"conditions,optional"` // 条件 74 Condition []*Condition `json:"conditions,optional"` // 条件
60 } 75 }
61 - SearchTableFieldOptionalValuesResponse struct{ 76 + SearchTableFieldOptionalValuesResponse {
62 Values []string `json:"values"` 77 Values []string `json:"values"`
63 Total int64 `json:"total"` 78 Total int64 `json:"total"`
64 } 79 }
65 - Condition struct { 80 + Condition {
66 FieldName string `json:"field"` // 条件字段 81 FieldName string `json:"field"` // 条件字段
67 //SqlName string `json:"sqlName,optional"` // 字段SqlName 82 //SqlName string `json:"sqlName,optional"` // 字段SqlName
68 Like string `json:"like,optional"` // 模糊匹配 83 Like string `json:"like,optional"` // 模糊匹配
@@ -70,22 +85,28 @@ type ( @@ -70,22 +85,28 @@ type (
70 Order string `json:"order,optional,options=ASC||DESC"` // 排序 ASC DESC 默认ASC 85 Order string `json:"order,optional,options=ASC||DESC"` // 排序 ASC DESC 默认ASC
71 } 86 }
72 87
73 - GetTableDetailRequest struct { 88 + GetTableDetailRequest {
74 Token string `header:"x-mmm-accesstoken,optional"` 89 Token string `header:"x-mmm-accesstoken,optional"`
75 TableId int `path:"tableId"` // 表ID 90 TableId int `path:"tableId"` // 表ID
76 } 91 }
77 - GetTableDetailResponse struct{  
78 - 92 + GetTableDetailResponse {
79 } 93 }
80 94
81 - SearchTableDataRequest struct{ 95 + SearchTableDataRequest {
82 Token string `header:"x-mmm-accesstoken,optional"` 96 Token string `header:"x-mmm-accesstoken,optional"`
83 ObjectId int `json:"objectId,optional"` // 对象ID 97 ObjectId int `json:"objectId,optional"` // 对象ID
84 PageNumber int `json:"page,optional"` // 分页数 98 PageNumber int `json:"page,optional"` // 分页数
85 PageSize int `json:"size,optional"` // 页码 99 PageSize int `json:"size,optional"` // 页码
86 Condition []*Condition `json:"conditions,optional"` // 条件 100 Condition []*Condition `json:"conditions,optional"` // 条件
87 } 101 }
88 - SearchTableDataResponse struct{ 102 + SearchTableDataResponse {
  103 + }
  104 +
  105 + SyncTableDataPusher {
  106 + CompanyId int64 `json:"companyId,string"` //公司ID
  107 + ObjectId int `json:"objectId"`
  108 + }
  109 + SyncTableResponse {
89 110
90 } 111 }
91 ) 112 )
1 -  
2 -CREATE TABLE `chart` ( 1 +CREATE TABLE `chart`
  2 +(
3 `id` bigint(0) NOT NULL COMMENT 'ID', 3 `id` bigint(0) NOT NULL COMMENT 'ID',
4 `pid` bigint(0) NOT NULL COMMENT '父级ID', 4 `pid` bigint(0) NOT NULL COMMENT '父级ID',
5 `type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '类型', 5 `type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '类型',
@@ -8,7 +8,8 @@ CREATE TABLE `chart` ( @@ -8,7 +8,8 @@ CREATE TABLE `chart` (
8 PRIMARY KEY (`id`) USING BTREE 8 PRIMARY KEY (`id`) USING BTREE
9 ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; 9 ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
10 10
11 -CREATE TABLE `chart_setting` ( 11 +CREATE TABLE `chart_setting`
  12 +(
12 `id` bigint(0) NOT NULL COMMENT 'ID ', 13 `id` bigint(0) NOT NULL COMMENT 'ID ',
13 `chart_id` bigint(0) NOT NULL COMMENT '图表ID', 14 `chart_id` bigint(0) NOT NULL COMMENT '图表ID',
14 `property` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '属性', 15 `property` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '属性',
@@ -17,7 +18,26 @@ CREATE TABLE `chart_setting` ( @@ -17,7 +18,26 @@ CREATE TABLE `chart_setting` (
17 PRIMARY KEY (`id`) USING BTREE 18 PRIMARY KEY (`id`) USING BTREE
18 ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; 19 ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
19 20
20 -CREATE TABLE `app_page` ( 21 +CREATE TABLE `app_page`
  22 +(
21 `id` int(0) NOT NULL COMMENT '唯一标识', 23 `id` int(0) NOT NULL COMMENT '唯一标识',
22 PRIMARY KEY (`id`) USING BTREE 24 PRIMARY KEY (`id`) USING BTREE
23 ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; 25 ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
  26 +
  27 +Create Table `object_table`
  28 +(
  29 + `id` int not null comment 'ID',
  30 + PRIMARY KEY (`id`) USING BTREE
  31 +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
  32 +
  33 +Create Table `object_field`
  34 +(
  35 + `id` int not null comment 'ID',
  36 + PRIMARY KEY (`id`) USING BTREE
  37 +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
  38 +
  39 +Create Table `object_notice`
  40 +(
  41 + `id` int not null comment 'ID',
  42 + PRIMARY KEY (`id`) USING BTREE
  43 +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
@@ -6,10 +6,14 @@ require ( @@ -6,10 +6,14 @@ require (
6 github.com/golang-jwt/jwt/v4 v4.5.0 6 github.com/golang-jwt/jwt/v4 v4.5.0
7 github.com/jinzhu/copier v0.4.0 7 github.com/jinzhu/copier v0.4.0
8 github.com/jinzhu/now v1.1.5 8 github.com/jinzhu/now v1.1.5
  9 + github.com/magiconair/properties v1.8.0
9 github.com/pkg/errors v0.9.1 10 github.com/pkg/errors v0.9.1
  11 + github.com/samber/lo v1.38.1
10 github.com/stretchr/testify v1.8.4 12 github.com/stretchr/testify v1.8.4
11 github.com/tiptok/gocomm v1.0.14 13 github.com/tiptok/gocomm v1.0.14
  14 + github.com/zeromicro/go-queue v1.1.8
12 github.com/zeromicro/go-zero v1.5.5 15 github.com/zeromicro/go-zero v1.5.5
  16 + golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17
13 google.golang.org/grpc v1.57.0 17 google.golang.org/grpc v1.57.0
14 gorm.io/driver/mysql v1.5.1 18 gorm.io/driver/mysql v1.5.1
15 gorm.io/driver/postgres v1.5.2 19 gorm.io/driver/postgres v1.5.2
@@ -37,7 +41,6 @@ require ( @@ -37,7 +41,6 @@ require (
37 github.com/garyburd/redigo v1.6.3 // indirect 41 github.com/garyburd/redigo v1.6.3 // indirect
38 github.com/gin-contrib/sse v0.1.0 // indirect 42 github.com/gin-contrib/sse v0.1.0 // indirect
39 github.com/gin-gonic/gin v1.5.0 // indirect 43 github.com/gin-gonic/gin v1.5.0 // indirect
40 - github.com/go-gota/gota v0.12.0 // indirect  
41 github.com/go-logr/logr v1.2.3 // indirect 44 github.com/go-logr/logr v1.2.3 // indirect
42 github.com/go-logr/stdr v1.2.2 // indirect 45 github.com/go-logr/stdr v1.2.2 // indirect
43 github.com/go-openapi/jsonpointer v0.19.6 // indirect 46 github.com/go-openapi/jsonpointer v0.19.6 // indirect
@@ -73,7 +76,6 @@ require ( @@ -73,7 +76,6 @@ require (
73 github.com/json-iterator/go v1.1.12 // indirect 76 github.com/json-iterator/go v1.1.12 // indirect
74 github.com/klauspost/compress v1.15.15 // indirect 77 github.com/klauspost/compress v1.15.15 // indirect
75 github.com/leodido/go-urn v1.1.0 // indirect 78 github.com/leodido/go-urn v1.1.0 // indirect
76 - github.com/magiconair/properties v1.8.0 // indirect  
77 github.com/mailru/easyjson v0.7.7 // indirect 79 github.com/mailru/easyjson v0.7.7 // indirect
78 github.com/mattn/go-colorable v0.1.13 // indirect 80 github.com/mattn/go-colorable v0.1.13 // indirect
79 github.com/mattn/go-isatty v0.0.17 // indirect 81 github.com/mattn/go-isatty v0.0.17 // indirect
@@ -93,7 +95,7 @@ require ( @@ -93,7 +95,7 @@ require (
93 github.com/prometheus/common v0.42.0 // indirect 95 github.com/prometheus/common v0.42.0 // indirect
94 github.com/prometheus/procfs v0.10.1 // indirect 96 github.com/prometheus/procfs v0.10.1 // indirect
95 github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect 97 github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
96 - github.com/samber/lo v1.38.1 // indirect 98 + github.com/segmentio/kafka-go v0.4.38 // indirect
97 github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 // indirect 99 github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 // indirect
98 github.com/spaolacci/murmur3 v1.1.0 // indirect 100 github.com/spaolacci/murmur3 v1.1.0 // indirect
99 github.com/spf13/afero v1.2.2 // indirect 101 github.com/spf13/afero v1.2.2 // indirect
@@ -121,7 +123,6 @@ require ( @@ -121,7 +123,6 @@ require (
121 go.uber.org/multierr v1.9.0 // indirect 123 go.uber.org/multierr v1.9.0 // indirect
122 go.uber.org/zap v1.24.0 // indirect 124 go.uber.org/zap v1.24.0 // indirect
123 golang.org/x/crypto v0.12.0 // indirect 125 golang.org/x/crypto v0.12.0 // indirect
124 - golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect  
125 golang.org/x/net v0.14.0 // indirect 126 golang.org/x/net v0.14.0 // indirect
126 golang.org/x/oauth2 v0.7.0 // indirect 127 golang.org/x/oauth2 v0.7.0 // indirect
127 golang.org/x/sys v0.11.0 // indirect 128 golang.org/x/sys v0.11.0 // indirect
@@ -137,7 +138,7 @@ require ( @@ -137,7 +138,7 @@ require (
137 gopkg.in/inf.v0 v0.9.1 // indirect 138 gopkg.in/inf.v0 v0.9.1 // indirect
138 gopkg.in/yaml.v2 v2.4.0 // indirect 139 gopkg.in/yaml.v2 v2.4.0 // indirect
139 gopkg.in/yaml.v3 v3.0.1 // indirect 140 gopkg.in/yaml.v3 v3.0.1 // indirect
140 - gorm.io/datatypes v1.2.0 // indirect 141 + gorm.io/driver/sqlite v1.4.3 // indirect
141 k8s.io/api v0.26.3 // indirect 142 k8s.io/api v0.26.3 // indirect
142 k8s.io/apimachinery v0.27.0-alpha.3 // indirect 143 k8s.io/apimachinery v0.27.0-alpha.3 // indirect
143 k8s.io/client-go v0.26.3 // indirect 144 k8s.io/client-go v0.26.3 // indirect
此 diff 太大无法显示。
  1 +package rd
  2 +
  3 +import (
  4 + "fmt"
  5 + "github.com/zeromicro/go-zero/core/logx"
  6 + "github.com/zeromicro/go-zero/core/stores/redis"
  7 + "github.com/zeromicro/go-zero/rest"
  8 + "net/http"
  9 + "strings"
  10 +)
  11 +
  12 +func Routers(rd *redis.Redis, appName string) []rest.Route {
  13 + return []rest.Route{
  14 + {
  15 + Method: http.MethodGet,
  16 + Path: "/rd/clean",
  17 + Handler: CleanCache(rd, appName),
  18 + },
  19 + }
  20 +}
  21 +
  22 +func CleanCache(rd *redis.Redis, appName string) http.HandlerFunc {
  23 + return func(w http.ResponseWriter, r *http.Request) {
  24 + var (
  25 + success int
  26 + )
  27 + if strings.TrimSpace(appName) == "" {
  28 + return
  29 + }
  30 + keyPattern := fmt.Sprintf("%s*", appName)
  31 + list, err := rd.Keys(keyPattern)
  32 + if err != nil {
  33 + return
  34 + }
  35 + for _, key := range list {
  36 + if _, err = rd.Del(key); err == nil {
  37 + success++
  38 + }
  39 + }
  40 + logx.Infof("清理缓存:%d/%d", success, len(list))
  41 + w.WriteHeader(http.StatusOK)
  42 + w.Write([]byte(fmt.Sprintf("清理缓存:%d/%d", success, len(list))))
  43 + return
  44 + }
  45 +}