Bladeren bron

初始化配置测试通过

qdy 2 maanden geleden
bovenliggende
commit
fe42afaf99

+ 5
- 0
main.go Bestand weergeven

47
 		myhandle.QueryHandlerMap(w, r, dbFactory, service.QueryYamlConfigure)
47
 		myhandle.QueryHandlerMap(w, r, dbFactory, service.QueryYamlConfigure)
48
 	})))
48
 	})))
49
 
49
 
50
+	// 初始化配置模版
51
+	webService.Handle("/api/init/config/template", middleware.JWTAuthMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
52
+		myhandle.QueryHandlerMap(w, r, dbFactory, service.InitConfigTemplates)
53
+	})))
54
+
50
 }
55
 }
51
 
56
 
52
 func creteTabel(factory *database.DBFactory) {
57
 func creteTabel(factory *database.DBFactory) {

+ 45
- 75
models/Config_template_builder.go Bestand weergeven

19
 }
19
 }
20
 
20
 
21
 // StartTemplate 开始创建新模板
21
 // StartTemplate 开始创建新模板
22
-func (b *ConfigTemplateBuilder) StartTemplate(name, rootKey, description string) *ConfigTemplateBuilder {
22
+func (b *ConfigTemplateBuilder) StartTemplate(id, name, description string) *ConfigTemplateBuilder {
23
 	b.current = &ConfigTemplate{
23
 	b.current = &ConfigTemplate{
24
-		TemplateName: name,
25
-		YamlRootKey:  rootKey,
26
-		Description:  description,
27
-		IsDefault:    true,
28
-		SortOrder:    len(b.templates) + 1,
29
-		Creator:      "system",
30
-		CreatedAt:    time.Now(),
31
-		UpdatedAt:    time.Now(),
32
-		Details:      make([]ConfigTemplateDetail, 0),
24
+		ConfigTemplateID: id,
25
+		TemplateName:     name,
26
+		Description:      description,
27
+		IsDefault:        true,
28
+		SortOrder:        len(b.templates) + 1,
29
+		Creator:          "system",
30
+		CreatedAt:        time.Now(),
31
+		UpdatedAt:        time.Now(),
32
+		Details:          make([]ConfigTemplateDetail, 0),
33
 	}
33
 	}
34
 	return b
34
 	return b
35
 }
35
 }
76
 	return b.templates
76
 	return b.templates
77
 }
77
 }
78
 
78
 
79
-// // BuildSampleTemplates 构建示例模板
80
-// func (b *ConfigTemplateBuilder) BuildSampleTemplates() *ConfigTemplateBuilder {
81
-// 	// Service模板
82
-// 	b.StartTemplate("Service配置", "service", "服务基础配置").
83
-// 		AddInt("port", "服务监听端口").Default("8080").Min(1024).Max(65535).Required().FinishDetail().
84
-// 		AddString("service_name", "服务名称").Default("svc-configure").Pattern("^[a-zA-Z][a-zA-Z0-9_-]*$").Required().FinishDetail().
85
-// 		AddString("instance_name", "实例名称").Default("svc-configure-01").Required().FinishDetail().
86
-// 		AddInt("read_timeout", "读取超时时间(秒)").Default("30").Min(1).Max(300).Required().FinishDetail().
87
-// 		AddInt("write_timeout", "写入超时时间(秒)").Default("30").Min(1).Max(300).Required().FinishDetail().
88
-// 		AddInt("idle_timeout", "空闲超时时间(秒)").Default("60").Min(10).Max(600).Required().FinishDetail().
89
-// 		FinishTemplate()
90
-
91
-// 	// Log模板
92
-// 	b.StartTemplate("日志配置", "log", "日志相关配置").
93
-// 		AddEnum("level", "日志级别", []string{"debug", "info", "warn", "error", "fatal"}).Default("debug").Required().FinishDetail().
94
-// 		AddString("output", "日志输出目标").Default("console,file").FinishDetail().
95
-// 		AddBoolean("json_format", "是否以JSON格式输出日志").Default("true").FinishDetail().
96
-// 		FinishTemplate()
97
-
98
-// 	// Doris模板
99
-// 	b.StartTemplate("Doris配置", "doris", "Doris数据库连接配置").
100
-// 		AddString("fe_host", "Doris FE节点主机地址").Default("161.189.89.196").Pattern(`^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$`).Required().FinishDetail().
101
-// 		AddInt("fe_port", "Doris FE端口号").Default("8040").Min(1).Max(65535).Required().FinishDetail().
102
-// 		AddString("fe_username", "Doris FE用户名").Default("root").Required().FinishDetail().
103
-// 		AddString("fe_password", "Doris FE密码").Default("mos8555").Sensitive().Required().MinLength(6).MaxLength(100).FinishDetail().
104
-// 		AddInt("stream_load_timeout", "Stream Load超时时间(秒)").Default("300").Min(10).Max(3600).FinishDetail().
105
-// 		AddInt("batch_size", "批量大小").Default("1000").Min(1).Max(10000).FinishDetail().
106
-// 		FinishTemplate()
107
-
108
-// 	return b
109
-// }
110
-
111
 // 私有方法
79
 // 私有方法
