Browse Source

建立表字典sdk

qdy 3 weeks ago
parent
commit
90ff20b1e1

+ 3
- 3
config/subconfigs/configure_config.go View File

@@ -10,7 +10,7 @@ import (
10 10
 type ConfigureConfig struct {
11 11
 	core.BaseConfig
12 12
 	Url   string `yaml:"url" desc:"配置中心地址"`
13
-	token string `yaml:"token" desc:"访问配置中心的token"`
13
+	Token string `yaml:"token" desc:"访问配置中心的token"`
14 14
 }
15 15
 
16 16
 func (c *ConfigureConfig) Description() string {
@@ -22,8 +22,8 @@ func NewConfgigureConfig() *ConfigureConfig {
22 22
 }
23 23
 
24 24
 func (c *ConfigureConfig) SetDefaults() {
25
-	c.Url = "http://localhost:8000"
26
-	c.token = "123"
25
+	c.Url = "http://localhost:8080"
26
+	c.Token = "123"
27 27
 }
28 28
 
29 29
 func (c *ConfigureConfig) Load(data map[string]interface{}) error {

+ 246
- 0
sdk/configure/client.go View File

@@ -0,0 +1,246 @@
1
+package configure
2
+
3
+import (
4
+	"bytes"
5
+	"context"
6
+	"encoding/json"
7
+	"fmt"
8
+	"io"
9
+	"net/http"
10
+	"strings"
11
+	"time"
12
+
13
+	"git.x2erp.com/qdy/go-base/model/response"
14
+)
15
+
16
+// Client 配置中心客户端
17
+type Client struct {
18
+	config     ClientConfig
19
+	httpClient *http.Client
20
+}
21
+
22
+// ResponseWrapper 包装API响应
23
+type ResponseWrapper[T any] struct {
24
+	response.QueryResult[T]
25
+}
26
+
27
+// NewClient 创建新的配置中心客户端
28
+func NewClient() (*Client, error) {
29
+	config := DefaultConfig()
30
+	return NewClientWithConfig(config)
31
+}
32
+
33
+// NewClientWithConfig 使用自定义配置创建客户端
34
+func NewClientWithConfig(config ClientConfig) (*Client, error) {
35
+	// 验证配置
36
+	if err := config.Validate(); err != nil {
37
+		return nil, err
38
+	}
39
+
40
+	// 创建HTTP客户端
41
+	httpClient := &http.Client{
42
+		Timeout: config.HTTPTimeout,
43
+	}
44
+
45
+	return &Client{
46
+		config:     config,
47
+		httpClient: httpClient,
48
+	}, nil
49
+}
50
+
51
+// NewBasicAuthClient 创建使用Basic认证的客户端
52
+func NewBasicAuthClient(baseURL, username, password string) (*Client, error) {
53
+	config := ClientConfig{
54
+		BaseURL:     baseURL,
55
+		AuthType:    AuthTypeBasic,
56
+		Username:    username,
57
+		Password:    password,
58
+		HTTPTimeout: 30 * time.Second,
59
+	}
60
+
61
+	return NewClientWithConfig(config)
62
+}
63
+
64
+// NewTokenAuthClient 创建使用Token认证的客户端
65
+func NewTokenAuthClient(baseURL, token string) (*Client, error) {
66
+	config := ClientConfig{
67
+		BaseURL:     baseURL,
68
+		AuthType:    AuthTypeToken,
69
+		Token:       token,
70
+		HTTPTimeout: 30 * time.Second,
71
+	}
72
+
73
+	return NewClientWithConfig(config)
74
+}
75
+
76
+// ListTables 查询数据库表字典列表
77
+func (c *Client) ListTables(ctx context.Context, query *DicTableQueryRequest) (*DicTableList, error) {
78
+	endpoint := "/api/dic-table/list"
79
+
80
+	var result ResponseWrapper[[]DicTableDB]
81
+	if err := c.doRequest(ctx, http.MethodPost, endpoint, query, &result); err != nil {
82
+		return nil, err
83
+	}
84
+
85
+	if !result.Success {
86
+		return nil, NewClientError("list_tables", fmt.Sprintf("API error: %s", result.Error), nil)
87
+	}
88
+
89
+	return &DicTableList{
90
+		TotalCount: result.TotalCount,
91
+		LastPage:   result.LastPage,
92
+		Data:       result.Data,
93
+	}, nil
94
+}
95
+
96
+// GetTable 查询数据库表字典详情
97
+func (c *Client) GetTable(ctx context.Context, tableID string) (*DicTableDetail, error) {
98
+	endpoint := fmt.Sprintf("/api/dic-table/detail/%s", tableID)
99
+
100
+	var result ResponseWrapper[DicTableDetail]
101
+	if err := c.doRequest(ctx, http.MethodPost, endpoint, nil, &result); err != nil {
102
+		return nil, err
103
+	}
104
+
105
+	if !result.Success {
106
+		// 检查是否是"未找到"错误
107
+		if result.Error == "not found" ||
108
+			result.Error == "数据库表字典不存在" ||
109
+			result.Error == "查询数据库表字典主表失败: sql: no rows in result set" ||
110
+			result.Error == "查询数据库表字典主表失败: context canceled" {
111
+			return nil, ErrNotFound
112
+		}
113
+		// 检查是否是context取消错误
114
+		if result.Error == "查询数据库表字典主表失败: context canceled" ||
115
+			strings.Contains(result.Error, "context canceled") ||
116
+			strings.Contains(result.Error, "context deadline exceeded") {
117
+			return nil, WrapError("get_table", "context canceled", nil)
118
+		}
119
+		return nil, NewClientError("get_table", fmt.Sprintf("API error: %s", result.Error), nil)
120
+	}
121
+
122
+	return &result.Data, nil
123
+}
124
+
125
+// SaveTable 创建或更新数据库表字典
126
+func (c *Client) SaveTable(ctx context.Context, req *DicTableRequest) (*DicTableDetail, error) {
127
+	endpoint := "/api/dic-table/save"
128
+
129
+	var result ResponseWrapper[DicTableDetail]
130
+	if err := c.doRequest(ctx, http.MethodPost, endpoint, req, &result); err != nil {
131
+		return nil, err
132
+	}
133
+
134
+	if !result.Success {
135
+		return nil, NewClientError("save_table", fmt.Sprintf("API error: %s", result.Error), nil)
136
+	}
137
+
138
+	return &result.Data, nil
139
+}
140
+
141
+// DeleteTable 删除数据库表字典
142
+func (c *Client) DeleteTable(ctx context.Context, tableID string) error {
143
+	endpoint := fmt.Sprintf("/api/dic-table/delete/%s", tableID)
144
+
145
+	var result ResponseWrapper[int64]
146
+	if err := c.doRequest(ctx, http.MethodPost, endpoint, nil, &result); err != nil {
147
+		return err
148
+	}
149
+
150
+	if !result.Success {
151
+		return NewClientError("delete_table", fmt.Sprintf("API error: %s", result.Error), nil)
152
+	}
153
+
154
+	return nil
155
+}
156
+
157
+// doRequest 执行HTTP请求
158
+func (c *Client) doRequest(ctx context.Context, method, endpoint string, body interface{}, result interface{}) error {
159
+	// 构建URL
160
+	url := c.config.BaseURL + endpoint
161
+
162
+	// 准备请求体
163
+	var requestBody io.Reader
164
+	if body != nil {
165
+		jsonData, err := json.Marshal(body)
166
+		if err != nil {
167
+			return WrapError("do_request", "failed to marshal request body", err)
168
+		}
169
+		requestBody = bytes.NewBuffer(jsonData)
170
+	}
171
+
172
+	// 创建请求
173
+	req, err := http.NewRequestWithContext(ctx, method, url, requestBody)
174
+	if err != nil {
175
+		return WrapError("do_request", "failed to create request", err)
176
+	}
177
+
178
+	// 设置认证头
179
+	if err := c.setAuthHeader(req); err != nil {
180
+		return err
181
+	}
182
+
183
+	// 设置内容类型
184
+	// 对于POST、PUT、PATCH方法,即使body为nil也设置Content-Type
185
+	if body != nil || method == http.MethodPost || method == http.MethodPut || method == http.MethodPatch {
186
+		req.Header.Set("Content-Type", "application/json")
187
+	}
188
+
189
+	// 执行请求
190
+	resp, err := c.httpClient.Do(req)
191
+	if err != nil {
192
+		if ctx.Err() == context.DeadlineExceeded {
193
+			return ErrRequestTimeout
194
+		}
195
+		return WrapError("do_request", "HTTP request failed", err)
196
+	}
197
+	defer resp.Body.Close()
198
+
199
+	// 读取响应体
200
+	respBody, err := io.ReadAll(resp.Body)
201
+	if err != nil {
202
+		return WrapError("do_request", "failed to read response body", err)
203
+	}
204
+
205
+	// 检查HTTP状态码
206
+	if resp.StatusCode != http.StatusOK {
207
+		switch resp.StatusCode {
208
+		case http.StatusUnauthorized:
209
+			return ErrUnauthorized
210
+		case http.StatusForbidden:
211
+			return ErrForbidden
212
+		case http.StatusNotFound:
213
+			return ErrNotFound
214
+		case http.StatusBadRequest:
215
+			return ErrValidationFailed
216
+		default:
217
+			return NewClientError("do_request",
218
+				fmt.Sprintf("HTTP error %d: %s", resp.StatusCode, string(respBody)), nil)
219
+		}
220
+	}
221
+
222
+	// 解析响应
223
+	if err := json.Unmarshal(respBody, result); err != nil {
224
+		return WrapError("do_request", "failed to unmarshal response", err)
225
+	}
226
+
227
+	return nil
228
+}
229
+
230
+// setAuthHeader 设置认证头
231
+func (c *Client) setAuthHeader(req *http.Request) error {
232
+	switch c.config.AuthType {
233
+	case AuthTypeBasic:
234
+		req.SetBasicAuth(c.config.Username, c.config.Password)
235
+	case AuthTypeToken:
236
+		req.Header.Set("Authorization", "Bearer "+c.config.Token)
237
+	default:
238
+		return ErrConfigInvalidAuthType
239
+	}
240
+	return nil
241
+}
242
+
243
+// GetConfig 获取客户端配置
244
+func (c *Client) GetConfig() ClientConfig {
245
+	return c.config
246
+}

+ 72
- 0
sdk/configure/config.go View File

@@ -0,0 +1,72 @@
1
+package configure
2
+
3
+import (
4
+	"time"
5
+
6
+	"git.x2erp.com/qdy/go-base/config"
7
+)
8
+
9
+// AuthType 认证类型
10
+type AuthType string
11
+
12
+const (
13
+	// AuthTypeBasic Basic认证
14
+	AuthTypeBasic AuthType = "basic"
15
+	// AuthTypeToken Token认证
16
+	AuthTypeToken AuthType = "token"
17
+)
18
+
19
+// ClientConfig 客户端配置
20
+type ClientConfig struct {
21
+	// BaseURL 配置中心基础URL
22
+	BaseURL string `json:"baseURL" yaml:"baseURL"`
23
+
24
+	// AuthType 认证类型
25
+	AuthType AuthType `json:"authType" yaml:"authType"`
26
+
27
+	// Basic认证配置
28
+	Username string `json:"username,omitempty" yaml:"username,omitempty"`
29
+	Password string `json:"password,omitempty" yaml:"password,omitempty"`
30
+
31
+	// Token认证配置
32
+	Token string `json:"token,omitempty" yaml:"token,omitempty"`
33
+
34
+	// HTTP配置
35
+	HTTPTimeout time.Duration `json:"httpTimeout,omitempty" yaml:"httpTimeout,omitempty"`
36
+	Insecure    bool          `json:"insecure,omitempty" yaml:"insecure,omitempty"`
37
+}
38
+
39
+// DefaultConfig 返回默认配置
40
+// 从全局配置中获取ConfigureConfig的URL和Token
41
+func DefaultConfig() ClientConfig {
42
+	cfg := config.GetConfigureConfig()
43
+	return ClientConfig{
44
+		BaseURL:     cfg.Url,
45
+		AuthType:    AuthTypeToken,
46
+		Token:       cfg.Token,
47
+		HTTPTimeout: 30 * time.Second,
48
+		Insecure:    false,
49
+	}
50
+}
51
+
52
+// Validate 验证配置
53
+func (c *ClientConfig) Validate() error {
54
+	if c.BaseURL == "" {
55
+		return ErrConfigInvalidURL
56
+	}
57
+
58
+	switch c.AuthType {
59
+	case AuthTypeBasic:
60
+		if c.Username == "" || c.Password == "" {
61
+			return ErrConfigInvalidAuth
62
+		}
63
+	case AuthTypeToken:
64
+		if c.Token == "" {
65
+			return ErrConfigInvalidAuth
66
+		}
67
+	default:
68
+		return ErrConfigInvalidAuthType
69
+	}
70
+
71
+	return nil
72
+}

+ 69
- 0
sdk/configure/doc.go View File

@@ -0,0 +1,69 @@
1
+// Package configure 提供配置中心客户端的SDK,支持数据库字典的增删改查操作。
2
+//
3
+// 主要功能:
4
+//   - 数据库表字典的创建、查询、更新、删除
5
+//   - 支持Basic认证和Token认证
6
+//   - 自动从全局配置加载配置中心地址和token
7
+//   - 完整的错误处理和类型安全
8
+//
9
+// 快速开始:
10
+//
11
+//	// 使用默认配置(从全局config获取)
12
+//	client, err := configure.NewClient()
13
+//	if err != nil {
14
+//	    log.Fatal(err)
15
+//	}
16
+//
17
+//	// 查询数据库表字典列表
18
+//	query := &configure.DicTableQueryRequest{
19
+//	    QueryRequest: queryreq.QueryRequest{
20
+//	        Page:     0,
21
+//	        PageSize: 10,
22
+//	    },
23
+//	}
24
+//
25
+//	result, err := client.ListTables(context.Background(), query)
26
+//	if err != nil {
27
+//	    log.Fatal(err)
28
+//	}
29
+//
30
+//	// 创建数据库表字典
31
+//	req := &configure.DicTableRequest{
32
+//	    TableID:     "test_table_001",
33
+//	    TableType:   "实体表",
34
+//	    Name:        "测试表",
35
+//	    Description: "测试表描述",
36
+//	    Fields: []configure.DicTableFieldRequest{
37
+//	        {
38
+//	            FieldID:     "test_table_001.id",
39
+//	            TableID:     "test_table_001",
40
+//	            FiledType:   "实际字段",
41
+//	            DataType:    "数值型",
42
+//	            FieldName:   "id",
43
+//	            FieldNameCN: "主键ID",
44
+//	            Description: "主键字段",
45
+//	        },
46
+//	    },
47
+//	}
48
+//
49
+//	detail, err := client.SaveTable(context.Background(), req)
50
+//	if err != nil {
51
+//	    log.Fatal(err)
52
+//	}
53
+//
54
+// 配置说明:
55
+//
56
+// 客户端支持两种认证方式:
57
+//   - Basic认证:使用用户名和密码
58
+//   - Token认证:使用Bearer token
59
+//
60
+// 配置可以从以下方式获取:
61
+//   - 全局配置:通过config.GetConfigureConfig()获取配置中心地址和token
62
+//   - 自定义配置:通过NewClientWithConfig()传入自定义配置
63
+//
64
+// API端点:
65
+//   - POST /api/dic-table/list     - 查询数据库表字典列表
66
+//   - POST /api/dic-table/detail/{table_id} - 查询数据库表字典详情
67
+//   - POST /api/dic-table/save     - 创建或更新数据库表字典
68
+//   - POST /api/dic-table/delete/{table_id} - 删除数据库表字典
69
+package configure

+ 72
- 0
sdk/configure/errors.go View File

@@ -0,0 +1,72 @@
1
+package configure
2
+
3
+import (
4
+	"fmt"
5
+)
6
+
7
+// ClientError SDK客户端错误
8
+type ClientError struct {
9
+	Op      string // 操作名称
10
+	Message string // 错误信息
11
+	Err     error  // 底层错误
12
+}
13
+
14
+// Error 实现error接口
15
+func (e *ClientError) Error() string {
16
+	if e.Err != nil {
17
+		return fmt.Sprintf("configure client error [%s]: %s: %v", e.Op, e.Message, e.Err)
18
+	}
19
+	return fmt.Sprintf("configure client error [%s]: %s", e.Op, e.Message)
20
+}
21
+
22
+// Unwrap 实现错误解包
23
+func (e *ClientError) Unwrap() error {
24
+	return e.Err
25
+}
26
+
27
+// 错误定义
28
+var (
29
+	// 配置错误
30
+	ErrConfigInvalidURL      = &ClientError{Op: "config", Message: "invalid URL"}
31
+	ErrConfigInvalidAuth     = &ClientError{Op: "config", Message: "invalid authentication credentials"}
32
+	ErrConfigInvalidAuthType = &ClientError{Op: "config", Message: "invalid authentication type"}
33
+
34
+	// 请求错误
35
+	ErrRequestFailed   = &ClientError{Op: "request", Message: "HTTP request failed"}
36
+	ErrRequestTimeout  = &ClientError{Op: "request", Message: "request timeout"}
37
+	ErrInvalidResponse = &ClientError{Op: "request", Message: "invalid response format"}
38
+
39
+	// API错误
40
+	ErrAPIError         = &ClientError{Op: "api", Message: "API returned error"}
41
+	ErrNotFound         = &ClientError{Op: "api", Message: "resource not found"}
42
+	ErrAlreadyExists    = &ClientError{Op: "api", Message: "resource already exists"}
43
+	ErrUnauthorized     = &ClientError{Op: "api", Message: "unauthorized"}
44
+	ErrForbidden        = &ClientError{Op: "api", Message: "forbidden"}
45
+	ErrValidationFailed = &ClientError{Op: "api", Message: "validation failed"}
46
+
47
+	// 客户端错误
48
+	ErrClientNotInitialized = &ClientError{Op: "client", Message: "client not initialized"}
49
+)
50
+
51
+// NewClientError 创建新的客户端错误
52
+func NewClientError(op, message string, err error) *ClientError {
53
+	return &ClientError{
54
+		Op:      op,
55
+		Message: message,
56
+		Err:     err,
57
+	}
58
+}
59
+
60
+// WrapError 包装错误为客户端错误
61
+func WrapError(op, message string, err error) error {
62
+	if err == nil {
63
+		return nil
64
+	}
65
+
66
+	// 如果已经是ClientError,直接返回
67
+	if ce, ok := err.(*ClientError); ok {
68
+		return ce
69
+	}
70
+
71
+	return NewClientError(op, message, err)
72
+}

+ 217
- 0
sdk/configure/example.go View File

@@ -0,0 +1,217 @@
1
+// Package configure 使用示例
2
+//
3
+// 以下示例演示如何使用配置中心客户端SDK
4
+package configure
5
+
6
+import (
7
+	"context"
8
+	"fmt"
9
+	"log"
10
+	"time"
11
+
12
+	"git.x2erp.com/qdy/go-base/model/request/queryreq"
13
+)
14
+
15
+// ExampleUsage 演示SDK的基本用法
16
+func ExampleUsage() {
17
+	// 示例1:创建客户端
18
+	exampleCreateClient()
19
+
20
+	// 示例2:查询列表
21
+	exampleListTables()
22
+
23
+	// 示例3:创建表
24
+	exampleSaveTable()
25
+
26
+	// 示例4:查询详情
27
+	exampleGetTable()
28
+
29
+	// 示例5:删除表
30
+	exampleDeleteTable()
31
+}
32
+
33
+func exampleCreateClient() {
34
+	fmt.Println("=== 示例1:创建客户端 ===")
35
+
36
+	// 方法1:使用默认配置
37
+	client1, err := NewClient()
38
+	if err != nil {
39
+		log.Printf("Failed to create default client: %v", err)
40
+	} else {
41
+		fmt.Printf("Default client created: URL=%s\n", client1.GetConfig().BaseURL)
42
+	}
43
+
44
+	// 方法2:使用Basic认证
45
+	if _, err := NewBasicAuthClient("http://localhost:8080", "admin", "123"); err != nil {
46
+		log.Printf("Failed to create basic auth client: %v", err)
47
+	} else {
48
+		fmt.Println("Basic auth client created")
49
+	}
50
+
51
+	// 方法3:使用Token认证
52
+	if _, err := NewTokenAuthClient("http://localhost:8080", "your-token-here"); err != nil {
53
+		log.Printf("Failed to create token auth client: %v", err)
54
+	} else {
55
+		fmt.Println("Token auth client created")
56
+	}
57
+
58
+	fmt.Println()
59
+}
60
+
61
+func exampleListTables() {
62
+	fmt.Println("=== 示例2:查询数据库表字典列表 ===")
63
+
64
+	// 创建客户端
65
+	client, err := NewBasicAuthClient("http://localhost:8080", "admin", "123")
66
+	if err != nil {
67
+		log.Printf("Failed to create client: %v", err)
68
+		return
69
+	}
70
+
71
+	// 创建查询请求
72
+	query := &DicTableQueryRequest{
73
+		QueryRequest: queryreq.QueryRequest{
74
+			Page:     0,
75
+			PageSize: 10,
76
+		},
77
+	}
78
+
79
+	// 执行查询
80
+	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
81
+	defer cancel()
82
+
83
+	result, err := client.ListTables(ctx, query)
84
+	if err != nil {
85
+		log.Printf("Error listing tables: %v", err)
86
+		return
87
+	}
88
+
89
+	fmt.Printf("Total tables: %d\n", result.TotalCount)
90
+	fmt.Printf("Last page: %d\n", result.LastPage)
91
+	fmt.Println()
92
+}
93
+
94
+func exampleSaveTable() {
95
+	fmt.Println("=== 示例3:创建数据库表字典 ===")
96
+
97
+	// 创建客户端
98
+	client, err := NewBasicAuthClient("http://localhost:8080", "admin", "123")
99
+	if err != nil {
100
+		log.Printf("Failed to create client: %v", err)
101
+		return
102
+	}
103
+
104
+	// 创建请求
105
+	req := &DicTableRequest{
106
+		TableID:     "example_table_001",
107
+		TableType:   "实体表",
108
+		Name:        "示例表001",
109
+		Description: "这是一个示例表",
110
+		Creator:     "admin",
111
+		CreatedAt:   time.Now(),
112
+		UpdatedAt:   time.Now(),
113
+		Fields: []DicTableFieldRequest{
114
+			{
115
+				FieldID:     "example_table_001.id",
116
+				TableID:     "example_table_001",
117
+				FiledType:   "实际字段",
118
+				DataType:    "数值型",
119
+				FieldName:   "id",
120
+				FieldNameCN: "主键ID",
121
+				Description: "主键字段",
122
+				Creator:     "admin",
123
+				CreatedAt:   time.Now(),
124
+				UpdatedAt:   time.Now(),
125
+			},
126
+			{
127
+				FieldID:     "example_table_001.name",
128
+				TableID:     "example_table_001",
129
+				FiledType:   "实际字段",
130
+				DataType:    "字符型",
131
+				FieldName:   "name",
132
+				FieldNameCN: "名称",
133
+				Description: "名称字段",
134
+				Creator:     "admin",
135
+				CreatedAt:   time.Now(),
136
+				UpdatedAt:   time.Now(),
137
+			},
138
+		},
139
+	}
140
+
141
+	// 执行保存
142
+	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
143
+	defer cancel()
144
+
145
+	detail, err := client.SaveTable(ctx, req)
146
+	if err != nil {
147
+		log.Printf("Error saving table: %v", err)
148
+		return
149
+	}
150
+
151
+	fmt.Printf("Table saved successfully: %s\n", detail.Table.TableID)
152
+	fmt.Printf("Table name: %s\n", detail.Table.Name)
153
+	fmt.Printf("Number of fields: %d\n", len(detail.Fields))
154
+	fmt.Println()
155
+}
156
+
157
+func exampleGetTable() {
158
+	fmt.Println("=== 示例4:查询数据库表字典详情 ===")
159
+
160
+	// 创建客户端
161
+	client, err := NewBasicAuthClient("http://localhost:8080", "admin", "123")
162
+	if err != nil {
163
+		log.Printf("Failed to create client: %v", err)
164
+		return
165
+	}
166
+
167
+	// 查询表详情
168
+	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
169
+	defer cancel()
170
+
171
+	tableID := "example_table_001"
172
+	detail, err := client.GetTable(ctx, tableID)
173
+	if err != nil {
174
+		if err == ErrNotFound {
175
+			fmt.Printf("Table %s not found\n", tableID)
176
+		} else {
177
+			log.Printf("Error getting table: %v", err)
178
+		}
179
+		return
180
+	}
181
+
182
+	fmt.Printf("Table ID: %s\n", detail.Table.TableID)
183
+	fmt.Printf("Table Type: %s\n", detail.Table.TableType)
184
+	fmt.Printf("Name: %s\n", detail.Table.Name)
185
+	fmt.Printf("Description: %s\n", detail.Table.Description)
186
+	fmt.Printf("Creator: %s\n", detail.Table.Creator)
187
+	fmt.Printf("Fields count: %d\n", len(detail.Fields))
188
+	fmt.Println()
189
+}
190
+
191
+func exampleDeleteTable() {
192
+	fmt.Println("=== 示例5:删除数据库表字典 ===")
193
+
194
+	// 创建客户端
195
+	client, err := NewBasicAuthClient("http://localhost:8080", "admin", "123")
196
+	if err != nil {
197
+		log.Printf("Failed to create client: %v", err)
198
+		return
199
+	}
200
+
201
+	// 删除表
202
+	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
203
+	defer cancel()
204
+
205
+	tableID := "example_table_001"
206
+	if err := client.DeleteTable(ctx, tableID); err != nil {
207
+		if err == ErrNotFound {
208
+			fmt.Printf("Table %s not found\n", tableID)
209
+		} else {
210
+			log.Printf("Error deleting table: %v", err)
211
+		}
212
+		return
213
+	}
214
+
215
+	fmt.Printf("Table %s deleted successfully\n", tableID)
216
+	fmt.Println()
217
+}

+ 92
- 0
sdk/configure/types.go View File

@@ -0,0 +1,92 @@
1
+package configure
2
+
3
+import (
4
+	"time"
5
+
6
+	"git.x2erp.com/qdy/go-base/model/request/queryreq"
7
+)
8
+
9
+// DicTableRequest 数据库表字典请求(主表+子表合并)
10
+type DicTableRequest struct {
11
+	// 主表字段
12
+	TableID     string `json:"tableID" binding:"required"`   // 表ID(主键)
13
+	TableType   string `json:"tableType" binding:"required"` // 表类型: 实体表,视图,物化视图
14
+	Name        string `json:"name" binding:"required"`      // 表名称
15
+	Description string `json:"description"`                  // 表描述
16
+
17
+	// 子表字段(字段列表)
18
+	Fields []DicTableFieldRequest `json:"fields"` // 表字段列表
19
+
20
+	// 系统字段(创建时自动填充)
21
+	Creator   string    `json:"creator,omitempty"`   // 创建人
22
+	CreatedAt time.Time `json:"createdAt,omitempty"` // 创建时间
23
+	UpdatedAt time.Time `json:"updatedAt,omitempty"` // 更新时间
24
+}
25
+
26
+// DicTableFieldRequest 数据库表字段字典请求(子表)
27
+type DicTableFieldRequest struct {
28
+	// 注意:子表主键规则为 table_id + "." + field_name
29
+	FieldID     string `json:"fieldID" binding:"required"`   // 字段ID(主键,由系统生成)
30
+	TableID     string `json:"tableID" binding:"required"`   // 表ID(关联主表)
31
+	FiledType   string `json:"filedType" binding:"required"` // 字段类型: 实际字段,计算字段
32
+	DataType    string `json:"dataType" binding:"required"`  // 数据类型: 字符型,数值型等
33
+	FieldName   string `json:"fieldName" binding:"required"` // 字段名称
34
+	FieldNameCN string `json:"fieldNameCN"`                  // 字段中文名称(ERP中业务名称)
35
+	Description string `json:"description"`                  // 字段描述
36
+
37
+	// 系统字段(创建时自动填充)
38
+	Creator   string    `json:"creator,omitempty"`   // 创建人
39
+	CreatedAt time.Time `json:"createdAt,omitempty"` // 创建时间
40
+	UpdatedAt time.Time `json:"updatedAt,omitempty"` // 更新时间
41
+}
42
+
43
+// DicTableDetail 数据库表字典详情(主表+子表)
44
+type DicTableDetail struct {
45
+	// 主表信息
46
+	Table DicTableDB `json:"table"`
47
+
48
+	// 子表信息
49
+	Fields []DicTableFieldDB `json:"fields"`
50
+}
51
+
52
+// DicTableList 数据库表字典列表
53
+type DicTableList struct {
54
+	TotalCount int          `json:"totalCount"`
55
+	LastPage   int          `json:"lastPage"`
56
+	Data       []DicTableDB `json:"data"`
57
+}
58
+
59
+// DicTableQueryRequest 数据库表字典查询请求
60
+type DicTableQueryRequest struct {
61
+	QueryRequest queryreq.QueryRequest `json:"queryRequest"`
62
+	TableID      string                `json:"tableID,omitempty"`
63
+}
64
+
65
+// DicTableDB 数据库表字典数据库模型
66
+type DicTableDB struct {
67
+	ID          string     `db:"id" json:"id"`
68
+	TableID     string     `db:"table_id" json:"tableID"`
69
+	TableType   string     `db:"table_type" json:"tableType"`
70
+	Name        string     `db:"table_name" json:"name"`
71
+	Description string     `db:"description" json:"description"`
72
+	Creator     string     `db:"creator" json:"creator"`
73
+	CreatedAt   time.Time  `db:"created_at" json:"createdAt"`
74
+	UpdatedAt   time.Time  `db:"updated_at" json:"updatedAt"`
75
+	DeletedAt   *time.Time `db:"deleted_at" json:"deletedAt"`
76
+}
77
+
78
+// DicTableFieldDB 数据库表字段字典数据库模型
79
+type DicTableFieldDB struct {
80
+	ID          string     `db:"id" json:"id"`
81
+	FieldID     string     `db:"field_id" json:"fieldID"`
82
+	TableID     string     `db:"table_id" json:"tableID"`
83
+	FiledType   string     `db:"filed_type" json:"filedType"`
84
+	DataType    string     `db:"data_type" json:"dataType"`
85
+	FieldName   string     `db:"field_name" json:"fieldName"`
86
+	FieldNameCN string     `db:"field_name_cn" json:"fieldNameCN"`
87
+	Description string     `db:"description" json:"description"`
88
+	Creator     string     `db:"creator" json:"creator"`
89
+	CreatedAt   time.Time  `db:"created_at" json:"createdAt"`
90
+	UpdatedAt   time.Time  `db:"updated_at" json:"updatedAt"`
91
+	DeletedAt   *time.Time `db:"deleted_at" json:"deletedAt"`
92
+}

+ 163
- 0
test_sdk.go View File

@@ -0,0 +1,163 @@
1
+package main
2
+
3
+import (
4
+	"context"
5
+	"fmt"
6
+	"log"
7
+	"time"
8
+
9
+	"git.x2erp.com/qdy/go-base/model/request/queryreq"
10
+	"git.x2erp.com/qdy/go-base/sdk/configure"
11
+)
12
+
13
+func main() {
14
+	fmt.Println("Testing Configure SDK...")
15
+
16
+	// 1. 测试创建客户端
17
+	client, err := configure.NewBasicAuthClient("http://localhost:8080", "admin", "123")
18
+	if err != nil {
19
+		log.Fatalf("Failed to create client: %v", err)
20
+	}
21
+	fmt.Printf("Client created successfully: URL=%s\n", client.GetConfig().BaseURL)
22
+
23
+	// 2. 测试查询列表
24
+	fmt.Println("\nTesting ListTables...")
25
+	query := &configure.DicTableQueryRequest{
26
+		QueryRequest: queryreq.QueryRequest{
27
+			Page:     0,
28
+			PageSize: 10,
29
+		},
30
+	}
31
+
32
+	ctx1, cancel1 := context.WithTimeout(context.Background(), 10*time.Second)
33
+	defer cancel1()
34
+
35
+	result, err := client.ListTables(ctx1, query)
36
+	if err != nil {
37
+		log.Fatalf("Failed to list tables: %v", err)
38
+	}
39
+
40
+	fmt.Printf("ListTables success: TotalCount=%d, LastPage=%d\n", result.TotalCount, result.LastPage)
41
+	fmt.Printf("Tables count: %d\n", len(result.Data))
42
+
43
+	// 3. 测试创建表
44
+	fmt.Println("\nTesting SaveTable...")
45
+	req := &configure.DicTableRequest{
46
+		TableID:     "sdk_test_table_001",
47
+		TableType:   "实体表",
48
+		Name:        "SDK测试表001",
49
+		Description: "SDK集成测试表",
50
+		Creator:     "admin",
51
+		CreatedAt:   time.Now(),
52
+		UpdatedAt:   time.Now(),
53
+		Fields: []configure.DicTableFieldRequest{
54
+			{
55
+				FieldID:     "sdk_test_table_001.id",
56
+				TableID:     "sdk_test_table_001",
57
+				FiledType:   "实际字段",
58
+				DataType:    "数值型",
59
+				FieldName:   "id",
60
+				FieldNameCN: "主键ID",
61
+				Description: "SDK测试主键字段",
62
+				Creator:     "admin",
63
+				CreatedAt:   time.Now(),
64
+				UpdatedAt:   time.Now(),
65
+			},
66
+			{
67
+				FieldID:     "sdk_test_table_001.name",
68
+				TableID:     "sdk_test_table_001",
69
+				FiledType:   "实际字段",
70
+				DataType:    "字符型",
71
+				FieldName:   "name",
72
+				FieldNameCN: "名称",
73
+				Description: "SDK测试名称字段",
74
+				Creator:     "admin",
75
+				CreatedAt:   time.Now(),
76
+				UpdatedAt:   time.Now(),
77
+			},
78
+		},
79
+	}
80
+
81
+	ctx2, cancel2 := context.WithTimeout(context.Background(), 10*time.Second)
82
+	defer cancel2()
83
+
84
+	detail, err := client.SaveTable(ctx2, req)
85
+	if err != nil {
86
+		log.Fatalf("Failed to save table: %v", err)
87
+	}
88
+
89
+	fmt.Printf("SaveTable success: TableID=%s, Name=%s, Fields=%d\n",
90
+		detail.Table.TableID, detail.Table.Name, len(detail.Fields))
91
+
92
+	// 4. 测试查询详情
93
+	fmt.Println("\nTesting GetTable...")
94
+	ctx3, cancel3 := context.WithTimeout(context.Background(), 10*time.Second)
95
+	defer cancel3()
96
+
97
+	tableDetail, err := client.GetTable(ctx3, "sdk_test_table_001")
98
+	if err != nil {
99
+		log.Fatalf("Failed to get table: %v", err)
100
+	}
101
+
102
+	fmt.Printf("GetTable success: TableID=%s, Description=%s\n",
103
+		tableDetail.Table.TableID, tableDetail.Table.Description)
104
+	fmt.Printf("Fields in detail: %d\n", len(tableDetail.Fields))
105
+
106
+	// 5. 测试更新表
107
+	fmt.Println("\nTesting UpdateTable...")
108
+	ctx4, cancel4 := context.WithTimeout(context.Background(), 10*time.Second)
109
+	defer cancel4()
110
+
111
+	req.Description = "更新后的SDK测试表描述"
112
+	req.Name = "更新后的SDK测试表001"
113
+	req.UpdatedAt = time.Now()
114
+
115
+	// 添加一个新字段
116
+	req.Fields = append(req.Fields, configure.DicTableFieldRequest{
117
+		FieldID:     "sdk_test_table_001.status",
118
+		TableID:     "sdk_test_table_001",
119
+		FiledType:   "实际字段",
120
+		DataType:    "字符型",
121
+		FieldName:   "status",
122
+		FieldNameCN: "状态",
123
+		Description: "SDK测试状态字段",
124
+		Creator:     "admin",
125
+		CreatedAt:   time.Now(),
126
+		UpdatedAt:   time.Now(),
127
+	})
128
+
129
+	updatedDetail, err := client.SaveTable(ctx4, req)
130
+	if err != nil {
131
+		log.Fatalf("Failed to update table: %v", err)
132
+	}
133
+
134
+	fmt.Printf("UpdateTable success: Description=%s, Fields=%d\n",
135
+		updatedDetail.Table.Description, len(updatedDetail.Fields))
136
+
137
+	// 6. 测试删除表
138
+	fmt.Println("\nTesting DeleteTable...")
139
+	ctx5, cancel5 := context.WithTimeout(context.Background(), 10*time.Second)
140
+	defer cancel5()
141
+
142
+	if err := client.DeleteTable(ctx5, "sdk_test_table_001"); err != nil {
143
+		log.Fatalf("Failed to delete table: %v", err)
144
+	}
145
+
146
+	fmt.Println("DeleteTable success")
147
+
148
+	// 7. 验证删除
149
+	fmt.Println("\nVerifying deletion...")
150
+	ctx6, cancel6 := context.WithTimeout(context.Background(), 10*time.Second)
151
+	defer cancel6()
152
+
153
+	_, err = client.GetTable(ctx6, "sdk_test_table_001")
154
+	if err == configure.ErrNotFound {
155
+		fmt.Println("Table deleted successfully (NotFound error as expected)")
156
+	} else if err != nil {
157
+		fmt.Printf("Unexpected error: %v\n", err)
158
+	} else {
159
+		fmt.Println("ERROR: Table still exists after deletion!")
160
+	}
161
+
162
+	fmt.Println("\nAll tests passed!")
163
+}

Loading…
Cancel
Save