qdy преди 1 месец
родител
ревизия
1380199a1e
променени са 6 файла, в които са добавени 252 реда и са изтрити 19 реда
  1. 8
    1
      internal/auth/auth_middleware.go
  2. 45
    0
      internal/handler/register_router.go
  3. 50
    0
      internal/model/dim_ business.go
  4. 41
    0
      internal/model/dim_table.go
  5. 61
    0
      internal/model/dim_table_field.go
  6. 47
    18
      main.go

+ 8
- 1
internal/auth/auth_middleware.go Целия файл

@@ -3,11 +3,18 @@ package auth
3 3
 import (
4 4
 	"context"
5 5
 	"net/http"
6
+
7
+	"git.x2erp.com/qdy/go-db/factory/database"
6 8
 )
7 9
 
8 10
 // authMiddleware 验证 Authorization 头和项目 ID 头
9
-func AuthMiddleware(next http.Handler, authToken, projectIDHeader string) http.Handler {
11
+func AuthMiddleware(next http.Handler, dbFactory *database.DBFactory) http.Handler {
12
+
13
+	projectIDHeader := "X-Project-ID"
14
+	authToken := "123"
15
+
10 16
 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
17
+
11 18
 		// 验证 Authorization 头
12 19
 		authHeader := r.Header.Get("Authorization")
13 20
 		if authHeader == "" {

+ 45
- 0
internal/handler/register_router.go Целия файл

@@ -0,0 +1,45 @@
1
+package handler
2
+
3
+import (
4
+	"encoding/json"
5
+	"log"
6
+
7
+	"git.x2erp.com/qdy/go-base/ctx"
8
+	"git.x2erp.com/qdy/go-base/middleware"
9
+	"git.x2erp.com/qdy/go-base/model/response"
10
+	"git.x2erp.com/qdy/go-base/webx/router"
11
+	"git.x2erp.com/qdy/go-db/factory/database"
12
+)
13
+
14
+func RegisterRouter(ws *router.RouterService, dbFactory *database.DBFactory) {
15
+
16
+	// POST示例:Body参数绑定
17
+	ws.POST("/api/tenant/config",
18
+		func(req ctx.RequestContext, reqCtx *ctx.RequestContext) (*response.QueryResult[interface{}], error) {
19
+			log.Print("ctx TenantID:", reqCtx.TenantID)
20
+			//log.Print("mongoDBFactory:", mongoDBFactory.GetConfig().URI)
21
+			//log.Print("dbFactory:", dbFactory.GetDBName())
22
+			jsonBytes, _ := json.Marshal(req)
23
+			log.Printf("TenantConfig :%s", string(jsonBytes))
24
+
25
+			//queryResult, err := dbFactory.InsertOne("tenant_configs", req)
26
+			//log.Print("TenantConfig InsertOne:", queryResult)
27
+			// req 自动从JSON Body绑定
28
+			return nil, nil
29
+		},
30
+	).Use(middleware.JWTAuthMiddleware).Register()
31
+
32
+	// // 您的业务路由
33
+	// ws.POST("/api/query/yaml",
34
+	// 	func() (interface{}, error) {
35
+	// 		return queryYaml(nil) // 需要修改queryYaml函数以获取dbFactory
36
+	// 	},
37
+	// ).Use(middleware.JWTAuthMiddleware).Register()
38
+
39
+	// ws.POST("/api/init/config/template",
40
+	// 	func() (interface{}, error) {
41
+	// 		return initConfigTemplate(nil) // 需要修改initConfigTemplate函数以获取dbFactory
42
+	// 	},
43
+	// ).Use(middleware.JWTAuthMiddleware).Register()
44
+
45
+}

+ 50
- 0
internal/model/dim_ business.go Целия файл

@@ -0,0 +1,50 @@
1
+package model
2
+
3
+import (
4
+	"time"
5
+
6
+	"git.x2erp.com/qdy/go-db/sqldef"
7
+)
8
+
9
+func init() {
10
+	sqldef.AddRegistration(func(r *sqldef.Registry) {
11
+		tb := sqldef.NewTable("dim_business", "业务词典表").
12
+			ID("id", 64).Comment("主键ID").End().
13
+			String("project_id", 8).NotNull().Comment("项目编号").End().
14
+			String("table_name", 64).NotNull().Comment("表名").End().
15
+			String("field_name", 64).NotNull().Comment("字段名称(英文)").End().
16
+			String("business_alias", 128).NotNull().Comment("业务别名").End().
17
+			String("description", 128).Comment("描述").End().
18
+			String("creator", 32).NotNull().Comment("创建人").End().
19
+			DateTime("created_at").NotNull().Default("CURRENT_TIMESTAMP").Comment("创建时间").End().
20
+			DateTime("updated_at").NotNull().Default("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP").Comment("更新时间").End()
21
+
22
+		// 核心唯一索引:同一项目下业务别名必须唯一
23
+		tb.AddUniqueIndex("uk_project_alias", "project_id", "business_alias")
24
+
25
+		// 常用查询索引
26
+		tb.AddIndex("idx_project_table_field", "project_id", "table_name", "field_name")
27
+		tb.AddIndex("idx_standard_name", "standard_cn_name")
28
+		tb.AddIndex("idx_category", "category")
29
+		tb.AddIndex("idx_created_at", "created_at")
30
+
31
+		r.RegisterTable(tb.Build())
32
+	})
33
+}
34
+
35
+// DimBusiness 业务词典结构体
36
+type DimBusiness struct {
37
+	ID            string    `gorm:"column:id;type:varchar(64);primaryKey;comment:主键ID"`
38
+	ProjectID     string    `gorm:"column:project_id;type:varchar(8);not null;index:idx_project_id;comment:项目编号"`
39
+	TableName     string    `gorm:"column:table_name;type:varchar(64);not null;comment:表名"`
40
+	FieldName     string    `gorm:"column:field_name;type:varchar(64);not null;comment:字段名称(英文)"`
41
+	BusinessAlias string    `gorm:"column:business_alias;type:varchar(128);not null;comment:业务别名"`
42
+	Description   string    `gorm:"column:description;type:text;comment:描述"`
43
+	Creator       string    `gorm:"column:creator;type:varchar(32);not null;comment:创建人"`
44
+	CreatedAt     time.Time `gorm:"column:created_at;type:datetime;not null;default:CURRENT_TIMESTAMP;comment:创建时间"`
45
+	UpdatedAt     time.Time `gorm:"column:updated_at;type:datetime;not null;default:CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;comment:更新时间"`
46
+}
47
+
48
+func (DimBusiness) DimBusiness() string {
49
+	return "dim_business"
50
+}

+ 41
- 0
internal/model/dim_table.go Целия файл

@@ -0,0 +1,41 @@
1
+package model
2
+
3
+import (
4
+	"time"
5
+
6
+	"git.x2erp.com/qdy/go-db/sqldef"
7
+)
8
+
9
+func init() {
10
+	sqldef.AddRegistration(func(r *sqldef.Registry) {
11
+		tb := sqldef.NewTable("dim_table", "表字典").
12
+			ID("id", 64).Comment("主键ID").End().
13
+			String("projectId", 8).NotNull().Comment("项目编号").End().
14
+			String("table_name", 64).NotNull().Comment("表名").End().       // 最大64字符
15
+			String("table_name_cn", 128).NotNull().Comment("中文表名").End(). // 中文名可以稍长
16
+			Text("description").Comment("描述").End().
17
+			String("primary_key_field_name", 64).NotNull().Comment("主键字段名").End(). // 修改为64
18
+			String("creator", 32).NotNull().Comment("创建人").End().
19
+			DateTime("created_at").NotNull().Default("CURRENT_TIMESTAMP").Comment("创建时间").End()
20
+		r.RegisterTable(tb.Build())
21
+
22
+		tb.AddIndex("idx_table_name", "table_name")
23
+
24
+	})
25
+}
26
+
27
+// TableRequest 表字典结构体
28
+type DimTable struct {
29
+	ID                  string    `gorm:"column:id;type:varchar(64);primaryKey;comment:主键ID"`
30
+	ProjectId           string    `gorm:"column:project_id;type:varchar(8);not null;comment:项目名称"`
31
+	TableName           string    `gorm:"column:table_name;type:varchar(64);not null;comment:表名"`
32
+	TableNameCN         string    `gorm:"column:table_name_cn;type:varchar(128);not null;comment:中文表名"`
33
+	Description         string    `gorm:"column:description;type:text;comment:描述"`
34
+	PrimaryKeyFieldName string    `gorm:"column:primary_key_field_name;type:varchar(64);not null;comment:主键字段名"`
35
+	Creator             string    `gorm:"column:creator;type:varchar(32);not null;comment:创建人"`
36
+	CreatedAt           time.Time `gorm:"column:created_at;type:datetime;not null;default:CURRENT_TIMESTAMP;comment:创建时间"`
37
+}
38
+
39
+func (DimTable) DimTable() string {
40
+	return "dim_table"
41
+}

+ 61
- 0
internal/model/dim_table_field.go Целия файл

@@ -0,0 +1,61 @@
1
+package model
2
+
3
+import (
4
+	"time"
5
+
6
+	"git.x2erp.com/qdy/go-db/sqldef"
7
+)
8
+
9
+func init() {
10
+	sqldef.AddRegistration(func(r *sqldef.Registry) {
11
+		tb := sqldef.NewTable("dim_table_field", "表字段字典").
12
+			ID("id", 64).Comment("主键ID").End().
13
+			String("project_id", 8).NotNull().Comment("项目编号").End().
14
+			String("table_name", 64).NotNull().Comment("表名").End().
15
+			String("field_name", 64).NotNull().Comment("字段名称(英文)").End().
16
+			String("field_name_cn", 128).NotNull().Comment("字段中文名称").End().
17
+			Text("description").Comment("字段描述").End().
18
+			String("field_type", 64).NotNull().Comment("字段类型(如:varchar, int, datetime等)").End().
19
+			Int("field_length").Comment("字段长度/精度").End().
20
+			Bool("is_primary_key").Default("0").NotNull().Comment("是否为主键(0:否, 1:是)").End().
21
+			Bool("is_nullable").Default("1").NotNull().Comment("是否允许为空(0:否, 1:是)").End().
22
+			Int("decimal_places").Comment("小数位数(对于decimal类型)").End().
23
+			String("creator", 32).NotNull().Comment("创建人").End().
24
+			DateTime("created_at").NotNull().Default("CURRENT_TIMESTAMP").Comment("创建时间").End().
25
+			DateTime("updated_at").NotNull().Default("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP").Comment("更新时间").End()
26
+
27
+		// 添加唯一索引:同一项目下同一表的字段名不能重复
28
+		//tb.AddUniqueIndex("uk_project_table_field", "project_id", "table_name", "field_name")
29
+
30
+		// 添加普通索引,方便查询
31
+		tb.AddIndex("idx_project_id", "project_id")
32
+		tb.AddIndex("idx_table_name", "table_name")
33
+		tb.AddIndex("idx_field_name", "field_name")
34
+		tb.AddIndex("idx_field_name_cn", "field_name_cn")
35
+		tb.AddIndex("idx_description", "description")
36
+
37
+		r.RegisterTable(tb.Build())
38
+	})
39
+}
40
+
41
+// DimTableField 表字段字典结构体
42
+type DimTableField struct {
43
+	ID            string    `gorm:"column:id;type:varchar(64);primaryKey;comment:主键ID"`
44
+	ProjectID     string    `gorm:"column:project_id;type:varchar(8);not null;index:idx_project_id;comment:项目编号"`
45
+	TableName     string    `gorm:"column:table_name;type:varchar(64);not null;index:idx_table_name;comment:表名"`
46
+	FieldName     string    `gorm:"column:field_name;type:varchar(64);not null;comment:字段名称(英文)"`
47
+	FieldNameCN   string    `gorm:"column:field_name_cn;type:varchar(128);not null;comment:字段中文名称"`
48
+	Description   string    `gorm:"column:description;type:text;comment:字段描述"`
49
+	FieldType     string    `gorm:"column:field_type;type:varchar(64);not null;comment:字段类型(如:varchar, int, datetime等)"`
50
+	FieldLength   *int      `gorm:"column:field_length;type:int;comment:字段长度/精度"`
51
+	IsPrimaryKey  bool      `gorm:"column:is_primary_key;type:tinyint(1);not null;default:0;comment:是否为主键(0:否, 1:是)"`
52
+	IsNullable    bool      `gorm:"column:is_nullable;type:tinyint(1);not null;default:1;comment:是否允许为空(0:否, 1:是)"`
53
+	DecimalPlaces *int      `gorm:"column:decimal_places;type:int;comment:小数位数(对于decimal类型)"`
54
+	Creator       string    `gorm:"column:creator;type:varchar(32);not null;comment:创建人"`
55
+	CreatedAt     time.Time `gorm:"column:created_at;type:datetime;not null;default:CURRENT_TIMESTAMP;comment:创建时间"`
56
+	UpdatedAt     time.Time `gorm:"column:updated_at;type:datetime;not null;default:CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;comment:更新时间"`
57
+}
58
+
59
+func (DimTableField) DimTableField() string {
60
+	return "dim_table_field"
61
+}

+ 47
- 18
main.go Целия файл

@@ -3,10 +3,11 @@ package main
3 3
 import (
4 4
 	"log"
5 5
 	"net/http"
6
-	"os"
7 6
 
8 7
 	"git.x2erp.com/qdy/go-svc-mcp/internal/auth"
8
+	"git.x2erp.com/qdy/go-svc-mcp/internal/handler"
9 9
 	"git.x2erp.com/qdy/go-svc-mcp/internal/mcp"
10
+
10 11
 	_ "git.x2erp.com/qdy/go-svc-mcp/internal/tools" // 触发工具自动注册
11 12
 
12 13
 	"git.x2erp.com/qdy/go-base/config"
@@ -14,6 +15,9 @@ import (
14 15
 	"git.x2erp.com/qdy/go-base/ctx"
15 16
 	"git.x2erp.com/qdy/go-base/graceful"
16 17
 	"git.x2erp.com/qdy/go-base/logger"
18
+	"git.x2erp.com/qdy/go-base/webx"
19
+	"git.x2erp.com/qdy/go-base/webx/router"
20
+
17 21
 	"git.x2erp.com/qdy/go-db/factory/database"
18 22
 	mcpsdk "github.com/modelcontextprotocol/go-sdk/mcp"
19 23
 )
@@ -42,6 +46,44 @@ func main() {
42 46
 	dbFactory := container.Create(ctr, database.CreateDBFactory)
43 47
 	dbFactory.TestConnection()
44 48
 
49
+	// 创建mongodb
50
+	//mongoDBFactory := container.Create(ctr, mongodb.CreateFactory)
51
+	//mongoDBFactory.TestConnection()
52
+
53
+	// 创建mcpservice
54
+	mcpServer := createMcpService(cfg, dbFactory)
55
+
56
+	//启用运行日志
57
+	container.Create(ctr, logger.InitRuntimeLogger)
58
+
59
+	//建立httpservice
60
+	webxService := createMHttpService(cfg, dbFactory)
61
+
62
+	//等待关闭
63
+	graceful.WaitForShutdown(cfg.GetServiceConfig().ServiceName, ctr, mcpServer.GetHTTPServer(), webxService.GetServer())
64
+}
65
+
66
+// 创建httpService
67
+func createMHttpService(cfg config.IConfig, dbFactory *database.DBFactory) *webx.WebService {
68
+	//得到webservice服务工厂
69
+	webxFactory := webx.GetWebServiceFactory()
70
+
71
+	//建立hhtpService服务
72
+	webServcie, _ := webxFactory.CreateService(cfg.GetServiceConfig())
73
+
74
+	//建立路由-api
75
+	routerService := router.NewWebService(webServcie.GetRouter())
76
+	//注册路由--api
77
+	handler.RegisterRouter(routerService, dbFactory)
78
+
79
+	//启动服务
80
+	webServcie.Run()
81
+	return webServcie
82
+}
83
+
84
+// createMcpService 创建mcpService
85
+func createMcpService(cfg config.IConfig, dbFactory *database.DBFactory) *mcp.Server {
86
+
45 87
 	// 4. 创建基础请求上下文(可从配置或认证中提取)
46 88
 	baseCtx := &ctx.RequestContext{
47 89
 		TenantID: "default-tenant", // 实际应从认证中间件获取
@@ -54,8 +96,8 @@ func main() {
54 96
 		Description: "MCP 工具服务,提供自动注册发现和依赖注入",
55 97
 		DBFactory:   dbFactory,
56 98
 		BaseCtx:     baseCtx,
57
-		Port:        cfg.GetServiceConfig().Port,
58
-		ServiceName: cfg.GetServiceConfig().ServiceName,
99
+		Port:        cfg.GetMcpServiceConfig().Port,
100
+		ServiceName: cfg.GetMcpServiceConfig().ServiceName,
59 101
 	})
60 102
 	if err != nil {
61 103
 		log.Fatalf("Failed to create MCP server: %v", err)
@@ -65,26 +107,13 @@ func main() {
65 107
 	// 6. 获取 SDK 服务器实例
66 108
 	sdkServer := mcpServer.GetSDKServer()
67 109
 
68
-	// 7. 创建 HTTP 处理器(带验证中间件)
69
-	authToken := os.Getenv("MCP_AUTH_TOKEN")
70
-	if authToken == "" {
71
-		authToken = "123" // 仅用于开发,生产环境必须设置
72
-	}
73
-	projectIDHeader := os.Getenv("MCP_PROJECT_ID_HEADER")
74
-	if projectIDHeader == "" {
75
-		projectIDHeader = "X-Project-ID"
76
-	}
77 110
 	mcpHandler := mcpsdk.NewStreamableHTTPHandler(func(req *http.Request) *mcpsdk.Server {
78 111
 		return sdkServer
79 112
 	}, nil)
80 113
 	// 包装验证中间件
81
-	handler := auth.AuthMiddleware(mcpHandler, authToken, projectIDHeader)
114
+	handler := auth.AuthMiddleware(mcpHandler, dbFactory)
82 115
 
83 116
 	mcpServer.Run(handler)
84 117
 
85
-	//启用运行日志
86
-	container.Create(ctr, logger.InitRuntimeLogger)
87
-
88
-	//等待关闭
89
-	graceful.WaitForShutdown(appName, mcpServer.GetHTTPServer(), ctr)
118
+	return mcpServer
90 119
 }

Loading…
Отказ
Запис