112
 func (b *ConfigTemplateBuilder) addDetail(key, description, valueType, dataType string) *DetailBuilder {
80
 func (b *ConfigTemplateBuilder) addDetail(key, description, valueType, dataType string) *DetailBuilder {
113
 	if b.current == nil {
81
 	if b.current == nil {
114
-		b.StartTemplate("未命名模板", "untitled", "未描述模板")
82
+		b.StartTemplate("untitled", "未命名模板", "未描述模板")
115
 	}
83
 	}
116
-
84
+	detailID := b.current.ConfigTemplateID + "." + key
117
 	detail := ConfigTemplateDetail{
85
 	detail := ConfigTemplateDetail{
118
-		ConfigKey:   key,
119
-		Description: description,
120
-		ValueType:   valueType,
121
-		DataType:    dataType,
122
-		IsRequired:  false,
123
-		IsSensitive: false,
124
-		IsReadonly:  false,
125
-		SortOrder:   len(b.current.Details) + 1,
126
-		Creator:     "system",
127
-		CreatedAt:   time.Now(),
128
-		UpdatedAt:   time.Now(),
86
+		ConfigTemplateDetailID: detailID,
87
+		ConfigTemplateID:       b.current.ConfigTemplateID,
88
+		ConfigKey:              key,
89
+		Description:            description,
90
+		ValueType:              valueType,
91
+		DataType:               dataType,
92
+		IsRequired:             false,
93
+		IsSensitive:            false,
94
+		IsReadonly:             false,
95
+		SortOrder:              len(b.current.Details) + 1,
96
+		Creator:                "system",
97
+		CreatedAt:              time.Now(),
98
+		UpdatedAt:              time.Now(),
129
 	}
99
 	}
130
 
100
 
131
 	return &DetailBuilder{
101
 	return &DetailBuilder{
237
 	return builder.GetTemplates()
207
 	return builder.GetTemplates()
238
 }
208
 }
239
 
209
 
240
-// 更简洁的使用示例
241
-func CreateConfigTemplates() []*ConfigTemplate {
242
-	builder := NewConfigTemplateBuilder()
210
+// // 更简洁的使用示例
211
+// func CreateConfigTemplates() []*ConfigTemplate {
212
+// 	builder := NewConfigTemplateBuilder()
243
 
213
 
244
-	// Service模板 - 更简洁的写法
245
-	builder.StartTemplate("Service配置", "service", "服务基础配置")
246
-	builder.AddInt("port", "服务监听端口").Default("8080").Min(1024).Max(65535).Required().FinishDetail()
247
-	builder.AddString("service_name", "服务名称").Default("svc-configure").Required().FinishDetail()
248
-	builder.FinishTemplate()
214
+// 	// Service模板 - 更简洁的写法
215
+// 	builder.StartTemplate("Service配置", "service", "服务基础配置")
216
+// 	builder.AddInt("port", "服务监听端口").Default("8080").Min(1024).Max(65535).Required().FinishDetail()
217
+// 	builder.AddString("service_name", "服务名称").Default("svc-configure").Required().FinishDetail()
218
+// 	builder.FinishTemplate()
249
 
219
 
250
-	// Log模板
251
-	builder.StartTemplate("日志配置", "log", "日志相关配置")
252
-	builder.AddEnum("level", "日志级别", []string{"debug", "info", "warn", "error", "fatal"}).Default("debug").Required().FinishDetail()
253
-	builder.AddString("output", "日志输出").Default("console,file").FinishDetail()
254
-	builder.FinishTemplate()
220
+// 	// Log模板
221
+// 	builder.StartTemplate("日志配置", "log", "日志相关配置")
222
+// 	builder.AddEnum("level", "日志级别", []string{"debug", "info", "warn", "error", "fatal"}).Default("debug").Required().FinishDetail()
223
+// 	builder.AddString("output", "日志输出").Default("console,file").FinishDetail()
224
+// 	builder.FinishTemplate()
255
 
225
 
256
-	// Doris模板
257
-	builder.StartTemplate("Doris配置", "doris", "Doris连接配置")
258
-	builder.AddString("fe_host", "FE主机").Default("localhost").Required().FinishDetail()
259
-	builder.AddString("fe_password", "密码").Sensitive().Required().FinishDetail()
260
-	builder.FinishTemplate()
226
+// 	// Doris模板
227
+// 	builder.StartTemplate("Doris配置", "doris", "Doris连接配置")
228
+// 	builder.AddString("fe_host", "FE主机").Default("localhost").Required().FinishDetail()
229
+// 	builder.AddString("fe_password", "密码").Sensitive().Required().FinishDetail()
230
+// 	builder.FinishTemplate()
261
 
231
 
262
-	return builder.GetTemplates()
263
-}
232
+// 	return builder.GetTemplates()
233
+// }

+ 3
- 4
models/config_template.go Bestand weergeven

6
 
6
 
7
 // ConfigTemplate 配置模板
7
 // ConfigTemplate 配置模板
8
 type ConfigTemplate struct {
8
 type ConfigTemplate struct {
9
-	ConfigTemplateID int64     `gorm:"column:config_template_id;primaryKey;autoIncrement" json:"config_template_id"`
9
+	ConfigTemplateID string    `gorm:"column:config_template_id;primaryKey;type:varchar(128)" json:"config_template_id"`
10
 	TemplateName     string    `gorm:"column:template_name;type:varchar(100);not null;uniqueIndex;comment:模板名称" json:"template_name"`
10
 	TemplateName     string    `gorm:"column:template_name;type:varchar(100);not null;uniqueIndex;comment:模板名称" json:"template_name"`
11
-	YamlRootKey      string    `gorm:"column:yaml_root_key;type:varchar(100);comment:YAML根键名" json:"yaml_root_key"`
12
 	IsDefault        bool      `gorm:"column:is_default;type:boolean;default:false;comment:是否为默认模板" json:"is_default"`
11
 	IsDefault        bool      `gorm:"column:is_default;type:boolean;default:false;comment:是否为默认模板" json:"is_default"`
13
 	SortOrder        int       `gorm:"column:sort_order;type:integer;default:0;comment:排序序号" json:"sort_order"`
12
 	SortOrder        int       `gorm:"column:sort_order;type:integer;default:0;comment:排序序号" json:"sort_order"`
14
 	Description      string    `gorm:"column:description;type:text;comment:模板描述" json:"description"`
13
 	Description      string    `gorm:"column:description;type:text;comment:模板描述" json:"description"`
27
 
26
 
28
 // ConfigTemplateDetail 配置模板详情
27
 // ConfigTemplateDetail 配置模板详情
29
 type ConfigTemplateDetail struct {
28
 type ConfigTemplateDetail struct {
30
-	ConfigTemplateDetailID int64     `gorm:"column:config_template_detail_id;primaryKey;autoIncrement" json:"config_template_detail_id"`
31
-	ConfigTemplateID       int64     `gorm:"column:config_template_id;not null;index" json:"config_template_id"`
29
+	ConfigTemplateDetailID string    `gorm:"column:config_template_detail_id;primaryKey;autoIncrement" json:"config_template_detail_id"`
30
+	ConfigTemplateID       string    `gorm:"column:config_template_id;not null;index" json:"config_template_id"`
32
 	ConfigKey              string    `gorm:"column:config_key;type:varchar(100);not null;index" json:"config_key"`
31
 	ConfigKey              string    `gorm:"column:config_key;type:varchar(100);not null;index" json:"config_key"`
33
 	ConfigValue            string    `gorm:"column:config_value;type:text" json:"config_value"`
32
 	ConfigValue            string    `gorm:"column:config_value;type:text" json:"config_value"`
34
 	ValueType              string    `gorm:"column:value_type;type:varchar(20);not null;default:'string';comment:值类型:string,number,boolean,json,array" json:"value_type"`
33
 	ValueType              string    `gorm:"column:value_type;type:varchar(20);not null;default:'string';comment:值类型:string,number,boolean,json,array" json:"value_type"`

+ 81
- 28
service/create_config_template.go Bestand weergeven

4
 	"fmt"
4
 	"fmt"
5
 	"time"
5
 	"time"
6
 
6
 
7
+	"git.x2erp.com/qdy/go-base/ctx"
8
+	"git.x2erp.com/qdy/go-base/logger"
9
+	"git.x2erp.com/qdy/go-base/myservice"
10
+	"git.x2erp.com/qdy/go-base/types"
11
+	"git.x2erp.com/qdy/go-db/factory/database"
7
 	"git.x2erp.com/qdy/go-svc-configure/models"
12
 	"git.x2erp.com/qdy/go-svc-configure/models"
8
 	"github.com/jmoiron/sqlx"
13
 	"github.com/jmoiron/sqlx"
9
 )
14
 )
10
 
15
 
16
+func InitConfigTemplates(dbFactory *database.DBFactory, req types.QueryRequest, reqCtx *ctx.RequestContext) *types.QueryResult[map[string]interface{}] {
17
+	return initConfigTemplates(dbFactory.GetDB(), reqCtx)
18
+
19
+}
20
+
11
 // InitConfigTemplates 初始化默认配置信息
21
 // InitConfigTemplates 初始化默认配置信息
12
-func InitConfigTemplates(db *sqlx.DB) error {
22
+func initConfigTemplates(db *sqlx.DB, reqCtx *ctx.RequestContext) *types.QueryResult[map[string]interface{}] {
13
 
23
 
14
 	builder := models.NewConfigTemplateBuilder()
24
 	builder := models.NewConfigTemplateBuilder()
15
 
25
 
16
 	templates := builder.
26
 	templates := builder.
17
 		// Service模板
27
 		// Service模板
18
-		StartTemplate("Service配置", "service", "服务基础配置").
28
+		StartTemplate("service", "Service配置", "服务基础配置").
19
 		AddInt("port", "服务监听端口").Default("8080").Min(1024).Max(65535).Required().FinishDetail().
29
 		AddInt("port", "服务监听端口").Default("8080").Min(1024).Max(65535).Required().FinishDetail().
20
 		AddString("service_name", "服务名称").Default("svc-configure").Pattern("^[a-zA-Z][a-zA-Z0-9_-]*$").Required().FinishDetail().
30
 		AddString("service_name", "服务名称").Default("svc-configure").Pattern("^[a-zA-Z][a-zA-Z0-9_-]*$").Required().FinishDetail().
21
 		AddString("instance_name", "实例名称").Default("svc-configure-01").Required().FinishDetail().
31
 		AddString("instance_name", "实例名称").Default("svc-configure-01").Required().FinishDetail().
24
 		AddInt("idle_timeout", "空闲超时时间(秒)").Default("60").Min(10).Max(600).Required().FinishDetail().
34
 		AddInt("idle_timeout", "空闲超时时间(秒)").Default("60").Min(10).Max(600).Required().FinishDetail().
25
 		FinishTemplate().
35
 		FinishTemplate().
26
 
36
 
37
+		// 通用数据库配置
38
+		StartTemplate("database", "通用数据库配置", "关系型数据库通用连接配置").
39
+		AddEnum("type", "数据库类型", []string{"postgresql", "mysql", "oracle"}).Default("postgresql").Required().FinishDetail().
40
+		AddString("host", "数据库主机地址").Default("localhost").Required().FinishDetail().
41
+		AddInt("port", "数据库端口").Default("5432").Min(1).Max(65535).Required().FinishDetail().
42
+		AddString("database", "数据库名称").Default("").Required().FinishDetail().
43
+		AddString("username", "用户名").Default("").Required().FinishDetail().
44
+		AddString("password", "密码").Default("").Sensitive().Required().FinishDetail().
45
+		AddInt("max_conns", "最大连接数").Default("100").Min(1).Max(1000).FinishDetail().
46
+		AddInt("min_conns", "最小连接数").Default("5").Min(0).Max(100).FinishDetail().
47
+		AddInt("max_lifetime", "连接最大生存时间(秒)").Default("3600").Min(60).Max(86400).FinishDetail().
48
+		AddInt("max_idle_time", "连接最大空闲时间(秒)").Default("1800").Min(30).Max(3600).FinishDetail().
49
+		AddInt("connect_timeout", "连接超时时间(秒)").Default("5").Min(1).Max(30).FinishDetail().
50
+		AddInt("read_timeout", "读取超时时间(秒)").Default("30").Min(1).Max(300).FinishDetail().
51
+		AddInt("write_timeout", "写入超时时间(秒)").Default("30").Min(1).Max(300).FinishDetail().
52
+		AddBoolean("ssl_enabled", "启用SSL加密").Default("false").FinishDetail().
53
+		AddString("ssl_ca", "CA证书路径").Default("").FinishDetail().
54
+		AddString("ssl_cert", "客户端证书路径").Default("").FinishDetail().
55
+		AddString("ssl_key", "客户端密钥路径").Default("").FinishDetail().
56
+		AddString("charset", "字符集").Default("utf8mb4").FinishDetail().
57
+		AddString("timezone", "时区").Default("Asia/Shanghai").FinishDetail().
58
+		AddBoolean("parse_time", "解析时间字段").Default("true").FinishDetail().
59
+		AddString("loc", "时区位置").Default("Asia/Shanghai").FinishDetail().
60
+		AddInt("max_prepared_stmt_count", "最大预处理语句数").Default("128").Min(0).Max(1024).FinishDetail().
61
+		AddInt("max_allowed_packet", "最大允许数据包大小(MB)").Default("64").Min(1).Max(1024).FinishDetail().
62
+		AddInt("timeout", "全局超时时间(秒)").Default("30").Min(1).Max(300).FinishDetail().
63
+		AddBoolean("debug_mode", "调试模式").Default("false").FinishDetail().
64
+		FinishTemplate().
65
+
27
 		// Log模板
66
 		// Log模板
28
-		StartTemplate("日志增强配置", "log", "增强版日志配置").
67
+		StartTemplate("log", "日志增强配置", "增强版日志配置").
29
 		AddEnum("level", "日志级别", []string{"debug", "info", "warn", "error", "fatal"}).Default("debug").Required().FinishDetail().
68
 		AddEnum("level", "日志级别", []string{"debug", "info", "warn", "error", "fatal"}).Default("debug").Required().FinishDetail().
30
 		AddString("output", "日志输出目标").Default("console,es").FinishDetail().
69
 		AddString("output", "日志输出目标").Default("console,es").FinishDetail().
31
 		//AddBoolean("json_format", "JSON格式输出").Default("true").FinishDetail().
70
 		//AddBoolean("json_format", "JSON格式输出").Default("true").FinishDetail().
40
 		FinishTemplate().
79
 		FinishTemplate().
41
 
80
 
42
 		// Doris模板
81
 		// Doris模板
43
-		StartTemplate("Doris配置", "doris", "Doris数据库连接配置").
82
+		StartTemplate("doris", "Doris配置", "Doris数据库连接配置").
44
 		AddString("fe_host", "Doris FE节点主机地址").Default("161.189.89.196").Pattern(`^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$`).Required().FinishDetail().
83
 		AddString("fe_host", "Doris FE节点主机地址").Default("161.189.89.196").Pattern(`^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$`).Required().FinishDetail().
45
 		AddInt("fe_port", "Doris FE端口号").Default("8040").Min(1).Max(65535).Required().FinishDetail().
84
 		AddInt("fe_port", "Doris FE端口号").Default("8040").Min(1).Max(65535).Required().FinishDetail().
46
 		AddString("fe_username", "Doris FE用户名").Default("root").Required().FinishDetail().
85
 		AddString("fe_username", "Doris FE用户名").Default("root").Required().FinishDetail().
50
 		FinishTemplate().
89
 		FinishTemplate().
51
 
90
 
52
 		// micro 注册发现配置
91
 		// micro 注册发现配置
53
-		StartTemplate("Micro服务配置", "micro", "Micro服务基础配置").
92
+		StartTemplate("micro", "Micro服务配置", "Micro服务基础配置").
54
 		AddString("service_name", "服务名称").Default("svc-worker").Required().FinishDetail().
93
 		AddString("service_name", "服务名称").Default("svc-worker").Required().FinishDetail().
55
 		AddString("service_address", "服务地址").Default(":7070").Required().FinishDetail().
94
 		AddString("service_address", "服务地址").Default(":7070").Required().FinishDetail().
56
 		AddString("registry_address", "注册中心地址").Default("localhost:8500").Required().FinishDetail().
95
 		AddString("registry_address", "注册中心地址").Default("localhost:8500").Required().FinishDetail().
59
 		FinishTemplate().
98
 		FinishTemplate().
60
 
99
 
61
 		// rabbitmq
100
 		// rabbitmq
62
-		StartTemplate("RabbitMQ配置", "rabbitmq", "RabbitMQ消息队列配置").
101
+		StartTemplate("rabbitmq", "RabbitMQ配置", "RabbitMQ消息队列配置").
63
 		AddString("host", "主机地址").Default("localhost").Required().FinishDetail().
102
 		AddString("host", "主机地址").Default("localhost").Required().FinishDetail().
64
 		AddInt("port", "端口").Default("5672").Required().FinishDetail().
103
 		AddInt("port", "端口").Default("5672").Required().FinishDetail().
65
 		AddString("username", "用户名").Default("guest").Required().FinishDetail().
104
 		AddString("username", "用户名").Default("guest").Required().FinishDetail().
87
 		FinishTemplate().
126
 		FinishTemplate().
88
 		GetTemplates()
127
 		GetTemplates()
89
 
128
 
90
-	return CreateOrUpdateConfigTemplates(db, templates)
129
+	return createOrUpdateConfigTemplates(db, templates, reqCtx)
130
+}
131
+
132
+func CreateOrUpdateConfigTemplates(dbFactory *database.DBFactory, req *models.ConfigTemplate, reqCtx *ctx.RequestContext) *types.QueryResult[map[string]interface{}] {
133
+	configTemplates := []*models.ConfigTemplate{req}
134
+	return createOrUpdateConfigTemplates(dbFactory.GetDB(), configTemplates, reqCtx)
135
+
91
 }
136
 }
92
 
137
 
93
 // CreateOrUpdateConfigTemplates 创建或更新配置模板(支持部分更新)
138
 // CreateOrUpdateConfigTemplates 创建或更新配置模板(支持部分更新)
94
-func CreateOrUpdateConfigTemplates(db *sqlx.DB, templates []*models.ConfigTemplate) error {
139
+func createOrUpdateConfigTemplates(db *sqlx.DB, templates []*models.ConfigTemplate, reqCtx *ctx.RequestContext) *types.QueryResult[map[string]interface{}] {
140
+	startTime := time.Now()
95
 	if db == nil {
141
 	if db == nil {
96
-		return fmt.Errorf("database connection is nil")
142
+		return myservice.CreateErrorResult[map[string]interface{}]("database connection is nil", startTime, reqCtx)
97
 	}
143
 	}
98
 
144
 
99
 	// 开始事务
145
 	// 开始事务
100
 	tx, err := db.Beginx()
146
 	tx, err := db.Beginx()
101
 	if err != nil {
147
 	if err != nil {
102
-		return fmt.Errorf("begin transaction failed: %v", err)
148
+		return myservice.CreateErrorResult[map[string]interface{}](fmt.Sprintf("begin transaction failed: %v", err), startTime, reqCtx)
103
 	}
149
 	}
104
 	defer func() {
150
 	defer func() {
105
 		if err != nil {
151
 		if err != nil {
117
 		template.UpdatedAt = now
163
 		template.UpdatedAt = now
118
 
164
 
119
 		// 1. 插入或更新模板主表
165
 		// 1. 插入或更新模板主表
120
-		templateID, err := upsertTemplate(tx, template, now)
166
+		err := upsertTemplate(tx, template, now, reqCtx)
121
 		if err != nil {
167
 		if err != nil {
122
-			return err
168
+			return myservice.CreateErrorResult[map[string]interface{}](fmt.Sprintf("upsertTemplate: %v", err), startTime, reqCtx)
123
 		}
169
 		}
124
 
170
 
125
 		// 2. 处理模板详情(部分更新)
171
 		// 2. 处理模板详情(部分更新)
126
 		if len(template.Details) > 0 {
172
 		if len(template.Details) > 0 {
127
-			err = upsertTemplateDetails(tx, templateID, template.Details, now)
173
+			err = upsertTemplateDetails(tx, template.Details, now)
128
 			if err != nil {
174
 			if err != nil {
129
-				return err
175
+				return myservice.CreateErrorResult[map[string]interface{}](fmt.Sprintf("upsertTemplateDetails: %v", err), startTime, reqCtx)
176
+
130
 			}
177
 			}
131
 		}
178
 		}
132
 	}
179
 	}
133
 
180
 
134
-	return tx.Commit()
181
+	errCommit := tx.Commit()
182
+	if errCommit != nil {
183
+		return myservice.CreateErrorResult[map[string]interface{}](fmt.Sprintf("db commit: %v", errCommit), startTime, reqCtx)
184
+	}
185
+
186
+	return myservice.CreateSuccessResult[map[string]interface{}](startTime, reqCtx)
135
 }
187
 }
136
 
188
 
137
 // upsertTemplate 插入或更新模板主表
189
 // upsertTemplate 插入或更新模板主表
138
-func upsertTemplate(tx *sqlx.Tx, template *models.ConfigTemplate, now time.Time) (int64, error) {
190
+func upsertTemplate(tx *sqlx.Tx, template *models.ConfigTemplate, now time.Time, reqCtx *ctx.RequestContext) error {
139
 	sqlStr := `
191
 	sqlStr := `
140
 		INSERT INTO config_template (
192
 		INSERT INTO config_template (
193
+			config_template_id,
141
 			template_name, 
194
 			template_name, 
142
-			yaml_root_key, 
143
 			is_default, 
195
 			is_default, 
144
 			sort_order, 
196
 			sort_order, 
145
 			description, 
197
 			description, 
147
 			created_at, 
199
 			created_at, 
148
 			updated_at
200
 			updated_at
149
 		) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
201
 		) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
150
-		ON CONFLICT (template_name) DO UPDATE SET
151
-			yaml_root_key = EXCLUDED.yaml_root_key,
202
+		ON CONFLICT (config_template_id) DO UPDATE SET
152
 			is_default = EXCLUDED.is_default,
203
 			is_default = EXCLUDED.is_default,
153
 			sort_order = EXCLUDED.sort_order,
204
 			sort_order = EXCLUDED.sort_order,
154
 			description = EXCLUDED.description,
205
 			description = EXCLUDED.description,
156
 			updated_at = $8
207
 			updated_at = $8
157
 		RETURNING config_template_id`
208
 		RETURNING config_template_id`
158
 
209
 
159
-	var templateID int64
210
+	var templateID string
160
 	err := tx.QueryRow(sqlStr,
211
 	err := tx.QueryRow(sqlStr,
212
+		template.ConfigTemplateID,
161
 		template.TemplateName,
213
 		template.TemplateName,
162
-		template.YamlRootKey,
163
 		template.IsDefault,
214
 		template.IsDefault,
164
 		template.SortOrder,
215
 		template.SortOrder,
165
 		template.Description,
216
 		template.Description,
169
 	).Scan(&templateID)
220
 	).Scan(&templateID)
170
 
221
 
171
 	if err != nil {
222
 	if err != nil {
172
-		return 0, fmt.Errorf("upsert template failed: %v", err)
223
+		return logger.ErrorCf(reqCtx, "upsert template failed: %v", err)
173
 	}
224
 	}
174
-
175
-	return templateID, nil
225
+	logger.DebugC(reqCtx, "save data:%s", templateID)
226
+	return nil
176
 }
227
 }
177
 
228
 
178
 // upsertTemplateDetails 插入或更新模板详情(基于config_key唯一性)
229
 // upsertTemplateDetails 插入或更新模板详情(基于config_key唯一性)
179
-func upsertTemplateDetails(tx *sqlx.Tx, templateID int64, details []models.ConfigTemplateDetail, now time.Time) error {
230
+func upsertTemplateDetails(tx *sqlx.Tx, details []models.ConfigTemplateDetail, now time.Time) error {
180
 	for _, detail := range details {
231
 	for _, detail := range details {
181
 		// 设置时间和模板ID
232
 		// 设置时间和模板ID
182
 		if detail.CreatedAt.IsZero() {
233
 		if detail.CreatedAt.IsZero() {
183
 			detail.CreatedAt = now
234
 			detail.CreatedAt = now
184
 		}
235
 		}
185
 		detail.UpdatedAt = now
236
 		detail.UpdatedAt = now
186
-		detail.ConfigTemplateID = templateID
237
+		//detail.ConfigTemplateID = templateID
187
 
238
 
188
 		sqlStr := `
239
 		sqlStr := `
189
 			INSERT INTO config_template_detail (
240
 			INSERT INTO config_template_detail (
241
+				config_template_detail_id,
190
 				config_template_id,
242
 				config_template_id,
191
 				config_key,
243
 				config_key,
192
 				config_value,
244
 				config_value,
202
 				creator,
254
 				creator,
203
 				created_at,
255
 				created_at,
204
 				updated_at
256
 				updated_at
205
-			) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)
206
-			ON CONFLICT (config_template_id, config_key) DO UPDATE SET
257
+			) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15,$16)
258
+			ON CONFLICT (config_template_detail_id) DO UPDATE SET
207
 				config_value = EXCLUDED.config_value,
259
 				config_value = EXCLUDED.config_value,
208
 				value_type = EXCLUDED.value_type,
260
 				value_type = EXCLUDED.value_type,
209
 				data_type = EXCLUDED.data_type,
261
 				data_type = EXCLUDED.data_type,
218
 				updated_at = $15`
270
 				updated_at = $15`
219
 
271
 
220
 		_, err := tx.Exec(sqlStr,
272
 		_, err := tx.Exec(sqlStr,
273
+			detail.ConfigTemplateDetailID,
221
 			detail.ConfigTemplateID,
274
 			detail.ConfigTemplateID,
222
 			detail.ConfigKey,
275
 			detail.ConfigKey,
223
 			detail.ConfigValue,
276
 			detail.ConfigValue,

+ 7
- 17
service/query_yaml_configure.go Bestand weergeven

8
 
8
 
9
 	"git.x2erp.com/qdy/go-base/ctx"
9
 	"git.x2erp.com/qdy/go-base/ctx"
10
 	"git.x2erp.com/qdy/go-base/logger"
10
 	"git.x2erp.com/qdy/go-base/logger"
11
+	"git.x2erp.com/qdy/go-base/myservice"
11
 	"git.x2erp.com/qdy/go-base/types"
12
 	"git.x2erp.com/qdy/go-base/types"
12
 	"git.x2erp.com/qdy/go-db/factory/database"
13
 	"git.x2erp.com/qdy/go-db/factory/database"
13
 	"github.com/jmoiron/sqlx"
14
 	"github.com/jmoiron/sqlx"
25
 
26
 
26
 	// 安全检查
27
 	// 安全检查
27
 	if db == nil {
28
 	if db == nil {
28
-		return createErrorResult("database connection is nil", startTime, reqCtx)
29
+		return myservice.CreateErrorResult[map[string]interface{}]("database connection is nil", startTime, reqCtx)
29
 	}
30
 	}
30
 
31
 
31
 	sqlStr := `
32
 	sqlStr := `
42
 	// 执行查询
43
 	// 执行查询
43
 	rows, err := db.Queryx(sqlStr, params...)
44
 	rows, err := db.Queryx(sqlStr, params...)
44
 	if err != nil {
45
 	if err != nil {
45
-		return createErrorResult(fmt.Sprintf("Query execution failed: %v", err), startTime, reqCtx)
46
+		return myservice.CreateErrorResult[map[string]interface{}](fmt.Sprintf("Query execution failed: %v", err), startTime, reqCtx)
46
 	}
47
 	}
47
 	defer rows.Close()
48
 	defer rows.Close()
48
 
49
 
59
 	// 获取列信息
60
 	// 获取列信息
60
 	columns, err := rows.Columns()
61
 	columns, err := rows.Columns()
61
 	if err != nil {
62
 	if err != nil {
62
-		return createErrorResult(fmt.Sprintf("Failed to get columns: %v", err), startTime, reqCtx)
63
+		return myservice.CreateErrorResult[map[string]interface{}](fmt.Sprintf("Failed to get columns: %v", err), startTime, reqCtx)
63
 	}
64
 	}
64
 
65
 
65
 	// 存储最终结果:根key -> 内层配置map
66
 	// 存储最终结果:根key -> 内层配置map
81
 
82
 
82
 		// 扫描行数据
83
 		// 扫描行数据
83
 		if err := rows.Scan(valuePtrs...); err != nil {
84
 		if err := rows.Scan(valuePtrs...); err != nil {
84
-			return createErrorResult(fmt.Sprintf("Scan row %d failed: %v", count, err), startTime, reqCtx)
85
+			return myservice.CreateErrorResult[map[string]interface{}](fmt.Sprintf("Scan row %d failed: %v", count, err), startTime, reqCtx)
85
 		}
86
 		}
86
 
87
 
87
 		// 提取当前行的三个核心字段
88
 		// 提取当前行的三个核心字段
108
 		// 解析 detailID 获取根key(倒数第3段)
109
 		// 解析 detailID 获取根key(倒数第3段)
109
 		parts := strings.Split(detailID, ".")
110
 		parts := strings.Split(detailID, ".")
110
 		if len(parts) < 3 {
111
 		if len(parts) < 3 {
111
-			return createErrorResult(fmt.Sprintf("Row %d detailID format error: %s", count, detailID), startTime, reqCtx)
112
+			return myservice.CreateErrorResult[map[string]interface{}](fmt.Sprintf("Row %d detailID format error: %s", count, detailID), startTime, reqCtx)
112
 		}
113
 		}
113
 
114
 
114
 		rootKey := parts[len(parts)-3] // 取倒数第3段,例如 "database"
115
 		rootKey := parts[len(parts)-3] // 取倒数第3段,例如 "database"
127
 
128
 
128
 	// 检查行遍历错误
129
 	// 检查行遍历错误
129
 	if err := rows.Err(); err != nil {
130
 	if err := rows.Err(); err != nil {
130
-		return createErrorResult(fmt.Sprintf("Row iteration error: %v", err), startTime, reqCtx)
131
+		return myservice.CreateErrorResult[map[string]interface{}](fmt.Sprintf("Row iteration error: %v", err), startTime, reqCtx)
131
 	}
132
 	}
132
 
133
 
133
 	// 构建成功结果
134
 	// 构建成功结果
140
 	return result
141
 	return result
141
 }
142
 }
142
 
143
 
143
-// createErrorResult 创建错误结果的辅助函数(复用你提供的)
144
-func createErrorResult(errorMsg string, startTime time.Time, reqCtx *ctx.RequestContext) *types.QueryResult[map[string]interface{}] {
145
-	logger.ErrorC(reqCtx, errorMsg)
146
-	return &types.QueryResult[map[string]interface{}]{
147
-		Success:  false,
148
-		Error:    errorMsg,
149
-		Time:     time.Since(startTime).String(),
150
-		Metadata: reqCtx,
151
-	}
152
-}
153
-
154
 // 辅助函数:转换为字符串
144
 // 辅助函数:转换为字符串
155
 func toString(v interface{}) string {
145
 func toString(v interface{}) string {
156
 	switch val := v.(type) {
146
 	switch val := v.(type) {

+ 3
- 3
tables/config_template.go Bestand weergeven

9
 		tb := sqldef.NewTable("config_template", "配置模版").
9
 		tb := sqldef.NewTable("config_template", "配置模版").
10
 			ID("config_template_id", 128).NotNull().Comment("主键ID").End().
10
 			ID("config_template_id", 128).NotNull().Comment("主键ID").End().
11
 			String("template_name", 64).NotNull().Comment("模版名称").End().
11
 			String("template_name", 64).NotNull().Comment("模版名称").End().
12
-			String("yaml_root_key", 32).NotNull().Comment("YAML配置的根节点名称").End().
12
+			//String("yaml_root_key", 32).NotNull().Comment("YAML配置的根节点名称").End().
13
 			//String("service_type", 32).Comment("适用服务类型,如:auth/order/payment").End().
13
 			//String("service_type", 32).Comment("适用服务类型,如:auth/order/payment").End().
14
 			Bool("is_default").NotNull().Default("0").Comment("是否默认模版").End().
14
 			Bool("is_default").NotNull().Default("0").Comment("是否默认模版").End().
15
 			Int("sort_order").NotNull().Default("0").Comment("排序号,小的在前").End().
15
 			Int("sort_order").NotNull().Default("0").Comment("排序号,小的在前").End().
19
 			DateTime("updated_at").Default("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP").Comment("更新时间").End()
19
 			DateTime("updated_at").Default("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP").Comment("更新时间").End()
20
 
20
 
21
 		// 添加索引
21
 		// 添加索引
22
-		tb.AddIndex("idx_type_code", "yaml_root_key")
22
+		//tb.AddIndex("idx_type_code", "yaml_root_key")
23
 		//AddIndex("idx_service_type", "service_type").
23
 		//AddIndex("idx_service_type", "service_type").
24
-		//AddIndex("idx_sort_order", "sort_order")
24
+		tb.AddIndex("idx_sort_order", "sort_order")
25
 		//AddUniqueIndex("uk_name_type", "template_name", "yaml_root_key")
25
 		//AddUniqueIndex("uk_name_type", "template_name", "yaml_root_key")
26
 
26
 
27
 		// 注册表
27
 		// 注册表

+ 73
- 0
test/my_init_template_test.go Bestand weergeven

1
+package main
2
+
3
+import (
4
+	"fmt"
5
+	"log"
6
+	"testing"
7
+
8
+	"git.x2erp.com/qdy/go-base/types"
9
+	"git.x2erp.com/qdy/go-db/factory/http"
10
+)
11
+
12
+func TestInit(t *testing.T) {
13
+	// 记录总开始时间
14
+	//totalStartTime := time.Now()
15
+
16
+	// 1. 获取HTTP工厂实例
17
+	httpFactory, err := http.GetHTTPFactory()
18
+	if err != nil {
19
+		t.Fatalf("Failed to get HTTP factory: %v", err)
20
+	}
21
+	fmt.Println("HTTP factory created successfully")
22
+
23
+	// 7. 获取Doris工厂实例
24
+	//dorisFactory1, err := doris.GetDorisFactory(httpFactory)
25
+	if err != nil {
26
+		t.Fatalf("Failed to get Doris factory: %v", err)
27
+	}
28
+	//fmt.Println("Doris factory created successfully")
29
+
30
+	// 获取Doris配置
31
+	//cfg, err := config.GetConfig()
32
+	if err != nil {
33
+		t.Fatalf("failed to load config: %v", err)
34
+		return
35
+	}
36
+
37
+	queryParams := []interface{}{
38
+		"dev",
39
+		"svc-worker",
40
+	}
41
+	// 准备查询请求
42
+	queryRequest := types.QueryRequest{
43
+
44
+		PositionalParams: queryParams,
45
+	}
46
+
47
+	httpClient := httpFactory.CreateClient()
48
+	// 发送POST请求到 /api/query/csv 获取CSV格式数据
49
+	resp, err := httpClient.PostWithAuth(
50
+		"http://localhost:8080/api/init/config/template",
51
+		queryRequest,
52
+		"123", // Bearer Token
53
+		nil,
54
+	)
55
+
56
+	if err != nil {
57
+		csvData := string(resp.Body())
58
+		log.Printf("查询失败:%v", err)
59
+		log.Printf("csvData--err:%s", csvData)
60
+
61
+		return
62
+	}
63
+
64
+	if resp.StatusCode() != 200 {
65
+		log.Printf("\n 询请求失败, 状态码: %d", resp.StatusCode())
66
+	}
67
+
68
+	// 获取CSV数据
69
+	csvData := string(resp.Body())
70
+
71
+	log.Printf("\n csvData:%s", csvData)
72
+
73
+}

+ 1
- 1
test/my_post_query_test.go Bestand weergeven

25
 	if err != nil {
25
 	if err != nil {
26
 		t.Fatalf("Failed to get Doris factory: %v", err)
26
 		t.Fatalf("Failed to get Doris factory: %v", err)
27
 	}
27
 	}
28
-	fmt.Println("Doris factory created successfully")
28
+	//fmt.Println("Doris factory created successfully")
29
 
29
 
30
 	// 获取Doris配置
30
 	// 获取Doris配置
31
 	//cfg, err := config.GetConfig()
31
 	//cfg, err := config.GetConfig()

Laden…
Annuleren
Opslaan