作者 yangfu

feat: flush / loaddata

正在显示 69 个修改的文件 包含 2595 行增加202 行删除
@@ -26,4 +26,5 @@ _testmain.go @@ -26,4 +26,5 @@ _testmain.go
26 26
27 app.log 27 app.log
28 go.sum 28 go.sum
29 -lastupdate.tmp  
  29 +lastupdate.tmp
  30 +*.log
@@ -69,14 +69,12 @@ @@ -69,14 +69,12 @@
69 "data": { 69 "data": {
70 "dataFields": [ 70 "dataFields": [
71 { 71 {
72 - "index": 1,  
73 "name": "产品名称", 72 "name": "产品名称",
74 - "Type": "string" 73 + "type": "string"
75 }, 74 },
76 { 75 {
77 - "index": 2,  
78 "name": "产品数量", 76 "name": "产品数量",
79 - "Type": "number" 77 + "type": "int"
80 } 78 }
81 ], 79 ],
82 "dataRows": [ 80 "dataRows": [
  1 +version: v1
  2 +kind: HttpApi
  3 +metadata:
  4 + service: log
  5 + path: /logs
  6 + endpoints:
  7 + - method: createLog
  8 + route:
  9 + post: /
  10 + - method: updateLog
  11 + route:
  12 + put: /{logId}
  13 + - method: getLog
  14 + route:
  15 + get: /{logId}
  16 + - method: removeLog
  17 + route:
  18 + delete: /{logId}
  19 + - method: listLog
  20 + route:
  21 + get: /
  22 + params:
  23 + - name: offset
  24 + - name: limit
  25 + - method: searchLog
  26 + route:
  27 + post: /search
  1 +version: v1
  2 +kind: Method
  3 +metadata:
  4 + name: createLog
  5 + type: command
  6 + description: 创建日志服务
  7 + payload:
  8 + - ref: objectName
  9 + required: true
  10 + - ref: objectType
  11 + required: true
  12 + - ref: operationType
  13 + required: true
  14 + - ref: content
  15 + required: true
  16 + - ref: operatorName
  17 + required: true
  18 + result:
  19 + - name: log
  20 + type:
  21 + schema: log
  22 + required: true
  1 +version: v1
  2 +kind: Method
  3 +metadata:
  4 + name: getLog
  5 + type: query
  6 + description: 返回日志服务
  7 + payload:
  8 + - ref: logId
  9 + required: true
  10 + result:
  11 + - name: log
  12 + type:
  13 + schema: log
  14 + required: true
  1 +version: v1
  2 +kind: Method
  3 +metadata:
  4 + name: listLog
  5 + type: query
  6 + description: 返回日志服务列表
  7 + payload:
  8 + - ref: offset
  9 + required: true
  10 + - ref: limit
  11 + required: true
  12 + result:
  13 + - ref: count
  14 + required: true
  15 + - name: logs
  16 + type:
  17 + array: log
  18 + required: true
  1 +version: v1
  2 +kind: Method
  3 +metadata:
  4 + name: removeLog
  5 + type: command
  6 + description: 移除日志服务
  7 + payload:
  8 + - ref: logId
  9 + required: true
  10 + result:
  11 + - name: log
  12 + type:
  13 + schema: log
  14 + required: true
  1 +version: v1
  2 +kind: Method
  3 +metadata:
  4 + name: searchLog
  5 + type: command
  6 + description: 搜索日志
  7 + payload:
  8 + - ref: content
  9 + required: false
  10 + result:
  11 + - name: log
  12 + type:
  13 + schema: log
  14 + required: true
  1 +version: v1
  2 +kind: Method
  3 +metadata:
  4 + name: updateLog
  5 + type: command
  6 + description: 更新日志服务
  7 + payload:
  8 + - ref: logId
  9 + required: true
  10 + result:
  11 + - name: log
  12 + type:
  13 + schema: log
  14 + required: true
  1 +version: v1
  2 +kind: Service
  3 +metadata:
  4 + name: log
  5 + description: 日志服务
@@ -3,15 +3,14 @@ module gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion @@ -3,15 +3,14 @@ module gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion
3 go 1.16 3 go 1.16
4 4
5 require ( 5 require (
6 - github.com/Shopify/sarama v1.25.0  
7 github.com/ajg/form v1.5.1 // indirect 6 github.com/ajg/form v1.5.1 // indirect
8 github.com/beego/beego/v2 v2.0.1 7 github.com/beego/beego/v2 v2.0.1
  8 + github.com/bwmarrin/snowflake v0.3.0
9 github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072 // indirect 9 github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072 // indirect
10 github.com/fatih/structs v1.1.0 // indirect 10 github.com/fatih/structs v1.1.0 // indirect
11 github.com/gavv/httpexpect v2.0.0+incompatible 11 github.com/gavv/httpexpect v2.0.0+incompatible
12 github.com/go-pg/pg/v10 v10.9.0 12 github.com/go-pg/pg/v10 v10.9.0
13 - github.com/go-redis/redis v6.15.9+incompatible // indirect  
14 - github.com/go-redis/redis/v7 v7.4.1 // indirect 13 + github.com/go-redis/redis v6.15.9+incompatible
15 github.com/golang/snappy v0.0.3 // indirect 14 github.com/golang/snappy v0.0.3 // indirect
16 github.com/google/go-cmp v0.5.6 // indirect 15 github.com/google/go-cmp v0.5.6 // indirect
17 github.com/google/go-querystring v1.1.0 // indirect 16 github.com/google/go-querystring v1.1.0 // indirect
@@ -22,13 +21,16 @@ require ( @@ -22,13 +21,16 @@ require (
22 github.com/onsi/ginkgo v1.15.2 21 github.com/onsi/ginkgo v1.15.2
23 github.com/onsi/gomega v1.11.0 22 github.com/onsi/gomega v1.11.0
24 github.com/sergi/go-diff v1.2.0 // indirect 23 github.com/sergi/go-diff v1.2.0 // indirect
  24 + github.com/shopspring/decimal v1.2.0
25 github.com/smartystreets/goconvey v1.7.2 // indirect 25 github.com/smartystreets/goconvey v1.7.2 // indirect
  26 + github.com/stretchr/testify v1.7.0
26 github.com/valyala/fasthttp v1.38.0 // indirect 27 github.com/valyala/fasthttp v1.38.0 // indirect
27 github.com/xeipuuv/gojsonschema v1.2.0 // indirect 28 github.com/xeipuuv/gojsonschema v1.2.0 // indirect
28 github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 // indirect 29 github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 // indirect
29 github.com/yudai/gojsondiff v1.0.0 // indirect 30 github.com/yudai/gojsondiff v1.0.0 // indirect
30 github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect 31 github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect
31 github.com/yudai/pp v2.0.1+incompatible // indirect 32 github.com/yudai/pp v2.0.1+incompatible // indirect
  33 + golang.org/x/text v0.3.7
32 ) 34 )
33 35
34 replace github.com/linmadan/egglib-go v0.0.0-20210313060205-8b5e456b11f7 => github.com/tiptok/egglib-go v0.0.0-20220421085958-9682d0ac42c1 36 replace github.com/linmadan/egglib-go v0.0.0-20210313060205-8b5e456b11f7 => github.com/tiptok/egglib-go v0.0.0-20220421085958-9682d0ac42c1
@@ -4,12 +4,12 @@ import ( @@ -4,12 +4,12 @@ import (
4 "fmt" 4 "fmt"
5 "github.com/beego/beego/v2/server/web" 5 "github.com/beego/beego/v2/server/web"
6 "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/constant" 6 "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/constant"
  7 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/pg"
7 "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/redis" 8 "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/redis"
8 "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/log" 9 "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/log"
9 "time" 10 "time"
10 11
11 _ "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/constant" 12 _ "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/constant"
12 - _ "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/pg"  
13 _ "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/redis" 13 _ "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/redis"
14 _ "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/log" 14 _ "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/log"
15 _ "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/port/beego" 15 _ "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/port/beego"
@@ -24,6 +24,7 @@ func main() { @@ -24,6 +24,7 @@ func main() {
24 24
25 log.InitLogHook(constant.ENABLE_KAFKA_LOG, true) 25 log.InitLogHook(constant.ENABLE_KAFKA_LOG, true)
26 redis.InitRedis() 26 redis.InitRedis()
  27 + pg.Init()
27 28
28 time.Sleep(time.Second) 29 time.Sleep(time.Second)
29 log.Logger.Info("server start!") 30 log.Logger.Info("server start!")
1 package factory 1 package factory
  2 +
  3 +import (
  4 + "github.com/linmadan/egglib-go/core/application"
  5 + "github.com/linmadan/egglib-go/transaction/pg"
  6 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
  7 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/domainService"
  8 +)
  9 +
  10 +func FastLog(transactionContext application.TransactionContext, logType domain.LogType, sourceId int, logEntry domainService.Log) error {
  11 + logService, _ := domainService.NewPGLogService(transactionContext.(*pg.TransactionContext))
  12 + return logService.Log(logType, sourceId, logEntry)
  13 +}
  14 +
  15 +func CreateLoadDataTableService(transactionContext application.TransactionContext) (domain.LoadDataTableService, error) {
  16 + return domainService.NewLoadDataTableService(transactionContext.(*pg.TransactionContext))
  17 +}
  18 +
  19 +func CreateFlushDataTableService(transactionContext application.TransactionContext) (domain.FlushDataTableService, error) {
  20 + return domainService.NewFlushDataTableService(transactionContext.(*pg.TransactionContext))
  21 +}
  22 +
  23 +func CreateDeleteFileService(transactionContext application.TransactionContext) (domain.DeleteFileService, error) {
  24 + return domainService.NewDeleteFileService(transactionContext.(*pg.TransactionContext))
  25 +}
  26 +
  27 +func CreateGenerateMainTableService(transactionContext application.TransactionContext) (domain.GenerateMainTableService, error) {
  28 + return domainService.NewGenerateMainTableService(transactionContext.(*pg.TransactionContext))
  29 +}
  1 +package factory
  2 +
  3 +import (
  4 + "github.com/linmadan/egglib-go/core/application"
  5 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
  6 +)
  7 +
  8 +// FastPgFile 快速返回文件对象
  9 +//
  10 +// transactionContext 事务
  11 +// id 对象唯一标识
  12 +func FastPgFile(transactionContext application.TransactionContext, id int) (domain.FileRepository, *domain.File, error) {
  13 + var rep domain.FileRepository
  14 + var mod *domain.File
  15 + var err error
  16 + if value, err := CreateFileRepository(map[string]interface{}{
  17 + "transactionContext": transactionContext,
  18 + }); err != nil {
  19 + return nil, nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  20 + } else {
  21 + rep = value
  22 + }
  23 + if id > 0 {
  24 + if mod, err = rep.FindOne(map[string]interface{}{"fileId": id}); err != nil {
  25 + if err == domain.ErrorNotFound {
  26 + return nil, nil, application.ThrowError(application.RES_NO_FIND_ERROR, "该文件不存在")
  27 + }
  28 + return nil, nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  29 + }
  30 + }
  31 + //if err = fastPgDataAuth(transactionContext, mod, options...); err != nil {
  32 + // return nil, nil, err
  33 + //}
  34 + return rep, mod, err
  35 +}
  36 +
  37 +// FastPgTable 快速返回表格对象
  38 +//
  39 +// transactionContext 事务
  40 +// id 对象唯一标识
  41 +func FastPgTable(transactionContext application.TransactionContext, id int) (domain.TableRepository, *domain.Table, error) {
  42 + var rep domain.TableRepository
  43 + var mod *domain.Table
  44 + var err error
  45 + if value, err := CreateTableRepository(map[string]interface{}{
  46 + "transactionContext": transactionContext,
  47 + }); err != nil {
  48 + return nil, nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  49 + } else {
  50 + rep = value
  51 + }
  52 + if id > 0 {
  53 + if mod, err = rep.FindOne(map[string]interface{}{"tableId": id}); err != nil {
  54 + if err == domain.ErrorNotFound {
  55 + return nil, nil, application.ThrowError(application.RES_NO_FIND_ERROR, "该表格不存在")
  56 + }
  57 + return nil, nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  58 + }
  59 + }
  60 + return rep, mod, err
  61 +}
@@ -2,6 +2,8 @@ package command @@ -2,6 +2,8 @@ package command
2 2
3 import ( 3 import (
4 "fmt" 4 "fmt"
  5 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
  6 + "path/filepath"
5 "reflect" 7 "reflect"
6 "strings" 8 "strings"
7 9
@@ -18,7 +20,11 @@ type CreateFileCommand struct { @@ -18,7 +20,11 @@ type CreateFileCommand struct {
18 } 20 }
19 21
20 func (createFileCommand *CreateFileCommand) Valid(validation *validation.Validation) { 22 func (createFileCommand *CreateFileCommand) Valid(validation *validation.Validation) {
21 - 23 + ext := filepath.Ext(createFileCommand.Name)
  24 + if !(ext == domain.XLS || ext == domain.XLSX) {
  25 + validation.Error(fmt.Sprintf("仅支持文件格式 xls 、 xlsx"))
  26 + return
  27 + }
22 } 28 }
23 29
24 func (createFileCommand *CreateFileCommand) ValidateCommand() error { 30 func (createFileCommand *CreateFileCommand) ValidateCommand() error {
@@ -2,6 +2,7 @@ package command @@ -2,6 +2,7 @@ package command
2 2
3 import ( 3 import (
4 "fmt" 4 "fmt"
  5 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/file/dto"
5 "reflect" 6 "reflect"
6 "strings" 7 "strings"
7 8
@@ -11,10 +12,14 @@ import ( @@ -11,10 +12,14 @@ import (
11 type FlushDataTableCommand struct { 12 type FlushDataTableCommand struct {
12 // 文件ID 13 // 文件ID
13 FileId int `cname:"文件ID" json:"fileId" valid:"Required"` 14 FileId int `cname:"文件ID" json:"fileId" valid:"Required"`
  15 + // 记录数
  16 + RowCount int `cname:"记录数" json:"rowCount" valid:"Required"`
  17 + // 数据列
  18 + DataFields []*dto.Field `cname:"数据列" json:"dataFields" valid:"Required"`
14 } 19 }
15 20
16 func (flushDataTableCommand *FlushDataTableCommand) Valid(validation *validation.Validation) { 21 func (flushDataTableCommand *FlushDataTableCommand) Valid(validation *validation.Validation) {
17 - validation.SetError("CustomValid", "未实现的自定义认证") 22 +
18 } 23 }
19 24
20 func (flushDataTableCommand *FlushDataTableCommand) ValidateCommand() error { 25 func (flushDataTableCommand *FlushDataTableCommand) ValidateCommand() error {
@@ -11,10 +11,12 @@ import ( @@ -11,10 +11,12 @@ import (
11 type GenerateMainTableCommand struct { 11 type GenerateMainTableCommand struct {
12 // 文件ID 12 // 文件ID
13 FileId int `cname:"文件ID" json:"fileId" valid:"Required"` 13 FileId int `cname:"文件ID" json:"fileId" valid:"Required"`
  14 + // 表名
  15 + TableName string `cname:"表名" json:"tableName" valid:"Required"`
14 } 16 }
15 17
16 func (generateMainTableCommand *GenerateMainTableCommand) Valid(validation *validation.Validation) { 18 func (generateMainTableCommand *GenerateMainTableCommand) Valid(validation *validation.Validation) {
17 - validation.SetError("CustomValid", "未实现的自定义认证") 19 +
18 } 20 }
19 21
20 func (generateMainTableCommand *GenerateMainTableCommand) ValidateCommand() error { 22 func (generateMainTableCommand *GenerateMainTableCommand) ValidateCommand() error {
@@ -11,6 +11,10 @@ import ( @@ -11,6 +11,10 @@ import (
11 type LoadDataTableCommand struct { 11 type LoadDataTableCommand struct {
12 // 文件ID 12 // 文件ID
13 FileId int `cname:"文件ID" json:"fileId" valid:"Required"` 13 FileId int `cname:"文件ID" json:"fileId" valid:"Required"`
  14 + // 页号
  15 + PageNumber int `cname:"页号" json:"pageNumber"`
  16 + // 页号
  17 + PageSize int `cname:"数量" json:"pageSize"`
14 } 18 }
15 19
16 func (loadDataTableCommand *LoadDataTableCommand) Valid(validation *validation.Validation) { 20 func (loadDataTableCommand *LoadDataTableCommand) Valid(validation *validation.Validation) {
1 package dto 1 package dto
2 2
  3 +import "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
  4 +
3 type DataTableDto struct { 5 type DataTableDto struct {
  6 + FileId int `json:"fileId"`
4 DataFields []*Field `json:"dataFields"` 7 DataFields []*Field `json:"dataFields"`
5 DataRows [][]interface{} `json:"dataRows"` 8 DataRows [][]interface{} `json:"dataRows"`
6 Total int `json:"total"` 9 Total int `json:"total"`
@@ -10,11 +13,11 @@ type DataTableDto struct { @@ -10,11 +13,11 @@ type DataTableDto struct {
10 13
11 type Field struct { 14 type Field struct {
12 // 索引序号 15 // 索引序号
13 - Index int `json:"index"` 16 + // Index int `json:"index"`
14 // 名称 17 // 名称
15 Name string `json:"name"` 18 Name string `json:"name"`
16 // 对应数据库类型 19 // 对应数据库类型
17 - Type string `json:"Type"` 20 + Type string `json:"type"`
18 } 21 }
19 22
20 type InValidCell struct { 23 type InValidCell struct {
@@ -23,18 +26,18 @@ type InValidCell struct { @@ -23,18 +26,18 @@ type InValidCell struct {
23 Error string `json:"error"` 26 Error string `json:"error"`
24 } 27 }
25 28
26 -func NewDataTableDtoDemo() DataTableDto { 29 +func NewDataTableDtoDemo(fileId int) DataTableDto {
27 return DataTableDto{ 30 return DataTableDto{
28 DataFields: []*Field{ 31 DataFields: []*Field{
29 { 32 {
30 - Index: 1,  
31 - Name: "产品名称",  
32 - Type: "string", 33 + //Index: 1,
  34 + Name: "产品名称",
  35 + Type: domain.String.ToString(),
33 }, 36 },
34 { 37 {
35 - Index: 2,  
36 - Name: "产品数量",  
37 - Type: "number", 38 + //Index: 2,
  39 + Name: "产品数量",
  40 + Type: domain.Int.ToString(),
38 }, 41 },
39 }, 42 },
40 DataRows: [][]interface{}{ 43 DataRows: [][]interface{}{
@@ -52,5 +55,6 @@ func NewDataTableDtoDemo() DataTableDto { @@ -52,5 +55,6 @@ func NewDataTableDtoDemo() DataTableDto {
52 }, 55 },
53 PageNumber: 1, 56 PageNumber: 1,
54 Total: 100, 57 Total: 100,
  58 + FileId: fileId,
55 } 59 }
56 } 60 }
  1 +package dto
  2 +
  3 +import (
  4 + "github.com/linmadan/egglib-go/utils/xtime"
  5 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
  6 +)
  7 +
  8 +type FileDto struct {
  9 + // 文件ID
  10 + FileId int `json:"fileId"`
  11 + // 名称
  12 + Name string `json:"name"`
  13 + // 文件地址
  14 + Url string `json:"url"`
  15 + // 创建时间
  16 + Time string `json:"time"`
  17 +}
  18 +
  19 +func (d *FileDto) Load(f *domain.File) {
  20 + d.FileId = f.FileId
  21 + d.Name = f.FileInfo.Name
  22 + d.Url = f.FileInfo.Url
  23 + d.Time = xtime.New(f.CreatedAt).Local().Format("2006-01-02 15:04:05")
  24 +}
@@ -17,7 +17,7 @@ type SearchFileQuery struct { @@ -17,7 +17,7 @@ type SearchFileQuery struct {
17 // 页码 17 // 页码
18 // PageNumber int `cname:"页码" json:"pageNumber,omitempty"` 18 // PageNumber int `cname:"页码" json:"pageNumber,omitempty"`
19 // 页数 19 // 页数
20 - FileName int `cname:"文件名称" json:"fileName,omitempty"` 20 + FileName string `cname:"文件名称" json:"fileName,omitempty"`
21 PageSize int `cname:"页数" json:"pageSize,omitempty"` 21 PageSize int `cname:"页数" json:"pageSize,omitempty"`
22 LastId int `cname:"最后一条记录ID" json:"lastId"` 22 LastId int `cname:"最后一条记录ID" json:"lastId"`
23 FileType domain.FileType `cname:"文件类型" json:"fileType" valid:"Required"` 23 FileType domain.FileType `cname:"文件类型" json:"fileType" valid:"Required"`
  1 +package service
  2 +
  3 +import (
  4 + "github.com/linmadan/egglib-go/core/application"
  5 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/factory"
  6 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/file/command"
  7 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/file/dto"
  8 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
  9 +)
  10 +
  11 +// 加载表格数据
  12 +func (fileService *FileService) LoadDataTable(loadDataTableCommand *command.LoadDataTableCommand) (interface{}, error) {
  13 + if err := loadDataTableCommand.ValidateCommand(); err != nil {
  14 + return nil, application.ThrowError(application.ARG_ERROR, err.Error())
  15 + }
  16 + transactionContext, err := factory.CreateTransactionContext(nil)
  17 + if err != nil {
  18 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  19 + }
  20 + if err := transactionContext.StartTransaction(); err != nil {
  21 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  22 + }
  23 + defer func() {
  24 + transactionContext.RollbackTransaction()
  25 + }()
  26 +
  27 + loadDataTableService, _ := factory.CreateLoadDataTableService(transactionContext)
  28 + if _, err := loadDataTableService.Load(loadDataTableCommand.FileId); err != nil {
  29 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  30 + }
  31 +
  32 + if err := transactionContext.CommitTransaction(); err != nil {
  33 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  34 + }
  35 +
  36 + return dto.NewDataTableDtoDemo(loadDataTableService.GetFileId()), nil
  37 +}
  38 +
  39 +// 编辑表格数据
  40 +func (fileService *FileService) EditDataTable(editDataTableCommand *command.EditDataTableCommand) (interface{}, error) {
  41 + if err := editDataTableCommand.ValidateCommand(); err != nil {
  42 + return nil, application.ThrowError(application.ARG_ERROR, err.Error())
  43 + }
  44 + transactionContext, err := factory.CreateTransactionContext(nil)
  45 + if err != nil {
  46 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  47 + }
  48 + if err := transactionContext.StartTransaction(); err != nil {
  49 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  50 + }
  51 + defer func() {
  52 + transactionContext.RollbackTransaction()
  53 + }()
  54 + if err := transactionContext.CommitTransaction(); err != nil {
  55 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  56 + }
  57 + return struct{}{}, nil
  58 +}
  59 +
  60 +// 持久化表格数据
  61 +func (fileService *FileService) FlushDataTable(flushDataTableCommand *command.FlushDataTableCommand) (interface{}, error) {
  62 + if err := flushDataTableCommand.ValidateCommand(); err != nil {
  63 + return nil, application.ThrowError(application.ARG_ERROR, err.Error())
  64 + }
  65 + transactionContext, err := factory.CreateTransactionContext(nil)
  66 + if err != nil {
  67 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  68 + }
  69 + if err := transactionContext.StartTransaction(); err != nil {
  70 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  71 + }
  72 + defer func() {
  73 + transactionContext.RollbackTransaction()
  74 + }()
  75 + flushDataTableService, _ := factory.CreateFlushDataTableService(transactionContext)
  76 + fields := make([]*domain.Field, 0)
  77 + for _, f := range flushDataTableCommand.DataFields {
  78 + fields = append(fields, &domain.Field{
  79 + Name: f.Name,
  80 + SQLType: f.Type,
  81 + })
  82 + }
  83 + if _, err := flushDataTableService.Flush(flushDataTableCommand.FileId, &domain.Table{
  84 + DataFields: fields,
  85 + RowCount: flushDataTableCommand.RowCount,
  86 + }); err != nil {
  87 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  88 + }
  89 + if err := transactionContext.CommitTransaction(); err != nil {
  90 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  91 + }
  92 + return struct{}{}, nil
  93 +}
  94 +
  95 +// 生成主表
  96 +func (fileService *FileService) GenerateMainTable(generateMainTableCommand *command.GenerateMainTableCommand) (interface{}, error) {
  97 + if err := generateMainTableCommand.ValidateCommand(); err != nil {
  98 + return nil, application.ThrowError(application.ARG_ERROR, err.Error())
  99 + }
  100 + transactionContext, err := factory.CreateTransactionContext(nil)
  101 + if err != nil {
  102 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  103 + }
  104 + if err := transactionContext.StartTransaction(); err != nil {
  105 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  106 + }
  107 + defer func() {
  108 + transactionContext.RollbackTransaction()
  109 + }()
  110 +
  111 + generateMainTableService, _ := factory.CreateGenerateMainTableService(transactionContext)
  112 + _, err = generateMainTableService.GenerateTable(generateMainTableCommand.FileId, generateMainTableCommand.TableName)
  113 + if err != nil {
  114 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  115 + }
  116 + if err := transactionContext.CommitTransaction(); err != nil {
  117 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  118 + }
  119 + return struct{}{}, nil
  120 +}
@@ -9,6 +9,10 @@ import ( @@ -9,6 +9,10 @@ import (
9 "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/file/dto" 9 "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/file/dto"
10 "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/file/query" 10 "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/file/query"
11 "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" 11 "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
  12 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/domainService"
  13 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/utils"
  14 + "path/filepath"
  15 + "time"
12 ) 16 )
13 17
14 // 文件服务 18 // 文件服务
@@ -30,92 +34,35 @@ func (fileService *FileService) CreateFile(createFileCommand *command.CreateFile @@ -30,92 +34,35 @@ func (fileService *FileService) CreateFile(createFileCommand *command.CreateFile
30 defer func() { 34 defer func() {
31 transactionContext.RollbackTransaction() 35 transactionContext.RollbackTransaction()
32 }() 36 }()
33 - //newFile := &domain.File{  
34 - //Name: createFileCommand.Name,  
35 - //Url: createFileCommand.Url,  
36 - //FileSize: createFileCommand.FileSize,  
37 - //}  
38 - //var fileRepository domain.FileRepository  
39 - //if value, err := factory.CreateFileRepository(map[string]interface{}{  
40 - // "transactionContext": transactionContext,  
41 - //}); err != nil {  
42 - // return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())  
43 - //} else {  
44 - // fileRepository = value  
45 - //}  
46 - //file, err := fileRepository.Save(newFile)  
47 - //if err != nil {  
48 - // return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())  
49 - //}  
50 - if err := transactionContext.CommitTransaction(); err != nil {  
51 - return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())  
52 - }  
53 - return struct{}{}, nil  
54 -}  
55 -  
56 -// 编辑表格数据  
57 -func (fileService *FileService) EditDataTable(editDataTableCommand *command.EditDataTableCommand) (interface{}, error) {  
58 - if err := editDataTableCommand.ValidateCommand(); err != nil {  
59 - return nil, application.ThrowError(application.ARG_ERROR, err.Error())  
60 - }  
61 - transactionContext, err := factory.CreateTransactionContext(nil) 37 + newFile := &domain.File{
  38 + FileType: domain.SourceFile.ToString(),
  39 + FileInfo: &domain.FileInfo{
  40 + Name: domain.FileName(createFileCommand.Name),
  41 + Url: createFileCommand.Url,
  42 + FileSize: createFileCommand.FileSize,
  43 + Ext: filepath.Ext(createFileCommand.Name),
  44 + },
  45 + SourceFileId: 0,
  46 + Operator: "",
  47 + CreatedAt: time.Now(),
  48 + UpdatedAt: time.Now(),
  49 + }
  50 + fileRepository, _, _ := factory.FastPgFile(transactionContext, 0)
  51 + file, err := fileRepository.Save(newFile)
62 if err != nil { 52 if err != nil {
63 - return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) 53 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
64 } 54 }
65 - if err := transactionContext.StartTransaction(); err != nil {  
66 - return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) 55 + if err = factory.FastLog(transactionContext, domain.CommonLog, file.FileId, &domainService.FileUploadSuccessLog{
  56 + LogEntry: domain.NewLogEntry(file.FileInfo.Name, domain.SourceFile.ToString(), domain.FileUpload, ""),
  57 + }); err != nil {
  58 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
67 } 59 }
68 - defer func() {  
69 - transactionContext.RollbackTransaction()  
70 - }()  
71 if err := transactionContext.CommitTransaction(); err != nil { 60 if err := transactionContext.CommitTransaction(); err != nil {
72 return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) 61 return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
73 } 62 }
74 return struct{}{}, nil 63 return struct{}{}, nil
75 } 64 }
76 65
77 -// 持久化表格数据  
78 -func (fileService *FileService) FlushDataTable(flushDataTableCommand *command.FlushDataTableCommand) (interface{}, error) {  
79 - if err := flushDataTableCommand.ValidateCommand(); err != nil {  
80 - return nil, application.ThrowError(application.ARG_ERROR, err.Error())  
81 - }  
82 - transactionContext, err := factory.CreateTransactionContext(nil)  
83 - if err != nil {  
84 - return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())  
85 - }  
86 - if err := transactionContext.StartTransaction(); err != nil {  
87 - return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())  
88 - }  
89 - defer func() {  
90 - transactionContext.RollbackTransaction()  
91 - }()  
92 - if err := transactionContext.CommitTransaction(); err != nil {  
93 - return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())  
94 - }  
95 - return nil, nil  
96 -}  
97 -  
98 -// 生成主表  
99 -func (fileService *FileService) GenerateMainTable(generateMainTableCommand *command.GenerateMainTableCommand) (interface{}, error) {  
100 - if err := generateMainTableCommand.ValidateCommand(); err != nil {  
101 - return nil, application.ThrowError(application.ARG_ERROR, err.Error())  
102 - }  
103 - transactionContext, err := factory.CreateTransactionContext(nil)  
104 - if err != nil {  
105 - return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())  
106 - }  
107 - if err := transactionContext.StartTransaction(); err != nil {  
108 - return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())  
109 - }  
110 - defer func() {  
111 - transactionContext.RollbackTransaction()  
112 - }()  
113 - if err := transactionContext.CommitTransaction(); err != nil {  
114 - return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())  
115 - }  
116 - return nil, nil  
117 -}  
118 -  
119 // 返回文件服务 66 // 返回文件服务
120 func (fileService *FileService) GetFile(getFileQuery *query.GetFileQuery) (interface{}, error) { 67 func (fileService *FileService) GetFile(getFileQuery *query.GetFileQuery) (interface{}, error) {
121 if err := getFileQuery.ValidateQuery(); err != nil { 68 if err := getFileQuery.ValidateQuery(); err != nil {
@@ -212,41 +159,25 @@ func (fileService *FileService) SearchFile(listFileQuery *query.SearchFileQuery) @@ -212,41 +159,25 @@ func (fileService *FileService) SearchFile(listFileQuery *query.SearchFileQuery)
212 } else { 159 } else {
213 fileRepository = value 160 fileRepository = value
214 } 161 }
215 - count, files, err := fileRepository.Find(tool_funs.SimpleStructToMap(listFileQuery)) 162 + count, files, err := fileRepository.Find(utils.ObjectToMap(listFileQuery))
216 if err != nil { 163 if err != nil {
217 return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) 164 return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
218 } 165 }
  166 + var fileDtos = make([]*dto.FileDto, 0)
  167 + for _, file := range files {
  168 + var item = &dto.FileDto{}
  169 + item.Load(file)
  170 + fileDtos = append(fileDtos, item)
  171 + }
219 if err := transactionContext.CommitTransaction(); err != nil { 172 if err := transactionContext.CommitTransaction(); err != nil {
220 return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) 173 return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
221 } 174 }
222 return map[string]interface{}{ 175 return map[string]interface{}{
223 "count": count, 176 "count": count,
224 - "files": files, 177 + "files": fileDtos,
225 }, nil 178 }, nil
226 } 179 }
227 180
228 -// 加载表格数据  
229 -func (fileService *FileService) LoadDataTable(loadDataTableCommand *command.LoadDataTableCommand) (interface{}, error) {  
230 - if err := loadDataTableCommand.ValidateCommand(); err != nil {  
231 - return nil, application.ThrowError(application.ARG_ERROR, err.Error())  
232 - }  
233 - transactionContext, err := factory.CreateTransactionContext(nil)  
234 - if err != nil {  
235 - return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())  
236 - }  
237 - if err := transactionContext.StartTransaction(); err != nil {  
238 - return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())  
239 - }  
240 - defer func() {  
241 - transactionContext.RollbackTransaction()  
242 - }()  
243 - if err := transactionContext.CommitTransaction(); err != nil {  
244 - return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())  
245 - }  
246 -  
247 - return dto.NewDataTableDtoDemo(), nil  
248 -}  
249 -  
250 // 移除文件服务 181 // 移除文件服务
251 func (fileService *FileService) RemoveFile(removeFileCommand *command.RemoveFileCommand) (interface{}, error) { 182 func (fileService *FileService) RemoveFile(removeFileCommand *command.RemoveFileCommand) (interface{}, error) {
252 if err := removeFileCommand.ValidateCommand(); err != nil { 183 if err := removeFileCommand.ValidateCommand(); err != nil {
@@ -277,14 +208,15 @@ func (fileService *FileService) RemoveFile(removeFileCommand *command.RemoveFile @@ -277,14 +208,15 @@ func (fileService *FileService) RemoveFile(removeFileCommand *command.RemoveFile
277 if file == nil { 208 if file == nil {
278 return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(removeFileCommand.FileId))) 209 return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(removeFileCommand.FileId)))
279 } 210 }
280 - if file, err := fileRepository.Remove(file); err != nil { 211 + deleteFileService, _ := factory.CreateDeleteFileService(transactionContext)
  212 + err = deleteFileService.Delete(file)
  213 + if err != nil {
281 return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) 214 return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
282 - } else {  
283 - if err := transactionContext.CommitTransaction(); err != nil {  
284 - return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())  
285 - }  
286 - return file, nil  
287 } 215 }
  216 + if err := transactionContext.CommitTransaction(); err != nil {
  217 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  218 + }
  219 + return struct{}{}, nil
288 } 220 }
289 221
290 // 更新文件服务 222 // 更新文件服务
  1 +package command
  2 +
  3 +import (
  4 + "fmt"
  5 + "reflect"
  6 + "strings"
  7 +
  8 + "github.com/beego/beego/v2/core/validation"
  9 +)
  10 +
  11 +type CreateLogCommand struct {
  12 + // 对象名称 数据表名 / 文件名
  13 + ObjectName string `cname:"对象名称 数据表名 / 文件名" json:"objectName" valid:"Required"`
  14 + // 对象类型 1.主表 2.分表 3.副表 4.源文件 5.校验文件
  15 + ObjectType string `cname:"对象类型 1.主表 2.分表 3.副表 4.源文件 5.校验文件" json:"objectType" valid:"Required"`
  16 + // 操作类型 1.主表生成 2.主表拆分 3.数据导入 4.分表生成 5.表复制 6.编辑记录 7.文件上传 8.文件校验
  17 + OperationType string `cname:"操作类型 1.主表生成 2.主表拆分 3.数据导入 4.分表生成 5.表复制 6.编辑记录 7.文件上传 8.文件校验" json:"operationType" valid:"Required"`
  18 + // 日志内容
  19 + Content string `cname:"日志内容" json:"content" valid:"Required"`
  20 + // 操作人名称
  21 + OperatorName string `cname:"操作人名称" json:"operatorName" valid:"Required"`
  22 +}
  23 +
  24 +func (createLogCommand *CreateLogCommand) Valid(validation *validation.Validation) {
  25 + validation.SetError("CustomValid", "未实现的自定义认证")
  26 +}
  27 +
  28 +func (createLogCommand *CreateLogCommand) ValidateCommand() error {
  29 + valid := validation.Validation{}
  30 + b, err := valid.Valid(createLogCommand)
  31 + if err != nil {
  32 + return err
  33 + }
  34 + if !b {
  35 + elem := reflect.TypeOf(createLogCommand).Elem()
  36 + for _, validErr := range valid.Errors {
  37 + field, isExist := elem.FieldByName(validErr.Field)
  38 + if isExist {
  39 + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1))
  40 + } else {
  41 + return fmt.Errorf(validErr.Message)
  42 + }
  43 + }
  44 + }
  45 + return nil
  46 +}
  1 +package command
  2 +
  3 +import (
  4 + "fmt"
  5 + "reflect"
  6 + "strings"
  7 +
  8 + "github.com/beego/beego/v2/core/validation"
  9 +)
  10 +
  11 +type RemoveLogCommand struct {
  12 + // 日志ID
  13 + LogId int `cname:"日志ID" json:"logId" valid:"Required"`
  14 +}
  15 +
  16 +func (removeLogCommand *RemoveLogCommand) Valid(validation *validation.Validation) {
  17 + validation.SetError("CustomValid", "未实现的自定义认证")
  18 +}
  19 +
  20 +func (removeLogCommand *RemoveLogCommand) ValidateCommand() error {
  21 + valid := validation.Validation{}
  22 + b, err := valid.Valid(removeLogCommand)
  23 + if err != nil {
  24 + return err
  25 + }
  26 + if !b {
  27 + elem := reflect.TypeOf(removeLogCommand).Elem()
  28 + for _, validErr := range valid.Errors {
  29 + field, isExist := elem.FieldByName(validErr.Field)
  30 + if isExist {
  31 + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1))
  32 + } else {
  33 + return fmt.Errorf(validErr.Message)
  34 + }
  35 + }
  36 + }
  37 + return nil
  38 +}
  1 +package command
  2 +
  3 +import (
  4 + "fmt"
  5 + "reflect"
  6 + "strings"
  7 +
  8 + "github.com/beego/beego/v2/core/validation"
  9 +)
  10 +
  11 +type SearchLogCommand struct {
  12 + // 日志内容
  13 + Content string `cname:"日志内容" json:"content,omitempty"`
  14 +}
  15 +
  16 +func (searchLogCommand *SearchLogCommand) Valid(validation *validation.Validation) {
  17 + validation.SetError("CustomValid", "未实现的自定义认证")
  18 +}
  19 +
  20 +func (searchLogCommand *SearchLogCommand) ValidateCommand() error {
  21 + valid := validation.Validation{}
  22 + b, err := valid.Valid(searchLogCommand)
  23 + if err != nil {
  24 + return err
  25 + }
  26 + if !b {
  27 + elem := reflect.TypeOf(searchLogCommand).Elem()
  28 + for _, validErr := range valid.Errors {
  29 + field, isExist := elem.FieldByName(validErr.Field)
  30 + if isExist {
  31 + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1))
  32 + } else {
  33 + return fmt.Errorf(validErr.Message)
  34 + }
  35 + }
  36 + }
  37 + return nil
  38 +}
  1 +package command
  2 +
  3 +import (
  4 + "fmt"
  5 + "reflect"
  6 + "strings"
  7 +
  8 + "github.com/beego/beego/v2/core/validation"
  9 +)
  10 +
  11 +type UpdateLogCommand struct {
  12 + // 日志ID
  13 + LogId int `cname:"日志ID" json:"logId" valid:"Required"`
  14 +}
  15 +
  16 +func (updateLogCommand *UpdateLogCommand) Valid(validation *validation.Validation) {
  17 + validation.SetError("CustomValid", "未实现的自定义认证")
  18 +}
  19 +
  20 +func (updateLogCommand *UpdateLogCommand) ValidateCommand() error {
  21 + valid := validation.Validation{}
  22 + b, err := valid.Valid(updateLogCommand)
  23 + if err != nil {
  24 + return err
  25 + }
  26 + if !b {
  27 + elem := reflect.TypeOf(updateLogCommand).Elem()
  28 + for _, validErr := range valid.Errors {
  29 + field, isExist := elem.FieldByName(validErr.Field)
  30 + if isExist {
  31 + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1))
  32 + } else {
  33 + return fmt.Errorf(validErr.Message)
  34 + }
  35 + }
  36 + }
  37 + return nil
  38 +}
  1 +package query
  2 +
  3 +import (
  4 + "fmt"
  5 + "reflect"
  6 + "strings"
  7 +
  8 + "github.com/beego/beego/v2/core/validation"
  9 +)
  10 +
  11 +type GetLogQuery struct {
  12 + // 日志ID
  13 + LogId int `cname:"日志ID" json:"logId" valid:"Required"`
  14 +}
  15 +
  16 +func (getLogQuery *GetLogQuery) Valid(validation *validation.Validation) {
  17 + validation.SetError("CustomValid", "未实现的自定义认证")
  18 +}
  19 +
  20 +func (getLogQuery *GetLogQuery) ValidateQuery() error {
  21 + valid := validation.Validation{}
  22 + b, err := valid.Valid(getLogQuery)
  23 + if err != nil {
  24 + return err
  25 + }
  26 + if !b {
  27 + elem := reflect.TypeOf(getLogQuery).Elem()
  28 + for _, validErr := range valid.Errors {
  29 + field, isExist := elem.FieldByName(validErr.Field)
  30 + if isExist {
  31 + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1))
  32 + } else {
  33 + return fmt.Errorf(validErr.Message)
  34 + }
  35 + }
  36 + }
  37 + return nil
  38 +}
  1 +package query
  2 +
  3 +import (
  4 + "fmt"
  5 + "reflect"
  6 + "strings"
  7 +
  8 + "github.com/beego/beego/v2/core/validation"
  9 +)
  10 +
  11 +type ListLogQuery struct {
  12 + // 查询偏离量
  13 + Offset int `cname:"查询偏离量" json:"offset" valid:"Required"`
  14 + // 查询限制
  15 + Limit int `cname:"查询限制" json:"limit" valid:"Required"`
  16 +}
  17 +
  18 +func (listLogQuery *ListLogQuery) Valid(validation *validation.Validation) {
  19 + validation.SetError("CustomValid", "未实现的自定义认证")
  20 +}
  21 +
  22 +func (listLogQuery *ListLogQuery) ValidateQuery() error {
  23 + valid := validation.Validation{}
  24 + b, err := valid.Valid(listLogQuery)
  25 + if err != nil {
  26 + return err
  27 + }
  28 + if !b {
  29 + elem := reflect.TypeOf(listLogQuery).Elem()
  30 + for _, validErr := range valid.Errors {
  31 + field, isExist := elem.FieldByName(validErr.Field)
  32 + if isExist {
  33 + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1))
  34 + } else {
  35 + return fmt.Errorf(validErr.Message)
  36 + }
  37 + }
  38 + }
  39 + return nil
  40 +}
  1 +package service
  2 +
  3 +import (
  4 + "fmt"
  5 + "github.com/linmadan/egglib-go/core/application"
  6 + "github.com/linmadan/egglib-go/utils/tool_funs"
  7 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/factory"
  8 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/log/command"
  9 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/log/query"
  10 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
  11 +)
  12 +
  13 +// 日志服务
  14 +type LogService struct {
  15 +}
  16 +
  17 +// 创建日志服务
  18 +func (logService *LogService) CreateLog(createLogCommand *command.CreateLogCommand) (interface{}, error) {
  19 + if err := createLogCommand.ValidateCommand(); err != nil {
  20 + return nil, application.ThrowError(application.ARG_ERROR, err.Error())
  21 + }
  22 + transactionContext, err := factory.CreateTransactionContext(nil)
  23 + if err != nil {
  24 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  25 + }
  26 + if err := transactionContext.StartTransaction(); err != nil {
  27 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  28 + }
  29 + defer func() {
  30 + transactionContext.RollbackTransaction()
  31 + }()
  32 + newLog := &domain.Log{
  33 + ObjectName: createLogCommand.ObjectName,
  34 + ObjectType: createLogCommand.ObjectType,
  35 + OperationType: createLogCommand.OperationType,
  36 + Content: createLogCommand.Content,
  37 + OperatorName: createLogCommand.OperatorName,
  38 + }
  39 + var logRepository domain.LogRepository
  40 + if value, err := factory.CreateLogRepository(map[string]interface{}{
  41 + "transactionContext": transactionContext,
  42 + }); err != nil {
  43 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  44 + } else {
  45 + logRepository = value
  46 + }
  47 + if log, err := logRepository.Save(newLog); err != nil {
  48 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  49 + } else {
  50 + if err := transactionContext.CommitTransaction(); err != nil {
  51 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  52 + }
  53 + return log, nil
  54 + }
  55 +}
  56 +
  57 +// 返回日志服务
  58 +func (logService *LogService) GetLog(getLogQuery *query.GetLogQuery) (interface{}, error) {
  59 + if err := getLogQuery.ValidateQuery(); err != nil {
  60 + return nil, application.ThrowError(application.ARG_ERROR, err.Error())
  61 + }
  62 + transactionContext, err := factory.CreateTransactionContext(nil)
  63 + if err != nil {
  64 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  65 + }
  66 + if err := transactionContext.StartTransaction(); err != nil {
  67 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  68 + }
  69 + defer func() {
  70 + transactionContext.RollbackTransaction()
  71 + }()
  72 + var logRepository domain.LogRepository
  73 + if value, err := factory.CreateLogRepository(map[string]interface{}{
  74 + "transactionContext": transactionContext,
  75 + }); err != nil {
  76 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  77 + } else {
  78 + logRepository = value
  79 + }
  80 + log, err := logRepository.FindOne(map[string]interface{}{"logId": getLogQuery.LogId})
  81 + if err != nil {
  82 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  83 + }
  84 + if log == nil {
  85 + return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(getLogQuery.LogId)))
  86 + } else {
  87 + if err := transactionContext.CommitTransaction(); err != nil {
  88 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  89 + }
  90 + return log, nil
  91 + }
  92 +}
  93 +
  94 +// 返回日志服务列表
  95 +func (logService *LogService) ListLog(listLogQuery *query.ListLogQuery) (interface{}, error) {
  96 + if err := listLogQuery.ValidateQuery(); err != nil {
  97 + return nil, application.ThrowError(application.ARG_ERROR, err.Error())
  98 + }
  99 + transactionContext, err := factory.CreateTransactionContext(nil)
  100 + if err != nil {
  101 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  102 + }
  103 + if err := transactionContext.StartTransaction(); err != nil {
  104 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  105 + }
  106 + defer func() {
  107 + transactionContext.RollbackTransaction()
  108 + }()
  109 + var logRepository domain.LogRepository
  110 + if value, err := factory.CreateLogRepository(map[string]interface{}{
  111 + "transactionContext": transactionContext,
  112 + }); err != nil {
  113 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  114 + } else {
  115 + logRepository = value
  116 + }
  117 + if count, logs, err := logRepository.Find(tool_funs.SimpleStructToMap(listLogQuery)); err != nil {
  118 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  119 + } else {
  120 + if err := transactionContext.CommitTransaction(); err != nil {
  121 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  122 + }
  123 + return map[string]interface{}{
  124 + "count": count,
  125 + "logs": logs,
  126 + }, nil
  127 + }
  128 +}
  129 +
  130 +// 移除日志服务
  131 +func (logService *LogService) RemoveLog(removeLogCommand *command.RemoveLogCommand) (interface{}, error) {
  132 + if err := removeLogCommand.ValidateCommand(); err != nil {
  133 + return nil, application.ThrowError(application.ARG_ERROR, err.Error())
  134 + }
  135 + transactionContext, err := factory.CreateTransactionContext(nil)
  136 + if err != nil {
  137 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  138 + }
  139 + if err := transactionContext.StartTransaction(); err != nil {
  140 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  141 + }
  142 + defer func() {
  143 + transactionContext.RollbackTransaction()
  144 + }()
  145 + var logRepository domain.LogRepository
  146 + if value, err := factory.CreateLogRepository(map[string]interface{}{
  147 + "transactionContext": transactionContext,
  148 + }); err != nil {
  149 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  150 + } else {
  151 + logRepository = value
  152 + }
  153 + log, err := logRepository.FindOne(map[string]interface{}{"logId": removeLogCommand.LogId})
  154 + if err != nil {
  155 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  156 + }
  157 + if log == nil {
  158 + return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(removeLogCommand.LogId)))
  159 + }
  160 + if log, err := logRepository.Remove(log); err != nil {
  161 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  162 + } else {
  163 + if err := transactionContext.CommitTransaction(); err != nil {
  164 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  165 + }
  166 + return log, nil
  167 + }
  168 +}
  169 +
  170 +// 搜索日志
  171 +func (logService *LogService) SearchLog(searchLogCommand *command.SearchLogCommand) (interface{}, error) {
  172 + if err := searchLogCommand.ValidateCommand(); err != nil {
  173 + return nil, application.ThrowError(application.ARG_ERROR, err.Error())
  174 + }
  175 + transactionContext, err := factory.CreateTransactionContext(nil)
  176 + if err != nil {
  177 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  178 + }
  179 + if err := transactionContext.StartTransaction(); err != nil {
  180 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  181 + }
  182 + defer func() {
  183 + transactionContext.RollbackTransaction()
  184 + }()
  185 + if err := transactionContext.CommitTransaction(); err != nil {
  186 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  187 + }
  188 + return nil, nil
  189 +}
  190 +
  191 +// 更新日志服务
  192 +func (logService *LogService) UpdateLog(updateLogCommand *command.UpdateLogCommand) (interface{}, error) {
  193 + if err := updateLogCommand.ValidateCommand(); err != nil {
  194 + return nil, application.ThrowError(application.ARG_ERROR, err.Error())
  195 + }
  196 + transactionContext, err := factory.CreateTransactionContext(nil)
  197 + if err != nil {
  198 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  199 + }
  200 + if err := transactionContext.StartTransaction(); err != nil {
  201 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  202 + }
  203 + defer func() {
  204 + transactionContext.RollbackTransaction()
  205 + }()
  206 + var logRepository domain.LogRepository
  207 + if value, err := factory.CreateLogRepository(map[string]interface{}{
  208 + "transactionContext": transactionContext,
  209 + }); err != nil {
  210 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  211 + } else {
  212 + logRepository = value
  213 + }
  214 + log, err := logRepository.FindOne(map[string]interface{}{"logId": updateLogCommand.LogId})
  215 + if err != nil {
  216 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  217 + }
  218 + if log == nil {
  219 + return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(updateLogCommand.LogId)))
  220 + }
  221 + if err := log.Update(tool_funs.SimpleStructToMap(updateLogCommand)); err != nil {
  222 + return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
  223 + }
  224 + if log, err := logRepository.Save(log); err != nil {
  225 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  226 + } else {
  227 + if err := transactionContext.CommitTransaction(); err != nil {
  228 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  229 + }
  230 + return log, nil
  231 + }
  232 +}
  233 +
  234 +func NewLogService(options map[string]interface{}) *LogService {
  235 + newLogService := &LogService{}
  236 + return newLogService
  237 +}
@@ -8,12 +8,6 @@ var ( @@ -8,12 +8,6 @@ var (
8 8
9 // 是否关闭仓储层缓存 9 // 是否关闭仓储层缓存
10 ENABLE_REPOSITORY_CACHE = true 10 ENABLE_REPOSITORY_CACHE = true
11 - // 缓存过期时间 单位秒  
12 - REPOSITORY_CACHE_EXPIRE = 30 * 60  
13 - // redis 考勤机打卡消息队列  
14 - REDIS_ZKTECO_KEY = "allied-creation-zkteco"  
15 - // redis 车间数据消息队列  
16 - REDIS_WORKSHOP_KEY = "allied-creation-workshop"  
17 ) 11 )
18 12
19 func init() { 13 func init() {
  1 +package domain
  2 +
  3 +type LoadDataTableService interface {
  4 + Load(fileId int) (interface{}, error)
  5 + GetFileId() int
  6 +}
  7 +
  8 +type FlushDataTableService interface {
  9 + Flush(fileId int, table *Table) (interface{}, error)
  10 +}
  11 +
  12 +type DeleteFileService interface {
  13 + Delete(files ...*File) error
  14 +}
  15 +
  16 +type GenerateMainTableService interface {
  17 + GenerateTable(fileId int, tableName string) (interface{}, error)
  18 +}
1 package domain 1 package domain
2 2
3 -type FileType string 3 +import "fmt"
4 4
5 var ( 5 var (
6 - SourceFile FileType = "SourceFile"  
7 - VerifiedFile FileType = "VerifiedFile"  
8 - TemporaryFile FileType = "TemporaryFile" 6 + ErrorNotFound = fmt.Errorf("没有此资源")
9 ) 7 )
10 8
11 var ( 9 var (
12 GenerateMainTable OperationType = "GenerateMainTable" // 主表生成 10 GenerateMainTable OperationType = "GenerateMainTable" // 主表生成
13 SpiltMainTable OperationType = "SpiltMainTable" //主表拆分 11 SpiltMainTable OperationType = "SpiltMainTable" //主表拆分
14 - ImportData OperationType = "ImportData" //数据导入  
15 - GenerateSubTable OperationType = "GenerateSubTable" //分表生成 12 + AppendData OperationType = "AppendData" //数据追加
  13 + EditSubTable OperationType = "EditSubTable" //分表编辑
16 CopyTable OperationType = "CopyTable" //表复制 14 CopyTable OperationType = "CopyTable" //表复制
17 RowEdit OperationType = "RowEdit" // 编辑记录 15 RowEdit OperationType = "RowEdit" // 编辑记录
  16 + DeleteTable OperationType = "DeleteTable" // 表删除
18 FileUpload OperationType = "FileUpload" // 文件上传 17 FileUpload OperationType = "FileUpload" // 文件上传
19 FileVerify OperationType = "FileVerify" // 文件校验 18 FileVerify OperationType = "FileVerify" // 文件校验
20 ) 19 )
21 20
  21 +var OperationTypeMap = map[string]string{
  22 + GenerateMainTable.ToString(): "主表生成",
  23 + SpiltMainTable.ToString(): "主表拆分",
  24 + AppendData.ToString(): "数据追加",
  25 + EditSubTable.ToString(): "分表编辑",
  26 + CopyTable.ToString(): "表复制",
  27 + RowEdit.ToString(): "编辑记录",
  28 + DeleteTable.ToString(): "表删除",
  29 + FileUpload.ToString(): "文件上传",
  30 + FileVerify.ToString(): "文件校验",
  31 +}
  32 +
  33 +var (
  34 + VerifiedStepLog LogType = "VerifiedStepLog"
  35 + CommonLog LogType = "CommonLog"
  36 +)
  37 +
  38 +var (
  39 + PKField int = 0 // 主键字段
  40 + MainTableField int = 1 // 主表字段
  41 + ManualField int = 2 // 手动添加
  42 +)
  43 +
  44 +var (
  45 + MainTable TableType = "MainTable"
  46 + SideTable TableType = "SideTable"
  47 + SubTable TableType = "SubTable"
  48 + ExcelTable TableType = "ExcelTable"
  49 +)
  50 +
  51 +var (
  52 + SourceFile FileType = "SourceFile"
  53 + VerifiedFile FileType = "VerifiedFile"
  54 + TemporaryFile FileType = "TemporaryFile"
  55 +)
  56 +
  57 +var ObjectTypeMap = map[string]string{
  58 + MainTable.ToString(): "主表",
  59 + SideTable.ToString(): "副表",
  60 + SubTable.ToString(): "分表",
  61 + SourceFile.ToString(): "源文件",
  62 + VerifiedFile.ToString(): "校验文件",
  63 +}
  64 +
22 var ( 65 var (
23 - VerifiedStepLog LogType = 1  
24 - CommonLog LogType = 2 66 + XLS = ".xls"
  67 + XLSX = ".xlsx"
25 ) 68 )
26 69
27 var ( 70 var (
28 - MainTable TableType = "MainTable"  
29 - SideTable TableType = "SideTable"  
30 - SubTable TableType = "SubTable"  
31 - ExcelTable TableType = "ExcelTable"  
32 - VerifiedExcelTable TableType = "VerifiedExcelTable" 71 + String SQLType = "string"
  72 + Int SQLType = "int"
  73 + Float SQLType = "float"
  74 + Date SQLType = "date"
  75 + Datetime SQLType = "datetime"
33 ) 76 )
34 77
  78 +type FileType string
  79 +
35 func (t FileType) ToString() string { 80 func (t FileType) ToString() string {
36 return string(t) 81 return string(t)
37 } 82 }
38 83
39 -type LogType int 84 +type LogType string
  85 +
  86 +func (t LogType) ToString() string {
  87 + return string(t)
  88 +}
40 89
41 type TableType string 90 type TableType string
42 91
@@ -51,3 +100,16 @@ type OperationType string @@ -51,3 +100,16 @@ type OperationType string
51 func (t OperationType) ToString() string { 100 func (t OperationType) ToString() string {
52 return string(t) 101 return string(t)
53 } 102 }
  103 +
  104 +type SQLType string
  105 +
  106 +func (t SQLType) ToString() string {
  107 + return string(t)
  108 +}
  109 +
  110 +func EnumsDescription(m map[string]string, key string) string {
  111 + if v, ok := m[key]; ok {
  112 + return v
  113 + }
  114 + return ""
  115 +}
@@ -3,7 +3,7 @@ package domain @@ -3,7 +3,7 @@ package domain
3 // Field 字段 3 // Field 字段
4 type Field struct { 4 type Field struct {
5 // 字段Id 5 // 字段Id
6 - FieldId int `json:"fieldId"` 6 + // FieldId int `json:"fieldId"`
7 // 索引序号 7 // 索引序号
8 Index int `json:"index"` 8 Index int `json:"index"`
9 // 名称 9 // 名称
1 package domain 1 package domain
2 2
3 -import "time" 3 +import (
  4 + "path/filepath"
  5 + "strings"
  6 + "time"
  7 +)
4 8
5 // File 文件 9 // File 文件
6 type File struct { 10 type File struct {
@@ -11,7 +15,7 @@ type File struct { @@ -11,7 +15,7 @@ type File struct {
11 // 文件信息 15 // 文件信息
12 FileInfo *FileInfo `json:"fileInfo"` 16 FileInfo *FileInfo `json:"fileInfo"`
13 // 源文件Id(FileType为TemporaryFile或VerifiedFile时有值) 17 // 源文件Id(FileType为TemporaryFile或VerifiedFile时有值)
14 - SourceFileId string `json:"sourceFileId"` 18 + SourceFileId int `json:"sourceFileId"`
15 // 操作人 19 // 操作人
16 Operator string `json:"operator"` 20 Operator string `json:"operator"`
17 // 创建时间 21 // 创建时间
@@ -41,3 +45,26 @@ func (file *File) Identify() interface{} { @@ -41,3 +45,26 @@ func (file *File) Identify() interface{} {
41 func (file *File) Update(data map[string]interface{}) error { 45 func (file *File) Update(data map[string]interface{}) error {
42 return nil 46 return nil
43 } 47 }
  48 +
  49 +func FileName(fileName string) string {
  50 + base := filepath.Base(fileName)
  51 + return strings.Split(base, ".")[0]
  52 +}
  53 +
  54 +func (file *File) CopyTo(fileType FileType) *File {
  55 + t := &File{
  56 + FileType: fileType.ToString(),
  57 + FileInfo: &FileInfo{
  58 + Name: file.FileInfo.Name,
  59 + FileSize: file.FileInfo.FileSize,
  60 + Url: file.FileInfo.Url,
  61 + Ext: file.FileInfo.Ext,
  62 + RowCount: file.FileInfo.RowCount,
  63 + },
  64 + CreatedAt: time.Now(),
  65 + UpdatedAt: time.Now(),
  66 + SourceFileId: file.FileId,
  67 + Operator: file.Operator,
  68 + }
  69 + return t
  70 +}
@@ -8,4 +8,12 @@ type FileInfo struct { @@ -8,4 +8,12 @@ type FileInfo struct {
8 Url string `json:"url"` 8 Url string `json:"url"`
9 // 文件大小 9 // 文件大小
10 FileSize int `json:"fileSize"` 10 FileSize int `json:"fileSize"`
  11 + // 文件编号,以固定字符“F”+4位年+2位月+2位日+三位流水,每天编号从001开始
  12 + // FileCode string `json:"fileCode"`
  13 + //
  14 + Ext string `json:"ext"`
  15 + // 记录数
  16 + RowCount int `json:"rowCount"`
  17 + // 表结构ID
  18 + TableId int `json:"tableId"`
11 } 19 }
@@ -7,11 +7,21 @@ type Log struct { @@ -7,11 +7,21 @@ type Log struct {
7 // 日志ID 7 // 日志ID
8 LogId int `json:"logId"` 8 LogId int `json:"logId"`
9 // 日志类型 1.校验步骤 2.常规日志 9 // 日志类型 1.校验步骤 2.常规日志
10 - LogType int `json:"logType"` 10 + LogType string `json:"logType"`
11 // 源数据ID 11 // 源数据ID
12 SourceId int `json:"sourceId"` 12 SourceId int `json:"sourceId"`
13 // 日志内容 13 // 日志内容
14 Entry *LogEntry `json:"entry"` 14 Entry *LogEntry `json:"entry"`
  15 + // 对象名称 数据表名 / 文件名
  16 + ObjectName string `json:"objectName"`
  17 + // 对象类型 1.主表 2.分表 3.副表 4.源文件 5.校验文件
  18 + ObjectType string `json:"objectType"`
  19 + // 操作类型 1.主表生成 2.主表拆分 3.数据导入 4.分表生成 5.表复制 6.编辑记录 7.文件上传 8.文件校验
  20 + OperationType string `json:"operationType"`
  21 + // 日志内容
  22 + Content string `json:"content"`
  23 + // 操作人名称
  24 + OperatorName string `json:"operatorName"`
15 // 创建时间 25 // 创建时间
16 CreatedAt time.Time `json:"createdAt"` 26 CreatedAt time.Time `json:"createdAt"`
17 } 27 }
@@ -13,3 +13,16 @@ type LogEntry struct { @@ -13,3 +13,16 @@ type LogEntry struct {
13 // 操作人名称 13 // 操作人名称
14 OperatorName string `json:"operatorName"` 14 OperatorName string `json:"operatorName"`
15 } 15 }
  16 +
  17 +func (l LogEntry) Entry() LogEntry {
  18 + return l
  19 +}
  20 +
  21 +func NewLogEntry(fileOrTableName string, objectType string, operationType OperationType, operatorName string) LogEntry {
  22 + return LogEntry{
  23 + ObjectName: fileOrTableName,
  24 + ObjectType: objectType,
  25 + OperationType: operationType.ToString(),
  26 + OperatorName: operatorName,
  27 + }
  28 +}
@@ -11,9 +11,9 @@ type Table struct { @@ -11,9 +11,9 @@ type Table struct {
11 // 名称 11 // 名称
12 Name string `json:"name"` 12 Name string `json:"name"`
13 // 对应数据库名称 13 // 对应数据库名称
14 - SQLName string `json:"sQLName"` 14 + SQLName string `json:"sqlName"`
15 // 父级ID 15 // 父级ID
16 - ParentId int64 `json:"parentId,string"` 16 + ParentId int `json:"parentId"`
17 // 数据字段序号 17 // 数据字段序号
18 DataFieldIndex int `json:"dataFieldIndex"` 18 DataFieldIndex int `json:"dataFieldIndex"`
19 // 主键字段 19 // 主键字段
@@ -30,6 +30,9 @@ type Table struct { @@ -30,6 +30,9 @@ type Table struct {
30 DeletedAt time.Time `json:"deletedAt"` 30 DeletedAt time.Time `json:"deletedAt"`
31 // 版本 31 // 版本
32 Version int `json:"version"` 32 Version int `json:"version"`
  33 +
  34 + // 业务字段
  35 + RowCount int `json:"rowCount,omitempty"`
33 } 36 }
34 37
35 type TableRepository interface { 38 type TableRepository interface {
  1 +package dao
  2 +
  3 +import (
  4 + "github.com/go-pg/pg/v10"
  5 + pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
  6 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
  7 +)
  8 +
  9 +func FileDelete(ptr *pgTransaction.TransactionContext, fileId int, fileType domain.FileType) error {
  10 + sql := "delete from metadata.files where file_id = ? and file_type = ?"
  11 + _, err := ptr.PgTx.Exec(sql, fileId, fileType.ToString())
  12 + return err
  13 +}
  14 +
  15 +func FileDeleteBySourceFileId(ptr *pgTransaction.TransactionContext, fileId int, fileType domain.FileType, excludeFileIs ...int) error {
  16 + sql := "delete from metadata.files where source_file_id = ? and file_type =? and file_id not in (?)"
  17 + _, err := ptr.PgTx.Exec(sql, fileId, fileType.ToString(), pg.In(excludeFileIs))
  18 + return err
  19 +}
  1 +package dao
  2 +
  3 +import (
  4 + pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
  5 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
  6 +)
  7 +
  8 +func ChangeStepLogOwner(ptr *pgTransaction.TransactionContext, from int, to int) error {
  9 + sql := "update metadata.logs set source_id = ? where source_id=? and log_type=?"
  10 + _, err := ptr.PgTx.Exec(sql, to, from, domain.VerifiedStepLog)
  11 + return err
  12 +}
  13 +
  14 +func LogDelete(ptr *pgTransaction.TransactionContext, sourceId int, logType domain.LogType) error {
  15 + sql := "delete from metadata.logs where source_id = ? and log_type = ?"
  16 + _, err := ptr.PgTx.Exec(sql, sourceId, logType)
  17 + return err
  18 +}
  1 +package dao
  2 +
  3 +import (
  4 + pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
  5 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
  6 +)
  7 +
  8 +func TableDelete(ptr *pgTransaction.TransactionContext, tableId int, tableType domain.TableType) error {
  9 + sql := "delete from metadata.tables where table_id = ? and table_type = ?"
  10 + _, err := ptr.PgTx.Exec(sql, tableId, tableType.ToString())
  11 + return err
  12 +}
  1 +package domainService
  2 +
  3 +import (
  4 + "fmt"
  5 + pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
  6 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
  7 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/dao"
  8 +)
  9 +
  10 +type DeleteFileService struct {
  11 + transactionContext *pgTransaction.TransactionContext
  12 +}
  13 +
  14 +func NewDeleteFileService(transactionContext *pgTransaction.TransactionContext) (*DeleteFileService, error) {
  15 + if transactionContext == nil {
  16 + return nil, fmt.Errorf("transactionContext参数不能为nil")
  17 + } else {
  18 + return &DeleteFileService{
  19 + transactionContext: transactionContext,
  20 + }, nil
  21 + }
  22 +}
  23 +
  24 +func (ptr *DeleteFileService) Delete(files ...*domain.File) error {
  25 + for _, file := range files {
  26 + if err := ptr.delete(file); err != nil {
  27 + return err
  28 + }
  29 + }
  30 + return nil
  31 +}
  32 +
  33 +func (ptr *DeleteFileService) delete(file *domain.File) error {
  34 + // delete file
  35 + if err := dao.FileDelete(ptr.transactionContext, file.FileId, domain.FileType(file.FileType)); err != nil {
  36 + return err
  37 + }
  38 + // delete table
  39 + if file.FileInfo.TableId > 0 {
  40 + if err := dao.TableDelete(ptr.transactionContext, file.FileInfo.TableId, domain.ExcelTable); err != nil {
  41 + return err
  42 + }
  43 + }
  44 + // delete log
  45 + if err := dao.LogDelete(ptr.transactionContext, file.FileId, domain.VerifiedStepLog); err != nil {
  46 + return err
  47 + }
  48 + return nil
  49 +}
  1 +package domainService
  2 +
  3 +import pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
  4 +
  5 +type DeleteTableService struct {
  6 + transactionContext *pgTransaction.TransactionContext
  7 +}
  8 +
  9 +func (ptr *DeleteTableService) Delete(tableIds ...int) error {
  10 + // delete table
  11 +
  12 + // delete log
  13 + return nil
  14 +}
  1 +package domainService
  2 +
  3 +import (
  4 + "fmt"
  5 + "github.com/google/uuid"
  6 + pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
  7 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
  8 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/dao"
  9 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/repository"
  10 + "time"
  11 +)
  12 +
  13 +type FlushDataTableService struct {
  14 + FileId int
  15 + transactionContext *pgTransaction.TransactionContext
  16 +}
  17 +
  18 +func (ptr *FlushDataTableService) Flush(fileId int, table *domain.Table) (interface{}, error) {
  19 + fileRepository, _ := repository.NewFileRepository(ptr.transactionContext)
  20 + file, err := fileRepository.FindOne(map[string]interface{}{"fileId": fileId})
  21 + if err != nil {
  22 + return nil, fmt.Errorf("临时文件不存在")
  23 + }
  24 + sourceFile, err := fileRepository.FindOne(map[string]interface{}{"fileId": file.SourceFileId})
  25 + if err != nil {
  26 + return nil, fmt.Errorf("源文件不存在")
  27 + }
  28 + // New Table
  29 + table = NewTable(domain.ExcelTable, file.FileInfo.Name, table.DataFields, table.RowCount)
  30 +
  31 + // 来自源文件的
  32 + // 临时文件 -》校验文件
  33 + switch sourceFile.FileType {
  34 + case domain.SourceFile.ToString():
  35 + if err = ptr.flushSourceFile(table, file, sourceFile, fileRepository); err != nil {
  36 + return nil, err
  37 + }
  38 + case domain.VerifiedFile.ToString():
  39 + if err = ptr.flushVerifiedFile(table, file, sourceFile, fileRepository); err != nil {
  40 + return nil, err
  41 + }
  42 + }
  43 + // 日志
  44 + if err = FastLog(ptr.transactionContext, domain.CommonLog, file.FileId, &FileVerifyLog{
  45 + LogEntry: domain.NewLogEntry(file.FileInfo.Name, domain.VerifiedFile.ToString(), domain.FileVerify, ""),
  46 + Total: table.RowCount,
  47 + }); err != nil {
  48 + return nil, err
  49 + }
  50 + // 通知底层保存、进行回调
  51 +
  52 + return struct{}{}, nil
  53 +}
  54 +
  55 +func (ptr *FlushDataTableService) flushSourceFile(table *domain.Table, file *domain.File, sourceFile *domain.File, fileRepository domain.FileRepository) error {
  56 + var err error
  57 + // 新增
  58 + tableRepository, _ := repository.NewTableRepository(ptr.transactionContext)
  59 + table, err = tableRepository.Save(table)
  60 + if err != nil {
  61 + return err
  62 + }
  63 + file.FileInfo.TableId = table.TableId
  64 + file.FileType = domain.VerifiedFile.ToString()
  65 + if file, err = fileRepository.Save(file); err != nil {
  66 + return err
  67 + }
  68 + // 删除跟源文件有关系的校验文件
  69 + //if err = dao.FileDeleteBySourceFileId(ptr.transactionContext, sourceFile.FileId, domain.VerifiedFile, file.FileId); err != nil {
  70 + // return err
  71 + //}
  72 + _, files, err := fileRepository.Find(map[string]interface{}{"sourceFileId": sourceFile.FileId, "fileType": domain.VerifiedFile.ToString(), "notInFileIds": []int{file.FileId}})
  73 + if err != nil {
  74 + return err
  75 + }
  76 + deleteFileService, _ := NewDeleteFileService(ptr.transactionContext)
  77 + if err = deleteFileService.Delete(files...); err != nil {
  78 + return err
  79 + }
  80 + return nil
  81 +}
  82 +
  83 +func (ptr *FlushDataTableService) flushVerifiedFile(table *domain.Table, file *domain.File, sourceFile *domain.File, fileRepository domain.FileRepository) error {
  84 + var err error
  85 + temporaryFileTableId := table.TableId
  86 + // 校验文件对应的表更新
  87 + table.TableId = file.FileInfo.TableId
  88 + // 追加日志到校验文件
  89 + if err = dao.ChangeStepLogOwner(ptr.transactionContext, file.FileId, sourceFile.FileId); err != nil {
  90 + return err
  91 + }
  92 + // 删除中间文件
  93 + if err = dao.FileDelete(ptr.transactionContext, file.FileId, domain.TemporaryFile); err != nil {
  94 + return err
  95 + }
  96 + // 删除中间表
  97 + if err = dao.TableDelete(ptr.transactionContext, temporaryFileTableId, domain.ExcelTable); err != nil {
  98 + return err
  99 + }
  100 + if _, err = fileRepository.Save(sourceFile); err != nil {
  101 + return err
  102 + }
  103 + // 更新
  104 + tableRepository, _ := repository.NewTableRepository(ptr.transactionContext)
  105 + table, err = tableRepository.Save(table)
  106 + if err != nil {
  107 + return err
  108 + }
  109 + return nil
  110 +}
  111 +
  112 +func NewFlushDataTableService(transactionContext *pgTransaction.TransactionContext) (*FlushDataTableService, error) {
  113 + if transactionContext == nil {
  114 + return nil, fmt.Errorf("transactionContext参数不能为nil")
  115 + } else {
  116 + return &FlushDataTableService{
  117 + transactionContext: transactionContext,
  118 + }, nil
  119 + }
  120 +}
  121 +
  122 +func NewTable(tableType domain.TableType, fileName string, dataFields []*domain.Field, rowCount int) *domain.Table {
  123 + var table = &domain.Table{}
  124 + // New Table
  125 + table.TableType = tableType.ToString()
  126 + table.Name = fileName
  127 + table.SQLName = SQLTableName()
  128 + table.PK = PK()
  129 + table.DataFieldIndex = len(dataFields)
  130 + for i, field := range dataFields {
  131 + table.DataFields = append(table.DataFields, DataField(field.Name, field.SQLType, domain.MainTableField, i))
  132 + }
  133 + table.ManualFields = make([]*domain.Field, 0)
  134 + table.CreatedAt = time.Now()
  135 + table.UpdatedAt = time.Now()
  136 + table.RowCount = rowCount
  137 + return table
  138 +}
  139 +
  140 +func SQLTableName() string {
  141 + id, _ := uuid.NewUUID()
  142 + return id.String()
  143 +}
  144 +
  145 +func PK() *domain.Field {
  146 + return &domain.Field{
  147 + Index: 0,
  148 + Name: "序号",
  149 + SQLName: "id",
  150 + SQLType: domain.Int.ToString(),
  151 + Description: "主键",
  152 + Flag: 0,
  153 + }
  154 +}
  155 +
  156 +func DataField(name string, sqlType string, flag int, index int) *domain.Field {
  157 + return &domain.Field{
  158 + Index: index,
  159 + Name: name,
  160 + SQLName: fieldName(index + 1),
  161 + SQLType: sqlType,
  162 + Description: "",
  163 + Flag: flag,
  164 + }
  165 +}
  166 +
  167 +func fieldName(index int) string {
  168 + return fmt.Sprintf("col%02d", index)
  169 +}
  1 +package domainService
  2 +
  3 +import (
  4 + "fmt"
  5 + pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
  6 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
  7 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/repository"
  8 +)
  9 +
  10 +type GenerateMainTableService struct {
  11 + transactionContext *pgTransaction.TransactionContext
  12 +}
  13 +
  14 +func (ptr *GenerateMainTableService) GenerateTable(fileId int, tableName string) (interface{}, error) {
  15 + fileRepository, _ := repository.NewFileRepository(ptr.transactionContext)
  16 + file, err := fileRepository.FindOne(map[string]interface{}{"fileId": fileId})
  17 + if err != nil {
  18 + return nil, fmt.Errorf("文件不存在")
  19 + }
  20 +
  21 + tableRepository, _ := repository.NewTableRepository(ptr.transactionContext)
  22 + table, err := tableRepository.FindOne(map[string]interface{}{"tableId": file.FileInfo.TableId})
  23 + if err != nil {
  24 + return nil, fmt.Errorf("文件未校验")
  25 + }
  26 +
  27 + mainTable := NewTable(domain.MainTable, tableName, table.DataFields, table.RowCount)
  28 + _, err = tableRepository.Save(mainTable)
  29 + if err != nil {
  30 + return nil, err
  31 + }
  32 + return struct{}{}, nil
  33 +}
  34 +
  35 +func NewGenerateMainTableService(transactionContext *pgTransaction.TransactionContext) (*GenerateMainTableService, error) {
  36 + if transactionContext == nil {
  37 + return nil, fmt.Errorf("transactionContext参数不能为nil")
  38 + } else {
  39 + return &GenerateMainTableService{
  40 + transactionContext: transactionContext,
  41 + }, nil
  42 + }
  43 +}
  1 +package domainService
  2 +
  3 +import (
  4 + "fmt"
  5 + pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
  6 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
  7 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/repository"
  8 +)
  9 +
  10 +type LoadDataTableService struct {
  11 + FileId int
  12 + transactionContext *pgTransaction.TransactionContext
  13 +}
  14 +
  15 +func (ptr *LoadDataTableService) Load(fileId int) (interface{}, error) {
  16 + fileRepository, _ := repository.NewFileRepository(ptr.transactionContext)
  17 + file, err := fileRepository.FindOne(map[string]interface{}{"fileId": fileId})
  18 + if err != nil {
  19 + return nil, fmt.Errorf("文件不存在")
  20 + }
  21 +
  22 + // Copy to TemporaryFile
  23 + if file.FileType != domain.TemporaryFile.ToString() {
  24 + file = file.CopyTo(domain.TemporaryFile)
  25 + if file, err = fileRepository.Save(file); err != nil {
  26 + return nil, err
  27 + }
  28 + }
  29 + //TEST
  30 + ptr.FileId = file.FileId
  31 +
  32 + // Load Data From Excel(python api)
  33 +
  34 + return map[string]interface{}{
  35 + "fileId": file.FileId,
  36 + }, nil
  37 +}
  38 +
  39 +func (ptr *LoadDataTableService) GetFileId() int {
  40 + return ptr.FileId
  41 +}
  42 +
  43 +func NewLoadDataTableService(transactionContext *pgTransaction.TransactionContext) (*LoadDataTableService, error) {
  44 + if transactionContext == nil {
  45 + return nil, fmt.Errorf("transactionContext参数不能为nil")
  46 + } else {
  47 + return &LoadDataTableService{
  48 + transactionContext: transactionContext,
  49 + }, nil
  50 + }
  51 +}
  1 +package domainService
  2 +
  3 +import (
  4 + "fmt"
  5 + pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
  6 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
  7 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/repository"
  8 + "time"
  9 +)
  10 +
  11 +type PGLogService struct {
  12 + transactionContext *pgTransaction.TransactionContext
  13 +}
  14 +
  15 +func NewPGLogService(transactionContext *pgTransaction.TransactionContext) (*PGLogService, error) {
  16 + if transactionContext == nil {
  17 + return nil, fmt.Errorf("transactionContext参数不能为nil")
  18 + } else {
  19 + return &PGLogService{
  20 + transactionContext: transactionContext,
  21 + }, nil
  22 + }
  23 +}
  24 +
  25 +func FastLog(transactionContext *pgTransaction.TransactionContext, logType domain.LogType, sourceId int, logEntry Log) error {
  26 + logService, _ := NewPGLogService(transactionContext)
  27 + return logService.Log(logType, sourceId, logEntry)
  28 +}
  29 +
  30 +func (ptr *PGLogService) Log(logType domain.LogType, sourceId int, logEntry Log) error {
  31 + logRepository, _ := repository.NewLogRepository(ptr.transactionContext)
  32 + entry := logEntry.Entry()
  33 + log := &domain.Log{
  34 + LogType: logType.ToString(),
  35 + SourceId: sourceId,
  36 + Entry: &entry,
  37 + ObjectName: entry.ObjectName,
  38 + ObjectType: domain.EnumsDescription(domain.ObjectTypeMap, entry.ObjectType),
  39 + OperationType: domain.EnumsDescription(domain.OperationTypeMap, entry.OperationType),
  40 + Content: logEntry.Content(),
  41 + OperatorName: entry.OperatorName,
  42 + CreatedAt: time.Now(),
  43 + }
  44 + _, err := logRepository.Save(log)
  45 + return err
  46 +}
  47 +
  48 +func (ptr *PGLogService) NewLogEntry() domain.LogEntry {
  49 + return domain.LogEntry{}
  50 +}
  51 +
  52 +type Log interface {
  53 + Content() string
  54 + Entry() domain.LogEntry
  55 +}
  56 +
  57 +var _ Log = (*FileUploadSuccessLog)(nil)
  58 +
  59 +// 1.1文件上传成功
  60 +type FileUploadSuccessLog struct {
  61 + domain.LogEntry
  62 +}
  63 +
  64 +func (l *FileUploadSuccessLog) Content() string {
  65 + return fmt.Sprintf("上传成功")
  66 +}
  67 +
  68 +// 1.2文件上传失败
  69 +type FileUploadFailLog struct {
  70 + domain.LogEntry
  71 + Reason string
  72 +}
  73 +
  74 +func (l *FileUploadFailLog) Content() string {
  75 + return fmt.Sprintf("上传失败,失败原因:%s", l.Reason)
  76 +}
  77 +
  78 +// 2.文件校验
  79 +type FileVerifyLog struct {
  80 + domain.LogEntry
  81 + // 错误信息
  82 + Errors []string
  83 + // 记录数
  84 + Total int
  85 +}
  86 +
  87 +func (l *FileVerifyLog) Content() string {
  88 + msg := fmt.Sprintf("校验完成,共计%d条记录 ", l.Total)
  89 + if len(l.Errors) > 0 {
  90 + msg += fmt.Sprintf("存在%v条报错", len(l.Errors))
  91 + }
  92 + return msg
  93 +}
1 package pg 1 package pg
2 2
3 import ( 3 import (
  4 + "context"
4 "fmt" 5 "fmt"
  6 + "github.com/beego/beego/v2/core/logs"
5 "github.com/go-pg/pg/v10" 7 "github.com/go-pg/pg/v10"
6 "github.com/go-pg/pg/v10/orm" 8 "github.com/go-pg/pg/v10/orm"
7 "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/constant" 9 "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/constant"
8 "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/pg/models" 10 "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/pg/models"
9 -  
10 - //_ "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/pg/models"  
11 - "github.com/linmadan/egglib-go/persistent/pg/comment"  
12 - "github.com/linmadan/egglib-go/persistent/pg/hooks" 11 + "log"
13 ) 12 )
14 13
15 var DB *pg.DB 14 var DB *pg.DB
16 15
17 -func init() { 16 +func Init() {
18 DB = pg.Connect(&pg.Options{ 17 DB = pg.Connect(&pg.Options{
19 User: constant.POSTGRESQL_USER, 18 User: constant.POSTGRESQL_USER,
20 Password: constant.POSTGRESQL_PASSWORD, 19 Password: constant.POSTGRESQL_PASSWORD,
@@ -22,7 +21,7 @@ func init() { @@ -22,7 +21,7 @@ func init() {
22 Addr: fmt.Sprintf("%s:%s", constant.POSTGRESQL_HOST, constant.POSTGRESQL_PORT), 21 Addr: fmt.Sprintf("%s:%s", constant.POSTGRESQL_HOST, constant.POSTGRESQL_PORT),
23 }) 22 })
24 if !constant.DISABLE_SQL_GENERATE_PRINT { 23 if !constant.DISABLE_SQL_GENERATE_PRINT {
25 - DB.AddQueryHook(hooks.SqlGeneratePrintHook{}) 24 + DB.AddQueryHook(SqlGeneratePrintHook{})
26 } 25 }
27 if !constant.DISABLE_CREATE_TABLE { 26 if !constant.DISABLE_CREATE_TABLE {
28 for _, model := range []interface{}{ 27 for _, model := range []interface{}{
@@ -38,7 +37,24 @@ func init() { @@ -38,7 +37,24 @@ func init() {
38 if err != nil { 37 if err != nil {
39 panic(err) 38 panic(err)
40 } 39 }
41 - comment.AddComments(DB, model) 40 + //comment.AddComments(DB, model)
42 } 41 }
43 } 42 }
44 } 43 }
  44 +
  45 +type SqlGeneratePrintHook struct{}
  46 +
  47 +func (hook SqlGeneratePrintHook) BeforeQuery(c context.Context, q *pg.QueryEvent) (context.Context, error) {
  48 + return c, nil
  49 +}
  50 +
  51 +func (hook SqlGeneratePrintHook) AfterQuery(c context.Context, q *pg.QueryEvent) error {
  52 + sqlStr, err := q.FormattedQuery()
  53 + if err != nil {
  54 + return err
  55 + }
  56 + //log.Logger.Debug(string(sqlStr))
  57 + log.Println(string(sqlStr))
  58 + logs.Debug(string(sqlStr))
  59 + return nil
  60 +}
@@ -14,7 +14,7 @@ type File struct { @@ -14,7 +14,7 @@ type File struct {
14 // 文件信息 14 // 文件信息
15 FileInfo *domain.FileInfo `comment:"文件信息"` 15 FileInfo *domain.FileInfo `comment:"文件信息"`
16 // 源文件Id(FileType为TemporaryFile或VerifiedFile时有值) 16 // 源文件Id(FileType为TemporaryFile或VerifiedFile时有值)
17 - SourceFileId string `comment:"源文件Id(FileType为TemporaryFile或VerifiedFile时有值)"` 17 + SourceFileId int `comment:"源文件Id(FileType为TemporaryFile或VerifiedFile时有值)"`
18 // 操作人 18 // 操作人
19 Operator string `comment:"操作人"` 19 Operator string `comment:"操作人"`
20 // 创建时间 20 // 创建时间
@@ -10,11 +10,21 @@ type Log struct { @@ -10,11 +10,21 @@ type Log struct {
10 // 日志ID 10 // 日志ID
11 LogId int `comment:"日志ID" pg:"pk:log_id"` 11 LogId int `comment:"日志ID" pg:"pk:log_id"`
12 // 日志类型 1.校验步骤 2.常规日志 12 // 日志类型 1.校验步骤 2.常规日志
13 - LogType int `comment:"日志类型 1.校验步骤 2.常规日志"` 13 + LogType string `comment:"日志类型 1.校验步骤 2.常规日志"`
14 // 源数据ID 14 // 源数据ID
15 SourceId int `comment:"源数据ID"` 15 SourceId int `comment:"源数据ID"`
16 // 日志内容 16 // 日志内容
17 Entry *domain.LogEntry `comment:"日志内容"` 17 Entry *domain.LogEntry `comment:"日志内容"`
  18 + // 对象名称 数据表名 / 文件名
  19 + ObjectName string `json:"objectName"`
  20 + // 对象类型 1.主表 2.分表 3.副表 4.源文件 5.校验文件
  21 + ObjectType string `json:"objectType"`
  22 + // 操作类型 1.主表生成 2.主表拆分 3.数据导入 4.分表生成 5.表复制 6.编辑记录 7.文件上传 8.文件校验
  23 + OperationType string `json:"operationType"`
  24 + // 日志内容
  25 + Content string `json:"content"`
  26 + // 操作人名称
  27 + OperatorName string `json:"operatorName"`
18 // 创建时间 28 // 创建时间
19 CreatedAt time.Time `comment:"创建时间"` 29 CreatedAt time.Time `comment:"创建时间"`
20 } 30 }
@@ -16,7 +16,7 @@ type Table struct { @@ -16,7 +16,7 @@ type Table struct {
16 // 对应数据库名称 16 // 对应数据库名称
17 SQLName string `comment:"对应数据库名称"` 17 SQLName string `comment:"对应数据库名称"`
18 // 父级ID 18 // 父级ID
19 - ParentId int64 `comment:"父级ID"` 19 + ParentId int `comment:"父级ID"`
20 // 数据字段序号 20 // 数据字段序号
21 DataFieldIndex int `comment:"数据字段序号"` 21 DataFieldIndex int `comment:"数据字段序号"`
22 // 主键字段 22 // 主键字段
@@ -7,10 +7,15 @@ import ( @@ -7,10 +7,15 @@ import (
7 7
8 func TransformToLogDomainModelFromPgModels(logModel *models.Log) (*domain.Log, error) { 8 func TransformToLogDomainModelFromPgModels(logModel *models.Log) (*domain.Log, error) {
9 return &domain.Log{ 9 return &domain.Log{
10 - LogId: logModel.LogId,  
11 - LogType: logModel.LogType,  
12 - SourceId: logModel.SourceId,  
13 - Entry: logModel.Entry,  
14 - CreatedAt: logModel.CreatedAt, 10 + LogId: logModel.LogId,
  11 + LogType: logModel.LogType,
  12 + SourceId: logModel.SourceId,
  13 + Entry: logModel.Entry,
  14 + ObjectName: logModel.ObjectName,
  15 + ObjectType: logModel.ObjectType,
  16 + OperationType: logModel.OperationType,
  17 + Content: logModel.Content,
  18 + OperatorName: logModel.OperatorName,
  19 + CreatedAt: logModel.CreatedAt,
15 }, nil 20 }, nil
16 } 21 }
@@ -3,7 +3,6 @@ package repository @@ -3,7 +3,6 @@ package repository
3 import ( 3 import (
4 "fmt" 4 "fmt"
5 "github.com/go-pg/pg/v10" 5 "github.com/go-pg/pg/v10"
6 -  
7 "github.com/linmadan/egglib-go/persistent/pg/sqlbuilder" 6 "github.com/linmadan/egglib-go/persistent/pg/sqlbuilder"
8 pgTransaction "github.com/linmadan/egglib-go/transaction/pg" 7 pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
9 "github.com/linmadan/egglib-go/utils/snowflake" 8 "github.com/linmadan/egglib-go/utils/snowflake"
@@ -56,7 +55,6 @@ func (repository *FileRepository) Save(file *domain.File) (*domain.File, error) @@ -56,7 +55,6 @@ func (repository *FileRepository) Save(file *domain.File) (*domain.File, error)
56 &file.Version, 55 &file.Version,
57 ), 56 ),
58 fmt.Sprintf("INSERT INTO metadata.files (%s) VALUES (%s) RETURNING %s", insertFieldsSnippet, insertPlaceHoldersSnippet, returningFieldsSnippet), 57 fmt.Sprintf("INSERT INTO metadata.files (%s) VALUES (%s) RETURNING %s", insertFieldsSnippet, insertPlaceHoldersSnippet, returningFieldsSnippet),
59 - file.FileId,  
60 file.FileType, 58 file.FileType,
61 file.FileInfo, 59 file.FileInfo,
62 file.SourceFileId, 60 file.SourceFileId,
@@ -83,14 +81,12 @@ func (repository *FileRepository) Save(file *domain.File) (*domain.File, error) @@ -83,14 +81,12 @@ func (repository *FileRepository) Save(file *domain.File) (*domain.File, error)
83 &file.Version, 81 &file.Version,
84 ), 82 ),
85 fmt.Sprintf("UPDATE metadata.files SET %s WHERE file_id=? and version=? RETURNING %s", updateFieldsSnippet, returningFieldsSnippet), 83 fmt.Sprintf("UPDATE metadata.files SET %s WHERE file_id=? and version=? RETURNING %s", updateFieldsSnippet, returningFieldsSnippet),
86 - file.FileId,  
87 file.FileType, 84 file.FileType,
88 file.FileInfo, 85 file.FileInfo,
89 file.SourceFileId, 86 file.SourceFileId,
90 file.Operator, 87 file.Operator,
91 file.CreatedAt, 88 file.CreatedAt,
92 file.UpdatedAt, 89 file.UpdatedAt,
93 - file.DeletedAt,  
94 file.Version, 90 file.Version,
95 file.Identify(), 91 file.Identify(),
96 oldVersion, 92 oldVersion,
@@ -132,6 +128,15 @@ func (repository *FileRepository) Find(queryOptions map[string]interface{}) (int @@ -132,6 +128,15 @@ func (repository *FileRepository) Find(queryOptions map[string]interface{}) (int
132 var fileModels []*models.File 128 var fileModels []*models.File
133 files := make([]*domain.File, 0) 129 files := make([]*domain.File, 0)
134 query := sqlbuilder.BuildQuery(tx.Model(&fileModels), queryOptions) 130 query := sqlbuilder.BuildQuery(tx.Model(&fileModels), queryOptions)
  131 + query.SetWhereByQueryOption("file_id > ?", "lastId")
  132 + query.SetWhereByQueryOption("file_type = ?", "fileType")
  133 + query.SetWhereByQueryOption(fmt.Sprintf("file_info->>'name' like '%%%v%%'", queryOptions["fileName"]), "fileName")
  134 +
  135 + query.SetWhereByQueryOption("source_file_id = ?", "sourceFileId")
  136 + if v, ok := queryOptions["notInFileIds"]; ok && len(v.([]int)) > 0 {
  137 + query.Where(`file_id not in (?)`, pg.In(v.([]int)))
  138 + }
  139 +
135 query.SetOffsetAndLimit(20) 140 query.SetOffsetAndLimit(20)
136 query.SetOrderDirect("file_id", "DESC") 141 query.SetOrderDirect("file_id", "DESC")
137 if count, err := query.SelectAndCount(); err != nil { 142 if count, err := query.SelectAndCount(); err != nil {
@@ -29,8 +29,13 @@ func (repository *LogRepository) Save(log *domain.Log) (*domain.Log, error) { @@ -29,8 +29,13 @@ func (repository *LogRepository) Save(log *domain.Log) (*domain.Log, error) {
29 "log_id", 29 "log_id",
30 "log_type", 30 "log_type",
31 "source_id", 31 "source_id",
32 - "entry", 32 + "object_name",
  33 + "object_type",
  34 + "operation_type",
  35 + "content",
  36 + "operator_name",
33 "created_at", 37 "created_at",
  38 + "entry",
34 } 39 }
35 insertFieldsSnippet := sqlbuilder.SqlFieldsSnippet(sqlbuilder.RemoveSqlFields(sqlBuildFields, "log_id")) 40 insertFieldsSnippet := sqlbuilder.SqlFieldsSnippet(sqlbuilder.RemoveSqlFields(sqlBuildFields, "log_id"))
36 insertPlaceHoldersSnippet := sqlbuilder.SqlPlaceHoldersSnippet(sqlbuilder.RemoveSqlFields(sqlBuildFields, "log_id")) 41 insertPlaceHoldersSnippet := sqlbuilder.SqlPlaceHoldersSnippet(sqlbuilder.RemoveSqlFields(sqlBuildFields, "log_id"))
@@ -44,15 +49,24 @@ func (repository *LogRepository) Save(log *domain.Log) (*domain.Log, error) { @@ -44,15 +49,24 @@ func (repository *LogRepository) Save(log *domain.Log) (*domain.Log, error) {
44 &log.LogId, 49 &log.LogId,
45 &log.LogType, 50 &log.LogType,
46 &log.SourceId, 51 &log.SourceId,
47 - &log.Entry, 52 + &log.ObjectName,
  53 + &log.ObjectType,
  54 + &log.OperationType,
  55 + &log.Content,
  56 + &log.OperatorName,
48 &log.CreatedAt, 57 &log.CreatedAt,
  58 + &log.Entry,
49 ), 59 ),
50 fmt.Sprintf("INSERT INTO metadata.logs (%s) VALUES (%s) RETURNING %s", insertFieldsSnippet, insertPlaceHoldersSnippet, returningFieldsSnippet), 60 fmt.Sprintf("INSERT INTO metadata.logs (%s) VALUES (%s) RETURNING %s", insertFieldsSnippet, insertPlaceHoldersSnippet, returningFieldsSnippet),
51 - //log.LogId,  
52 log.LogType, 61 log.LogType,
53 log.SourceId, 62 log.SourceId,
54 - log.Entry, 63 + log.ObjectName,
  64 + log.ObjectType,
  65 + log.OperationType,
  66 + log.Content,
  67 + log.OperatorName,
55 log.CreatedAt, 68 log.CreatedAt,
  69 + log.Entry,
56 ); err != nil { 70 ); err != nil {
57 return log, err 71 return log, err
58 } 72 }
@@ -62,15 +76,24 @@ func (repository *LogRepository) Save(log *domain.Log) (*domain.Log, error) { @@ -62,15 +76,24 @@ func (repository *LogRepository) Save(log *domain.Log) (*domain.Log, error) {
62 &log.LogId, 76 &log.LogId,
63 &log.LogType, 77 &log.LogType,
64 &log.SourceId, 78 &log.SourceId,
65 - &log.Entry, 79 + &log.ObjectName,
  80 + &log.ObjectType,
  81 + &log.OperationType,
  82 + &log.Content,
  83 + &log.OperatorName,
66 &log.CreatedAt, 84 &log.CreatedAt,
  85 + &log.Entry,
67 ), 86 ),
68 fmt.Sprintf("UPDATE metadata.logs SET %s WHERE log_id=? RETURNING %s", updateFieldsSnippet, returningFieldsSnippet), 87 fmt.Sprintf("UPDATE metadata.logs SET %s WHERE log_id=? RETURNING %s", updateFieldsSnippet, returningFieldsSnippet),
69 - //log.LogId,  
70 log.LogType, 88 log.LogType,
71 log.SourceId, 89 log.SourceId,
72 - log.Entry, 90 + log.ObjectName,
  91 + log.ObjectType,
  92 + log.OperationType,
  93 + log.Content,
  94 + log.OperatorName,
73 log.CreatedAt, 95 log.CreatedAt,
  96 + &log.Entry,
74 log.Identify(), 97 log.Identify(),
75 ); err != nil { 98 ); err != nil {
76 return log, err 99 return log, err
@@ -40,10 +40,10 @@ func (repository *TableRepository) Save(table *domain.Table) (*domain.Table, err @@ -40,10 +40,10 @@ func (repository *TableRepository) Save(table *domain.Table) (*domain.Table, err
40 "deleted_at", 40 "deleted_at",
41 "version", 41 "version",
42 } 42 }
43 - insertFieldsSnippet := sqlbuilder.SqlFieldsSnippet(sqlBuildFields)  
44 - insertPlaceHoldersSnippet := sqlbuilder.SqlPlaceHoldersSnippet(sqlBuildFields) 43 + insertFieldsSnippet := sqlbuilder.SqlFieldsSnippet(sqlbuilder.RemoveSqlFields(sqlBuildFields, "table_id", "deleted_at"))
  44 + insertPlaceHoldersSnippet := sqlbuilder.SqlPlaceHoldersSnippet(sqlbuilder.RemoveSqlFields(sqlBuildFields, "table_id", "deleted_at"))
45 returningFieldsSnippet := sqlbuilder.SqlFieldsSnippet(sqlBuildFields) 45 returningFieldsSnippet := sqlbuilder.SqlFieldsSnippet(sqlBuildFields)
46 - updateFields := sqlbuilder.RemoveSqlFields(sqlBuildFields, "table_id") 46 + updateFields := sqlbuilder.RemoveSqlFields(sqlBuildFields, "table_id", "deleted_at")
47 updateFieldsSnippet := sqlbuilder.SqlUpdateFieldsSnippet(updateFields) 47 updateFieldsSnippet := sqlbuilder.SqlUpdateFieldsSnippet(updateFields)
48 tx := repository.transactionContext.PgTx 48 tx := repository.transactionContext.PgTx
49 if table.Identify() == nil { 49 if table.Identify() == nil {
@@ -64,7 +64,6 @@ func (repository *TableRepository) Save(table *domain.Table) (*domain.Table, err @@ -64,7 +64,6 @@ func (repository *TableRepository) Save(table *domain.Table) (*domain.Table, err
64 &table.Version, 64 &table.Version,
65 ), 65 ),
66 fmt.Sprintf("INSERT INTO metadata.tables (%s) VALUES (%s) RETURNING %s", insertFieldsSnippet, insertPlaceHoldersSnippet, returningFieldsSnippet), 66 fmt.Sprintf("INSERT INTO metadata.tables (%s) VALUES (%s) RETURNING %s", insertFieldsSnippet, insertPlaceHoldersSnippet, returningFieldsSnippet),
67 - table.TableId,  
68 table.TableType, 67 table.TableType,
69 table.Name, 68 table.Name,
70 table.SQLName, 69 table.SQLName,
@@ -75,7 +74,6 @@ func (repository *TableRepository) Save(table *domain.Table) (*domain.Table, err @@ -75,7 +74,6 @@ func (repository *TableRepository) Save(table *domain.Table) (*domain.Table, err
75 table.ManualFields, 74 table.ManualFields,
76 table.CreatedAt, 75 table.CreatedAt,
77 table.UpdatedAt, 76 table.UpdatedAt,
78 - table.DeletedAt,  
79 table.Version, 77 table.Version,
80 ); err != nil { 78 ); err != nil {
81 return table, err 79 return table, err
@@ -100,7 +98,6 @@ func (repository *TableRepository) Save(table *domain.Table) (*domain.Table, err @@ -100,7 +98,6 @@ func (repository *TableRepository) Save(table *domain.Table) (*domain.Table, err
100 &table.Version, 98 &table.Version,
101 ), 99 ),
102 fmt.Sprintf("UPDATE metadata.tables SET %s WHERE table_id=? and version=? RETURNING %s", updateFieldsSnippet, returningFieldsSnippet), 100 fmt.Sprintf("UPDATE metadata.tables SET %s WHERE table_id=? and version=? RETURNING %s", updateFieldsSnippet, returningFieldsSnippet),
103 - table.TableId,  
104 table.TableType, 101 table.TableType,
105 table.Name, 102 table.Name,
106 table.SQLName, 103 table.SQLName,
@@ -111,7 +108,6 @@ func (repository *TableRepository) Save(table *domain.Table) (*domain.Table, err @@ -111,7 +108,6 @@ func (repository *TableRepository) Save(table *domain.Table) (*domain.Table, err
111 table.ManualFields, 108 table.ManualFields,
112 table.CreatedAt, 109 table.CreatedAt,
113 table.UpdatedAt, 110 table.UpdatedAt,
114 - table.DeletedAt,  
115 table.Version, 111 table.Version,
116 oldVersion, 112 oldVersion,
117 table.Identify(), 113 table.Identify(),
@@ -134,7 +130,7 @@ func (repository *TableRepository) FindOne(queryOptions map[string]interface{}) @@ -134,7 +130,7 @@ func (repository *TableRepository) FindOne(queryOptions map[string]interface{})
134 tx := repository.transactionContext.PgTx 130 tx := repository.transactionContext.PgTx
135 tableModel := new(models.Table) 131 tableModel := new(models.Table)
136 query := sqlbuilder.BuildQuery(tx.Model(tableModel), queryOptions) 132 query := sqlbuilder.BuildQuery(tx.Model(tableModel), queryOptions)
137 - query.SetWhereByQueryOption("table.table_id = ?", "tableId") 133 + query.SetWhereByQueryOption("table_id = ?", "tableId")
138 if err := query.First(); err != nil { 134 if err := query.First(); err != nil {
139 if err.Error() == "pg: no rows in result set" { 135 if err.Error() == "pg: no rows in result set" {
140 return nil, fmt.Errorf("没有此资源") 136 return nil, fmt.Errorf("没有此资源")
  1 +package utils
  2 +
  3 +import (
  4 + "bytes"
  5 + "encoding/json"
  6 + "fmt"
  7 + "github.com/beego/beego/v2/core/validation"
  8 + "github.com/bwmarrin/snowflake"
  9 + jsonlib "github.com/linmadan/egglib-go/utils/json"
  10 + "github.com/shopspring/decimal"
  11 + "golang.org/x/text/encoding/simplifiedchinese"
  12 + "golang.org/x/text/transform"
  13 + "io"
  14 + "io/ioutil"
  15 + "reflect"
  16 + "strconv"
  17 + "strings"
  18 + "time"
  19 +)
  20 +
  21 +func CamelCase(name string, firstUpper bool) string {
  22 + array := []byte(name)
  23 + if len(array) == 0 {
  24 + return ""
  25 + }
  26 + rspArray := make([]byte, len(array))
  27 + if firstUpper {
  28 + copy(rspArray[:1], strings.ToUpper(string(array[:1])))
  29 + } else {
  30 + copy(rspArray[:1], strings.ToLower(string(array[:1])))
  31 + }
  32 + copy(rspArray[1:], array[1:])
  33 + return string(rspArray)
  34 +}
  35 +
  36 +func ObjectToMap(o interface{}) map[string]interface{} {
  37 + if o == nil {
  38 + return nil
  39 + }
  40 + value := reflect.ValueOf(o)
  41 + if value.Kind() != reflect.Ptr {
  42 + return nil
  43 + }
  44 + elem := value.Elem()
  45 + relType := elem.Type()
  46 + m := make(map[string]interface{})
  47 + for i := 0; i < relType.NumField(); i++ {
  48 + field := relType.Field(i)
  49 + if elem.Field(i).IsZero() {
  50 + continue
  51 + }
  52 + m[CamelCase(field.Name, false)] = elem.Field(i).Interface()
  53 + }
  54 + return m
  55 +}
  56 +
  57 +func ToMap(o interface{}) map[string]interface{} {
  58 + if o == nil {
  59 + return nil
  60 + }
  61 + m := make(map[string]interface{})
  62 + data, _ := json.Marshal(o)
  63 + json.Unmarshal(data, &m)
  64 + return m
  65 +}
  66 +
  67 +func DeleteMapKeys(options map[string]interface{}, keys ...string) map[string]interface{} {
  68 + for i := range keys {
  69 + if _, ok := options[keys[i]]; ok {
  70 + delete(options, keys[i])
  71 + }
  72 + }
  73 + return options
  74 +}
  75 +
  76 +// AssertString convert v to string value
  77 +func AssertString(v interface{}) string {
  78 + if v == nil {
  79 + return ""
  80 + }
  81 +
  82 + // if func (v *Type) String() string, we can't use Elem()
  83 + switch vt := v.(type) {
  84 + case fmt.Stringer:
  85 + return vt.String()
  86 + }
  87 +
  88 + val := reflect.ValueOf(v)
  89 + if val.Kind() == reflect.Ptr && !val.IsNil() {
  90 + val = val.Elem()
  91 + }
  92 +
  93 + switch vt := val.Interface().(type) {
  94 + case bool:
  95 + return strconv.FormatBool(vt)
  96 + case error:
  97 + return vt.Error()
  98 + case float32:
  99 + return strconv.FormatFloat(float64(vt), 'f', -1, 32)
  100 + case float64:
  101 + return strconv.FormatFloat(vt, 'f', -1, 64)
  102 + case fmt.Stringer:
  103 + return vt.String()
  104 + case int:
  105 + return strconv.Itoa(vt)
  106 + case int8:
  107 + return strconv.Itoa(int(vt))
  108 + case int16:
  109 + return strconv.Itoa(int(vt))
  110 + case int32:
  111 + return strconv.Itoa(int(vt))
  112 + case int64:
  113 + return strconv.FormatInt(vt, 10)
  114 + case string:
  115 + return vt
  116 + case uint:
  117 + return strconv.FormatUint(uint64(vt), 10)
  118 + case uint8:
  119 + return strconv.FormatUint(uint64(vt), 10)
  120 + case uint16:
  121 + return strconv.FormatUint(uint64(vt), 10)
  122 + case uint32:
  123 + return strconv.FormatUint(uint64(vt), 10)
  124 + case uint64:
  125 + return strconv.FormatUint(vt, 10)
  126 + case []byte:
  127 + return string(vt)
  128 + default:
  129 + return fmt.Sprint(val.Interface())
  130 + }
  131 +}
  132 +
  133 +// ValidatePtr validate v is a ptr value
  134 +func ValidatePtr(v *reflect.Value) error {
  135 + // sequence is very important, IsNil must be called after checking Kind() with reflect.Ptr,
  136 + // panic otherwise
  137 + if !v.IsValid() || v.Kind() != reflect.Ptr || v.IsNil() {
  138 + return fmt.Errorf("not a valid pointer: %v", v)
  139 + }
  140 +
  141 + return nil
  142 +}
  143 +
  144 +func LoadCustomFieldToMap(src interface{}, fields ...string) map[string]interface{} {
  145 + rsp := LoadCustomField(src, fields...)
  146 + if rsp == nil {
  147 + return map[string]interface{}{}
  148 + }
  149 + return rsp.(map[string]interface{})
  150 +}
  151 +
  152 +func LoadCustomField(src interface{}, fields ...string) interface{} {
  153 + typeSrc := reflect.TypeOf(src)
  154 + valueSrc := reflect.ValueOf(src)
  155 +
  156 + if v, ok := src.(reflect.Value); ok {
  157 + valueSrc = v
  158 + typeSrc = v.Type()
  159 + }
  160 + if typeSrc.Kind() == reflect.Ptr {
  161 + valueSrc = valueSrc.Elem()
  162 + }
  163 + k := valueSrc.Kind()
  164 + switch k {
  165 + case reflect.Array, reflect.Slice:
  166 + len := valueSrc.Len()
  167 + retSliceMap := make([]map[string]interface{}, 0)
  168 + if len == 0 {
  169 + return retSliceMap
  170 + }
  171 + for i := 0; i < len; i++ {
  172 + v := valueSrc.Index(i)
  173 + retSliceMap = append(retSliceMap, (LoadCustomField(v, fields...)).(map[string]interface{}))
  174 + }
  175 + return retSliceMap
  176 + case reflect.Struct:
  177 + retSliceMap := make(map[string]interface{})
  178 + for _, filed := range fields {
  179 + f := valueSrc.FieldByName(filed)
  180 + if !f.IsValid() {
  181 + continue
  182 + }
  183 + v := f.Interface()
  184 + if t, ok := v.(time.Time); ok {
  185 + v = t.Local().Format("2006-01-02 15:04:05")
  186 + }
  187 + retSliceMap[CamelCase(filed, false)] = v
  188 + }
  189 + return retSliceMap
  190 + default:
  191 + return src
  192 + }
  193 + return src
  194 +}
  195 +
  196 +func AppendCustomField(src interface{}, options map[string]interface{}) interface{} {
  197 + var mapSrc map[string]interface{}
  198 + var ok bool
  199 + mapSrc, ok = src.(map[string]interface{})
  200 + if !ok {
  201 + jsonlib.Unmarshal([]byte(jsonlib.MarshalToString(src)), &mapSrc)
  202 + }
  203 + for field, value := range options {
  204 + mapSrc[CamelCase(field, false)] = value
  205 + }
  206 + return mapSrc
  207 +}
  208 +
  209 +/*
  210 +
  211 +json 格式化
  212 +
  213 +*/
  214 +
  215 +func Marshal(v interface{}) ([]byte, error) {
  216 + return json.Marshal(v)
  217 +}
  218 +
  219 +func Unmarshal(data []byte, v interface{}) error {
  220 + decoder := json.NewDecoder(bytes.NewReader(data))
  221 + if err := unmarshalUseNumber(decoder, v); err != nil {
  222 + return formatError(string(data), err)
  223 + }
  224 +
  225 + return nil
  226 +}
  227 +
  228 +func UnmarshalFromString(str string, v interface{}) error {
  229 + decoder := json.NewDecoder(strings.NewReader(str))
  230 + if err := unmarshalUseNumber(decoder, v); err != nil {
  231 + return formatError(str, err)
  232 + }
  233 +
  234 + return nil
  235 +}
  236 +
  237 +func UnmarshalFromReader(reader io.Reader, v interface{}) error {
  238 + var buf strings.Builder
  239 + teeReader := io.TeeReader(reader, &buf)
  240 + decoder := json.NewDecoder(teeReader)
  241 + if err := unmarshalUseNumber(decoder, v); err != nil {
  242 + return formatError(buf.String(), err)
  243 + }
  244 +
  245 + return nil
  246 +}
  247 +
  248 +func unmarshalUseNumber(decoder *json.Decoder, v interface{}) error {
  249 + decoder.UseNumber()
  250 + return decoder.Decode(v)
  251 +}
  252 +
  253 +func formatError(v string, err error) error {
  254 + return fmt.Errorf("string: `%s`, error: `%s`", v, err.Error())
  255 +}
  256 +
  257 +type ReflectVal struct {
  258 + T reflect.Type
  259 + V reflect.Value
  260 +}
  261 +
  262 +/*
  263 + 拷贝当前对象到目标对象,具有相同属性的值
  264 +*/
  265 +func CopyObject(src, dst interface{}) {
  266 + var srcMap = make(map[string]ReflectVal)
  267 +
  268 + vs := reflect.ValueOf(src)
  269 + ts := reflect.TypeOf(src)
  270 + vd := reflect.ValueOf(dst)
  271 + td := reflect.TypeOf(dst)
  272 +
  273 + ls := vs.Elem().NumField()
  274 + for i := 0; i < ls; i++ {
  275 + srcMap[ts.Elem().Field(i).Name] = ReflectVal{
  276 + T: vs.Elem().Field(i).Type(),
  277 + V: vs.Elem().Field(i),
  278 + }
  279 + }
  280 +
  281 + ld := vd.Elem().NumField()
  282 + for i := 0; i < ld; i++ {
  283 + n := td.Elem().Field(i).Name
  284 + t := vd.Elem().Field(i).Type()
  285 + if v, ok := srcMap[n]; ok && v.T == t && vd.Elem().Field(i).CanSet() {
  286 + vd.Elem().Field(i).Set(v.V)
  287 + }
  288 + }
  289 +}
  290 +
  291 +/*
  292 + 时间计算
  293 +*/
  294 +
  295 +func ValidWorkTime(t string) error {
  296 + ts := strings.Split(t, ":")
  297 + if len(ts) != 2 {
  298 + return fmt.Errorf("时间格式有误")
  299 + }
  300 + ts1, err := strconv.Atoi(ts[0])
  301 + if err != nil {
  302 + return fmt.Errorf("小时格式有误")
  303 + }
  304 + if !(ts1 < 24 && ts1 >= 0) {
  305 + return fmt.Errorf("小时格式有误")
  306 + }
  307 + ts2, err := strconv.Atoi(ts[1])
  308 + if err != nil {
  309 + return fmt.Errorf("分钟格式有误")
  310 + }
  311 + if !(ts2 < 60 && ts2 >= 0) {
  312 + return fmt.Errorf("分钟格式有误")
  313 + }
  314 + return nil
  315 +}
  316 +
  317 +// 计算两个时间间隔的时间
  318 +func ComputeTimeDuration(t1, t2 string) (result time.Duration, err error) {
  319 + if err = ValidWorkTime(t1); err != nil {
  320 + return
  321 + }
  322 + if err = ValidWorkTime(t2); err != nil {
  323 + return
  324 + }
  325 + t1s := strings.Split(t1, ":")
  326 + t1sHour, _ := strconv.Atoi(t1s[0])
  327 + t1sMin, _ := strconv.Atoi(t1s[1])
  328 +
  329 + t2s := strings.Split(t2, ":")
  330 + t2sHour, _ := strconv.Atoi(t2s[0])
  331 + t2sMin, _ := strconv.Atoi(t2s[1])
  332 + var t1t, t2t time.Time
  333 + if t1sHour < t2sHour {
  334 + t1t = time.Date(2006, 1, 1, t1sHour, t1sMin, 0, 0, time.Local)
  335 + t2t = time.Date(2006, 1, 1, t2sHour, t2sMin, 0, 0, time.Local)
  336 + } else {
  337 + t1t = time.Date(2006, 1, 1, t1sHour, t1sMin, 0, 0, time.Local)
  338 + t2t = time.Date(2006, 1, 2, t2sHour, t2sMin, 0, 0, time.Local)
  339 + }
  340 + ts := t2t.Sub(t1t)
  341 + return ts, nil
  342 +}
  343 +
  344 +func ToArrayString(inputs []int) []string {
  345 + result := make([]string, 0)
  346 + for i := range inputs {
  347 + result = append(result, strconv.Itoa(inputs[i]))
  348 + }
  349 + return result
  350 +}
  351 +
  352 +func ToArrayInt(inputs []string) []int {
  353 + result := make([]int, 0)
  354 + for i := range inputs {
  355 + v, _ := strconv.Atoi(inputs[i])
  356 + result = append(result, v)
  357 + }
  358 + return result
  359 +}
  360 +
  361 +func LoadQueryObject(queryOption map[string]interface{}, obj interface{}) error {
  362 + jsonlib.UnmarshalFromString(jsonlib.MarshalToString(queryOption), obj)
  363 + validation := validation.Validation{}
  364 + result, err := validation.Valid(obj)
  365 + if !result && len(validation.Errors) > 0 {
  366 + return validation.Errors[0]
  367 + }
  368 + return err
  369 +}
  370 +
  371 +// 字符串截取
  372 +func SubStr(str string, start, length int) string {
  373 + rs := []rune(str)
  374 + rl := len(rs)
  375 + end := 0
  376 + if start < 0 {
  377 + start = rl - 1 + start
  378 + }
  379 + end = start + length
  380 + if start > end {
  381 + start, end = end, start
  382 + }
  383 + if start < 0 {
  384 + start = 0
  385 + }
  386 + if start > rl {
  387 + start = rl
  388 + }
  389 + if end < 0 {
  390 + end = 0
  391 + }
  392 + if end > rl {
  393 + end = rl
  394 + }
  395 + return string(rs[start:end])
  396 +}
  397 +
  398 +//生成新ID
  399 +var snowFlakeNode *snowflake.Node
  400 +
  401 +func NewSnowflakeId() (int64, error) {
  402 + if snowFlakeNode == nil {
  403 + node, err := snowflake.NewNode(1)
  404 + if err != nil {
  405 + return 0, err
  406 + }
  407 + snowFlakeNode = node
  408 + }
  409 + // Generate a snowflake ID.
  410 + id := snowFlakeNode.Generate()
  411 + return id.Int64(), nil
  412 +}
  413 +
  414 +// Round 保留数值的精度位 四舍五入
  415 +func Round(value float64, places int32) float64 {
  416 + quantity := decimal.NewFromFloat(value)
  417 + d := quantity.Round(places)
  418 + rsp, _ := d.Float64()
  419 + return rsp
  420 +}
  421 +
  422 +// Truncate 截取数值固定长度的 eg:Truncate(99.99,1) Result: 99.9
  423 +func Truncate(value float64, places int32) float64 {
  424 + quantity := decimal.NewFromFloat(value).Truncate(places)
  425 + rsp, _ := quantity.Float64()
  426 + return rsp
  427 +}
  428 +
  429 +func Utf8ToGbk(s []byte) ([]byte, error) {
  430 + reader := transform.NewReader(bytes.NewReader(s), simplifiedchinese.GBK.NewEncoder())
  431 + d, e := ioutil.ReadAll(reader)
  432 + if e != nil {
  433 + return nil, e
  434 + }
  435 + return d, nil
  436 +}
  437 +
  438 +func GbkToUtf8(s []byte) ([]byte, error) {
  439 + reader := transform.NewReader(bytes.NewReader(s), simplifiedchinese.GBK.NewDecoder())
  440 + d, e := ioutil.ReadAll(reader)
  441 + if e != nil {
  442 + return nil, e
  443 + }
  444 + return d, nil
  445 +}
  1 +package utils
  2 +
  3 +import (
  4 + "fmt"
  5 + "github.com/stretchr/testify/assert"
  6 + "math"
  7 + "testing"
  8 + "time"
  9 +)
  10 +
  11 +func TestTimeSpan(t *testing.T) {
  12 + inputs := []struct {
  13 + t string
  14 + e bool
  15 + }{
  16 + {"10:00", false},
  17 + {"10:11", false},
  18 + {"24:00", true},
  19 + {"-1:00", true},
  20 + {"10:60", true},
  21 + {"A:B", true},
  22 + }
  23 + for i := range inputs {
  24 + err := ValidWorkTime(inputs[i].t)
  25 + if inputs[i].e {
  26 + assert.NotNil(t, err)
  27 + } else {
  28 + assert.Nil(t, err)
  29 + }
  30 + }
  31 +}
  32 +
  33 +func TestComputeTimeDuration(t *testing.T) {
  34 + assertDuration := func(s string) time.Duration {
  35 + t, _ := time.ParseDuration(s)
  36 + return t
  37 + }
  38 + inputs := []struct {
  39 + t1 string
  40 + t2 string
  41 + ts time.Duration
  42 + }{
  43 + {
  44 + "9:00", "18:00", assertDuration("9h"),
  45 + },
  46 + {
  47 + "23:00", "6:00", assertDuration("7h"),
  48 + },
  49 + }
  50 + for i := range inputs {
  51 + input := inputs[i]
  52 + out, err := ComputeTimeDuration(input.t1, input.t2)
  53 + assert.Nil(t, err)
  54 + assert.Equal(t, input.ts, out)
  55 + }
  56 +}
  57 +
  58 +const TIME_LAYOUT = "2006-01-02 15:04:05"
  59 +
  60 +func TestTimeParse(t *testing.T) {
  61 + fmt.Println(int(-1))
  62 + timeParse()
  63 +}
  64 +
  65 +func timeParse() {
  66 + fmt.Println("0. now: ", time.Now())
  67 + str := "2018-09-10 16:00:00"
  68 + fmt.Println("1. str: ", str)
  69 + t, err := time.Parse(TIME_LAYOUT, str)
  70 + fmt.Println("2. Parse time: ", t, err)
  71 + fmt.Println("2.1. Parse time: ", t.Local(), t.Local().Local())
  72 + parseInLocal, _ := time.ParseInLocation(TIME_LAYOUT, str, time.Local)
  73 + fmt.Println("2.2 parse in local", parseInLocal, parseInLocal.Local())
  74 + tStr := t.Format(TIME_LAYOUT)
  75 + fmt.Println("3. Format time str: ", tStr)
  76 + name, offset := t.Zone()
  77 + name2, offset2 := t.Local().Zone()
  78 + fmt.Printf("4. Zone name: %v, Zone offset: %v\n", name, offset)
  79 + fmt.Printf("5. Local Zone name: %v, Local Zone offset: %v\n", name2, offset2)
  80 + tLocal := t.Local()
  81 + tUTC := t.UTC()
  82 + fmt.Printf("6. t: %v, Local: %v, UTC: %v\n", t, tLocal, tUTC)
  83 + fmt.Printf("7. t: %v, Local: %v, UTC: %v\n", t.Format(TIME_LAYOUT), tLocal.Format(TIME_LAYOUT), tUTC.Format(TIME_LAYOUT))
  84 + fmt.Printf("8. Local.Unix: %v, UTC.Unix: %v\n", tLocal.Unix(), tUTC.Unix())
  85 + str2 := "1969-12-31 23:59:59"
  86 + t2, _ := time.Parse(TIME_LAYOUT, str2)
  87 + fmt.Printf("9. str2:%v,time: %v, Unix: %v\n", str2, t2, t2.Unix())
  88 + fmt.Printf("10. %v, %v\n", tLocal.Format(time.ANSIC), tUTC.Format(time.ANSIC))
  89 + fmt.Printf("11. %v, %v\n", tLocal.Format(time.RFC822), tUTC.Format(time.RFC822))
  90 + fmt.Printf("12. %v, %v\n", tLocal.Format(time.RFC822Z), tUTC.Format(time.RFC822Z))
  91 +
  92 + //指定时区
  93 + parseWithLocation("America/Cordoba", str)
  94 + parseWithLocation("Asia/Shanghai", str)
  95 + parseWithLocation("Asia/Beijing", str)
  96 +}
  97 +
  98 +func parseWithLocation(name string, timeStr string) (time.Time, error) {
  99 + locationName := name
  100 + if l, err := time.LoadLocation(locationName); err != nil {
  101 + println(err.Error())
  102 + return time.Time{}, err
  103 + } else {
  104 + lt, _ := time.ParseInLocation(TIME_LAYOUT, timeStr, l)
  105 + fmt.Println(locationName, lt)
  106 + return lt, nil
  107 + }
  108 +}
  109 +
  110 +func TestRound(t *testing.T) {
  111 + t.Logf("%v", Round(99.999, 1))
  112 + t.Logf("%v", Round(99.999, 2))
  113 +
  114 + t.Logf("%.1f", math.Floor(99.99))
  115 + t.Logf("%v", math.Ceil(99.99))
  116 +
  117 + t.Logf("%.1f", Truncate(99.99, 1))
  118 + t.Logf("%v", Truncate(99, 0))
  119 +}
  1 +package controllers
  2 +
  3 +import (
  4 + "github.com/linmadan/egglib-go/web/beego"
  5 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/log/command"
  6 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/log/query"
  7 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/log/service"
  8 +)
  9 +
  10 +type LogController struct {
  11 + beego.BaseController
  12 +}
  13 +
  14 +func (controller *LogController) CreateLog() {
  15 + logService := service.NewLogService(nil)
  16 + createLogCommand := &command.CreateLogCommand{}
  17 + controller.Unmarshal(createLogCommand)
  18 + data, err := logService.CreateLog(createLogCommand)
  19 + controller.Response(data, err)
  20 +}
  21 +
  22 +func (controller *LogController) UpdateLog() {
  23 + logService := service.NewLogService(nil)
  24 + updateLogCommand := &command.UpdateLogCommand{}
  25 + controller.Unmarshal(updateLogCommand)
  26 + logId, _ := controller.GetInt(":logId")
  27 + updateLogCommand.LogId = logId
  28 + data, err := logService.UpdateLog(updateLogCommand)
  29 + controller.Response(data, err)
  30 +}
  31 +
  32 +func (controller *LogController) GetLog() {
  33 + logService := service.NewLogService(nil)
  34 + getLogQuery := &query.GetLogQuery{}
  35 + logId, _ := controller.GetInt(":logId")
  36 + getLogQuery.LogId = logId
  37 + data, err := logService.GetLog(getLogQuery)
  38 + controller.Response(data, err)
  39 +}
  40 +
  41 +func (controller *LogController) RemoveLog() {
  42 + logService := service.NewLogService(nil)
  43 + removeLogCommand := &command.RemoveLogCommand{}
  44 + controller.Unmarshal(removeLogCommand)
  45 + logId, _ := controller.GetInt(":logId")
  46 + removeLogCommand.LogId = logId
  47 + data, err := logService.RemoveLog(removeLogCommand)
  48 + controller.Response(data, err)
  49 +}
  50 +
  51 +func (controller *LogController) ListLog() {
  52 + logService := service.NewLogService(nil)
  53 + listLogQuery := &query.ListLogQuery{}
  54 + offset, _ := controller.GetInt("offset")
  55 + listLogQuery.Offset = offset
  56 + limit, _ := controller.GetInt("limit")
  57 + listLogQuery.Limit = limit
  58 + data, err := logService.ListLog(listLogQuery)
  59 + controller.Response(data, err)
  60 +}
  61 +
  62 +func (controller *LogController) SearchLog() {
  63 + logService := service.NewLogService(nil)
  64 + searchLogCommand := &command.SearchLogCommand{}
  65 + controller.Unmarshal(searchLogCommand)
  66 + data, err := logService.SearchLog(searchLogCommand)
  67 + controller.Response(data, err)
  68 +}
@@ -6,18 +6,17 @@ import ( @@ -6,18 +6,17 @@ import (
6 ) 6 )
7 7
8 func init() { 8 func init() {
9 - web.Router("/bastion/files/", &controllers.FileController{}, "Post:CreateFile")  
10 - web.Router("/bastion/files/:fileId", &controllers.FileController{}, "Put:UpdateFile")  
11 - web.Router("/bastion/files/:fileId", &controllers.FileController{}, "Get:GetFile")  
12 - web.Router("/bastion/files/:fileId", &controllers.FileController{}, "Delete:RemoveFile")  
13 - web.Router("/bastion/files/", &controllers.FileController{}, "Get:ListFile")  
14 - web.Router("/bastion/files/search", &controllers.FileController{}, "Post:SearchFile")  
15 - web.Router("/bastion/files/search", &controllers.FileController{}, "Post:SearchFile")  
16 - web.Router("/bastion/files/search-source-file", &controllers.FileController{}, "Post:SearchSourceFile")  
17 - web.Router("/bastion/files/search-verified-file", &controllers.FileController{}, "Post:SearchVerifiedFile") 9 + web.Router("/data/files/", &controllers.FileController{}, "Post:CreateFile")
  10 + web.Router("/data/files/:fileId", &controllers.FileController{}, "Put:UpdateFile")
  11 + web.Router("/data/files/:fileId", &controllers.FileController{}, "Get:GetFile")
  12 + web.Router("/data/files/:fileId", &controllers.FileController{}, "Delete:RemoveFile")
  13 + web.Router("/data/files/", &controllers.FileController{}, "Get:ListFile")
  14 + web.Router("/data/files/search", &controllers.FileController{}, "Post:SearchFile")
  15 + web.Router("/data/files/search-source-file", &controllers.FileController{}, "Post:SearchSourceFile")
  16 + web.Router("/data/files/search-verified-file", &controllers.FileController{}, "Post:SearchVerifiedFile")
18 17
19 - web.Router("/bastion/load-data-table", &controllers.FileController{}, "Post:LoadDataTable")  
20 - web.Router("/bastion/edit-data-table", &controllers.FileController{}, "Post:EditDataTable")  
21 - web.Router("/bastion/flush-data-table", &controllers.FileController{}, "Post:FlushDataTable")  
22 - web.Router("/bastion/generate-main-table", &controllers.FileController{}, "Post:GenerateMainTable") 18 + web.Router("/data/load-data-table", &controllers.FileController{}, "Post:LoadDataTable")
  19 + web.Router("/data/edit-data-table", &controllers.FileController{}, "Post:EditDataTable")
  20 + web.Router("/data/flush-data-table", &controllers.FileController{}, "Post:FlushDataTable")
  21 + web.Router("/data/generate-main-table", &controllers.FileController{}, "Post:GenerateMainTable")
23 } 22 }
  1 +package routers
  2 +
  3 +import (
  4 + "github.com/beego/beego/v2/server/web"
  5 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/port/beego/controllers"
  6 +)
  7 +
  8 +func init() {
  9 + web.Router("/logs/", &controllers.LogController{}, "Post:CreateLog")
  10 + web.Router("/logs/:logId", &controllers.LogController{}, "Put:UpdateLog")
  11 + web.Router("/logs/:logId", &controllers.LogController{}, "Get:GetLog")
  12 + web.Router("/logs/:logId", &controllers.LogController{}, "Delete:RemoveLog")
  13 + web.Router("/logs/", &controllers.LogController{}, "Get:ListLog")
  14 + web.Router("/logs/search", &controllers.LogController{}, "Post:SearchLog")
  15 +}
  1 +package routers
  2 +
  3 +import (
  4 + "github.com/beego/beego/v2/server/web"
  5 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/constant"
  6 +)
  7 +
  8 +func init() {
  9 + web.SetStaticPath("/log", constant.LOG_FILE)
  10 +}
  1 +package log
  2 +
  3 +import (
  4 + "net/http"
  5 +
  6 + "github.com/gavv/httpexpect"
  7 + . "github.com/onsi/ginkgo"
  8 + . "github.com/onsi/gomega"
  9 + pG "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/pg"
  10 +)
  11 +
  12 +var _ = Describe("创建日志服务", func() {
  13 + Describe("提交数据创建日志服务", func() {
  14 + Context("提交正确的新日志数据", func() {
  15 + It("返回日志数据", func() {
  16 + httpExpect := httpexpect.New(GinkgoT(), server.URL)
  17 + body := map[string]interface{}{
  18 + "objectName": "string",
  19 + "objectType": "string",
  20 + "operationType": "string",
  21 + "content": "string",
  22 + "operatorName": "string",
  23 + }
  24 + httpExpect.POST("/logs/").
  25 + WithJSON(body).
  26 + Expect().
  27 + Status(http.StatusOK).
  28 + JSON().
  29 + Object().
  30 + ContainsKey("code").ValueEqual("code", 0).
  31 + ContainsKey("msg").ValueEqual("msg", "ok").
  32 + ContainsKey("data").Value("data").Object().
  33 + ContainsKey("logId").ValueNotEqual("logId", BeZero())
  34 + })
  35 + })
  36 + })
  37 + AfterEach(func() {
  38 + _, err := pG.DB.Exec("DELETE FROM logs WHERE true")
  39 + Expect(err).NotTo(HaveOccurred())
  40 + })
  41 +})
  1 +package log
  2 +
  3 +import (
  4 + "github.com/go-pg/pg/v10"
  5 + "net/http"
  6 +
  7 + "github.com/gavv/httpexpect"
  8 + . "github.com/onsi/ginkgo"
  9 + . "github.com/onsi/gomega"
  10 + pG "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/pg"
  11 +)
  12 +
  13 +var _ = Describe("返回日志服务", func() {
  14 + var logId int64
  15 + BeforeEach(func() {
  16 + _, err := pG.DB.QueryOne(
  17 + pg.Scan(&logId),
  18 + "INSERT INTO logs (log_id, log_type, source_id, entry, created_at) VALUES (?, ?, ?, ?, ?) RETURNING log_id",
  19 + "testLogId", "testLogType", "testSourceId", "testEntry", "testCreatedAt")
  20 + Expect(err).NotTo(HaveOccurred())
  21 + })
  22 + Describe("根据logId参数返回日志", func() {
  23 + Context("传入有效的logId", func() {
  24 + It("返回日志数据", func() {
  25 + httpExpect := httpexpect.New(GinkgoT(), server.URL)
  26 + httpExpect.GET("/logs/{logId}").
  27 + Expect().
  28 + Status(http.StatusOK).
  29 + JSON().
  30 + Object().
  31 + ContainsKey("code").ValueEqual("code", 0).
  32 + ContainsKey("msg").ValueEqual("msg", "ok").
  33 + ContainsKey("data").Value("data").Object()
  34 + })
  35 + })
  36 + })
  37 + AfterEach(func() {
  38 + _, err := pG.DB.Exec("DELETE FROM logs WHERE true")
  39 + Expect(err).NotTo(HaveOccurred())
  40 + })
  41 +})
  1 +package log
  2 +
  3 +import (
  4 + "github.com/go-pg/pg/v10"
  5 + "net/http"
  6 +
  7 + "github.com/gavv/httpexpect"
  8 + . "github.com/onsi/ginkgo"
  9 + . "github.com/onsi/gomega"
  10 + pG "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/pg"
  11 +)
  12 +
  13 +var _ = Describe("返回日志服务列表", func() {
  14 + var logId int64
  15 + BeforeEach(func() {
  16 + _, err := pG.DB.QueryOne(
  17 + pg.Scan(&logId),
  18 + "INSERT INTO logs (log_id, log_type, source_id, entry, created_at) VALUES (?, ?, ?, ?, ?) RETURNING log_id",
  19 + "testLogId", "testLogType", "testSourceId", "testEntry", "testCreatedAt")
  20 + Expect(err).NotTo(HaveOccurred())
  21 + })
  22 + Describe("根据参数返回日志列表", func() {
  23 + Context("传入有效的参数", func() {
  24 + It("返回日志数据列表", func() {
  25 + httpExpect := httpexpect.New(GinkgoT(), server.URL)
  26 + httpExpect.GET("/logs/").
  27 + WithQuery("offset", "int").
  28 + WithQuery("limit", "int").
  29 + Expect().
  30 + Status(http.StatusOK).
  31 + JSON().
  32 + Object().
  33 + ContainsKey("code").ValueEqual("code", 0).
  34 + ContainsKey("msg").ValueEqual("msg", "ok").
  35 + ContainsKey("data").Value("data").Object().
  36 + ContainsKey("count").ValueEqual("count", 1).
  37 + ContainsKey("logs").Value("logs").Array()
  38 + })
  39 + })
  40 + })
  41 + AfterEach(func() {
  42 + _, err := pG.DB.Exec("DELETE FROM logs WHERE true")
  43 + Expect(err).NotTo(HaveOccurred())
  44 + })
  45 +})
  1 +package log
  2 +
  3 +import (
  4 + "net/http"
  5 + "net/http/httptest"
  6 + "testing"
  7 +
  8 + "github.com/beego/beego/v2/server/web"
  9 + . "github.com/onsi/ginkgo"
  10 + . "github.com/onsi/gomega"
  11 + _ "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application"
  12 + _ "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/pg"
  13 + _ "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/port/beego"
  14 +)
  15 +
  16 +func TestLog(t *testing.T) {
  17 + RegisterFailHandler(Fail)
  18 + RunSpecs(t, "Beego Port Log Correlations Test Case Suite")
  19 +}
  20 +
  21 +var handler http.Handler
  22 +var server *httptest.Server
  23 +
  24 +var _ = BeforeSuite(func() {
  25 + handler = web.BeeApp.Handlers
  26 + server = httptest.NewServer(handler)
  27 +})
  28 +
  29 +var _ = AfterSuite(func() {
  30 + server.Close()
  31 +})
  1 +package log
  2 +
  3 +import (
  4 + "github.com/go-pg/pg/v10"
  5 + "net/http"
  6 +
  7 + "github.com/gavv/httpexpect"
  8 + . "github.com/onsi/ginkgo"
  9 + . "github.com/onsi/gomega"
  10 + pG "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/pg"
  11 +)
  12 +
  13 +var _ = Describe("移除日志服务", func() {
  14 + var logId int64
  15 + BeforeEach(func() {
  16 + _, err := pG.DB.QueryOne(
  17 + pg.Scan(&logId),
  18 + "INSERT INTO logs (log_id, log_type, source_id, entry, created_at) VALUES (?, ?, ?, ?, ?) RETURNING log_id",
  19 + "testLogId", "testLogType", "testSourceId", "testEntry", "testCreatedAt")
  20 + Expect(err).NotTo(HaveOccurred())
  21 + })
  22 + Describe("根据参数移除日志服务", func() {
  23 + Context("传入有效的logId", func() {
  24 + It("返回被移除日志的数据", func() {
  25 + httpExpect := httpexpect.New(GinkgoT(), server.URL)
  26 + httpExpect.DELETE("/logs/{logId}").
  27 + Expect().
  28 + Status(http.StatusOK).
  29 + JSON().
  30 + Object().
  31 + ContainsKey("code").ValueEqual("code", 0).
  32 + ContainsKey("msg").ValueEqual("msg", "ok").
  33 + ContainsKey("data").Value("data").Object()
  34 + })
  35 + })
  36 + })
  37 + AfterEach(func() {
  38 + _, err := pG.DB.Exec("DELETE FROM logs WHERE true")
  39 + Expect(err).NotTo(HaveOccurred())
  40 + })
  41 +})
  1 +package log
  2 +
  3 +import (
  4 + "github.com/go-pg/pg/v10"
  5 + "net/http"
  6 +
  7 + "github.com/gavv/httpexpect"
  8 + . "github.com/onsi/ginkgo"
  9 + . "github.com/onsi/gomega"
  10 + pG "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/pg"
  11 +)
  12 +
  13 +var _ = Describe("搜索日志", func() {
  14 + var logId int64
  15 + BeforeEach(func() {
  16 + _, err := pG.DB.QueryOne(
  17 + pg.Scan(&logId),
  18 + "INSERT INTO logs (log_id, log_type, source_id, entry, created_at) VALUES (?, ?, ?, ?, ?) RETURNING log_id",
  19 + "testLogId", "testLogType", "testSourceId", "testEntry", "testCreatedAt")
  20 + Expect(err).NotTo(HaveOccurred())
  21 + })
  22 + Describe("搜索日志", func() {
  23 + Context("", func() {
  24 + It("", func() {
  25 + httpExpect := httpexpect.New(GinkgoT(), server.URL)
  26 + body := map[string]interface{}{
  27 + "content": "string",
  28 + }
  29 + httpExpect.POST("/logs/search").
  30 + WithJSON(body).
  31 + Expect().
  32 + Status(http.StatusOK).
  33 + JSON().
  34 + Object().
  35 + ContainsKey("code").ValueEqual("code", 0).
  36 + ContainsKey("msg").ValueEqual("msg", "ok").
  37 + ContainsKey("data").Value("data").Object()
  38 + })
  39 + })
  40 + })
  41 + AfterEach(func() {
  42 + _, err := pG.DB.Exec("DELETE FROM logs WHERE true")
  43 + Expect(err).NotTo(HaveOccurred())
  44 + })
  45 +})
  1 +package log
  2 +
  3 +import (
  4 + "github.com/go-pg/pg/v10"
  5 + "net/http"
  6 +
  7 + "github.com/gavv/httpexpect"
  8 + . "github.com/onsi/ginkgo"
  9 + . "github.com/onsi/gomega"
  10 + pG "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/pg"
  11 +)
  12 +
  13 +var _ = Describe("更新日志服务", func() {
  14 + var logId int64
  15 + BeforeEach(func() {
  16 + _, err := pG.DB.QueryOne(
  17 + pg.Scan(&logId),
  18 + "INSERT INTO logs (log_id, log_type, source_id, entry, created_at) VALUES (?, ?, ?, ?, ?) RETURNING log_id",
  19 + "testLogId", "testLogType", "testSourceId", "testEntry", "testCreatedAt")
  20 + Expect(err).NotTo(HaveOccurred())
  21 + })
  22 + Describe("提交数据更新日志服务", func() {
  23 + Context("提交正确的日志数据", func() {
  24 + It("返回更新后的日志数据", func() {
  25 + httpExpect := httpexpect.New(GinkgoT(), server.URL)
  26 + body := map[string]interface{}{}
  27 + httpExpect.PUT("/logs/{logId}").
  28 + WithJSON(body).
  29 + Expect().
  30 + Status(http.StatusOK).
  31 + JSON().
  32 + Object().
  33 + ContainsKey("code").ValueEqual("code", 0).
  34 + ContainsKey("msg").ValueEqual("msg", "ok").
  35 + ContainsKey("data").Value("data").Object().
  36 + ContainsKey("logId").ValueEqual("logId", logId)
  37 + })
  38 + })
  39 + })
  40 + AfterEach(func() {
  41 + _, err := pG.DB.Exec("DELETE FROM logs WHERE true")
  42 + Expect(err).NotTo(HaveOccurred())
  43 + })
  44 +})