Переглянути джерело

feat(sdk): 初始化管理服务SDK

- 创建客户端结构体并实现基础配置功能
- 添加人员和资源管理服务接口
- 集成操作日志查询功能
- 定义完整的数据模型和参数结构
- 实现HTTP请求和响应处理逻辑
- 配置项目依赖和忽略文件规则
haolongfei 22 годин тому
батько
коміт
8d70d9fd46
7 змінених файлів з 539 додано та 0 видалено
  1. 51 0
      .gitignore
  2. 77 0
      client.go
  3. 7 0
      go.mod
  4. 44 0
      go.sum
  5. 129 0
      manage.go
  6. 198 0
      model.go
  7. 33 0
      operate_log.go

+ 51 - 0
.gitignore

@@ -0,0 +1,51 @@
+# Binaries for programs and plugins
+*.exe
+*.exe~
+*.dll
+*.so
+*.dylib
+
+# Test binary, built with `go test -c`
+*.test
+
+# Output of the go coverage tool, specifically when used with LiteIDE
+*.out
+
+# Dependency directories (remove the comment below to include it)
+# vendor/
+
+# Go workspace file
+go.work
+go.work.sum
+
+# env file
+.env
+.env.local
+.env.*.local
+
+# IDE specific files
+.idea/
+.vscode/
+*.swp
+*.swo
+*~
+.DS_Store
+
+# Build output
+/bin/
+/dist/
+/build/
+
+# Log files
+*.log
+
+# Temporary files
+/tmp/
+/temp/
+*.tmp
+
+# Debug files
+__debug_bin
+
+# OS specific files
+Thumbs.db

+ 77 - 0
client.go

@@ -0,0 +1,77 @@
+package managesdk
+
+import (
+	"fmt"
+	"time"
+
+	"github.com/go-resty/resty/v2"
+)
+
+type Client struct {
+	config *Config
+	http   *resty.Client
+	manage *ManageService
+	opLog  *OperateLogService
+}
+
+func NewClient(config Config) *Client {
+	timeout := 10
+	if config.Timeout > 0 {
+		timeout = config.Timeout
+	}
+
+	baseURL := config.BaseURL
+	if baseURL == "" {
+		switch config.Type {
+		case ServiceTypePerson:
+			baseURL = DefaultPersonBaseURL
+		case ServiceTypeResource:
+			baseURL = DefaultResourceBaseURL
+		default:
+			baseURL = DefaultPersonBaseURL
+		}
+	}
+
+	httpClient := resty.New().
+		SetBaseURL(baseURL).
+		SetTimeout(time.Duration(timeout)*time.Second).
+		SetHeader("Content-Type", "application/json")
+
+	c := &Client{
+		config: &config,
+		http:   httpClient,
+	}
+
+	c.manage = &ManageService{client: c}
+	c.opLog = &OperateLogService{client: c}
+
+	return c
+}
+
+func (c *Client) Type() ServiceType {
+	return c.config.Type
+}
+
+func (c *Client) Manage() *ManageService {
+	return c.manage
+}
+
+func (c *Client) OperateLog() *OperateLogService {
+	return c.opLog
+}
+
+func (c *Client) Version() (map[string]any, error) {
+	var resp VersionResponse
+	_, err := c.http.R().SetResult(&resp).Get("/version")
+	if err != nil {
+		return nil, fmt.Errorf("请求版本接口失败: %w", err)
+	}
+	if !resp.Success {
+		return nil, fmt.Errorf("获取版本失败: %s", resp.Msg)
+	}
+	return resp.Data, nil
+}
+
+func (c *Client) apiV1Path(path string) string {
+	return fmt.Sprintf("/v1%s", path)
+}

+ 7 - 0
go.mod

@@ -0,0 +1,7 @@
+module managesdk
+
+go 1.23.8
+
+require github.com/go-resty/resty/v2 v2.11.0
+
+require golang.org/x/net v0.17.0 // indirect

+ 44 - 0
go.sum

