k3cloud-sdk 0.4.7 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f4e97bc6484eec7584bfcc9de98131e7151ed09a76dfc2b3ea8eb4baa9a4e096
4
- data.tar.gz: 57e7395a941904011c00aba90008850ff5fbb369e9a108e7cee9d2cfb673f48b
3
+ metadata.gz: ac60c158c0d8bb63fa78e7412f1a7207ce7317f6bbaa1cbe751556740987770d
4
+ data.tar.gz: 8ab6ad5bff05101523fc21ac786d4c7611713bc5283f0cce6e6dd2ea61b5c030
5
5
  SHA512:
6
- metadata.gz: b3d2691366e94a654ba597e65c87dcfa441392ca01bd68130384b682d3a265d2d6ed3608e5585d0c46633b13ddfb7d774bcc50f93d538b0b55dd96b75d87e7bf
7
- data.tar.gz: adb88e87428a8dab018f2aa98bd3da3f1cd294f0d78b448c26f9cc4b4b7ad0441ab2e8e0fa6d4a44c2ac72eaad78df119de076b1fc0930db6c48ae2bce11fb6c
6
+ metadata.gz: '01281a40210d978bdda71290370b0e05a1504ee23f923ab54935e2858e6e66c5ae56ade375f9d674fb077d755fa043091208a4e681045aa9d9acc02befc2170f'
7
+ data.tar.gz: da96968ea62312e524f5abe5bad731506a23b07221060e6aef64751c653bbbd4ae45e8ae6e44f5240567858fa6a20e4bbca92ef831d50e2b4a37a493ba744260
data/.rubocop.yml CHANGED
@@ -1,5 +1,13 @@
1
1
  AllCops:
2
- TargetRubyVersion: 2.0
2
+ TargetRubyVersion: 2.5
3
+ NewCops: enable
4
+ SuggestExtensions: false
5
+ Exclude:
6
+ - "**/*.md"
7
+ - "ChangeLog*"
8
+ - "CHANGELOG*"
9
+ - "vendor/**/*"
10
+ - "pkg/**/*"
3
11
 
4
12
  Style/StringLiterals:
5
13
  Enabled: true
@@ -11,3 +19,40 @@ Style/StringLiteralsInInterpolation:
11
19
 
12
20
  Layout/LineLength:
13
21
  Max: 120