@@ -0,0 +1,44 @@
+github.com/go-resty/resty/v2 v2.11.0 h1:i7jMfNOJYMp69lq7qozJP+bjgzfAzeOhuGlyDrqxT/8=
+github.com/go-resty/resty/v2 v2.11.0/go.mod h1:iiP/OpA0CkcL3IGt1O0+/SIItFUbkkyw5BGXiVdTu+A=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
+golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
+golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
+golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

+ 129 - 0
manage.go

@@ -0,0 +1,129 @@
+package managesdk
+
+import (
+	"fmt"
+)
+
+type ManageService struct {
+	client *Client
+}
+
+func (s *ManageService) getServicePath() string {
+	switch s.client.config.Type {
+	case ServiceTypePerson:
+		return "/person"
+	case ServiceTypeResource:
+		return "/resource"
+	default:
+		return "/person"
+	}
+}
+
+func (s *ManageService) Save(params any) (string, error) {
+	var resp IDResponse
+	_, err := s.client.http.R().
+		SetBody(params).
+		SetResult(&resp).
+		Post(s.client.apiV1Path(s.getServicePath() + "/save"))
+	if err != nil {
+		return "", fmt.Errorf("保存失败: %w", err)
+	}
+	if !resp.Success {
+		return "", fmt.Errorf("保存失败: %s", resp.Msg)
+	}
+	return resp.Data, nil
+}
+
+func (s *ManageService) Query(params any) (*InfosData[map[string]any], error) {
+	var resp InfosResponse[map[string]any]
+	_, err := s.client.http.R().
+		SetBody(params).
+		SetResult(&resp).
+		Post(s.client.apiV1Path(s.getServicePath() + "/query"))
+	if err != nil {
+		return nil, fmt.Errorf("查询列表失败: %w", err)
+	}
+	if !resp.Success {
+		return nil, fmt.Errorf("查询列表失败: %s", resp.Msg)
+	}
+	return &resp.Data, nil
+}
+
+func (s *ManageService) Get(params GetPersonParams) (*map[string]any, error) {
+	var resp InfoResponse[map[string]any]
+	_, err := s.client.http.R().
+		SetQueryParam("id", params.ID).
+		SetResult(&resp).
+		Get(s.client.apiV1Path(s.getServicePath() + "/get"))
+	if err != nil {
+		return nil, fmt.Errorf("查询详情失败: %w", err)
+	}
+	if !resp.Success {
+		return nil, fmt.Errorf("查询详情失败: %s", resp.Msg)
+	}
+	return &resp.Data, nil
+}
+
+func (s *ManageService) Delete(params any) error {
+	var resp MsgResponse
+	_, err := s.client.http.R().
+		SetBody(params).
+		SetResult(&resp).
+		Delete(s.client.apiV1Path(s.getServicePath() + "/delete"))
+	if err != nil {
+		return fmt.Errorf("删除失败: %w", err)
+	}
+	if !resp.Success {
+		return fmt.Errorf("删除失败: %s", resp.Msg)
+	}
+	return nil
+}
+
+func (s *ManageService) Options() ([]map[string]any, error) {
+	var resp InfosResponse[map[string]any]
+	var path string
+	switch s.client.config.Type {
+	case ServiceTypePerson:
+		path = "/person/genders"
+	case ServiceTypeResource:
+		path = "/resource/categories"
+	}
+	_, err := s.client.http.R().
+		SetResult(&resp).
+		Get(s.client.apiV1Path(path))
+	if err != nil {
+		return nil, fmt.Errorf("查询选项列表失败: %w", err)
+	}
+	if !resp.Success {
+		return nil, fmt.Errorf("查询选项列表失败: %s", resp.Msg)
+	}
+	return resp.Data.Infos, nil
+}
+
+func (s *ManageService) States() ([]map[string]any, error) {
+	var resp InfosResponse[map[string]any]
+	_, err := s.client.http.R().
+		SetResult(&resp).
+		Get(s.client.apiV1Path(s.getServicePath() + "/states"))
+	if err != nil {
+		return nil, fmt.Errorf("查询状态列表失败: %w", err)
+	}
+	if !resp.Success {
+		return nil, fmt.Errorf("查询状态列表失败: %s", resp.Msg)
+	}
+	return resp.Data.Infos, nil
+}
+
+func (s *ManageService) PredefinedFields() ([]map[string]any, error) {
+	var resp InfosResponse[map[string]any]
+	_, err := s.client.http.R().
+		SetResult(&resp).
+		Get(s.client.apiV1Path(s.getServicePath() + "/predefined-fields"))
+	if err != nil {
+		return nil, fmt.Errorf("查询预定义字段失败: %w", err)
+	}
+	if !resp.Success {
+		return nil, fmt.Errorf("查询预定义字段失败: %s", resp.Msg)
+	}
+	return resp.Data.Infos, nil
+}