22
+
23
+ # 本仓库既有签名/加密逻辑偏过程式,文档与度量类 cops 放宽以避免大改业务逻辑。
24
+ Style/Documentation:
25
+ Enabled: false
26
+
27
+ Gemspec/RequireMFA:
28
+ Enabled: true
29
+
30
+ Style/FormatStringToken:
31
+ Enabled: false
32
+
33
+ Style/FormatString:
34
+ EnforcedStyle: format
35
+
36
+ Naming/FileName:
37
+ Exclude:
38
+ - "lib/k3cloud-sdk.rb"
39
+
40
+ Metrics/AbcSize:
41
+ Max: 40
42
+
43
+ Metrics/MethodLength:
44
+ Max: 30
45
+
46
+ Metrics/BlockLength:
47
+ Exclude:
48
+ - "spec/**/*"
49
+ - "k3cloud.gemspec"
50
+
51
+ Metrics/CyclomaticComplexity:
52
+ Max: 12
53
+
54
+ Metrics/ParameterLists:
55
+ Max: 10
56
+
57
+ Metrics/ClassLength:
58
+ Max: 150
data/CHANGELOG.md CHANGED
@@ -1,5 +1,121 @@
1
- ## [Unreleased]
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.6.0]
9
+
10
+ ### Added
11
+
12
+ - 请求重试:`Configuration#retry_max` / `retry_interval` / `retry_backoff`,仅对超时与 5xx 生效,默认重试 3 次指数退避。
13
+ - trace 日志:DEBUG 级记录每次请求的耗时(`elapsed_ms`)、状态码、重试次数、响应字节数。
14
+ - 单据查询分页封装 `execute_bill_query_all(data, limit:)`,自动按 `StartRow`/`Limit` 拉取全部单据。
15
+ - 配置校验:必填字段缺失时抛出 `K3cloud::ConfigurationError`,给出友好提示。
16
+ - 新增 `SECURITY.md` 漏洞上报流程与安全说明。
17
+
18
+ ### Changed
19
+
20
+ - 默认启用请求重试(`retry_max` 默认 3,原 0.5.0 不重试);如需保持不重试请设 `retry_max = 0`。
21
+ - `verify_ssl` 文档明确仅 https 生效(http URL 自动跳过)。
22
+ - 日志调用统一为字符串:text 模式输出干净字符串,json 模式包装为 `{msg, level, time}`。
23
+ - `handle_query_result` 错误识别更鲁棒:兼容顶层 Hash 与行内任意列含 `Message`/`InnerExWrapper`/`InnerException` 的错误对象。
24
+ - `WebApiClient#url_path` 对非 http(s) URL 抛 `ArgumentError`,避免签名错误。
25
+ - gemspec 启用 `metadata["rubygems_mfa_required"] = "true"`,提升发布安全。
26
+ - 异常与日志消息英文化。
27
+ - README 重写为英文,按目录组织并标注全部可调用方法。
28
+
29
+ ## [0.5.0] - 2026-07-17
30
+
31
+ ### ⚠ Breaking Changes
32
+
33
+ - 最低 Ruby 版本提升至 `>= 2.5.0`。
34
+ - 默认启用 HTTPS 证书校验;私有云 https 自签证书需显式设置 `Configuration#verify_ssl = false`。
35
+ - `Configuration` 为 `lcid`、`connect_timeout`(30s)、`request_timeout`(60s)、`verify_ssl` 提供默认值。
36
+ - 工具类与常量迁移至 `K3cloud` 命名空间(`K3cloud::Base64Utils`、`K3cloud::MD5Utils`、`K3cloud::ConstDefine`),不再保留无命名空间别名。
37
+ - `Http` 构造参数改为关键字参数。
38
+
39
+ ### Security
40
+
41
+ - 构造签名头失败时不再静默返回空 header,改为抛出异常。
42
+ - 签名密钥为空时 `MD5Utils.hash_mac` 改为抛出 `ArgumentError`。
43
+ - `K3cloudError.parse` 对空索引做判空保护,避免 `NoMethodError`。
44
+
45
+ ### Fixed
46
+
47
+ - 修复 `MD5Utils.encrypt` 在 Ruby 下始终返回空字符串的 bug。
48
+ - 修复公有云请求 URL 出现双斜杠的问题。
49
+
50
+ ### Added
51
+
52
+ - 日志输出支持可配置格式:`Configuration#log_format` 取 `:text`(默认,常规 Logger 格式)或 `:json`(每行一个 JSON,便于采集与检索)。
53
+ - 支持注入自定义 logger(`K3cloud.logger = Rails.logger`)与重建默认 logger(`K3cloud.reset_logger!`)。
54
+
55
+ ## [0.4.7] - 2025-02-18
56
+
57
+ ### Fixed
58
+
59
+ - 修复 `execute_bill_query` 查询成功时误返回空数组、丢失业务数据的问题。
60
+
61
+ ## [0.4.6] - 2025-02-18
62
+
63
+ ### Fixed
64
+
65
+ - 修复 `execute_bill_query` 在空结果时误判为错误的问题。
66
+
67
+ ## [0.4.5] - 2025-02-18
68
+
69
+ ### Changed
70
+
71
+ - 自定义错误类型统一改为抛出 `K3cloud::ResponseError`。
72
+ - `execute_bill_query` 增加对错误返回结构的识别:当首行首列为 Hash 时记录日志并返回空数组。
73
+ - User-Agent 携带 SDK 版本与运行环境信息。
74
+
75
+ ## [0.4.4] - 2024-07-19
76
+
77
+ ### Added
78
+
79
+ - HTTP 请求超时自动重试(最多 5 次,间隔 5 秒)。
80
+
81
+ ## [0.4.3] - 2023-11-29
82
+
83
+ ### Added
84
+
85
+ - 新增统一异常类 `K3cloud::ResponseError`、`K3cloud::K3cloudError`。
86
+
87
+ ## [0.4.2] - 2023-11-29
88
+
89
+ ### Fixed
90
+
91
+ - 修复非 200/206 响应被误判为失败的问题(`response.code` 为字符串比较恒为假)。
92
+
93
+ ## [0.4.1] - 2023-11-28
94
+
95
+ ### Changed
96
+
97
+ - HTTP 请求失败时改为抛出异常,不再静默返回 `nil`。
98
+
99
+ ## [0.4.0] - 2023-11-17
100
+
101
+ ### Changed
102
+
103
+ - 兼容更低版本 Ruby 语法。
104
+
105
+ ## [0.3.0] - 2023-11-14
106
+
107
+ ### Added
108
+
109
+ - 多账号配置支持:通过 `K3cloud.new_api(config)` 创建多账号客户端实例。
110
+
111
+ ## [0.2.0] - 2023-10-09
112
+
113
+ ### Fixed
114
+
115
+ - 修复入口文件大小写问题导致部分平台上 `require "k3cloud-sdk"` 失败。
2
116
 