+ 198 - 0
model.go

@@ -0,0 +1,198 @@
+package managesdk
+
+type ServiceType string
+
+const (
+	ServiceTypePerson   ServiceType = "person"
+	ServiceTypeResource ServiceType = "resource"
+)
+
+const (
+	DefaultPersonBaseURL   = "http://10.0.0.210:30684/mbpms/api"
+	DefaultResourceBaseURL = "http://10.0.0.210:30684/mbrms/api"
+)
+
+type Config struct {
+	Type    ServiceType
+	BaseURL string
+	Timeout int
+}
+
+type Response struct {
+	Success bool   `json:"success"`
+	ErrCode int    `json:"errCode"`
+	Msg     string `json:"msg"`
+}
+
+type IDResponse struct {
+	Success bool   `json:"success"`
+	ErrCode int    `json:"errCode"`
+	Msg     string `json:"msg"`
+	Data    string `json:"data"`
+}
+
+type MsgResponse struct {
+	Success bool   `json:"success"`
+	ErrCode int    `json:"errCode"`
+	Msg     string `json:"msg"`
+}
+
+type InfosData[T any] struct {
+	Infos      []T   `json:"infos"`
+	TotalCount int64 `json:"totalCount"`
+}
+
+type InfosResponse[T any] struct {
+	Success bool         `json:"success"`
+	ErrCode int          `json:"errCode"`
+	Msg     string       `json:"msg"`
+	Data    InfosData[T] `json:"data"`
+}
+
+type InfoResponse[T any] struct {
+	Success bool   `json:"success"`
+	ErrCode int    `json:"errCode"`
+	Msg     string `json:"msg"`
+	Data    T      `json:"data"`
+}
+
+type MapResponse struct {
+	Success bool           `json:"success"`
+	ErrCode int            `json:"errCode"`
+	Msg     string         `json:"msg"`
+	Data    map[string]any `json:"data"`
+}
+
+type VersionResponse struct {
+	Success bool           `json:"success"`
+	ErrCode int            `json:"errCode"`
+	Msg     string         `json:"msg"`
+	Data    map[string]any `json:"data"`
+}
+
+type BaseQueryParams struct {
+	PageNo   int `form:"pageNo"`
+	PageSize int `form:"pageSize"`
+}
+
+type PersonInfo struct {
+	ID                   string         `json:"id"`
+	Name                 string         `json:"name"`
+	UserID               string         `json:"userId"`
+	ExtendPropertyValues map[string]any `json:"extendProperties"`
+	TenantID             string         `json:"tenantId"`
+	CreatedTime          string         `json:"createdTime"`
+	LastUpdatedTime      string         `json:"lastUpdatedTime"`
+}
+
+type SavePersonParams struct {
+	ID               string         `json:"id"`
+	Name             string         `json:"name"`
+	UserID           string         `json:"userId"`
+	ExtendProperties map[string]any `json:"extendProperties"`
+	TenantID         string         `json:"tenantId"`
+	OperatorUserName string         `json:"operatorUserName"`
+}
+
+type DeletePersonParams struct {
+	ID               string `form:"id"`
+	OperatorUserName string `form:"operatorUserName"`
+}
+
+type QueryPersonsParams struct {
+	Name                 string         `form:"name"`
+	UserID               string         `form:"userId"`
+	ExtendPropertyValues map[string]any `form:"extendPropertyValues"`
+	TenantID             string         `form:"tenantId"`
+	BaseQueryParams
+}
+
+type GetPersonParams struct {
+	ID string `form:"id"`
+}
+
+type GenderInfo struct {
+	Gender string `json:"gender"`
+	Label  string `json:"label"`
+}
+
+type PersonStateInfo struct {
+	State string `json:"state"`
+	Label string `json:"label"`
+}
+
+type ResourceInfo struct {
+	ID                   string         `json:"id"`
+	Name                 string         `json:"name"`
+	Code                 string         `json:"code"`
+	BusinessType         string         `json:"businessType"`
+	ExtendPropertyValues map[string]any `json:"extendProperties"`
+	TenantID             string         `json:"tenantId"`
+	CreateUserID         string         `json:"createUserId"`
+	LastUpdateUserID     string         `json:"lastUpdateUserId"`
+	CreatedTime          string         `json:"createdTime"`
+	LastUpdatedTime      string         `json:"lastUpdatedTime"`
+}
+
+type SaveResourceParams struct {
+	ID               string         `json:"id"`
+	Name             string         `json:"name"`
+	Code             string         `json:"code"`
+	BusinessType     string         `json:"businessType"`
+	ExtendProperties map[string]any `json:"extendProperties"`
+	TenantID         string         `json:"tenantId"`
+	CreateUserID     string         `json:"createUserId"`
+	UpdateUserID     string         `json:"updateUserId"`
+	OperatorUserName string         `json:"operatorUserName"`
+}
+
+type DeleteResourceParams struct {
+	ID               string `form:"id"`
+	DeleteUserID     string `form:"deleteUserId"`
+	OperatorUserName string `form:"operatorUserName"`
+}
+
+type QueryResourcesParams struct {
+	Name                 string         `form:"name"`
+	BusinessType         string         `form:"businessType"`
+	ExtendPropertyValues map[string]any `form:"extendPropertyValues"`
+	UserID               string         `form:"userId"`
+	QueryMode            string         `form:"queryMode"`
+	CreateUserID         string         `form:"createUserId"`
+	TenantID             string         `form:"tenantId"`
+	BaseQueryParams
+}
+
+type GetResourceParams struct {
+	ID string `form:"id"`
+}
+
+type CategoryInfo struct {
+	Category     string   `json:"category"`
+	ExcludeField []string `json:"excludeField"`
+}
+
+type ResourceStateInfo struct {
+	State string `json:"state"`
+	Label string `json:"label"`
+}
+
+type OperateLogQueryParams struct {
+	Resource     string `form:"resource"`
+	Action       string `form:"action"`
+	OperatorName string `form:"operatorName"`
+	StartTime    string `form:"startTime"`
+	EndTime      string `form:"endTime"`
+	TenantID     string `form:"tenantId"`
+	BaseQueryParams
+}
+
+type OperateLogInfo struct {
+	ID           string `json:"id"`
+	Resource     string `json:"resource"`
+	Action       string `json:"action"`
+	OperatorName string `json:"operatorName"`
+	Content      string `json:"content"`
+	TenantID     string `json:"tenantId"`
+	CreatedTime  string `json:"createdTime"`
+}

+ 33 - 0
operate_log.go

@@ -0,0 +1,33 @@
+package managesdk
+
+import (
+	"fmt"
+)
+
+type OperateLogService struct {
+	client *Client
+}
+
+func (s *OperateLogService) Query(params OperateLogQueryParams) (*InfosData[OperateLogInfo], error) {
+	var resp InfosResponse[OperateLogInfo]
+	_, err := s.client.http.R().
+		SetQueryParams(map[string]string{
+			"resource":     params.Resource,
+			"action":       params.Action,
+			"operatorName": params.OperatorName,
+			"startTime":    params.StartTime,
+			"endTime":      params.EndTime,
+			"tenantId":     params.TenantID,
+			"pageNo":       fmt.Sprintf("%d", params.PageNo),
+			"pageSize":     fmt.Sprintf("%d", params.PageSize),
+		}).
+		SetResult(&resp).
+		Get(s.client.apiV1Path("/operate-log/query"))
+	if err != nil {
+		return nil, fmt.Errorf("查询操作日志失败: %w", err)
+	}
+	if !resp.Success {
+		return nil, fmt.Errorf("查询操作日志失败: %s", resp.Msg)
+	}
+	return &resp.Data, nil
+}