3
117
  ## [0.1.0] - 2023-09-26
4
118
 
5
- - Initial release
119
+ ### Added
120
+
121
+ - 初始版本:封装金蝶云星空 OpenApi,涵盖暂存/保存/提交/审核/查看/查询/删除/下推/分配等单据操作及附件、工作流、报表等共 26 个业务方法。
data/Gemfile CHANGED
@@ -6,5 +6,9 @@ source "https://rubygems.org"
6
6
  gemspec
7
7
 
8
8
  gem "rake", "~> 13.0"
9
-
10
9
  gem "rspec", "~> 3.0"
10
+ gem "rubocop", require: false
11
+ gem "webmock", "~> 3.0", group: :test
12
+ # Ruby 3.x: base64 became a bundled gem, declare explicitly so vendored bundle resolves it.
13
+ gem "base64", require: false
14
+ gem "json", require: false
data/Gemfile.lock CHANGED
@@ -1,13 +1,35 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- k3cloud-sdk (0.4.7)
4
+ k3cloud-sdk (0.6.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
+ addressable (2.9.0)
10
+ public_suffix (>= 2.0.2, < 8.0)
11
+ ast (2.4.3)
12
+ base64 (0.3.0)
13
+ bigdecimal (4.1.2)
14
+ crack (1.0.1)
15
+ bigdecimal
16
+ rexml
9
17
  diff-lcs (1.5.0)
18
+ hashdiff (1.2.1)
19
+ json (2.21.1)
20
+ language_server-protocol (3.17.0.6)
21
+ lint_roller (1.1.0)
22
+ parallel (2.1.0)
23
+ parser (3.3.12.0)
24
+ ast (~> 2.4.1)
25
+ racc
26
+ prism (1.9.0)
27
+ public_suffix (7.0.5)
28
+ racc (1.8.1)
29
+ rainbow (3.1.1)
10
30
  rake (13.0.6)
31
+ regexp_parser (2.12.0)
32
+ rexml (3.4.4)
11
33
  rspec (3.12.0)
12
34
  rspec-core (~> 3.12.0)
13
35
  rspec-expectations (~> 3.12.0)
@@ -21,15 +43,42 @@ GEM
21
43
  diff-lcs (>= 1.2.0, < 2.0)
22
44
  rspec-support (~> 3.12.0)
23
45
  rspec-support (3.12.1)
46
+ rubocop (1.88.2)
47
+ json (~> 2.3)
48
+ language_server-protocol (~> 3.17.0.2)
49
+ lint_roller (~> 1.1.0)
50
+ parallel (>= 1.10)
51
+ parser (>= 3.3.0.2)
52
+ rainbow (>= 2.2.2, < 4.0)
53
+ regexp_parser (>= 2.9.3, < 3.0)
54
+ rubocop-ast (>= 1.49.0, < 2.0)
55
+ ruby-progressbar (~> 1.7)
56
+ unicode-display_width (>= 2.4.0, < 4.0)
57
+ rubocop-ast (1.50.0)
58
+ parser (>= 3.3.7.2)
59
+ prism (~> 1.7)
60
+ ruby-progressbar (1.13.0)
61
+ unicode-display_width (3.2.0)
62
+ unicode-emoji (~> 4.1)
63
+ unicode-emoji (4.2.0)
64
+ webmock (3.26.2)
65
+ addressable (>= 2.8.0)
66
+ crack (>= 0.3.2)
67
+ hashdiff (>= 0.4.0, < 2.0.0)
24
68
 
25
69
  PLATFORMS
26
70
  arm64-darwin-22
27
71
  arm64-darwin-23
72
+ arm64-darwin-25
28
73
 
29
74
  DEPENDENCIES
75
+ base64
76
+ json
30
77
  k3cloud-sdk!
31
78
  rake (~> 13.0)
32
79
  rspec (~> 3.0)
80
+ rubocop
81
+ webmock (~> 3.0)
33
82
 
34
83
  BUNDLED WITH
35
84
  2.4.14
data/README.md CHANGED
@@ -1,9 +1,33 @@
1
- # K3cloud-sdk
2
- Ruby Gem for K3cloud OpenApi that uses cryptographic signature technology to avoid plaintext transmission of keys and enables automatic login.
1
+ # K3cloud SDK
2
+
3
+ Ruby Gem for Kingdee K3Cloud OpenApi. Uses cryptographic signature technology
4
+ to avoid plaintext transmission of keys and supports automatic login.
5
+
6
+ ## Table of Contents
7
+
8
+ - [Installation](#installation)
9
+ - [Configuration](#configuration)
10
+ - [Single Account](#single-account)
11
+ - [Multi Account](#multi-account)
12
+ - [Optional Settings](#optional-settings)
13
+ - [Error Handling](#error-handling)
14
+ - [In Scheduled Jobs](#in-scheduled-jobs-sidekiq--cron--rake)
15
+ - [Available API Methods](#available-api-methods)
16
+ - [Bill Operations](#bill-operations)
17
+ - [Query Operations](#query-operations)
18
+ - [Group Operations](#group-operations)
19
+ - [Attachment Operations](#attachment-operations)
20
+ - [Metadata & Report Operations](#metadata--report-operations)
21
+ - [Workflow & Organization Operations](#workflow--organization-operations)
22
+ - [Logger](#logger)
23
+ - [Development](#development)
24
+ - [Contributing](#contributing)
25
+ - [License](#license)
26
+ - [Code of Conduct](#code-of-conduct)
3
27
 
4
28
  ## Installation
5
29
 
6
- Install the gem and add to the Rails application's Gemfile by executing:
30
+ Install the gem and add it to a Rails application's Gemfile:
7
31
 
8
32
  $ bundle add k3cloud-sdk
9
33
 
@@ -11,81 +35,251 @@ If bundler is not being used to manage dependencies, install the gem by executin
11
35
 
12
36
  $ gem install k3cloud-sdk
13
37
 
14
- ## Usage
38
+ ## Configuration
15
39
 
16
- #### 1. Single Account Configuration:
17
- You'll need to configure it in `config/initializers/k3cloud.rb`:
40
+ ### Single Account
41
+
42
+ Configure it in `config/initializers/k3cloud.rb`:
18
43
 
19
44
  ```ruby
20
- K3cloud.configure do |config|
21
- config.acct_id = ENV['K3CLOUD_ACCT_ID']
22
- config.user_name = ENV['K3CLOUD_USERNAME']
23
- config.app_id = ENV['K3CLOUD_APP_ID']
24
- config.app_secret = ENV['K3CLOUD_APP_SECRET']
25
- config.server_url = ENV['K3CLOUD_SERVER_URL']
26
- end
45
+ K3cloud.configure do |config|
46
+ config.acct_id = ENV["K3CLOUD_ACCT_ID"]
47
+ config.user_name = ENV["K3CLOUD_USERNAME"]
48
+ config.app_id = ENV["K3CLOUD_APP_ID"]
49
+ config.app_secret = ENV["K3CLOUD_APP_SECRET"]
50
+ config.server_url = ENV["K3CLOUD_SERVER_URL"] # blank for public cloud
51
+ end
27
52
  ```
28
53
 
29
- Then you can call the k3cloud API using the following code:
54
+ Then call the K3Cloud API directly:
55
+
30
56
  ```ruby
31
- data = {
32
- FormId: "",
33
- FieldKeys: "",
34
- FilterString: ""
35
- }
36
- K3cloud.execute_bill_query(data)
57
+ data = {
58
+ FormId: "PRD_MO",
59
+ FieldKeys: "FMaterialId.FNumber, FNoStockInQty",
60
+ FilterString: "FStatus not in (6, 7)"
61
+ }
62
+ K3cloud.execute_bill_query(data)
37
63
  ```
38
64
 
39
- #### 2. Multi Account Configuration:
40
- You'll need to configure it in `config/initializers/k3cloud.rb`:
65
+ ### Multi Account
66
+
67
+ Create multiple `K3cloud::Configuration` instances and build clients for each:
41
68
 
42
69
  ```ruby
43
- config1 = K3cloud::Configuration.new do |c|
44
- c.acct_id = ENV['K3CLOUD1_ACCT_ID']
45
- c.user_name = ENV['K3CLOUD1_USERNAME']
46
- c.app_id = ENV['K3CLOUD1_APP_ID']
47
- c.app_secret= ENV['K3CLOUD1_APP_SECRET']
48
- c.server_url = ENV['K3CLOUD1_SERVER_URL']
49
- end
70
+ config1 = K3cloud::Configuration.new do |c|
71
+ c.acct_id = ENV["K3CLOUD1_ACCT_ID"]
72
+ c.user_name = ENV["K3CLOUD1_USERNAME"]
73
+ c.app_id = ENV["K3CLOUD1_APP_ID"]
74
+ c.app_secret = ENV["K3CLOUD1_APP_SECRET"]
75
+ c.server_url = ENV["K3CLOUD1_SERVER_URL"]
76
+ end
77
+
78
+ config2 = K3cloud::Configuration.new do |c|
79
+ c.acct_id = ENV["K3CLOUD2_ACCT_ID"]
80
+ c.user_name = ENV["K3CLOUD2_USERNAME"]
81
+ c.app_id = ENV["K3CLOUD2_APP_ID"]
82
+ c.app_secret = ENV["K3CLOUD2_APP_SECRET"]
83
+ c.server_url = ENV["K3CLOUD2_SERVER_URL"]
84
+ end
85
+
86
+ client1 = K3cloud.new_api(config1)
87
+ client2 = K3cloud.new_api(config2)
88
+
89
+ client1.execute_bill_query(data)
90
+ client2.execute_bill_query(data)
91
+ ```
92
+
93
+ ### Optional Settings
94
+
95
+ | Option | Default | Description |
96
+ | --- | --- | --- |
97
+ | `verify_ssl` | `true` | HTTPS certificate verification. Only affects `https` URLs (http URLs skip SSL automatically). Set `false` for private cloud self-signed certificates. |
98
+ | `connect_timeout` | `30` | Connection timeout in seconds. |
99
+ | `request_timeout` | `60` | Request read timeout in seconds. |
100
+ | `retry_max` | `3` | Max retries on timeout / 5xx. `0` disables retry. |
101
+ | `retry_interval` | `1` | First retry interval in seconds, then exponential backoff. |
102
+ | `retry_backoff` | `2` | Backoff multiplier between retries. |
103
+ | `log_format` | `:text` | Logger output format: `:text` or `:json`. |
104
+
105
+ ```ruby
106
+ K3cloud.configure do |config|
107
+ # ... required fields above ...
108
+ config.verify_ssl = true
109
+ config.connect_timeout = 30
110
+ config.request_timeout = 60
111
+ config.retry_max = 3
112
+ config.retry_interval = 1
113
+ config.log_format = :json
114
+ end
115
+ ```
116
+
117
+ ## Error Handling
118
+
119
+ All request failures raise `K3cloud::ResponseError`. A missing or invalid
120
+ configuration raises `K3cloud::ConfigurationError` on the first request. Wrap
121
+ calls accordingly:
122
+
123
+ ```ruby
124
+ begin
125
+ K3cloud.save("PRD_MO", data)
126
+ rescue K3cloud::ConfigurationError => e
127
+ # missing config: app_id / app_secret / acct_id / user_name
128
+ logger.error("Config error: #{e.message}")
129
+ rescue K3cloud::ResponseError => e
130
+ # network or Kingdee business error
131
+ logger.error("Request failed: #{e.message}")
132
+ end
133
+ ```
134
+
135
+ ### In Scheduled Jobs (Sidekiq / cron / rake)
136
+
137
+ The SDK raises `K3cloud::ResponseError` after retries are exhausted. Always
138
+ `rescue` explicitly in scheduled jobs to prevent the exception from bubbling up
139
+ and failing the container/process:
50
140
 
51
- config2 = K3cloud::Configuration.new do |c|
52
- c.acct_id = ENV['K3CLOUD2_ACCT_ID']
53
- c.user_name = ENV['K3CLOUD2_USERNAME']
54
- c.app_id = ENV['K3CLOUD2_APP_ID']
55
- c.app_secret= ENV['K3CLOUD2_APP_SECRET']
56
- c.server_url = ENV['K3CLOUD2_SERVER_URL']
141
+ ```ruby
142
+ class SyncK3cloudJob
143
+ def perform
144
+ rows = K3cloud.execute_bill_query_all({ FormId: "PRD_MO" }, limit: 1000)
145
+ # ... process rows ...
146
+ rescue K3cloud::ConfigurationError => e
147
+ logger.error("[k3cloud] config error: #{e.message}")
148
+ rescue K3cloud::ResponseError => e
149
+ logger.error("[k3cloud] request failed: #{e.message}")
150
+ # Re-raise so the scheduler (e.g. Sidekiq) can retry the job
151
+ raise e
57
152
  end
153
+ end
154
+ ```
155
+
156
+ > Tip: In scheduled jobs, set a small `retry_max` (e.g. 0 or 1) and let the
157
+ > job scheduler decide the next attempt, instead of sleeping inside the SDK
158
+ > and occupying the worker thread. For example:
159
+ > `K3cloud.configure { |c| c.retry_max = 1 }`.
160
+
161
+ ## Available API Methods
162
+
163
+ All methods are available on both:
164
+ - `K3cloud.<method>` — uses the default account (delegates to `K3cloud.default_api`).
165
+ - `K3cloud.new_api(config).<method>` — uses a specific account configuration.
166
+
167
+ ### Bill Operations
168
+
169
+ | Method | Signature | Description |
170
+ | --- | --- | --- |
171
+ | `draft` | `draft(form_id, data)` | Temporarily save a bill (暂存). |
172
+ | `save` | `save(form_id, data)` | Save a bill (保存). |
173
+ | `batch_save` | `batch_save(form_id, data)` | Batch save bills (批量保存). |
174
+ | `submit` | `submit(form_id, data)` | Submit a bill (提交). |
175
+ | `audit` | `audit(form_id, data)` | Audit a bill (审核). |
176
+ | `un_audit` | `un_audit(form_id, data)` | Un-audit a bill (反审核). |
177
+ | `view` | `view(form_id, data)` | View a bill detail (查看). |
178
+ | `delete` | `delete(form_id, data)` | Delete a bill (删除). |
179
+ | `cancel_assign` | `cancel_assign(form_id, data)` | Cancel assignment (撤销). |
180
+ | `push` | `push(form_id, data)` | Push down a bill (下推). |
181
+ | `execute_operation` | `execute_operation(form_id, op_number, data)` | Status transition: close/reopen/void/unvoid etc. (状态转换). |
182
+ | `allocate` | `allocate(form_id, data)` | Allocate a bill (分配). |
183
+ | `cancel_allocate` | `cancel_allocate(form_id, data)` | Cancel allocation (取消分配). |
184
+ | `disassembly` | `disassembly(form_id, data)` | Disassembly operation (拆单). |
185
+ | `flex_save` | `flex_save(form_id, data)` | Flex save (弹性域保存). |
186
+ | `send_msg` | `send_msg(form_id, data)` | Send message (发送消息). |
187
+
188
+ ### Query Operations
189
+
190
+ | Method | Signature | Description |
191
+ | --- | --- | --- |
192
+ | `execute_bill_query` | `execute_bill_query(data)` | Query bills with parameters `{ FormId:, FieldKeys:, FilterString: }` (单据查询). Returns a 2D array; returns `[]` on error. |
193
+ | `execute_bill_query_all` | `execute_bill_query_all(data, limit: 1000)` | Paginated query that fetches **all** bill rows by auto-injecting `StartRow` and `Limit` until a page returns fewer than `limit` rows (分页批量查询). Returns the merged 2D array. |
194
+
195
+ Example:
196
+
197
+ ```ruby
198
+ # Single-page query (you handle pagination manually)
199
+ rows = K3cloud.execute_bill_query(
200
+ FormId: "PRD_MO",
201
+ FieldKeys: "FMaterialId.FNumber, FNoStockInQty",
202
+ FilterString: "FStatus not in (6, 7)",
203
+ StartRow: 0,
204
+ Limit: 100
205
+ )
58
206
 
59
- K3cloud1 = K3cloud.new_api(config1)
60
- K3cloud2 = K3cloud.new_api(config2)
207
+ # Paginated query (SDK handles pagination for you)
208
+ all_rows = K3cloud.execute_bill_query_all(
209
+ { FormId: "PRD_MO", FieldKeys: "FMaterialId.FNumber", FilterString: "" },
210
+ limit: 1000
211
+ )
61
212
  ```
62
213
 
63
- Then you can call the k3cloud API using the following code:
214
+ ### Group Operations
215
+
216
+ | Method | Signature | Description |
217
+ | --- | --- | --- |
218
+ | `group_save` | `group_save(form_id, data)` | Save a group (分组保存). |
219
+ | `query_group_info` | `query_group_info(data)` | Query group info (分组信息查询). |
220
+ | `group_delete` | `group_delete(data)` | Delete a group (分组删除). |
221
+
222
+ ### Attachment Operations
223
+
224
+ | Method | Signature | Description |
225
+ | --- | --- | --- |
226
+ | `attachment_upload` | `attachment_upload(data)` | Upload an attachment (附件上传). |
227
+ | `attachment_download` | `attachment_download(data)` | Download an attachment (附件下载). |
228
+
229
+ ### Metadata & Report Operations
230
+
231
+ | Method | Signature | Description |
232
+ | --- | --- | --- |
233
+ | `query_business_info` | `query_business_info(data)` | Query business metadata (元数据查询). |
234
+ | `get_sys_report_data` | `get_sys_report_data(form_id, data)` | Query system report data (查询报表数据). |
235
+
236
+ ### Workflow & Organization Operations
237
+
238
+ | Method | Signature | Description |
239
+ | --- | --- | --- |
240
+ | `workflow_audit` | `workflow_audit(data)` | Workflow audit (工作流审核). |
241
+ | `switch_org` | `switch_org(data)` | Switch organization (切换组织). |
242
+
243
+ ## Logger
244
+
245
+ By default, logs are written to `$stderr` in plain text. You can switch to
246
+ JSON-per-line format (useful for log aggregation) or inject your own logger.
247
+
64
248
  ```ruby
65
- data = {
66
- FormId: "",
67
- FieldKeys: "",
68
- FilterString: ""
69
- }
70
- K3cloud1.execute_bill_query(data)
71
- K3cloud2.execute_bill_query(data)
249
+ # JSON format
250
+ K3cloud.configure { |c| c.log_format = :json }
251
+ K3cloud.reset_logger! # rebuild the default logger after changing log_format
252
+
253
+ # Inject a custom logger (e.g. Rails.logger)
254
+ K3cloud.logger = Rails.logger
72
255
  ```
73
256
 
74
257
  ## Development
75
258
 
76
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
259
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run
260
+ `rake spec` to run the tests. You can also run `bin/console` for an interactive
261
+ prompt that will allow you to experiment.
77
262
 
78
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
263
+ To install this gem onto your local machine, run `bundle exec rake install`. To
264
+ release a new version, update the version number in `version.rb`, and then run
265
+ `bundle exec rake release`, which will create a git tag for the version, push
266
+ git commits and the created tag, and push the `.gem` file to
267
+ [rubygems.org](https://rubygems.org).
79
268
 
80
269
  ## Contributing
81
270
 
82
- Bug reports and pull requests are welcome on GitHub at https://github.com/zevinto/k3cloud-sdk.
83
- This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/zevinto/k3cloud-sdk/blob/main/CODE_OF_CONDUCT.md).
271
+ Bug reports and pull requests are welcome on GitHub at
272
+ https://github.com/zevinto/k3cloud-sdk. This project is intended to be a safe,
273
+ welcoming space for collaboration, and contributors are expected to adhere to
274
+ the [code of conduct](https://github.com/zevinto/k3cloud-sdk/blob/main/CODE_OF_CONDUCT.md).
84
275
 
85
276
  ## License
86
277
 
87
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
278
+ The gem is available as open source under the terms of the
279
+ [MIT License](https://opensource.org/licenses/MIT).
88
280
 
89
281
  ## Code of Conduct
90
282
 
91
- Everyone interacting in the K3cloud-sdk project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/zevinto/k3cloud-sdk/blob/master/CODE_OF_CONDUCT.md).
283
+ Everyone interacting in the K3cloud-sdk project's codebases, issue trackers,
284
+ chat rooms and mailing lists is expected to follow the
285
+ [code of conduct](https://github.com/zevinto/k3cloud-sdk/blob/main/CODE_OF_CONDUCT.md).
data/k3cloud.gemspec CHANGED
@@ -9,11 +9,17 @@ Gem::Specification.new do |spec|
9
9
  spec.email = ["zevinto@163.com"]
10
10
 
11
11
  spec.summary = "Ruby Gem for K3cloud API."
12
- spec.description = "Ruby Gem for K3cloud OpenApi that uses cryptographic signature technology to avoid plaintext transmission of keys and enables automatic login."
12
+ spec.description = "Ruby Gem for K3cloud OpenApi. Uses cryptographic signature technology to avoid " \
13
+ "plaintext transmission of keys and enables automatic login."
13
14
  spec.homepage = "https://github.com/zevinto/k3cloud-sdk"
14
15
  spec.license = "MIT"
15
- spec.required_ruby_version = ">= 2.0.0"
16
+ spec.required_ruby_version = ">= 2.5.0"
16
17
  spec.metadata["homepage_uri"] = spec.homepage
18
+ spec.metadata["source_code_uri"] = spec.homepage
19
+ spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/CHANGELOG.md"
20
+ spec.metadata["bug_tracker_uri"] = "#{spec.homepage}/issues"
21
+ spec.metadata["rubygems_mfa_required"] = "true"
22
+ # spec.metadata["rubygems_mfa_required"] = "true"
17
23
 
18
24
  # Specify which files should be added to the gem when it is released.
19
25
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.